OSDN Git Service

* use nkf_malloc.
[nkf/nkf.git] / nkf.c
1 /** Network Kanji Filter. (PDS Version)
2  ** -*- coding: ISO-2022-JP -*-
3  ************************************************************************
4  ** Copyright (C) 1987, Fujitsu LTD. (Itaru ICHIKAWA)
5  ** \e$BO"Mm@h!'\e(B \e$B!J3t!KIY;NDL8&5f=j!!%=%U%H#38&!!;T@n!!;j\e(B
6  ** \e$B!J\e(BE-Mail Address: ichikawa@flab.fujitsu.co.jp\e$B!K\e(B
7  ** Copyright (C) 1996,1998
8  ** Copyright (C) 2002
9  ** \e$BO"Mm@h!'\e(B \e$BN05eBg3X>pJs9)3X2J\e(B \e$B2OLn\e(B \e$B??<#\e(B  mime/X0208 support
10  ** \e$B!J\e(BE-Mail Address: kono@ie.u-ryukyu.ac.jp\e$B!K\e(B
11  ** \e$BO"Mm@h!'\e(B COW for DOS & Win16 & Win32 & OS/2
12  ** \e$B!J\e(BE-Mail Address: GHG00637@niftyserve.or.p\e$B!K\e(B
13  **
14  **    \e$B$3$N%=!<%9$N$$$+$J$kJ#<L!$2~JQ!$=$@5$b5vBz$7$^$9!#$?$@$7!"\e(B
15  **    \e$B$=$N:]$K$O!"C/$,9W8%$7$?$r<($9$3$NItJ,$r;D$9$3$H!#\e(B
16  **    \e$B:FG[I[$d;(;o$NIUO?$J$I$NLd$$9g$o$;$bI,MW$"$j$^$;$s!#\e(B
17  **    \e$B1DMxMxMQ$b>e5-$KH?$7$J$$HO0O$G5v2D$7$^$9!#\e(B
18  **    \e$B%P%$%J%j$NG[I[$N:]$K$O\e(Bversion message\e$B$rJ]B8$9$k$3$H$r>r7o$H$7$^$9!#\e(B
19  **    \e$B$3$N%W%m%0%i%`$K$D$$$F$OFC$K2?$NJ]>Z$b$7$J$$!"0-$7$+$i$:!#\e(B
20  **
21  **    Everyone is permitted to do anything on this program
22  **    including copying, modifying, improving,
23  **    as long as you don't try to pretend that you wrote it.
24  **    i.e., the above copyright notice has to appear in all copies.
25  **    Binary distribution requires original version messages.
26  **    You don't have to ask before copying, redistribution or publishing.
27  **    THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
28  ***********************************************************************/
29
30 /***********************************************************************
31  * \e$B8=:_!"\e(Bnkf \e$B$O\e(B SorceForge \e$B$K$F%a%s%F%J%s%9$,B3$1$i$l$F$$$^$9!#\e(B
32  * http://sourceforge.jp/projects/nkf/
33  ***********************************************************************/
34 #define NKF_IDENT "$Id: nkf.c,v 1.191 2008/11/09 21:10:04 naruse Exp $"
35 #define NKF_VERSION "2.0.8"
36 #define NKF_RELEASE_DATE "2008-11-10"
37 #define COPY_RIGHT \
38     "Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa),2000 S. Kono, COW\n" \
39     "Copyright (C) 2002-2008 Kono, Furukawa, Naruse, mastodon"
40
41 #include "config.h"
42 #include "nkf.h"
43 #include "utf8tbl.h"
44 #ifdef __WIN32__
45 #include <windows.h>
46 #include <locale.h>
47 #endif
48 #if defined(__OS2__)
49 # define INCL_DOS
50 # define INCL_DOSERRORS
51 # include <os2.h>
52 #endif
53 #include <assert.h>
54
55 /* state of output_mode and input_mode
56
57    c2           0 means ASCII
58    JIS_X_0201_1976_K
59    ISO_8859_1
60    JIS_X_0208
61    EOF      all termination
62    c1           32bit data
63
64  */
65
66 /* MIME ENCODE */
67
68 #define         FIXED_MIME      7
69 #define         STRICT_MIME     8
70
71 /* byte order */
72 enum byte_order {
73     ENDIAN_BIG    = 1,
74     ENDIAN_LITTLE = 2,
75     ENDIAN_2143   = 3,
76     ENDIAN_3412   = 4
77 };
78
79 /* ASCII CODE */
80
81 #define         BS      0x08
82 #define         TAB     0x09
83 #define         LF      0x0a
84 #define         CR      0x0d
85 #define         ESC     0x1b
86 #define         SP      0x20
87 #define         DEL     0x7f
88 #define         SI      0x0f
89 #define         SO      0x0e
90 #define         SS2     0x8e
91 #define         SS3     0x8f
92 #define         CRLF    0x0D0A
93
94
95 /* encodings */
96
97 enum nkf_encodings {
98     ASCII,
99     ISO_8859_1,
100     ISO_2022_JP,
101     CP50220,
102     CP50221,
103     CP50222,
104     ISO_2022_JP_1,
105     ISO_2022_JP_3,
106     ISO_2022_JP_2004,
107     SHIFT_JIS,
108     WINDOWS_31J,
109     CP10001,
110     EUC_JP,
111     EUCJP_NKF,
112     CP51932,
113     EUCJP_MS,
114     EUCJP_ASCII,
115     SHIFT_JISX0213,
116     SHIFT_JIS_2004,
117     EUC_JISX0213,
118     EUC_JIS_2004,
119     UTF_8,
120     UTF_8N,
121     UTF_8_BOM,
122     UTF8_MAC,
123     UTF_16,
124     UTF_16BE,
125     UTF_16BE_BOM,
126     UTF_16LE,
127     UTF_16LE_BOM,
128     UTF_32,
129     UTF_32BE,
130     UTF_32BE_BOM,
131     UTF_32LE,
132     UTF_32LE_BOM,
133     BINARY,
134     NKF_ENCODING_TABLE_SIZE,
135     JIS_X_0201_1976_K = 0x1013, /* I */ /* JIS C 6220-1969 */
136     /* JIS_X_0201_1976_R = 0x1014, */ /* J */ /* JIS C 6220-1969 */
137     /* JIS_X_0208_1978   = 0x1040, */ /* @ */ /* JIS C 6226-1978 */
138     /* JIS_X_0208_1983   = 0x1087, */ /* B */ /* JIS C 6226-1983 */
139     JIS_X_0208        = 0x1168, /* @B */
140     JIS_X_0212        = 0x1159, /* D */
141     /* JIS_X_0213_2000_1 = 0x1228, */ /* O */
142     JIS_X_0213_2 = 0x1229, /* P */
143     JIS_X_0213_1 = 0x1233, /* Q */
144 };
145
146 static nkf_char s_iconv(nkf_char c2, nkf_char c1, nkf_char c0);
147 static nkf_char e_iconv(nkf_char c2, nkf_char c1, nkf_char c0);
148 static nkf_char w_iconv(nkf_char c2, nkf_char c1, nkf_char c0);
149 static nkf_char w_iconv16(nkf_char c2, nkf_char c1, nkf_char c0);
150 static nkf_char w_iconv32(nkf_char c2, nkf_char c1, nkf_char c0);
151 static void j_oconv(nkf_char c2, nkf_char c1);
152 static void s_oconv(nkf_char c2, nkf_char c1);
153 static void e_oconv(nkf_char c2, nkf_char c1);
154 static void w_oconv(nkf_char c2, nkf_char c1);
155 static void w_oconv16(nkf_char c2, nkf_char c1);
156 static void w_oconv32(nkf_char c2, nkf_char c1);
157
158 typedef struct {
159     const char *name;
160     nkf_char (*iconv)(nkf_char c2, nkf_char c1, nkf_char c0);
161     void (*oconv)(nkf_char c2, nkf_char c1);
162 } nkf_native_encoding;
163
164 nkf_native_encoding NkfEncodingASCII =          { "ASCII", e_iconv, e_oconv };
165 nkf_native_encoding NkfEncodingISO_2022_JP =    { "ISO-2022-JP", e_iconv, j_oconv };
166 nkf_native_encoding NkfEncodingShift_JIS =      { "Shift_JIS", s_iconv, s_oconv };
167 nkf_native_encoding NkfEncodingEUC_JP =         { "EUC-JP", e_iconv, e_oconv };
168 nkf_native_encoding NkfEncodingUTF_8 =          { "UTF-8", w_iconv, w_oconv };
169 nkf_native_encoding NkfEncodingUTF_16 =         { "UTF-16", w_iconv16, w_oconv16 };
170 nkf_native_encoding NkfEncodingUTF_32 =         { "UTF-32", w_iconv32, w_oconv32 };
171
172 typedef struct {
173     const int id;
174     const char *name;
175     const nkf_native_encoding *base_encoding;
176 } nkf_encoding;
177
178 nkf_encoding nkf_encoding_table[] = {
179     {ASCII,             "US-ASCII",             &NkfEncodingASCII},
180     {ISO_8859_1,        "ISO-8859-1",           &NkfEncodingASCII},
181     {ISO_2022_JP,       "ISO-2022-JP",          &NkfEncodingISO_2022_JP},
182     {CP50220,           "CP50220",              &NkfEncodingISO_2022_JP},
183     {CP50221,           "CP50221",              &NkfEncodingISO_2022_JP},
184     {CP50222,           "CP50222",              &NkfEncodingISO_2022_JP},
185     {ISO_2022_JP_1,     "ISO-2022-JP-1",        &NkfEncodingISO_2022_JP},
186     {ISO_2022_JP_3,     "ISO-2022-JP-3",        &NkfEncodingISO_2022_JP},
187     {ISO_2022_JP_2004,  "ISO-2022-JP-2004",     &NkfEncodingISO_2022_JP},
188     {SHIFT_JIS,         "Shift_JIS",            &NkfEncodingShift_JIS},
189     {WINDOWS_31J,       "Windows-31J",          &NkfEncodingShift_JIS},
190     {CP10001,           "CP10001",              &NkfEncodingShift_JIS},
191     {EUC_JP,            "EUC-JP",               &NkfEncodingEUC_JP},
192     {EUCJP_NKF,         "eucJP-nkf",            &NkfEncodingEUC_JP},
193     {CP51932,           "CP51932",              &NkfEncodingEUC_JP},
194     {EUCJP_MS,          "eucJP-MS",             &NkfEncodingEUC_JP},
195     {EUCJP_ASCII,       "eucJP-ASCII",          &NkfEncodingEUC_JP},
196     {SHIFT_JISX0213,    "Shift_JISX0213",       &NkfEncodingShift_JIS},
197     {SHIFT_JIS_2004,    "Shift_JIS-2004",       &NkfEncodingShift_JIS},
198     {EUC_JISX0213,      "EUC-JISX0213",         &NkfEncodingEUC_JP},
199     {EUC_JIS_2004,      "EUC-JIS-2004",         &NkfEncodingEUC_JP},
200     {UTF_8,             "UTF-8",                &NkfEncodingUTF_8},
201     {UTF_8N,            "UTF-8N",               &NkfEncodingUTF_8},
202     {UTF_8_BOM,         "UTF-8-BOM",            &NkfEncodingUTF_8},
203     {UTF8_MAC,          "UTF8-MAC",             &NkfEncodingUTF_8},
204     {UTF_16,            "UTF-16",               &NkfEncodingUTF_16},
205     {UTF_16BE,          "UTF-16BE",             &NkfEncodingUTF_16},
206     {UTF_16BE_BOM,      "UTF-16BE-BOM",         &NkfEncodingUTF_16},
207     {UTF_16LE,          "UTF-16LE",             &NkfEncodingUTF_16},
208     {UTF_16LE_BOM,      "UTF-16LE-BOM",         &NkfEncodingUTF_16},
209     {UTF_32,            "UTF-32",               &NkfEncodingUTF_32},
210     {UTF_32BE,          "UTF-32BE",             &NkfEncodingUTF_32},
211     {UTF_32BE_BOM,      "UTF-32BE-BOM",         &NkfEncodingUTF_32},
212     {UTF_32LE,          "UTF-32LE",             &NkfEncodingUTF_32},
213     {UTF_32LE_BOM,      "UTF-32LE-BOM",         &NkfEncodingUTF_32},
214     {BINARY,            "BINARY",               &NkfEncodingASCII},
215     {-1,                NULL,                   NULL}
216 };
217
218 struct {
219     const char *name;
220     const int id;
221 } encoding_name_to_id_table[] = {
222     {"US-ASCII",                ASCII},
223     {"ASCII",                   ASCII},
224     {"ISO-2022-JP",             ISO_2022_JP},
225     {"ISO2022JP-CP932",         CP50220},
226     {"CP50220",                 CP50220},
227     {"CP50221",                 CP50221},
228     {"CSISO2022JP",             CP50221},
229     {"CP50222",                 CP50222},
230     {"ISO-2022-JP-1",           ISO_2022_JP_1},
231     {"ISO-2022-JP-3",           ISO_2022_JP_3},
232     {"ISO-2022-JP-2004",        ISO_2022_JP_2004},
233     {"SHIFT_JIS",               SHIFT_JIS},
234     {"SJIS",                    SHIFT_JIS},
235     {"WINDOWS-31J",             WINDOWS_31J},
236     {"CSWINDOWS31J",            WINDOWS_31J},
237     {"CP932",                   WINDOWS_31J},
238     {"MS932",                   WINDOWS_31J},
239     {"CP10001",                 CP10001},
240     {"EUCJP",                   EUC_JP},
241     {"EUC-JP",                  EUC_JP},
242     {"EUCJP-NKF",               EUCJP_NKF},
243     {"CP51932",                 CP51932},
244     {"EUC-JP-MS",               EUCJP_MS},
245     {"EUCJP-MS",                EUCJP_MS},
246     {"EUCJPMS",                 EUCJP_MS},
247     {"EUC-JP-ASCII",            EUCJP_ASCII},
248     {"EUCJP-ASCII",             EUCJP_ASCII},
249     {"SHIFT_JISX0213",          SHIFT_JISX0213},
250     {"SHIFT_JIS-2004",          SHIFT_JIS_2004},
251     {"EUC-JISX0213",            EUC_JISX0213},
252     {"EUC-JIS-2004",            EUC_JIS_2004},
253     {"UTF-8",                   UTF_8},
254     {"UTF-8N",                  UTF_8N},
255     {"UTF-8-BOM",               UTF_8_BOM},
256     {"UTF8-MAC",                UTF8_MAC},
257     {"UTF-8-MAC",               UTF8_MAC},
258     {"UTF-16",                  UTF_16},
259     {"UTF-16BE",                UTF_16BE},
260     {"UTF-16BE-BOM",            UTF_16BE_BOM},
261     {"UTF-16LE",                UTF_16LE},
262     {"UTF-16LE-BOM",            UTF_16LE_BOM},
263     {"UTF-32",                  UTF_32},
264     {"UTF-32BE",                UTF_32BE},
265     {"UTF-32BE-BOM",            UTF_32BE_BOM},
266     {"UTF-32LE",                UTF_32LE},
267     {"UTF-32LE-BOM",            UTF_32LE_BOM},
268     {"BINARY",                  BINARY},
269     {NULL,                      -1}
270 };
271
272 #if defined(DEFAULT_CODE_JIS)
273 #define     DEFAULT_ENCIDX ISO_2022_JP
274 #elif defined(DEFAULT_CODE_SJIS)
275 #define     DEFAULT_ENCIDX SHIFT_JIS
276 #elif defined(DEFAULT_CODE_WINDOWS_31J)
277 #define     DEFAULT_ENCIDX WINDOWS_31J
278 #elif defined(DEFAULT_CODE_EUC)
279 #define     DEFAULT_ENCIDX EUC_JP
280 #elif defined(DEFAULT_CODE_UTF8)
281 #define     DEFAULT_ENCIDX UTF_8
282 #endif
283
284
285 #define         is_alnum(c)  \
286     (('a'<=c && c<='z')||('A'<= c && c<='Z')||('0'<=c && c<='9'))
287
288 /* I don't trust portablity of toupper */
289 #define nkf_toupper(c)  (('a'<=c && c<='z')?(c-('a'-'A')):c)
290 #define nkf_isoctal(c)  ('0'<=c && c<='7')
291 #define nkf_isdigit(c)  ('0'<=c && c<='9')
292 #define nkf_isxdigit(c)  (nkf_isdigit(c) || ('a'<=c && c<='f') || ('A'<=c && c <= 'F'))
293 #define nkf_isblank(c) (c == SP || c == TAB)
294 #define nkf_isspace(c) (nkf_isblank(c) || c == CR || c == LF)
295 #define nkf_isalpha(c) (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))
296 #define nkf_isalnum(c) (nkf_isdigit(c) || nkf_isalpha(c))
297 #define nkf_isprint(c) (SP<=c && c<='~')
298 #define nkf_isgraph(c) ('!'<=c && c<='~')
299 #define hex2bin(c) (('0'<=c&&c<='9') ? (c-'0') : \
300                     ('A'<=c&&c<='F') ? (c-'A'+10) : \
301                     ('a'<=c&&c<='f') ? (c-'a'+10) : 0)
302 #define bin2hex(c) ("0123456789ABCDEF"[c&15])
303 #define is_eucg3(c2) (((unsigned short)c2 >> 8) == SS3)
304 #define nkf_noescape_mime(c) ((c == CR) || (c == LF) || \
305                               ((c > SP) && (c < DEL) && (c != '?') && (c != '=') && (c != '_') \
306                                && (c != '(') && (c != ')') && (c != '.') && (c != 0x22)))
307
308 #define is_ibmext_in_sjis(c2) (CP932_TABLE_BEGIN <= c2 && c2 <= CP932_TABLE_END)
309 #define nkf_byte_jisx0201_katakana_p(c) (SP <= c && c < (0xE0&0x7F))
310
311 #define         HOLD_SIZE       1024
312 #if defined(INT_IS_SHORT)
313 #define         IOBUF_SIZE      2048
314 #else
315 #define         IOBUF_SIZE      16384
316 #endif
317
318 #define         DEFAULT_J       'B'
319 #define         DEFAULT_R       'B'
320
321
322 #define         GETA1   0x22
323 #define         GETA2   0x2e
324
325
326 /* MIME preprocessor */
327
328 #ifdef EASYWIN /*Easy Win */
329 extern POINT _BufferSize;
330 #endif
331
332 struct input_code{
333     const char *name;
334     nkf_char stat;
335     nkf_char score;
336     nkf_char index;
337     nkf_char buf[3];
338     void (*status_func)(struct input_code *, nkf_char);
339     nkf_char (*iconv_func)(nkf_char c2, nkf_char c1, nkf_char c0);
340     int _file_stat;
341 };
342
343 static const char *input_codename = NULL; /* NULL: unestablished, "": BINARY */
344 static nkf_encoding *input_encoding = NULL;
345 static nkf_encoding *output_encoding = NULL;
346
347 #if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
348 /* UCS Mapping
349  * 0: Shift_JIS, eucJP-ascii
350  * 1: eucJP-ms
351  * 2: CP932, CP51932
352  * 3: CP10001
353  */
354 #define UCS_MAP_ASCII   0
355 #define UCS_MAP_MS      1
356 #define UCS_MAP_CP932   2
357 #define UCS_MAP_CP10001 3
358 static int ms_ucs_map_f = UCS_MAP_ASCII;
359 #endif
360 #ifdef UTF8_INPUT_ENABLE
361 /* no NEC special, NEC-selected IBM extended and IBM extended characters */
362 static  int     no_cp932ext_f = FALSE;
363 /* ignore ZERO WIDTH NO-BREAK SPACE */
364 static  int     no_best_fit_chars_f = FALSE;
365 static  int     input_endian = ENDIAN_BIG;
366 static  nkf_char     unicode_subchar = '?'; /* the regular substitution character */
367 static  void    (*encode_fallback)(nkf_char c) = NULL;
368 static  void    w_status(struct input_code *, nkf_char);
369 #endif
370 #ifdef UTF8_OUTPUT_ENABLE
371 static  int     output_bom_f = FALSE;
372 static  int     output_endian = ENDIAN_BIG;
373 #endif
374
375 static  void    std_putc(nkf_char c);
376 static  nkf_char     std_getc(FILE *f);
377 static  nkf_char     std_ungetc(nkf_char c,FILE *f);
378
379 static  nkf_char     broken_getc(FILE *f);
380 static  nkf_char     broken_ungetc(nkf_char c,FILE *f);
381
382 static  nkf_char     mime_getc(FILE *f);
383
384 static void mime_putc(nkf_char c);
385
386 /* buffers */
387
388 #if !defined(PERL_XS) && !defined(WIN32DLL)
389 static unsigned char   stdibuf[IOBUF_SIZE];
390 static unsigned char   stdobuf[IOBUF_SIZE];
391 #endif
392
393 /* flags */
394 static int             unbuf_f = FALSE;
395 static int             estab_f = FALSE;
396 static int             nop_f = FALSE;
397 static int             binmode_f = TRUE;       /* binary mode */
398 static int             rot_f = FALSE;          /* rot14/43 mode */
399 static int             hira_f = FALSE;          /* hira/kata henkan */
400 static int             alpha_f = FALSE;        /* convert JIx0208 alphbet to ASCII */
401 static int             mime_f = MIME_DECODE_DEFAULT;   /* convert MIME B base64 or Q */
402 static int             mime_decode_f = FALSE;  /* mime decode is explicitly on */
403 static int             mimebuf_f = FALSE;      /* MIME buffered input */
404 static int             broken_f = FALSE;       /* convert ESC-less broken JIS */
405 static int             iso8859_f = FALSE;      /* ISO8859 through */
406 static int             mimeout_f = FALSE;       /* base64 mode */
407 static int             x0201_f = X0201_DEFAULT; /* convert JIS X 0201 */
408 static int             iso2022jp_f = FALSE;    /* replace non ISO-2022-JP with GETA */
409
410 #ifdef UNICODE_NORMALIZATION
411 static int nfc_f = FALSE;
412 static nkf_char (*i_nfc_getc)(FILE *) = std_getc; /* input of ugetc */
413 static nkf_char (*i_nfc_ungetc)(nkf_char c ,FILE *f) = std_ungetc;
414 #endif
415
416 #ifdef INPUT_OPTION
417 static int cap_f = FALSE;
418 static nkf_char (*i_cgetc)(FILE *) = std_getc; /* input of cgetc */
419 static nkf_char (*i_cungetc)(nkf_char c ,FILE *f) = std_ungetc;
420
421 static int url_f = FALSE;
422 static nkf_char (*i_ugetc)(FILE *) = std_getc; /* input of ugetc */
423 static nkf_char (*i_uungetc)(nkf_char c ,FILE *f) = std_ungetc;
424 #endif
425
426 #define PREFIX_EUCG3    NKF_INT32_C(0x8F00)
427 #define CLASS_MASK      NKF_INT32_C(0xFF000000)
428 #define CLASS_UNICODE   NKF_INT32_C(0x01000000)
429 #define VALUE_MASK      NKF_INT32_C(0x00FFFFFF)
430 #define UNICODE_BMP_MAX NKF_INT32_C(0x0000FFFF)
431 #define UNICODE_MAX     NKF_INT32_C(0x0010FFFF)
432 #define nkf_char_euc3_new(c) ((c) | PREFIX_EUCG3)
433 #define nkf_char_unicode_new(c) ((c) | CLASS_UNICODE)
434 #define nkf_char_unicode_p(c) ((c & CLASS_MASK) == CLASS_UNICODE)
435 #define nkf_char_unicode_bmp_p(c) ((c & VALUE_MASK) <= UNICODE_BMP_MAX)
436 #define nkf_char_unicode_value_p(c) ((c & VALUE_MASK) <= UNICODE_MAX)
437
438 #ifdef NUMCHAR_OPTION
439 static int numchar_f = FALSE;
440 static nkf_char (*i_ngetc)(FILE *) = std_getc; /* input of ugetc */
441 static nkf_char (*i_nungetc)(nkf_char c ,FILE *f) = std_ungetc;
442 #endif
443
444 #ifdef CHECK_OPTION
445 static int noout_f = FALSE;
446 static void no_putc(nkf_char c);
447 static int debug_f = FALSE;
448 static void debug(const char *str);
449 static nkf_char (*iconv_for_check)(nkf_char c2,nkf_char c1,nkf_char c0) = 0;
450 #endif
451
452 static int guess_f = 0; /* 0: OFF, 1: ON, 2: VERBOSE */
453 static  void    set_input_codename(const char *codename);
454
455 #ifdef EXEC_IO
456 static int exec_f = 0;
457 #endif
458
459 #ifdef SHIFTJIS_CP932
460 /* invert IBM extended characters to others */
461 static int cp51932_f = FALSE;
462
463 /* invert NEC-selected IBM extended characters to IBM extended characters */
464 static int cp932inv_f = TRUE;
465
466 /* static nkf_char cp932_conv(nkf_char c2, nkf_char c1); */
467 #endif /* SHIFTJIS_CP932 */
468
469 static int x0212_f = FALSE;
470 static int x0213_f = FALSE;
471
472 static unsigned char prefix_table[256];
473
474 static void e_status(struct input_code *, nkf_char);
475 static void s_status(struct input_code *, nkf_char);
476
477 struct input_code input_code_list[] = {
478     {"EUC-JP",    0, 0, 0, {0, 0, 0}, e_status, e_iconv, 0},
479     {"Shift_JIS", 0, 0, 0, {0, 0, 0}, s_status, s_iconv, 0},
480 #ifdef UTF8_INPUT_ENABLE
481     {"UTF-8",     0, 0, 0, {0, 0, 0}, w_status, w_iconv, 0},
482 #endif
483     {0}
484 };
485
486 static int              mimeout_mode = 0; /* 0, -1, 'Q', 'B', 1, 2 */
487 static int              base64_count = 0;
488
489 /* X0208 -> ASCII converter */
490
491 /* fold parameter */
492 static int             f_line = 0;    /* chars in line */
493 static int             f_prev = 0;
494 static int             fold_preserve_f = FALSE; /* preserve new lines */
495 static int             fold_f  = FALSE;
496 static int             fold_len  = 0;
497
498 /* options */
499 static unsigned char   kanji_intro = DEFAULT_J;
500 static unsigned char   ascii_intro = DEFAULT_R;
501
502 /* Folding */
503
504 #define FOLD_MARGIN  10
505 #define DEFAULT_FOLD 60
506
507 static int             fold_margin  = FOLD_MARGIN;
508
509 /* process default */
510
511 static nkf_char
512 no_connection2(nkf_char c2, nkf_char c1, nkf_char c0)
513 {
514     fprintf(stderr,"nkf internal module connection failure.\n");
515     exit(1);
516     return 0; /* LINT */
517 }
518
519 static void
520 no_connection(nkf_char c2, nkf_char c1)
521 {
522     no_connection2(c2,c1,0);
523 }
524
525 static nkf_char (*iconv)(nkf_char c2,nkf_char c1,nkf_char c0) = no_connection2;
526 static void (*oconv)(nkf_char c2,nkf_char c1) = no_connection;
527
528 static void (*o_zconv)(nkf_char c2,nkf_char c1) = no_connection;
529 static void (*o_fconv)(nkf_char c2,nkf_char c1) = no_connection;
530 static void (*o_eol_conv)(nkf_char c2,nkf_char c1) = no_connection;
531 static void (*o_rot_conv)(nkf_char c2,nkf_char c1) = no_connection;
532 static void (*o_hira_conv)(nkf_char c2,nkf_char c1) = no_connection;
533 static void (*o_base64conv)(nkf_char c2,nkf_char c1) = no_connection;
534 static void (*o_iso2022jp_check_conv)(nkf_char c2,nkf_char c1) = no_connection;
535
536 /* static redirections */
537
538 static  void   (*o_putc)(nkf_char c) = std_putc;
539
540 static  nkf_char    (*i_getc)(FILE *f) = std_getc; /* general input */
541 static  nkf_char    (*i_ungetc)(nkf_char c,FILE *f) =std_ungetc;
542
543 static  nkf_char    (*i_bgetc)(FILE *) = std_getc; /* input of mgetc */
544 static  nkf_char    (*i_bungetc)(nkf_char c ,FILE *f) = std_ungetc;
545
546 static  void   (*o_mputc)(nkf_char c) = std_putc ; /* output of mputc */
547
548 static  nkf_char    (*i_mgetc)(FILE *) = std_getc; /* input of mgetc */
549 static  nkf_char    (*i_mungetc)(nkf_char c ,FILE *f) = std_ungetc;
550
551 /* for strict mime */
552 static  nkf_char    (*i_mgetc_buf)(FILE *) = std_getc; /* input of mgetc_buf */
553 static  nkf_char    (*i_mungetc_buf)(nkf_char c,FILE *f) = std_ungetc;
554
555 /* Global states */
556 static int output_mode = ASCII;    /* output kanji mode */
557 static int input_mode =  ASCII;    /* input kanji mode */
558 static int mime_decode_mode =   FALSE;    /* MIME mode B base64, Q hex */
559
560 /* X0201 / X0208 conversion tables */
561
562 /* X0201 kana conversion table */
563 /* 90-9F A0-DF */
564 static const unsigned char cv[]= {
565     0x21,0x21,0x21,0x23,0x21,0x56,0x21,0x57,
566     0x21,0x22,0x21,0x26,0x25,0x72,0x25,0x21,
567     0x25,0x23,0x25,0x25,0x25,0x27,0x25,0x29,
568     0x25,0x63,0x25,0x65,0x25,0x67,0x25,0x43,
569     0x21,0x3c,0x25,0x22,0x25,0x24,0x25,0x26,
570     0x25,0x28,0x25,0x2a,0x25,0x2b,0x25,0x2d,
571     0x25,0x2f,0x25,0x31,0x25,0x33,0x25,0x35,
572     0x25,0x37,0x25,0x39,0x25,0x3b,0x25,0x3d,
573     0x25,0x3f,0x25,0x41,0x25,0x44,0x25,0x46,
574     0x25,0x48,0x25,0x4a,0x25,0x4b,0x25,0x4c,
575     0x25,0x4d,0x25,0x4e,0x25,0x4f,0x25,0x52,
576     0x25,0x55,0x25,0x58,0x25,0x5b,0x25,0x5e,
577     0x25,0x5f,0x25,0x60,0x25,0x61,0x25,0x62,
578     0x25,0x64,0x25,0x66,0x25,0x68,0x25,0x69,
579     0x25,0x6a,0x25,0x6b,0x25,0x6c,0x25,0x6d,
580     0x25,0x6f,0x25,0x73,0x21,0x2b,0x21,0x2c,
581     0x00,0x00};
582
583
584 /* X0201 kana conversion table for daguten */
585 /* 90-9F A0-DF */
586 static const unsigned char dv[]= {
587     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
588     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
589     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
590     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
591     0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x74,
592     0x00,0x00,0x00,0x00,0x25,0x2c,0x25,0x2e,
593     0x25,0x30,0x25,0x32,0x25,0x34,0x25,0x36,
594     0x25,0x38,0x25,0x3a,0x25,0x3c,0x25,0x3e,
595     0x25,0x40,0x25,0x42,0x25,0x45,0x25,0x47,
596     0x25,0x49,0x00,0x00,0x00,0x00,0x00,0x00,
597     0x00,0x00,0x00,0x00,0x25,0x50,0x25,0x53,
598     0x25,0x56,0x25,0x59,0x25,0x5c,0x00,0x00,
599     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
600     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
601     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
602     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
603     0x00,0x00};
604
605 /* X0201 kana conversion table for han-daguten */
606 /* 90-9F A0-DF */
607 static const unsigned char ev[]= {
608     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
609     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
610     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
611     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
612     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
613     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
614     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
615     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
616     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
617     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
618     0x00,0x00,0x00,0x00,0x25,0x51,0x25,0x54,
619     0x25,0x57,0x25,0x5a,0x25,0x5d,0x00,0x00,
620     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
621     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
622     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
623     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
624     0x00,0x00};
625
626
627 /* X0208 kigou conversion table */
628 /* 0x8140 - 0x819e */
629 static const unsigned char fv[] = {
630
631     0x00,0x00,0x00,0x00,0x2c,0x2e,0x00,0x3a,
632     0x3b,0x3f,0x21,0x00,0x00,0x27,0x60,0x00,
633     0x5e,0x00,0x5f,0x00,0x00,0x00,0x00,0x00,
634     0x00,0x00,0x00,0x00,0x00,0x2d,0x00,0x2f,
635     0x5c,0x00,0x00,0x7c,0x00,0x00,0x60,0x27,
636     0x22,0x22,0x28,0x29,0x00,0x00,0x5b,0x5d,
637     0x7b,0x7d,0x3c,0x3e,0x00,0x00,0x00,0x00,
638     0x00,0x00,0x00,0x00,0x2b,0x2d,0x00,0x00,
639     0x00,0x3d,0x00,0x3c,0x3e,0x00,0x00,0x00,
640     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
641     0x24,0x00,0x00,0x25,0x23,0x26,0x2a,0x40,
642     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
643 } ;
644
645
646
647 static int option_mode = 0;
648 static int             file_out_f = FALSE;
649 #ifdef OVERWRITE
650 static int             overwrite_f = FALSE;
651 static int             preserve_time_f = FALSE;
652 static int             backup_f = FALSE;
653 static char            *backup_suffix = "";
654 #endif
655
656 static int eolmode_f = 0;   /* CR, LF, CRLF */
657 static int input_eol = 0; /* 0: unestablished, EOF: MIXED */
658 static nkf_char prev_cr = 0; /* CR or 0 */
659 #ifdef EASYWIN /*Easy Win */
660 static int             end_check;
661 #endif /*Easy Win */
662
663 #define STD_GC_BUFSIZE (256)
664 nkf_char std_gc_buf[STD_GC_BUFSIZE];
665 nkf_char std_gc_ndx;
666
667 static void *
668 nkf_malloc(size_t size)
669 {
670     void *ptr;
671
672     if (size == 0) size = 1;
673
674     ptr = malloc(size);
675     if (ptr == NULL) {
676         perror("can't malloc");
677         exit(EXIT_FAILURE);
678     }
679
680     return ptr;
681 }
682
683 static void *
684 nkf_realloc(void *ptr, size_t size)
685 {
686     if (size == 0) size = 1;
687
688     ptr = realloc(ptr, size);
689     if (ptr == NULL) {
690         perror("can't realloc");
691         exit(EXIT_FAILURE);
692     }
693
694     return ptr;
695 }
696
697 #define nkf_free(ptr) free(ptr)
698
699 static int
700 nkf_str_caseeql(const char *src, const char *target)
701 {
702     int i;
703     for (i = 0; src[i] && target[i]; i++) {
704         if (nkf_toupper(src[i]) != nkf_toupper(target[i])) return FALSE;
705     }
706     if (src[i] || target[i]) return FALSE;
707     else return TRUE;
708 }
709
710 static nkf_encoding*
711 nkf_enc_from_index(int idx)
712 {
713     if (idx < 0 || NKF_ENCODING_TABLE_SIZE <= idx) {
714         return 0;
715     }
716     return &nkf_encoding_table[idx];
717 }
718
719 static int
720 nkf_enc_find_index(const char *name)
721 {
722     int i;
723     if (name[0] == 'X' && *(name+1) == '-') name += 2;
724     for (i = 0; encoding_name_to_id_table[i].id >= 0; i++) {
725         if (nkf_str_caseeql(encoding_name_to_id_table[i].name, name)) {
726             return encoding_name_to_id_table[i].id;
727         }
728     }
729     return -1;
730 }
731
732 static nkf_encoding*
733 nkf_enc_find(const char *name)
734 {
735     int idx = -1;
736     idx = nkf_enc_find_index(name);
737     if (idx < 0) return 0;
738     return nkf_enc_from_index(idx);
739 }
740
741 #define nkf_enc_name(enc) (enc)->name
742 #define nkf_enc_to_index(enc) (enc)->id
743 #define nkf_enc_to_base_encoding(enc) (enc)->base_encoding
744 #define nkf_enc_to_iconv(enc) nkf_enc_to_base_encoding(enc)->iconv
745 #define nkf_enc_to_oconv(enc) nkf_enc_to_base_encoding(enc)->oconv
746 #define nkf_enc_asciicompat(enc) (\
747                                   nkf_enc_to_base_encoding(enc) == &NkfEncodingASCII ||\
748                                   nkf_enc_to_base_encoding(enc) == &NkfEncodingISO_2022_JP)
749 #define nkf_enc_unicode_p(enc) (\
750                                 nkf_enc_to_base_encoding(enc) == &NkfEncodingUTF_8 ||\
751                                 nkf_enc_to_base_encoding(enc) == &NkfEncodingUTF_16 ||\
752                                 nkf_enc_to_base_encoding(enc) == &NkfEncodingUTF_32)
753 #define nkf_enc_cp5022x_p(enc) (\
754                                 nkf_enc_to_index(enc) == CP50220 ||\
755                                 nkf_enc_to_index(enc) == CP50221 ||\
756                                 nkf_enc_to_index(enc) == CP50222)
757
758 #ifdef DEFAULT_CODE_LOCALE
759 static char*
760 nkf_locale_charmap()
761 {
762 #ifdef HAVE_LANGINFO_H
763     return nl_langinfo(CODESET);
764 #elif defined(__WIN32__)
765     char buf[16];
766     char *str;
767     int len = sprintf(buf, "CP%d", GetACP());
768     if (len > 0) {
769       str = nkf_malloc(len + 1);
770       strcpy(str, buf);
771       str[len] = '\0';
772       return str;
773     }
774     else return NULL;
775 #elif defined(__OS2__)
776 # if defined(INT_IS_SHORT)
777     /* OS/2 1.x */
778     return NULL;
779 # else
780     /* OS/2 32bit */
781     static char buf[16];
782     ULONG ulCP[1], ulncp;
783     DosQueryCp(sizeof(ulCP), ulCP, &ulncp);
784     if (ulCP[0] == 932 || ulCP[0] == 943)
785         strcpy(buf, "Shift_JIS");
786     else
787         sprintf(buf, "CP%lu", ulCP[0]);
788     return buf;
789 # endif
790 #else
791     return NULL;
792 #endif
793 }
794
795 static nkf_encoding*
796 nkf_locale_encoding()
797 {
798     nkf_encoding *enc = 0;
799     char *encname = nkf_locale_charmap();
800     if (encname)
801         enc = nkf_enc_find(encname);
802     return enc;
803 }
804 #endif /* DEFAULT_CODE_LOCALE */
805
806 static nkf_encoding*
807 nkf_utf8_encoding()
808 {
809     return &nkf_encoding_table[UTF_8];
810 }
811
812 static nkf_encoding*
813 nkf_default_encoding()
814 {
815     nkf_encoding *enc = 0;
816 #ifdef DEFAULT_CODE_LOCALE
817     enc = nkf_locale_encoding();
818 #elif defined(DEFAULT_ENCIDX)
819     enc = nkf_enc_from_index(DEFAULT_ENCIDX);
820 #endif
821     if (!enc) enc = nkf_utf8_encoding();
822     return enc;
823 }
824
825 #ifndef PERL_XS
826 #ifdef WIN32DLL
827 #define fprintf dllprintf
828 #endif
829
830 static void
831 version(void)
832 {
833     fprintf(HELP_OUTPUT,"Network Kanji Filter Version " NKF_VERSION " (" NKF_RELEASE_DATE ") \n" COPY_RIGHT "\n");
834 }
835
836 static void
837 usage(void)
838 {
839     fprintf(HELP_OUTPUT,
840             "USAGE:  nkf(nkf32,wnkf,nkf2) -[flags] [in file] .. [out file for -O flag]\n"
841             "Flags:\n"
842             "b,u      Output is buffered (DEFAULT),Output is unbuffered\n"
843             "j,s,e,w  Output code is ISO-2022-JP, Shift JIS, EUC-JP, UTF-8N\n"
844 #ifdef UTF8_OUTPUT_ENABLE
845             "         After 'w' you can add more options. -w[ 8 [0], 16 [[BL] [0]] ]\n"
846 #endif
847             "J,S,E,W  Input assumption is JIS 7 bit , Shift JIS, EUC-JP, UTF-8\n"
848 #ifdef UTF8_INPUT_ENABLE
849             "         After 'W' you can add more options. -W[ 8, 16 [BL] ] \n"
850 #endif
851             "t        no conversion\n"
852             "i[@B]    Specify the Esc Seq for JIS X 0208-1978/83 (DEFAULT B)\n"
853             "o[BJH]   Specify the Esc Seq for ASCII/Roman        (DEFAULT B)\n"
854             "r        {de/en}crypt ROT13/47\n"
855             "h        1 katakana->hiragana, 2 hiragana->katakana, 3 both\n"
856             "m[BQSN0] MIME decode [B:base64,Q:quoted,S:strict,N:non-strict,0:no decode]\n"
857             "M[BQ]    MIME encode [B:base64 Q:quoted]\n"
858             "l        ISO8859-1 (Latin-1) support\n"
859             "f/F      Folding: -f60 or -f or -f60-10 (fold margin 10) F preserve nl\n"
860             "Z[0-4]   Default/0: Convert JISX0208 Alphabet to ASCII\n"
861             "         1: Kankaku to one space  2: to two spaces  3: HTML Entity\n"
862             "         4: JISX0208 Katakana to JISX0201 Katakana\n"
863             "X,x      Assume X0201 kana in MS-Kanji, -x preserves X0201\n"
864             "B[0-2]   Broken input  0: missing ESC,1: any X on ESC-[($]-X,2: ASCII on NL\n"
865 #ifdef MSDOS
866             "T        Text mode output\n"
867 #endif
868             "O        Output to File (DEFAULT 'nkf.out')\n"
869             "I        Convert non ISO-2022-JP charactor to GETA\n"
870             "d,c      Convert line breaks  -d: LF  -c: CRLF\n"
871             "-L[uwm]  line mode u:LF w:CRLF m:CR (DEFAULT noconversion)\n"
872             "v, V     Show this usage. V: show configuration\n"
873             "\n"
874             "Long name options\n"
875             " --ic=<input codeset>  --oc=<output codeset>\n"
876             "                   Specify the input or output codeset\n"
877             " --fj  --unix --mac  --windows\n"
878             " --jis  --euc  --sjis  --utf8  --utf16  --mime  --base64\n"
879             "                   Convert for the system or code\n"
880             " --hiragana  --katakana  --katakana-hiragana\n"
881             "                   To Hiragana/Katakana Conversion\n"
882             " --prefix=         Insert escape before troublesome characters of Shift_JIS\n"
883 #ifdef INPUT_OPTION
884             " --cap-input, --url-input  Convert hex after ':' or '%%'\n"
885 #endif
886 #ifdef NUMCHAR_OPTION
887             " --numchar-input   Convert Unicode Character Reference\n"
888 #endif
889 #ifdef UTF8_INPUT_ENABLE
890             " --fb-{skip, html, xml, perl, java, subchar}\n"
891             "                   Specify how nkf handles unassigned characters\n"
892 #endif
893 #ifdef OVERWRITE
894             " --in-place[=SUFFIX]  --overwrite[=SUFFIX]\n"
895             "                   Overwrite original listed files by filtered result\n"
896             "                   --overwrite preserves timestamp of original files\n"
897 #endif
898             " -g  --guess       Guess the input code\n"
899             " --help  --version Show this help/the version\n"
900             "                   For more information, see also man nkf\n"
901             "\n");
902     version();
903 }
904
905 static void
906 show_configuration(void)
907 {
908     fprintf(HELP_OUTPUT,
909             "Summary of my nkf " NKF_VERSION " (" NKF_RELEASE_DATE ") configuration:\n"
910             "  nkf identity:\n"
911             "    " NKF_IDENT "\n"
912             "  Compile-time options:\n"
913             "    Compiled at:                 " __DATE__ " " __TIME__ "\n"
914            );
915     fprintf(HELP_OUTPUT,
916             "    Default output encoding:     "
917 #ifdef DEFAULT_CODE_LOCALE
918             "LOCALE (%s)\n", nkf_enc_name(nkf_default_encoding())
919 #elif defined(DEFAULT_ENCIDX)
920             "CONFIG (%s)\n", nkf_enc_name(nkf_default_encoding())
921 #else
922             "NONE\n"
923 #endif
924            );
925     fprintf(HELP_OUTPUT,
926             "    Default output end of line:  "
927 #if DEFAULT_NEWLINE == CR
928             "CR"
929 #elif DEFAULT_NEWLINE == CRLF
930             "CRLF"
931 #else
932             "LF"
933 #endif
934             "\n"
935             "    Decode MIME encoded string:  "
936 #if MIME_DECODE_DEFAULT
937             "ON"
938 #else
939             "OFF"
940 #endif
941             "\n"
942             "    Convert JIS X 0201 Katakana: "
943 #if X0201_DEFAULT
944             "ON"
945 #else
946             "OFF"
947 #endif
948             "\n"
949             "    --help, --version output:    "
950 #if HELP_OUTPUT_HELP_OUTPUT
951             "HELP_OUTPUT"
952 #else
953             "STDOUT"
954 #endif
955             "\n");
956 }
957 #endif /*PERL_XS*/
958
959 #ifdef OVERWRITE
960 static char*
961 get_backup_filename(const char *suffix, const char *filename)
962 {
963     char *backup_filename;
964     int asterisk_count = 0;
965     int i, j;
966     int filename_length = strlen(filename);
967
968     for(i = 0; suffix[i]; i++){
969         if(suffix[i] == '*') asterisk_count++;
970     }
971
972     if(asterisk_count){
973         backup_filename = nkf_malloc(strlen(suffix) + (asterisk_count * (filename_length - 1)) + 1);
974         for(i = 0, j = 0; suffix[i];){
975             if(suffix[i] == '*'){
976                 backup_filename[j] = '\0';
977                 strncat(backup_filename, filename, filename_length);
978                 i++;
979                 j += filename_length;
980             }else{
981                 backup_filename[j++] = suffix[i++];
982             }
983         }
984         backup_filename[j] = '\0';
985     }else{
986         j = filename_length + strlen(suffix);
987         backup_filename = nkf_malloc(j + 1);
988         strcpy(backup_filename, filename);
989         strcat(backup_filename, suffix);
990         backup_filename[j] = '\0';
991     }
992     return backup_filename;
993 }
994 #endif
995
996 #ifdef UTF8_INPUT_ENABLE
997 static void
998 nkf_each_char_to_hex(void (*f)(nkf_char c2,nkf_char c1), nkf_char c)
999 {
1000     int shift = 20;
1001     c &= VALUE_MASK;
1002     while(shift >= 0){
1003         if(c >= 1<<shift){
1004             while(shift >= 0){
1005                 (*f)(0, bin2hex(c>>shift));
1006                 shift -= 4;
1007             }
1008         }else{
1009             shift -= 4;
1010         }
1011     }
1012     return;
1013 }
1014
1015 static void
1016 encode_fallback_html(nkf_char c)
1017 {
1018     (*oconv)(0, '&');
1019     (*oconv)(0, '#');
1020     c &= VALUE_MASK;
1021     if(c >= NKF_INT32_C(1000000))
1022         (*oconv)(0, 0x30+(c/NKF_INT32_C(1000000))%10);
1023     if(c >= NKF_INT32_C(100000))
1024         (*oconv)(0, 0x30+(c/NKF_INT32_C(100000) )%10);
1025     if(c >= 10000)
1026         (*oconv)(0, 0x30+(c/10000  )%10);
1027     if(c >= 1000)
1028         (*oconv)(0, 0x30+(c/1000   )%10);
1029     if(c >= 100)
1030         (*oconv)(0, 0x30+(c/100    )%10);
1031     if(c >= 10)
1032         (*oconv)(0, 0x30+(c/10     )%10);
1033     if(c >= 0)
1034         (*oconv)(0, 0x30+ c         %10);
1035     (*oconv)(0, ';');
1036     return;
1037 }
1038
1039 static void
1040 encode_fallback_xml(nkf_char c)
1041 {
1042     (*oconv)(0, '&');
1043     (*oconv)(0, '#');
1044     (*oconv)(0, 'x');
1045     nkf_each_char_to_hex(oconv, c);
1046     (*oconv)(0, ';');
1047     return;
1048 }
1049
1050 static void
1051 encode_fallback_java(nkf_char c)
1052 {
1053     (*oconv)(0, '\\');
1054     c &= VALUE_MASK;
1055     if(!nkf_char_unicode_bmp_p(c)){
1056         (*oconv)(0, 'U');
1057         (*oconv)(0, '0');
1058         (*oconv)(0, '0');
1059         (*oconv)(0, bin2hex(c>>20));
1060         (*oconv)(0, bin2hex(c>>16));
1061     }else{
1062         (*oconv)(0, 'u');
1063     }
1064     (*oconv)(0, bin2hex(c>>12));
1065     (*oconv)(0, bin2hex(c>> 8));
1066     (*oconv)(0, bin2hex(c>> 4));
1067     (*oconv)(0, bin2hex(c    ));
1068     return;
1069 }
1070
1071 static void
1072 encode_fallback_perl(nkf_char c)
1073 {
1074     (*oconv)(0, '\\');
1075     (*oconv)(0, 'x');
1076     (*oconv)(0, '{');
1077     nkf_each_char_to_hex(oconv, c);
1078     (*oconv)(0, '}');
1079     return;
1080 }
1081
1082 static void
1083 encode_fallback_subchar(nkf_char c)
1084 {
1085     c = unicode_subchar;
1086     (*oconv)((c>>8)&0xFF, c&0xFF);
1087     return;
1088 }
1089 #endif
1090
1091 static const struct {
1092     const char *name;
1093     const char *alias;
1094 } long_option[] = {
1095     {"ic=", ""},
1096     {"oc=", ""},
1097     {"base64","jMB"},
1098     {"euc","e"},
1099     {"euc-input","E"},
1100     {"fj","jm"},
1101     {"help","v"},
1102     {"jis","j"},
1103     {"jis-input","J"},
1104     {"mac","sLm"},
1105     {"mime","jM"},
1106     {"mime-input","m"},
1107     {"msdos","sLw"},
1108     {"sjis","s"},
1109     {"sjis-input","S"},
1110     {"unix","eLu"},
1111     {"version","V"},
1112     {"windows","sLw"},
1113     {"hiragana","h1"},
1114     {"katakana","h2"},
1115     {"katakana-hiragana","h3"},
1116     {"guess=", ""},
1117     {"guess", "g2"},
1118     {"cp932", ""},
1119     {"no-cp932", ""},
1120 #ifdef X0212_ENABLE
1121     {"x0212", ""},
1122 #endif
1123 #ifdef UTF8_OUTPUT_ENABLE
1124     {"utf8", "w"},
1125     {"utf16", "w16"},
1126     {"ms-ucs-map", ""},
1127     {"fb-skip", ""},
1128     {"fb-html", ""},
1129     {"fb-xml", ""},
1130     {"fb-perl", ""},
1131     {"fb-java", ""},
1132     {"fb-subchar", ""},
1133     {"fb-subchar=", ""},
1134 #endif
1135 #ifdef UTF8_INPUT_ENABLE
1136     {"utf8-input", "W"},
1137     {"utf16-input", "W16"},
1138     {"no-cp932ext", ""},
1139     {"no-best-fit-chars",""},
1140 #endif
1141 #ifdef UNICODE_NORMALIZATION
1142     {"utf8mac-input", ""},
1143 #endif
1144 #ifdef OVERWRITE
1145     {"overwrite", ""},
1146     {"overwrite=", ""},
1147     {"in-place", ""},
1148     {"in-place=", ""},
1149 #endif
1150 #ifdef INPUT_OPTION
1151     {"cap-input", ""},
1152     {"url-input", ""},
1153 #endif
1154 #ifdef NUMCHAR_OPTION
1155     {"numchar-input", ""},
1156 #endif
1157 #ifdef CHECK_OPTION
1158     {"no-output", ""},
1159     {"debug", ""},
1160 #endif
1161 #ifdef SHIFTJIS_CP932
1162     {"cp932inv", ""},
1163 #endif
1164 #ifdef EXEC_IO
1165     {"exec-in", ""},
1166     {"exec-out", ""},
1167 #endif
1168     {"prefix=", ""},
1169 };
1170
1171 static void
1172 set_input_encoding(nkf_encoding *enc)
1173 {
1174     switch (nkf_enc_to_index(enc)) {
1175     case ISO_8859_1:
1176         iso8859_f = TRUE;
1177         break;
1178     case CP50220:
1179     case CP50221:
1180     case CP50222:
1181 #ifdef SHIFTJIS_CP932
1182         cp51932_f = TRUE;
1183 #endif
1184 #ifdef UTF8_OUTPUT_ENABLE
1185         ms_ucs_map_f = UCS_MAP_CP932;
1186 #endif
1187         break;
1188     case ISO_2022_JP_1:
1189         x0212_f = TRUE;
1190         break;
1191     case ISO_2022_JP_3:
1192         x0212_f = TRUE;
1193         x0213_f = TRUE;
1194         break;
1195     case ISO_2022_JP_2004:
1196         x0212_f = TRUE;
1197         x0213_f = TRUE;
1198         break;
1199     case SHIFT_JIS:
1200         break;
1201     case WINDOWS_31J:
1202 #ifdef SHIFTJIS_CP932
1203         cp51932_f = TRUE;
1204 #endif
1205 #ifdef UTF8_OUTPUT_ENABLE
1206         ms_ucs_map_f = UCS_MAP_CP932;
1207 #endif
1208         break;
1209         break;
1210     case CP10001:
1211 #ifdef SHIFTJIS_CP932
1212         cp51932_f = TRUE;
1213 #endif
1214 #ifdef UTF8_OUTPUT_ENABLE
1215         ms_ucs_map_f = UCS_MAP_CP10001;
1216 #endif
1217         break;
1218     case EUC_JP:
1219         break;
1220     case EUCJP_NKF:
1221         break;
1222     case CP51932:
1223 #ifdef SHIFTJIS_CP932
1224         cp51932_f = TRUE;
1225 #endif
1226 #ifdef UTF8_OUTPUT_ENABLE
1227         ms_ucs_map_f = UCS_MAP_CP932;
1228 #endif
1229         break;
1230     case EUCJP_MS:
1231 #ifdef SHIFTJIS_CP932
1232         cp51932_f = FALSE;
1233 #endif
1234 #ifdef UTF8_OUTPUT_ENABLE
1235         ms_ucs_map_f = UCS_MAP_MS;
1236 #endif
1237         break;
1238     case EUCJP_ASCII:
1239 #ifdef SHIFTJIS_CP932
1240         cp51932_f = FALSE;
1241 #endif
1242 #ifdef UTF8_OUTPUT_ENABLE
1243         ms_ucs_map_f = UCS_MAP_ASCII;
1244 #endif
1245         break;
1246     case SHIFT_JISX0213:
1247     case SHIFT_JIS_2004:
1248         x0213_f = TRUE;
1249 #ifdef SHIFTJIS_CP932
1250         cp51932_f = FALSE;
1251 #endif
1252         break;
1253     case EUC_JISX0213:
1254     case EUC_JIS_2004:
1255         x0213_f = TRUE;
1256 #ifdef SHIFTJIS_CP932
1257         cp51932_f = FALSE;
1258 #endif
1259         break;
1260 #ifdef UTF8_INPUT_ENABLE
1261 #ifdef UNICODE_NORMALIZATION
1262     case UTF8_MAC:
1263         nfc_f = TRUE;
1264         break;
1265 #endif
1266     case UTF_16:
1267     case UTF_16BE:
1268     case UTF_16BE_BOM:
1269         input_endian = ENDIAN_BIG;
1270         break;
1271     case UTF_16LE:
1272     case UTF_16LE_BOM:
1273         input_endian = ENDIAN_LITTLE;
1274         break;
1275     case UTF_32:
1276     case UTF_32BE:
1277     case UTF_32BE_BOM:
1278         input_endian = ENDIAN_BIG;
1279         break;
1280     case UTF_32LE:
1281     case UTF_32LE_BOM:
1282         input_endian = ENDIAN_LITTLE;
1283         break;
1284 #endif
1285     }
1286 }
1287
1288 static void
1289 set_output_encoding(nkf_encoding *enc)
1290 {
1291     switch (nkf_enc_to_index(enc)) {
1292     case CP50220:
1293         x0201_f = TRUE;
1294 #ifdef SHIFTJIS_CP932
1295         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1296 #endif
1297 #ifdef UTF8_OUTPUT_ENABLE
1298         ms_ucs_map_f = UCS_MAP_CP932;
1299 #endif
1300         break;
1301     case CP50221:
1302 #ifdef SHIFTJIS_CP932
1303         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1304 #endif
1305 #ifdef UTF8_OUTPUT_ENABLE
1306         ms_ucs_map_f = UCS_MAP_CP932;
1307 #endif
1308         break;
1309     case ISO_2022_JP_1:
1310         x0212_f = TRUE;
1311 #ifdef SHIFTJIS_CP932
1312         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1313 #endif
1314         break;
1315     case ISO_2022_JP_3:
1316         x0212_f = TRUE;
1317         x0213_f = TRUE;
1318 #ifdef SHIFTJIS_CP932
1319         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1320 #endif
1321         break;
1322     case SHIFT_JIS:
1323         break;
1324     case WINDOWS_31J:
1325 #ifdef UTF8_OUTPUT_ENABLE
1326         ms_ucs_map_f = UCS_MAP_CP932;
1327 #endif
1328         break;
1329     case CP10001:
1330 #ifdef UTF8_OUTPUT_ENABLE
1331         ms_ucs_map_f = UCS_MAP_CP10001;
1332 #endif
1333         break;
1334     case EUC_JP:
1335         x0212_f = TRUE;
1336 #ifdef SHIFTJIS_CP932
1337         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1338 #endif
1339 #ifdef UTF8_OUTPUT_ENABLE
1340         ms_ucs_map_f = UCS_MAP_ASCII;
1341 #endif
1342         break;
1343     case EUCJP_NKF:
1344         x0212_f = FALSE;
1345 #ifdef SHIFTJIS_CP932
1346         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1347 #endif
1348 #ifdef UTF8_OUTPUT_ENABLE
1349         ms_ucs_map_f = UCS_MAP_ASCII;
1350 #endif
1351         break;
1352     case CP51932:
1353 #ifdef SHIFTJIS_CP932
1354         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1355 #endif
1356 #ifdef UTF8_OUTPUT_ENABLE
1357         ms_ucs_map_f = UCS_MAP_CP932;
1358 #endif
1359         break;
1360     case EUCJP_MS:
1361         x0212_f = TRUE;
1362 #ifdef UTF8_OUTPUT_ENABLE
1363         ms_ucs_map_f = UCS_MAP_MS;
1364 #endif
1365         break;
1366     case EUCJP_ASCII:
1367         x0212_f = TRUE;
1368 #ifdef UTF8_OUTPUT_ENABLE
1369         ms_ucs_map_f = UCS_MAP_ASCII;
1370 #endif
1371         break;
1372     case SHIFT_JISX0213:
1373     case SHIFT_JIS_2004:
1374         x0213_f = TRUE;
1375 #ifdef SHIFTJIS_CP932
1376         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1377 #endif
1378         break;
1379     case EUC_JISX0213:
1380     case EUC_JIS_2004:
1381         x0212_f = TRUE;
1382         x0213_f = TRUE;
1383 #ifdef SHIFTJIS_CP932
1384         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1385 #endif
1386         break;
1387 #ifdef UTF8_OUTPUT_ENABLE
1388     case UTF_8_BOM:
1389         output_bom_f = TRUE;
1390         break;
1391     case UTF_16:
1392     case UTF_16BE_BOM:
1393         output_bom_f = TRUE;
1394         break;
1395     case UTF_16LE:
1396         output_endian = ENDIAN_LITTLE;
1397         output_bom_f = FALSE;
1398         break;
1399     case UTF_16LE_BOM:
1400         output_endian = ENDIAN_LITTLE;
1401         output_bom_f = TRUE;
1402         break;
1403     case UTF_32BE_BOM:
1404         output_bom_f = TRUE;
1405         break;
1406     case UTF_32LE:
1407         output_endian = ENDIAN_LITTLE;
1408         output_bom_f = FALSE;
1409         break;
1410     case UTF_32LE_BOM:
1411         output_endian = ENDIAN_LITTLE;
1412         output_bom_f = TRUE;
1413         break;
1414 #endif
1415     }
1416 }
1417
1418 static struct input_code*
1419 find_inputcode_byfunc(nkf_char (*iconv_func)(nkf_char c2,nkf_char c1,nkf_char c0))
1420 {
1421     if (iconv_func){
1422         struct input_code *p = input_code_list;
1423         while (p->name){
1424             if (iconv_func == p->iconv_func){
1425                 return p;
1426             }
1427             p++;
1428         }
1429     }
1430     return 0;
1431 }
1432
1433 static void
1434 set_iconv(nkf_char f, nkf_char (*iconv_func)(nkf_char c2,nkf_char c1,nkf_char c0))
1435 {
1436 #ifdef INPUT_CODE_FIX
1437     if (f || !input_encoding)
1438 #endif
1439         if (estab_f != f){
1440             estab_f = f;
1441         }
1442
1443     if (iconv_func
1444 #ifdef INPUT_CODE_FIX
1445         && (f == -TRUE || !input_encoding) /* -TRUE means "FORCE" */
1446 #endif
1447        ){
1448         iconv = iconv_func;
1449     }
1450 #ifdef CHECK_OPTION
1451     if (estab_f && iconv_for_check != iconv){
1452         struct input_code *p = find_inputcode_byfunc(iconv);
1453         if (p){
1454             set_input_codename(p->name);
1455             debug(p->name);
1456         }
1457         iconv_for_check = iconv;
1458     }
1459 #endif
1460 }
1461
1462 #ifdef X0212_ENABLE
1463 static nkf_char
1464 x0212_shift(nkf_char c)
1465 {
1466     nkf_char ret = c;
1467     c &= 0x7f;
1468     if (is_eucg3(ret)){
1469         if (0x75 <= c && c <= 0x7f){
1470             ret = c + (0x109 - 0x75);
1471         }
1472     }else{
1473         if (0x75 <= c && c <= 0x7f){
1474             ret = c + (0x113 - 0x75);
1475         }
1476     }
1477     return ret;
1478 }
1479
1480
1481 static nkf_char
1482 x0212_unshift(nkf_char c)
1483 {
1484     nkf_char ret = c;
1485     if (0x7f <= c && c <= 0x88){
1486         ret = c + (0x75 - 0x7f);
1487     }else if (0x89 <= c && c <= 0x92){
1488         ret = PREFIX_EUCG3 | 0x80 | (c + (0x75 - 0x89));
1489     }
1490     return ret;
1491 }
1492 #endif /* X0212_ENABLE */
1493
1494 static nkf_char
1495 e2s_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1)
1496 {
1497     nkf_char ndx;
1498     if (is_eucg3(c2)){
1499         ndx = c2 & 0x7f;
1500         if (x0213_f){
1501             if((0x21 <= ndx && ndx <= 0x2F)){
1502                 if (p2) *p2 = ((ndx - 1) >> 1) + 0xec - ndx / 8 * 3;
1503                 if (p1) *p1 = c1 + ((ndx & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e);
1504                 return 0;
1505             }else if(0x6E <= ndx && ndx <= 0x7E){
1506                 if (p2) *p2 = ((ndx - 1) >> 1) + 0xbe;
1507                 if (p1) *p1 = c1 + ((ndx & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e);
1508                 return 0;
1509             }
1510             return 1;
1511         }
1512 #ifdef X0212_ENABLE
1513         else if(nkf_isgraph(ndx)){
1514             nkf_char val = 0;
1515             const unsigned short *ptr;
1516             ptr = x0212_shiftjis[ndx - 0x21];
1517             if (ptr){
1518                 val = ptr[(c1 & 0x7f) - 0x21];
1519             }
1520             if (val){
1521                 c2 = val >> 8;
1522                 c1 = val & 0xff;
1523                 if (p2) *p2 = c2;
1524                 if (p1) *p1 = c1;
1525                 return 0;
1526             }
1527             c2 = x0212_shift(c2);
1528         }
1529 #endif /* X0212_ENABLE */
1530     }
1531     if(0x7F < c2) return 1;
1532     if (p2) *p2 = ((c2 - 1) >> 1) + ((c2 <= 0x5e) ? 0x71 : 0xb1);
1533     if (p1) *p1 = c1 + ((c2 & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e);
1534     return 0;
1535 }
1536
1537 static nkf_char
1538 s2e_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1)
1539 {
1540 #if defined(SHIFTJIS_CP932) || defined(X0212_ENABLE)
1541     nkf_char val;
1542 #endif
1543     static const char shift_jisx0213_s1a3_table[5][2] ={ { 1, 8}, { 3, 4}, { 5,12}, {13,14}, {15, 0} };
1544     if (0xFC < c1) return 1;
1545 #ifdef SHIFTJIS_CP932
1546     if (!cp932inv_f && is_ibmext_in_sjis(c2)){
1547         val = shiftjis_cp932[c2 - CP932_TABLE_BEGIN][c1 - 0x40];
1548         if (val){
1549             c2 = val >> 8;
1550             c1 = val & 0xff;
1551         }
1552     }
1553     if (cp932inv_f
1554         && CP932INV_TABLE_BEGIN <= c2 && c2 <= CP932INV_TABLE_END){
1555         val = cp932inv[c2 - CP932INV_TABLE_BEGIN][c1 - 0x40];
1556         if (val){
1557             c2 = val >> 8;
1558             c1 = val & 0xff;
1559         }
1560     }
1561 #endif /* SHIFTJIS_CP932 */
1562 #ifdef X0212_ENABLE
1563     if (!x0213_f && is_ibmext_in_sjis(c2)){
1564         val = shiftjis_x0212[c2 - 0xfa][c1 - 0x40];
1565         if (val){
1566             if (val > 0x7FFF){
1567                 c2 = PREFIX_EUCG3 | ((val >> 8) & 0x7f);
1568                 c1 = val & 0xff;
1569             }else{
1570                 c2 = val >> 8;
1571                 c1 = val & 0xff;
1572             }
1573             if (p2) *p2 = c2;
1574             if (p1) *p1 = c1;
1575             return 0;
1576         }
1577     }
1578 #endif
1579     if(c2 >= 0x80){
1580         if(x0213_f && c2 >= 0xF0){
1581             if(c2 <= 0xF3 || (c2 == 0xF4 && c1 < 0x9F)){ /* k=1, 3<=k<=5, k=8, 12<=k<=15 */
1582                 c2 = PREFIX_EUCG3 | 0x20 | shift_jisx0213_s1a3_table[c2 - 0xF0][0x9E < c1];
1583             }else{ /* 78<=k<=94 */
1584                 c2 = PREFIX_EUCG3 | (c2 * 2 - 0x17B);
1585                 if (0x9E < c1) c2++;
1586             }
1587         }else{
1588 #define         SJ0162  0x00e1          /* 01 - 62 ku offset */
1589 #define         SJ6394  0x0161          /* 63 - 94 ku offset */
1590             c2 = c2 + c2 - ((c2 <= 0x9F) ? SJ0162 : SJ6394);
1591             if (0x9E < c1) c2++;
1592         }
1593         if (c1 < 0x9F)
1594             c1 = c1 - ((c1 > DEL) ? SP : 0x1F);
1595         else {
1596             c1 = c1 - 0x7E;
1597         }
1598     }
1599
1600 #ifdef X0212_ENABLE
1601     c2 = x0212_unshift(c2);
1602 #endif
1603     if (p2) *p2 = c2;
1604     if (p1) *p1 = c1;
1605     return 0;
1606 }
1607
1608 #if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
1609 static void
1610 nkf_unicode_to_utf8(nkf_char val, nkf_char *p1, nkf_char *p2, nkf_char *p3, nkf_char *p4)
1611 {
1612     val &= VALUE_MASK;
1613     if (val < 0x80){
1614         *p1 = val;
1615         *p2 = 0;
1616         *p3 = 0;
1617         *p4 = 0;
1618     }else if (val < 0x800){
1619         *p1 = 0xc0 | (val >> 6);
1620         *p2 = 0x80 | (val & 0x3f);
1621         *p3 = 0;
1622         *p4 = 0;
1623     } else if (nkf_char_unicode_bmp_p(val)) {
1624         *p1 = 0xe0 |  (val >> 12);
1625         *p2 = 0x80 | ((val >>  6) & 0x3f);
1626         *p3 = 0x80 | ( val        & 0x3f);
1627         *p4 = 0;
1628     } else if (nkf_char_unicode_value_p(val)) {
1629         *p1 = 0xe0 |  (val >> 16);
1630         *p2 = 0x80 | ((val >> 12) & 0x3f);
1631         *p3 = 0x80 | ((val >>  6) & 0x3f);
1632         *p4 = 0x80 | ( val        & 0x3f);
1633     } else {
1634         *p1 = 0;
1635         *p2 = 0;
1636         *p3 = 0;
1637         *p4 = 0;
1638     }
1639 }
1640
1641 static nkf_char
1642 nkf_utf8_to_unicode(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4)
1643 {
1644     nkf_char wc;
1645     if (c1 <= 0x7F) {
1646         /* single byte */
1647         wc = c1;
1648     }
1649     else if (c1 <= 0xC3) {
1650         /* trail byte or invalid */
1651         return -1;
1652     }
1653     else if (c1 <= 0xDF) {
1654         /* 2 bytes */
1655         wc  = (c1 & 0x1F) << 6;
1656         wc |= (c2 & 0x3F);
1657     }
1658     else if (c1 <= 0xEF) {
1659         /* 3 bytes */
1660         wc  = (c1 & 0x0F) << 12;
1661         wc |= (c2 & 0x3F) << 6;
1662         wc |= (c3 & 0x3F);
1663     }
1664     else if (c2 <= 0xF4) {
1665         /* 4 bytes */
1666         wc  = (c1 & 0x0F) << 18;
1667         wc |= (c2 & 0x3F) << 12;
1668         wc |= (c3 & 0x3F) << 6;
1669         wc |= (c4 & 0x3F);
1670     }
1671     else {
1672         return -1;
1673     }
1674     return wc;
1675 }
1676 #endif
1677
1678 #ifdef UTF8_INPUT_ENABLE
1679 static int
1680 unicode_to_jis_common2(nkf_char c1, nkf_char c0,
1681                        const unsigned short *const *pp, nkf_char psize,
1682                        nkf_char *p2, nkf_char *p1)
1683 {
1684     nkf_char c2;
1685     const unsigned short *p;
1686     unsigned short val;
1687
1688     if (pp == 0) return 1;
1689
1690     c1 -= 0x80;
1691     if (c1 < 0 || psize <= c1) return 1;
1692     p = pp[c1];
1693     if (p == 0)  return 1;
1694
1695     c0 -= 0x80;
1696     if (c0 < 0 || sizeof_utf8_to_euc_C2 <= c0) return 1;
1697     val = p[c0];
1698     if (val == 0) return 1;
1699     if (no_cp932ext_f && (
1700                           (val>>8) == 0x2D || /* NEC special characters */
1701                           val > NKF_INT32_C(0xF300) /* IBM extended characters */
1702                          )) return 1;
1703
1704     c2 = val >> 8;
1705     if (val > 0x7FFF){
1706         c2 &= 0x7f;
1707         c2 |= PREFIX_EUCG3;
1708     }
1709     if (c2 == SO) c2 = JIS_X_0201_1976_K;
1710     c1 = val & 0xFF;
1711     if (p2) *p2 = c2;
1712     if (p1) *p1 = c1;
1713     return 0;
1714 }
1715
1716 static int
1717 unicode_to_jis_common(nkf_char c2, nkf_char c1, nkf_char c0, nkf_char *p2, nkf_char *p1)
1718 {
1719     const unsigned short *const *pp;
1720     const unsigned short *const *const *ppp;
1721     static const char no_best_fit_chars_table_C2[] =
1722     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1723         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1724         1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 2, 1, 1, 2,
1725         0, 0, 1, 1, 0, 1, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1};
1726     static const char no_best_fit_chars_table_C2_ms[] =
1727     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1728         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1729         1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0,
1730         0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0};
1731     static const char no_best_fit_chars_table_932_C2[] =
1732     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1733         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1734         1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1,
1735         0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0};
1736     static const char no_best_fit_chars_table_932_C3[] =
1737     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1738         1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1739         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1740         1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1};
1741     nkf_char ret = 0;
1742
1743     if(c2 < 0x80){
1744         *p2 = 0;
1745         *p1 = c2;
1746     }else if(c2 < 0xe0){
1747         if(no_best_fit_chars_f){
1748             if(ms_ucs_map_f == UCS_MAP_CP932){
1749                 switch(c2){
1750                 case 0xC2:
1751                     if(no_best_fit_chars_table_932_C2[c1&0x3F]) return 1;
1752                     break;
1753                 case 0xC3:
1754                     if(no_best_fit_chars_table_932_C3[c1&0x3F]) return 1;
1755                     break;
1756                 }
1757             }else if(!cp932inv_f){
1758                 switch(c2){
1759                 case 0xC2:
1760                     if(no_best_fit_chars_table_C2[c1&0x3F]) return 1;
1761                     break;
1762                 case 0xC3:
1763                     if(no_best_fit_chars_table_932_C3[c1&0x3F]) return 1;
1764                     break;
1765                 }
1766             }else if(ms_ucs_map_f == UCS_MAP_MS){
1767                 if(c2 == 0xC2 && no_best_fit_chars_table_C2_ms[c1&0x3F]) return 1;
1768             }else if(ms_ucs_map_f == UCS_MAP_CP10001){
1769                 switch(c2){
1770                 case 0xC2:
1771                     switch(c1){
1772                     case 0xA2:
1773                     case 0xA3:
1774                     case 0xA5:
1775                     case 0xA6:
1776                     case 0xAC:
1777                     case 0xAF:
1778                     case 0xB8:
1779                         return 1;
1780                     }
1781                     break;
1782                 }
1783             }
1784         }
1785         pp =
1786             ms_ucs_map_f == UCS_MAP_CP932 ? utf8_to_euc_2bytes_932 :
1787             ms_ucs_map_f == UCS_MAP_MS ? utf8_to_euc_2bytes_ms :
1788             ms_ucs_map_f == UCS_MAP_CP10001 ? utf8_to_euc_2bytes_mac :
1789             utf8_to_euc_2bytes;
1790         ret =  unicode_to_jis_common2(c2, c1, pp, sizeof_utf8_to_euc_2bytes, p2, p1);
1791     }else if(c0 < 0xF0){
1792         if(no_best_fit_chars_f){
1793             if(ms_ucs_map_f == UCS_MAP_CP932){
1794                 if(c2 == 0xE3 && c1 == 0x82 && c0 == 0x94) return 1;
1795             }else if(ms_ucs_map_f == UCS_MAP_MS){
1796                 switch(c2){
1797                 case 0xE2:
1798                     switch(c1){
1799                     case 0x80:
1800                         if(c0 == 0x94 || c0 == 0x96 || c0 == 0xBE) return 1;
1801                         break;
1802                     case 0x88:
1803                         if(c0 == 0x92) return 1;
1804                         break;
1805                     }
1806                     break;
1807                 case 0xE3:
1808                     if(c1 == 0x80 || c0 == 0x9C) return 1;
1809                     break;
1810                 }
1811             }else if(ms_ucs_map_f == UCS_MAP_CP10001){
1812                 switch(c2){
1813                 case 0xE3:
1814                     switch(c1){
1815                     case 0x82:
1816                         if(c0 == 0x94) return 1;
1817                         break;
1818                     case 0x83:
1819                         if(c0 == 0xBB) return 1;
1820                         break;
1821                     }
1822                     break;
1823                 }
1824             }else{
1825                 switch(c2){
1826                 case 0xE2:
1827                     switch(c1){
1828                     case 0x80:
1829                         if(c0 == 0x95) return 1;
1830                         break;
1831                     case 0x88:
1832                         if(c0 == 0xA5) return 1;
1833                         break;
1834                     }
1835                     break;
1836                 case 0xEF:
1837                     switch(c1){
1838                     case 0xBC:
1839                         if(c0 == 0x8D) return 1;
1840                         break;
1841                     case 0xBD:
1842                         if(c0 == 0x9E && !cp932inv_f) return 1;
1843                         break;
1844                     case 0xBF:
1845                         if(0xA0 <= c0 && c0 <= 0xA5) return 1;
1846                         break;
1847                     }
1848                     break;
1849                 }
1850             }
1851         }
1852         ppp =
1853             ms_ucs_map_f == UCS_MAP_CP932 ? utf8_to_euc_3bytes_932 :
1854             ms_ucs_map_f == UCS_MAP_MS ? utf8_to_euc_3bytes_ms :
1855             ms_ucs_map_f == UCS_MAP_CP10001 ? utf8_to_euc_3bytes_mac :
1856             utf8_to_euc_3bytes;
1857         ret = unicode_to_jis_common2(c1, c0, ppp[c2 - 0xE0], sizeof_utf8_to_euc_C2, p2, p1);
1858     }else return -1;
1859 #ifdef SHIFTJIS_CP932
1860     if (!ret && !cp932inv_f && is_eucg3(*p2)) {
1861         nkf_char s2, s1;
1862         if (e2s_conv(*p2, *p1, &s2, &s1) == 0) {
1863             s2e_conv(s2, s1, p2, p1);
1864         }else{
1865             ret = 1;
1866         }
1867     }
1868 #endif
1869     return ret;
1870 }
1871
1872 #ifdef UTF8_OUTPUT_ENABLE
1873 static nkf_char
1874 e2w_conv(nkf_char c2, nkf_char c1)
1875 {
1876     const unsigned short *p;
1877
1878     if (c2 == JIS_X_0201_1976_K) {
1879         if (ms_ucs_map_f == UCS_MAP_CP10001) {
1880             switch (c1) {
1881             case 0x20:
1882                 return 0xA0;
1883             case 0x7D:
1884                 return 0xA9;
1885             }
1886         }
1887         p = euc_to_utf8_1byte;
1888 #ifdef X0212_ENABLE
1889     } else if (is_eucg3(c2)){
1890         if(ms_ucs_map_f == UCS_MAP_ASCII&& c2 == NKF_INT32_C(0x8F22) && c1 == 0x43){
1891             return 0xA6;
1892         }
1893         c2 = (c2&0x7f) - 0x21;
1894         if (0<=c2 && c2<sizeof_euc_to_utf8_2bytes)
1895             p = x0212_to_utf8_2bytes[c2];
1896         else
1897             return 0;
1898 #endif
1899     } else {
1900         c2 &= 0x7f;
1901         c2 = (c2&0x7f) - 0x21;
1902         if (0<=c2 && c2<sizeof_euc_to_utf8_2bytes)
1903             p =
1904                 ms_ucs_map_f == UCS_MAP_ASCII ? euc_to_utf8_2bytes[c2] :
1905                 ms_ucs_map_f == UCS_MAP_CP10001 ? euc_to_utf8_2bytes_mac[c2] :
1906                 euc_to_utf8_2bytes_ms[c2];
1907         else
1908             return 0;
1909     }
1910     if (!p) return 0;
1911     c1 = (c1 & 0x7f) - 0x21;
1912     if (0<=c1 && c1<sizeof_euc_to_utf8_1byte)
1913         return p[c1];
1914     return 0;
1915 }
1916 #endif
1917
1918 static nkf_char
1919 w2e_conv(nkf_char c2, nkf_char c1, nkf_char c0, nkf_char *p2, nkf_char *p1)
1920 {
1921     nkf_char ret = 0;
1922
1923     if (!c1){
1924         *p2 = 0;
1925         *p1 = c2;
1926     }else if (0xc0 <= c2 && c2 <= 0xef) {
1927         ret =  unicode_to_jis_common(c2, c1, c0, p2, p1);
1928 #ifdef NUMCHAR_OPTION
1929         if (ret > 0){
1930             if (p2) *p2 = 0;
1931             if (p1) *p1 = nkf_char_unicode_new(nkf_utf8_to_unicode(c2, c1, c0, 0));
1932             ret = 0;
1933         }
1934 #endif
1935     }
1936     return ret;
1937 }
1938
1939 #ifdef UTF8_INPUT_ENABLE
1940 static nkf_char
1941 w16e_conv(nkf_char val, nkf_char *p2, nkf_char *p1)
1942 {
1943     nkf_char c1, c2, c3, c4;
1944     nkf_char ret = 0;
1945     val &= VALUE_MASK;
1946     if (val < 0x80) {
1947         *p2 = 0;
1948         *p1 = val;
1949     }
1950     else if (nkf_char_unicode_bmp_p(val)){
1951         nkf_unicode_to_utf8(val, &c1, &c2, &c3, &c4);
1952         ret =  unicode_to_jis_common(c1, c2, c3, p2, p1);
1953         if (ret > 0){
1954             *p2 = 0;
1955             *p1 = nkf_char_unicode_new(val);
1956             ret = 0;
1957         }
1958     }
1959     else {
1960         *p2 = 0;
1961         *p1 = nkf_char_unicode_new(val);
1962     }
1963     return ret;
1964 }
1965 #endif
1966
1967 static nkf_char
1968 e_iconv(nkf_char c2, nkf_char c1, nkf_char c0)
1969 {
1970     if (c2 == JIS_X_0201_1976_K || c2 == SS2){
1971         if (iso2022jp_f && !x0201_f) {
1972             c2 = GETA1; c1 = GETA2;
1973         } else {
1974             c2 = JIS_X_0201_1976_K;
1975             c1 &= 0x7f;
1976         }
1977 #ifdef X0212_ENABLE
1978     }else if (c2 == 0x8f){
1979         if (c0 == 0){
1980             return -1;
1981         }
1982         if (!cp51932_f && !x0213_f && 0xF5 <= c1 && c1 <= 0xFE && 0xA1 <= c0 && c0 <= 0xFE) {
1983             /* encoding is eucJP-ms, so invert to Unicode Private User Area */
1984             c1 = nkf_char_unicode_new((c1 - 0xF5) * 94 + c0 - 0xA1 + 0xE3AC);
1985             c2 = 0;
1986         } else {
1987             c2 = (c2 << 8) | (c1 & 0x7f);
1988             c1 = c0 & 0x7f;
1989 #ifdef SHIFTJIS_CP932
1990             if (cp51932_f){
1991                 nkf_char s2, s1;
1992                 if (e2s_conv(c2, c1, &s2, &s1) == 0){
1993                     s2e_conv(s2, s1, &c2, &c1);
1994                     if (c2 < 0x100){
1995                         c1 &= 0x7f;
1996                         c2 &= 0x7f;
1997                     }
1998                 }
1999             }
2000 #endif /* SHIFTJIS_CP932 */
2001         }
2002 #endif /* X0212_ENABLE */
2003     } else if ((c2 == EOF) || (c2 == 0) || c2 < SP || c2 == ISO_8859_1) {
2004         /* NOP */
2005     } else {
2006         if (!cp51932_f && ms_ucs_map_f && 0xF5 <= c2 && c2 <= 0xFE && 0xA1 <= c1 && c1 <= 0xFE) {
2007             /* encoding is eucJP-ms, so invert to Unicode Private User Area */
2008             c1 = nkf_char_unicode_new((c2 - 0xF5) * 94 + c1 - 0xA1 + 0xE000);
2009             c2 = 0;
2010         } else {
2011             c1 &= 0x7f;
2012             c2 &= 0x7f;
2013 #ifdef SHIFTJIS_CP932
2014             if (cp51932_f && 0x79 <= c2 && c2 <= 0x7c){
2015                 nkf_char s2, s1;
2016                 if (e2s_conv(c2, c1, &s2, &s1) == 0){
2017                     s2e_conv(s2, s1, &c2, &c1);
2018                     if (c2 < 0x100){
2019                         c1 &= 0x7f;
2020                         c2 &= 0x7f;
2021                     }
2022                 }
2023             }
2024 #endif /* SHIFTJIS_CP932 */
2025         }
2026     }
2027     (*oconv)(c2, c1);
2028     return 0;
2029 }
2030
2031 static nkf_char
2032 s_iconv(nkf_char c2, nkf_char c1, nkf_char c0)
2033 {
2034     if (c2 == JIS_X_0201_1976_K || (0xA1 <= c2 && c2 <= 0xDF)) {
2035         if (iso2022jp_f && !x0201_f) {
2036             c2 = GETA1; c1 = GETA2;
2037         } else {
2038             c1 &= 0x7f;
2039         }
2040     } else if ((c2 == EOF) || (c2 == 0) || c2 < SP) {
2041         /* NOP */
2042     } else if (!x0213_f && 0xF0 <= c2 && c2 <= 0xF9 && 0x40 <= c1 && c1 <= 0xFC) {
2043         /* CP932 UDC */
2044         if(c1 == 0x7F) return 0;
2045         c1 = nkf_char_unicode_new((c2 - 0xF0) * 188 + (c1 - 0x40 - (0x7E < c1)) + 0xE000);
2046         c2 = 0;
2047     } else {
2048         nkf_char ret = s2e_conv(c2, c1, &c2, &c1);
2049         if (ret) return ret;
2050     }
2051     (*oconv)(c2, c1);
2052     return 0;
2053 }
2054
2055 static nkf_char
2056 w_iconv(nkf_char c1, nkf_char c2, nkf_char c3)
2057 {
2058     nkf_char ret = 0, c4 = 0;
2059     static const char w_iconv_utf8_1st_byte[] =
2060     { /* 0xC0 - 0xFF */
2061         20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
2062         21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
2063         30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 33,
2064         40, 41, 41, 41, 42, 43, 43, 43, 50, 50, 50, 50, 60, 60, 70, 70};
2065
2066     if (c3 > 0xFF) {
2067         c4 = c3 & 0xFF;
2068         c3 >>= 8;
2069     }
2070
2071     if (c1 < 0 || 0xff < c1) {
2072     }else if (c1 == 0) { /* 0 : 1 byte*/
2073         c3 = 0;
2074     } else if ((c1 & 0xC0) == 0x80) { /* 0x80-0xbf : trail byte */
2075         return 0;
2076     } else{
2077         switch (w_iconv_utf8_1st_byte[c1 - 0xC0]) {
2078         case 21:
2079             if (c2 < 0x80 || 0xBF < c2) return 0;
2080             break;
2081         case 30:
2082             if (c3 == 0) return -1;
2083             if (c2 < 0xA0 || 0xBF < c2 || (c3 & 0xC0) != 0x80)
2084                 return 0;
2085             break;
2086         case 31:
2087         case 33:
2088             if (c3 == 0) return -1;
2089             if ((c2 & 0xC0) != 0x80 || (c3 & 0xC0) != 0x80)
2090                 return 0;
2091             break;
2092         case 32:
2093             if (c3 == 0) return -1;
2094             if (c2 < 0x80 || 0x9F < c2 || (c3 & 0xC0) != 0x80)
2095                 return 0;
2096             break;
2097         case 40:
2098             if (c3 == 0) return -2;
2099             if (c2 < 0x90 || 0xBF < c2 || (c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2100                 return 0;
2101             break;
2102         case 41:
2103             if (c3 == 0) return -2;
2104             if (c2 < 0x80 || 0xBF < c2 || (c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2105                 return 0;
2106             break;
2107         case 42:
2108             if (c3 == 0) return -2;
2109             if (c2 < 0x80 || 0x8F < c2 || (c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2110                 return 0;
2111             break;
2112         default:
2113             return 0;
2114             break;
2115         }
2116     }
2117     if (c1 == 0 || c1 == EOF){
2118     } else if ((c1 & 0xf8) == 0xf0) { /* 4 bytes */
2119         c2 = nkf_char_unicode_new(nkf_utf8_to_unicode(c1, c2, c3, c4));
2120         c1 = 0;
2121     } else {
2122         ret = w2e_conv(c1, c2, c3, &c1, &c2);
2123     }
2124     if (ret == 0){
2125         (*oconv)(c1, c2);
2126     }
2127     return ret;
2128 }
2129
2130 #define NKF_ICONV_INVALID_CODE_RANGE -13
2131 static size_t
2132 unicode_iconv(nkf_char wc)
2133 {
2134     nkf_char c1, c2;
2135     int ret = 0;
2136
2137     if (wc < 0x80) {
2138         c2 = 0;
2139         c1 = wc;
2140     }else if ((wc>>11) == 27) {
2141         /* unpaired surrogate */
2142         return NKF_ICONV_INVALID_CODE_RANGE;
2143     }else if (wc < 0xFFFF) {
2144         ret = w16e_conv(wc, &c2, &c1);
2145         if (ret) return ret;
2146     }else if (wc < 0x10FFFF) {
2147         c2 = 0;
2148         c1 = nkf_char_unicode_new(wc);
2149     } else {
2150         return NKF_ICONV_INVALID_CODE_RANGE;
2151     }
2152     (*oconv)(c2, c1);
2153     return 0;
2154 }
2155
2156 #define NKF_ICONV_NEED_ONE_MORE_BYTE -1
2157 #define NKF_ICONV_NEED_TWO_MORE_BYTES -2
2158 #define UTF16_TO_UTF32(lead, trail) (((lead) << 10) + (trail) - NKF_INT32_C(0x35FDC00))
2159 static size_t
2160 nkf_iconv_utf_16(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4)
2161 {
2162     nkf_char wc;
2163
2164     if (c1 == EOF) {
2165         (*oconv)(EOF, 0);
2166         return 0;
2167     }
2168
2169     if (input_endian == ENDIAN_BIG) {
2170         if (0xD8 <= c1 && c1 <= 0xDB) {
2171             if (0xDC <= c3 && c3 <= 0xDF) {
2172                 wc = UTF16_TO_UTF32(c1 << 8 | c2, c3 << 8 | c4);
2173             } else return NKF_ICONV_NEED_TWO_MORE_BYTES;
2174         } else {
2175             wc = c1 << 8 | c2;
2176         }
2177     } else {
2178         if (0xD8 <= c2 && c2 <= 0xDB) {
2179             if (0xDC <= c4 && c4 <= 0xDF) {
2180                 wc = UTF16_TO_UTF32(c2 << 8 | c1, c4 << 8 | c3);
2181             } else return NKF_ICONV_NEED_TWO_MORE_BYTES;
2182         } else {
2183             wc = c2 << 8 | c1;
2184         }
2185     }
2186
2187     return (*unicode_iconv)(wc);
2188 }
2189
2190 static nkf_char
2191 w_iconv16(nkf_char c2, nkf_char c1, nkf_char c0)
2192 {
2193     return 0;
2194 }
2195
2196 static nkf_char
2197 w_iconv32(nkf_char c2, nkf_char c1, nkf_char c0)
2198 {
2199     return 0;
2200 }
2201
2202 static size_t
2203 nkf_iconv_utf_32(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4)
2204 {
2205     nkf_char wc;
2206
2207     if (c1 == EOF) {
2208         (*oconv)(EOF, 0);
2209         return 0;
2210     }
2211
2212     switch(input_endian){
2213     case ENDIAN_BIG:
2214         wc = c2 << 16 | c3 << 8 | c4;
2215         break;
2216     case ENDIAN_LITTLE:
2217         wc = c3 << 16 | c2 << 8 | c1;
2218         break;
2219     case ENDIAN_2143:
2220         wc = c1 << 16 | c4 << 8 | c3;
2221         break;
2222     case ENDIAN_3412:
2223         wc = c4 << 16 | c1 << 8 | c2;
2224         break;
2225     default:
2226         return NKF_ICONV_INVALID_CODE_RANGE;
2227     }
2228
2229     return (*unicode_iconv)(wc);
2230 }
2231 #endif
2232
2233 #define output_ascii_escape_sequence(mode) do { \
2234             if (output_mode != ASCII && output_mode != ISO_8859_1) { \
2235                     (*o_putc)(ESC); \
2236                     (*o_putc)('('); \
2237                     (*o_putc)(ascii_intro); \
2238                     output_mode = mode; \
2239             } \
2240     } while (0)
2241
2242 static void
2243 output_escape_sequence(int mode)
2244 {
2245     if (output_mode == mode)
2246         return;
2247     switch(mode) {
2248     case ISO_8859_1:
2249         (*o_putc)(ESC);
2250         (*o_putc)('.');
2251         (*o_putc)('A');
2252         break;
2253     case JIS_X_0201_1976_K:
2254         (*o_putc)(ESC);
2255         (*o_putc)('(');
2256         (*o_putc)('I');
2257         break;
2258     case JIS_X_0208:
2259         (*o_putc)(ESC);
2260         (*o_putc)('$');
2261         (*o_putc)(kanji_intro);
2262         break;
2263     case JIS_X_0212:
2264         (*o_putc)(ESC);
2265         (*o_putc)('$');
2266         (*o_putc)('(');
2267         (*o_putc)('D');
2268         break;
2269     case JIS_X_0213_1:
2270         (*o_putc)(ESC);
2271         (*o_putc)('$');
2272         (*o_putc)('(');
2273         (*o_putc)('Q');
2274         break;
2275     case JIS_X_0213_2:
2276         (*o_putc)(ESC);
2277         (*o_putc)('$');
2278         (*o_putc)('(');
2279         (*o_putc)('P');
2280         break;
2281     }
2282     output_mode = mode;
2283 }
2284
2285 static void
2286 j_oconv(nkf_char c2, nkf_char c1)
2287 {
2288 #ifdef NUMCHAR_OPTION
2289     if (c2 == 0 && nkf_char_unicode_p(c1)){
2290         w16e_conv(c1, &c2, &c1);
2291         if (c2 == 0 && nkf_char_unicode_p(c1)){
2292             c2 = c1 & VALUE_MASK;
2293             if (ms_ucs_map_f && 0xE000 <= c2 && c2 <= 0xE757) {
2294                 /* CP5022x UDC */
2295                 c1 &= 0xFFF;
2296                 c2 = 0x7F + c1 / 94;
2297                 c1 = 0x21 + c1 % 94;
2298             } else {
2299                 if (encode_fallback) (*encode_fallback)(c1);
2300                 return;
2301             }
2302         }
2303     }
2304 #endif
2305     if (c2 == 0) {
2306         output_ascii_escape_sequence(ASCII);
2307         (*o_putc)(c1);
2308     }
2309     else if (c2 == EOF) {
2310         output_ascii_escape_sequence(ASCII);
2311         (*o_putc)(EOF);
2312     }
2313     else if (c2 == ISO_8859_1) {
2314         output_ascii_escape_sequence(ISO_8859_1);
2315         (*o_putc)(c1|0x80);
2316     }
2317     else if (c2 == JIS_X_0201_1976_K) {
2318         output_escape_sequence(JIS_X_0201_1976_K);
2319         (*o_putc)(c1);
2320 #ifdef X0212_ENABLE
2321     } else if (is_eucg3(c2)){
2322         output_escape_sequence(x0213_f ? JIS_X_0213_2 : JIS_X_0212);
2323         (*o_putc)(c2 & 0x7f);
2324         (*o_putc)(c1);
2325 #endif
2326     } else {
2327         if(ms_ucs_map_f
2328            ? c2<0x20 || 0x92<c2 || c1<0x20 || 0x7e<c1
2329            : c2<0x20 || 0x7e<c2 || c1<0x20 || 0x7e<c1) return;
2330         output_escape_sequence(x0213_f ? JIS_X_0213_1 : JIS_X_0208);
2331         (*o_putc)(c2);
2332         (*o_putc)(c1);
2333     }
2334 }
2335
2336 static void
2337 e_oconv(nkf_char c2, nkf_char c1)
2338 {
2339     if (c2 == 0 && nkf_char_unicode_p(c1)){
2340         w16e_conv(c1, &c2, &c1);
2341         if (c2 == 0 && nkf_char_unicode_p(c1)){
2342             c2 = c1 & VALUE_MASK;
2343             if (x0212_f && 0xE000 <= c2 && c2 <= 0xE757) {
2344                 /* eucJP-ms UDC */
2345                 c1 &= 0xFFF;
2346                 c2 = c1 / 94;
2347                 c2 += c2 < 10 ? 0x75 : 0x8FEB;
2348                 c1 = 0x21 + c1 % 94;
2349                 if (is_eucg3(c2)){
2350                     (*o_putc)(0x8f);
2351                     (*o_putc)((c2 & 0x7f) | 0x080);
2352                     (*o_putc)(c1 | 0x080);
2353                 }else{
2354                     (*o_putc)((c2 & 0x7f) | 0x080);
2355                     (*o_putc)(c1 | 0x080);
2356                 }
2357                 return;
2358             } else {
2359                 if (encode_fallback) (*encode_fallback)(c1);
2360                 return;
2361             }
2362         }
2363     }
2364
2365     if (c2 == EOF) {
2366         (*o_putc)(EOF);
2367     } else if (c2 == 0) {
2368         output_mode = ASCII;
2369         (*o_putc)(c1);
2370     } else if (c2 == JIS_X_0201_1976_K) {
2371         output_mode = EUC_JP;
2372         (*o_putc)(SS2); (*o_putc)(c1|0x80);
2373     } else if (c2 == ISO_8859_1) {
2374         output_mode = ISO_8859_1;
2375         (*o_putc)(c1 | 0x080);
2376 #ifdef X0212_ENABLE
2377     } else if (is_eucg3(c2)){
2378         output_mode = EUC_JP;
2379 #ifdef SHIFTJIS_CP932
2380         if (!cp932inv_f){
2381             nkf_char s2, s1;
2382             if (e2s_conv(c2, c1, &s2, &s1) == 0){
2383                 s2e_conv(s2, s1, &c2, &c1);
2384             }
2385         }
2386 #endif
2387         if (c2 == 0) {
2388             output_mode = ASCII;
2389             (*o_putc)(c1);
2390         }else if (is_eucg3(c2)){
2391             if (x0212_f){
2392                 (*o_putc)(0x8f);
2393                 (*o_putc)((c2 & 0x7f) | 0x080);
2394                 (*o_putc)(c1 | 0x080);
2395             }
2396         }else{
2397             (*o_putc)((c2 & 0x7f) | 0x080);
2398             (*o_putc)(c1 | 0x080);
2399         }
2400 #endif
2401     } else {
2402         if (!nkf_isgraph(c1) || !nkf_isgraph(c2)) {
2403             set_iconv(FALSE, 0);
2404             return; /* too late to rescue this char */
2405         }
2406         output_mode = EUC_JP;
2407         (*o_putc)(c2 | 0x080);
2408         (*o_putc)(c1 | 0x080);
2409     }
2410 }
2411
2412 static void
2413 s_oconv(nkf_char c2, nkf_char c1)
2414 {
2415 #ifdef NUMCHAR_OPTION
2416     if (c2 == 0 && nkf_char_unicode_p(c1)){
2417         w16e_conv(c1, &c2, &c1);
2418         if (c2 == 0 && nkf_char_unicode_p(c1)){
2419             c2 = c1 & VALUE_MASK;
2420             if (!x0213_f && 0xE000 <= c2 && c2 <= 0xE757) {
2421                 /* CP932 UDC */
2422                 c1 &= 0xFFF;
2423                 c2 = c1 / 188 + (cp932inv_f ? 0xF0 : 0xEB);
2424                 c1 = c1 % 188;
2425                 c1 += 0x40 + (c1 > 0x3e);
2426                 (*o_putc)(c2);
2427                 (*o_putc)(c1);
2428                 return;
2429             } else {
2430                 if(encode_fallback)(*encode_fallback)(c1);
2431                 return;
2432             }
2433         }
2434     }
2435 #endif
2436     if (c2 == EOF) {
2437         (*o_putc)(EOF);
2438         return;
2439     } else if (c2 == 0) {
2440         output_mode = ASCII;
2441         (*o_putc)(c1);
2442     } else if (c2 == JIS_X_0201_1976_K) {
2443         output_mode = SHIFT_JIS;
2444         (*o_putc)(c1|0x80);
2445     } else if (c2 == ISO_8859_1) {
2446         output_mode = ISO_8859_1;
2447         (*o_putc)(c1 | 0x080);
2448 #ifdef X0212_ENABLE
2449     } else if (is_eucg3(c2)){
2450         output_mode = SHIFT_JIS;
2451         if (e2s_conv(c2, c1, &c2, &c1) == 0){
2452             (*o_putc)(c2);
2453             (*o_putc)(c1);
2454         }
2455 #endif
2456     } else {
2457         if (!nkf_isprint(c1) || !nkf_isprint(c2)) {
2458             set_iconv(FALSE, 0);
2459             return; /* too late to rescue this char */
2460         }
2461         output_mode = SHIFT_JIS;
2462         e2s_conv(c2, c1, &c2, &c1);
2463
2464 #ifdef SHIFTJIS_CP932
2465         if (cp932inv_f
2466             && CP932INV_TABLE_BEGIN <= c2 && c2 <= CP932INV_TABLE_END){
2467             nkf_char c = cp932inv[c2 - CP932INV_TABLE_BEGIN][c1 - 0x40];
2468             if (c){
2469                 c2 = c >> 8;
2470                 c1 = c & 0xff;
2471             }
2472         }
2473 #endif /* SHIFTJIS_CP932 */
2474
2475         (*o_putc)(c2);
2476         if (prefix_table[(unsigned char)c1]){
2477             (*o_putc)(prefix_table[(unsigned char)c1]);
2478         }
2479         (*o_putc)(c1);
2480     }
2481 }
2482
2483 #ifdef UTF8_OUTPUT_ENABLE
2484 static void
2485 w_oconv(nkf_char c2, nkf_char c1)
2486 {
2487     nkf_char c3, c4;
2488     nkf_char val;
2489
2490     if (output_bom_f) {
2491         output_bom_f = FALSE;
2492         (*o_putc)('\357');
2493         (*o_putc)('\273');
2494         (*o_putc)('\277');
2495     }
2496
2497     if (c2 == EOF) {
2498         (*o_putc)(EOF);
2499         return;
2500     }
2501
2502     if (c2 == 0 && nkf_char_unicode_p(c1)){
2503         val = c1 & VALUE_MASK;
2504         nkf_unicode_to_utf8(val, &c1, &c2, &c3, &c4);
2505         (*o_putc)(c1);
2506         if (c2) (*o_putc)(c2);
2507         if (c3) (*o_putc)(c3);
2508         if (c4) (*o_putc)(c4);
2509         return;
2510     }
2511
2512     if (c2 == 0) {
2513         (*o_putc)(c1);
2514     } else {
2515         val = e2w_conv(c2, c1);
2516         if (val){
2517             nkf_unicode_to_utf8(val, &c1, &c2, &c3, &c4);
2518             (*o_putc)(c1);
2519             if (c2) (*o_putc)(c2);
2520             if (c3) (*o_putc)(c3);
2521             if (c4) (*o_putc)(c4);
2522         }
2523     }
2524 }
2525
2526 static void
2527 w_oconv16(nkf_char c2, nkf_char c1)
2528 {
2529     if (output_bom_f) {
2530         output_bom_f = FALSE;
2531         if (output_endian == ENDIAN_LITTLE){
2532             (*o_putc)(0xFF);
2533             (*o_putc)(0xFE);
2534         }else{
2535             (*o_putc)(0xFE);
2536             (*o_putc)(0xFF);
2537         }
2538     }
2539
2540     if (c2 == EOF) {
2541         (*o_putc)(EOF);
2542         return;
2543     }
2544
2545     if (c2 == 0 && nkf_char_unicode_p(c1)) {
2546         if (nkf_char_unicode_bmp_p(c1)) {
2547             c2 = (c1 >> 8) & 0xff;
2548             c1 &= 0xff;
2549         } else {
2550             c1 &= VALUE_MASK;
2551             if (c1 <= UNICODE_MAX) {
2552                 c2 = (c1 >> 10) + NKF_INT32_C(0xD7C0);   /* high surrogate */
2553                 c1 = (c1 & 0x3FF) + NKF_INT32_C(0xDC00); /* low surrogate */
2554                 if (output_endian == ENDIAN_LITTLE){
2555                     (*o_putc)(c2 & 0xff);
2556                     (*o_putc)((c2 >> 8) & 0xff);
2557                     (*o_putc)(c1 & 0xff);
2558                     (*o_putc)((c1 >> 8) & 0xff);
2559                 }else{
2560                     (*o_putc)((c2 >> 8) & 0xff);
2561                     (*o_putc)(c2 & 0xff);
2562                     (*o_putc)((c1 >> 8) & 0xff);
2563                     (*o_putc)(c1 & 0xff);
2564                 }
2565             }
2566             return;
2567         }
2568     } else if (c2) {
2569         nkf_char val = e2w_conv(c2, c1);
2570         c2 = (val >> 8) & 0xff;
2571         c1 = val & 0xff;
2572         if (!val) return;
2573     }
2574
2575     if (output_endian == ENDIAN_LITTLE){
2576         (*o_putc)(c1);
2577         (*o_putc)(c2);
2578     }else{
2579         (*o_putc)(c2);
2580         (*o_putc)(c1);
2581     }
2582 }
2583
2584 static void
2585 w_oconv32(nkf_char c2, nkf_char c1)
2586 {
2587     if (output_bom_f) {
2588         output_bom_f = FALSE;
2589         if (output_endian == ENDIAN_LITTLE){
2590             (*o_putc)(0xFF);
2591             (*o_putc)(0xFE);
2592             (*o_putc)(0);
2593             (*o_putc)(0);
2594         }else{
2595             (*o_putc)(0);
2596             (*o_putc)(0);
2597             (*o_putc)(0xFE);
2598             (*o_putc)(0xFF);
2599         }
2600     }
2601
2602     if (c2 == EOF) {
2603         (*o_putc)(EOF);
2604         return;
2605     }
2606
2607     if (c2 == ISO_8859_1) {
2608         c1 |= 0x80;
2609     } else if (c2 == 0 && nkf_char_unicode_p(c1)) {
2610         c1 &= VALUE_MASK;
2611     } else if (c2) {
2612         c1 = e2w_conv(c2, c1);
2613         if (!c1) return;
2614     }
2615     if (output_endian == ENDIAN_LITTLE){
2616         (*o_putc)( c1        & 0xFF);
2617         (*o_putc)((c1 >>  8) & 0xFF);
2618         (*o_putc)((c1 >> 16) & 0xFF);
2619         (*o_putc)(0);
2620     }else{
2621         (*o_putc)(0);
2622         (*o_putc)((c1 >> 16) & 0xFF);
2623         (*o_putc)((c1 >>  8) & 0xFF);
2624         (*o_putc)( c1        & 0xFF);
2625     }
2626 }
2627 #endif
2628
2629 #define SCORE_L2       (1)                   /* \e$BBh\e(B2\e$B?e=`4A;z\e(B */
2630 #define SCORE_KANA     (SCORE_L2 << 1)       /* \e$B$$$o$f$kH>3Q%+%J\e(B */
2631 #define SCORE_DEPEND   (SCORE_KANA << 1)     /* \e$B5!<o0MB8J8;z\e(B */
2632 #define SCORE_CP932    (SCORE_DEPEND << 1)   /* CP932 \e$B$K$h$kFI$_49$(\e(B (IBM extended characters) */
2633 #define SCORE_X0212    (SCORE_CP932 << 1)    /* JIS X 0212 */
2634 #define SCORE_NO_EXIST (SCORE_X0212 << 1)    /* \e$BB8:_$7$J$$J8;z\e(B */
2635 #define SCORE_iMIME    (SCORE_NO_EXIST << 1) /* MIME \e$B$K$h$k;XDj\e(B */
2636 #define SCORE_ERROR    (SCORE_iMIME << 1) /* \e$B%(%i!<\e(B */
2637
2638 #define SCORE_INIT (SCORE_iMIME)
2639
2640 static const char score_table_A0[] = {
2641     0, 0, 0, 0,
2642     0, 0, 0, 0,
2643     0, SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND,
2644     SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND, SCORE_NO_EXIST,
2645 };
2646
2647 static const char score_table_F0[] = {
2648     SCORE_L2, SCORE_L2, SCORE_L2, SCORE_L2,
2649     SCORE_L2, SCORE_DEPEND, SCORE_NO_EXIST, SCORE_NO_EXIST,
2650     SCORE_DEPEND, SCORE_DEPEND, SCORE_CP932, SCORE_CP932,
2651     SCORE_CP932, SCORE_NO_EXIST, SCORE_NO_EXIST, SCORE_ERROR,
2652 };
2653
2654 static void
2655 set_code_score(struct input_code *ptr, nkf_char score)
2656 {
2657     if (ptr){
2658         ptr->score |= score;
2659     }
2660 }
2661
2662 static void
2663 clr_code_score(struct input_code *ptr, nkf_char score)
2664 {
2665     if (ptr){
2666         ptr->score &= ~score;
2667     }
2668 }
2669
2670 static void
2671 code_score(struct input_code *ptr)
2672 {
2673     nkf_char c2 = ptr->buf[0];
2674 #ifdef UTF8_OUTPUT_ENABLE
2675     nkf_char c1 = ptr->buf[1];
2676 #endif
2677     if (c2 < 0){
2678         set_code_score(ptr, SCORE_ERROR);
2679     }else if (c2 == SS2){
2680         set_code_score(ptr, SCORE_KANA);
2681     }else if (c2 == 0x8f){
2682         set_code_score(ptr, SCORE_X0212);
2683 #ifdef UTF8_OUTPUT_ENABLE
2684     }else if (!e2w_conv(c2, c1)){
2685         set_code_score(ptr, SCORE_NO_EXIST);
2686 #endif
2687     }else if ((c2 & 0x70) == 0x20){
2688         set_code_score(ptr, score_table_A0[c2 & 0x0f]);
2689     }else if ((c2 & 0x70) == 0x70){
2690         set_code_score(ptr, score_table_F0[c2 & 0x0f]);
2691     }else if ((c2 & 0x70) >= 0x50){
2692         set_code_score(ptr, SCORE_L2);
2693     }
2694 }
2695
2696 static void
2697 status_disable(struct input_code *ptr)
2698 {
2699     ptr->stat = -1;
2700     ptr->buf[0] = -1;
2701     code_score(ptr);
2702     if (iconv == ptr->iconv_func) set_iconv(FALSE, 0);
2703 }
2704
2705 static void
2706 status_push_ch(struct input_code *ptr, nkf_char c)
2707 {
2708     ptr->buf[ptr->index++] = c;
2709 }
2710
2711 static void
2712 status_clear(struct input_code *ptr)
2713 {
2714     ptr->stat = 0;
2715     ptr->index = 0;
2716 }
2717
2718 static void
2719 status_reset(struct input_code *ptr)
2720 {
2721     status_clear(ptr);
2722     ptr->score = SCORE_INIT;
2723 }
2724
2725 static void
2726 status_reinit(struct input_code *ptr)
2727 {
2728     status_reset(ptr);
2729     ptr->_file_stat = 0;
2730 }
2731
2732 static void
2733 status_check(struct input_code *ptr, nkf_char c)
2734 {
2735     if (c <= DEL && estab_f){
2736         status_reset(ptr);
2737     }
2738 }
2739
2740 static void
2741 s_status(struct input_code *ptr, nkf_char c)
2742 {
2743     switch(ptr->stat){
2744     case -1:
2745         status_check(ptr, c);
2746         break;
2747     case 0:
2748         if (c <= DEL){
2749             break;
2750         }else if (nkf_char_unicode_p(c)){
2751             break;
2752         }else if (0xa1 <= c && c <= 0xdf){
2753             status_push_ch(ptr, SS2);
2754             status_push_ch(ptr, c);
2755             code_score(ptr);
2756             status_clear(ptr);
2757         }else if ((0x81 <= c && c < 0xa0) || (0xe0 <= c && c <= 0xea)){
2758             ptr->stat = 1;
2759             status_push_ch(ptr, c);
2760         }else if (0xed <= c && c <= 0xee){
2761             ptr->stat = 3;
2762             status_push_ch(ptr, c);
2763 #ifdef SHIFTJIS_CP932
2764         }else if (is_ibmext_in_sjis(c)){
2765             ptr->stat = 2;
2766             status_push_ch(ptr, c);
2767 #endif /* SHIFTJIS_CP932 */
2768 #ifdef X0212_ENABLE
2769         }else if (0xf0 <= c && c <= 0xfc){
2770             ptr->stat = 1;
2771             status_push_ch(ptr, c);
2772 #endif /* X0212_ENABLE */
2773         }else{
2774             status_disable(ptr);
2775         }
2776         break;
2777     case 1:
2778         if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)){
2779             status_push_ch(ptr, c);
2780             s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]);
2781             code_score(ptr);
2782             status_clear(ptr);
2783         }else{
2784             status_disable(ptr);
2785         }
2786         break;
2787     case 2:
2788 #ifdef SHIFTJIS_CP932
2789         if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)) {
2790             status_push_ch(ptr, c);
2791             if (s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]) == 0) {
2792                 set_code_score(ptr, SCORE_CP932);
2793                 status_clear(ptr);
2794                 break;
2795             }
2796         }
2797 #endif /* SHIFTJIS_CP932 */
2798         status_disable(ptr);
2799         break;
2800     case 3:
2801         if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)){
2802             status_push_ch(ptr, c);
2803             s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]);
2804             set_code_score(ptr, SCORE_CP932);
2805             status_clear(ptr);
2806         }else{
2807             status_disable(ptr);
2808         }
2809         break;
2810     }
2811 }
2812
2813 static void
2814 e_status(struct input_code *ptr, nkf_char c)
2815 {
2816     switch (ptr->stat){
2817     case -1:
2818         status_check(ptr, c);
2819         break;
2820     case 0:
2821         if (c <= DEL){
2822             break;
2823         }else if (nkf_char_unicode_p(c)){
2824             break;
2825         }else if (SS2 == c || (0xa1 <= c && c <= 0xfe)){
2826             ptr->stat = 1;
2827             status_push_ch(ptr, c);
2828 #ifdef X0212_ENABLE
2829         }else if (0x8f == c){
2830             ptr->stat = 2;
2831             status_push_ch(ptr, c);
2832 #endif /* X0212_ENABLE */
2833         }else{
2834             status_disable(ptr);
2835         }
2836         break;
2837     case 1:
2838         if (0xa1 <= c && c <= 0xfe){
2839             status_push_ch(ptr, c);
2840             code_score(ptr);
2841             status_clear(ptr);
2842         }else{
2843             status_disable(ptr);
2844         }
2845         break;
2846 #ifdef X0212_ENABLE
2847     case 2:
2848         if (0xa1 <= c && c <= 0xfe){
2849             ptr->stat = 1;
2850             status_push_ch(ptr, c);
2851         }else{
2852             status_disable(ptr);
2853         }
2854 #endif /* X0212_ENABLE */
2855     }
2856 }
2857
2858 #ifdef UTF8_INPUT_ENABLE
2859 static void
2860 w_status(struct input_code *ptr, nkf_char c)
2861 {
2862     switch (ptr->stat){
2863     case -1:
2864         status_check(ptr, c);
2865         break;
2866     case 0:
2867         if (c <= DEL){
2868             break;
2869         }else if (nkf_char_unicode_p(c)){
2870             break;
2871         }else if (0xc0 <= c && c <= 0xdf){
2872             ptr->stat = 1;
2873             status_push_ch(ptr, c);
2874         }else if (0xe0 <= c && c <= 0xef){
2875             ptr->stat = 2;
2876             status_push_ch(ptr, c);
2877         }else if (0xf0 <= c && c <= 0xf4){
2878             ptr->stat = 3;
2879             status_push_ch(ptr, c);
2880         }else{
2881             status_disable(ptr);
2882         }
2883         break;
2884     case 1:
2885     case 2:
2886         if (0x80 <= c && c <= 0xbf){
2887             status_push_ch(ptr, c);
2888             if (ptr->index > ptr->stat){
2889                 int bom = (ptr->buf[0] == 0xef && ptr->buf[1] == 0xbb
2890                            && ptr->buf[2] == 0xbf);
2891                 w2e_conv(ptr->buf[0], ptr->buf[1], ptr->buf[2],
2892                          &ptr->buf[0], &ptr->buf[1]);
2893                 if (!bom){
2894                     code_score(ptr);
2895                 }
2896                 status_clear(ptr);
2897             }
2898         }else{
2899             status_disable(ptr);
2900         }
2901         break;
2902     case 3:
2903         if (0x80 <= c && c <= 0xbf){
2904             if (ptr->index < ptr->stat){
2905                 status_push_ch(ptr, c);
2906             } else {
2907                 status_clear(ptr);
2908             }
2909         }else{
2910             status_disable(ptr);
2911         }
2912         break;
2913     }
2914 }
2915 #endif
2916
2917 static void
2918 code_status(nkf_char c)
2919 {
2920     int action_flag = 1;
2921     struct input_code *result = 0;
2922     struct input_code *p = input_code_list;
2923     while (p->name){
2924         if (!p->status_func) {
2925             ++p;
2926             continue;
2927         }
2928         if (!p->status_func)
2929             continue;
2930         (p->status_func)(p, c);
2931         if (p->stat > 0){
2932             action_flag = 0;
2933         }else if(p->stat == 0){
2934             if (result){
2935                 action_flag = 0;
2936             }else{
2937                 result = p;
2938             }
2939         }
2940         ++p;
2941     }
2942
2943     if (action_flag){
2944         if (result && !estab_f){
2945             set_iconv(TRUE, result->iconv_func);
2946         }else if (c <= DEL){
2947             struct input_code *ptr = input_code_list;
2948             while (ptr->name){
2949                 status_reset(ptr);
2950                 ++ptr;
2951             }
2952         }
2953     }
2954 }
2955
2956 #ifndef WIN32DLL
2957 static nkf_char
2958 std_getc(FILE *f)
2959 {
2960     if (std_gc_ndx){
2961         return std_gc_buf[--std_gc_ndx];
2962     }
2963     return getc(f);
2964 }
2965 #endif /*WIN32DLL*/
2966
2967 static nkf_char
2968 std_ungetc(nkf_char c, FILE *f)
2969 {
2970     if (std_gc_ndx == STD_GC_BUFSIZE){
2971         return EOF;
2972     }
2973     std_gc_buf[std_gc_ndx++] = c;
2974     return c;
2975 }
2976
2977 #ifndef WIN32DLL
2978 static void
2979 std_putc(nkf_char c)
2980 {
2981     if(c!=EOF)
2982         putchar(c);
2983 }
2984 #endif /*WIN32DLL*/
2985
2986 static unsigned char   hold_buf[HOLD_SIZE*2];
2987 static int             hold_count = 0;
2988 static nkf_char
2989 push_hold_buf(nkf_char c2)
2990 {
2991     if (hold_count >= HOLD_SIZE*2)
2992         return (EOF);
2993     hold_buf[hold_count++] = (unsigned char)c2;
2994     return ((hold_count >= HOLD_SIZE*2) ? EOF : hold_count);
2995 }
2996
2997 static int
2998 h_conv(FILE *f, int c1, int c2)
2999 {
3000     int ret, c4, c3;
3001     int hold_index;
3002
3003
3004     /** it must NOT be in the kanji shifte sequence      */
3005     /** it must NOT be written in JIS7                   */
3006     /** and it must be after 2 byte 8bit code            */
3007
3008     hold_count = 0;
3009     push_hold_buf(c1);
3010     push_hold_buf(c2);
3011
3012     while ((c2 = (*i_getc)(f)) != EOF) {
3013         if (c2 == ESC){
3014             (*i_ungetc)(c2,f);
3015             break;
3016         }
3017         code_status(c2);
3018         if (push_hold_buf(c2) == EOF || estab_f) {
3019             break;
3020         }
3021     }
3022
3023     if (!estab_f) {
3024         struct input_code *p = input_code_list;
3025         struct input_code *result = p;
3026         if (c2 == EOF) {
3027             code_status(c2);
3028         }
3029         while (p->name) {
3030             if (p->status_func && p->score < result->score) {
3031                 result = p;
3032             }
3033             p++;
3034         }
3035         set_iconv(TRUE, result->iconv_func);
3036     }
3037
3038
3039     /** now,
3040      ** 1) EOF is detected, or
3041      ** 2) Code is established, or
3042      ** 3) Buffer is FULL (but last word is pushed)
3043      **
3044      ** in 1) and 3) cases, we continue to use
3045      ** Kanji codes by oconv and leave estab_f unchanged.
3046      **/
3047
3048     ret = c2;
3049     hold_index = 0;
3050     while (hold_index < hold_count){
3051         c1 = hold_buf[hold_index++];
3052         if (c1 <= DEL){
3053             (*iconv)(0, c1, 0);
3054             continue;
3055         }else if (iconv == s_iconv && 0xa1 <= c1 && c1 <= 0xdf){
3056             (*iconv)(JIS_X_0201_1976_K, c1, 0);
3057             continue;
3058         }
3059         if (hold_index < hold_count){
3060             c2 = hold_buf[hold_index++];
3061         }else{
3062             c2 = (*i_getc)(f);
3063             if (c2 == EOF){
3064                 c4 = EOF;
3065                 break;
3066             }
3067             code_status(c2);
3068         }
3069         c3 = 0;
3070         switch ((*iconv)(c1, c2, 0)) {  /* can be EUC/SJIS/UTF-8 */
3071         case -2:
3072             /* 4 bytes UTF-8 */
3073             if (hold_index < hold_count){
3074                 c3 = hold_buf[hold_index++];
3075             } else if ((c3 = (*i_getc)(f)) == EOF) {
3076                 ret = EOF;
3077                 break;
3078             } else {
3079                 code_status(c3);
3080                 if (hold_index < hold_count){
3081                     c4 = hold_buf[hold_index++];
3082                 } else if ((c4 = (*i_getc)(f)) == EOF) {
3083                     c3 = ret = EOF;
3084                     break;
3085                 } else {
3086                     code_status(c4);
3087                     (*iconv)(c1, c2, (c3<<8)|c4);
3088                 }
3089             }
3090             break;
3091         case -1:
3092             /* 3 bytes EUC or UTF-8 */
3093             if (hold_index < hold_count){
3094                 c3 = hold_buf[hold_index++];
3095             } else if ((c3 = (*i_getc)(f)) == EOF) {
3096                 ret = EOF;
3097                 break;
3098             } else {
3099                 code_status(c3);
3100             }
3101             (*iconv)(c1, c2, c3);
3102             break;
3103         }
3104         if (c3 == EOF) break;
3105     }
3106     return ret;
3107 }
3108
3109 /*
3110  * Check and Ignore BOM
3111  */
3112 static void
3113 check_bom(FILE *f)
3114 {
3115     int c2;
3116     switch(c2 = (*i_getc)(f)){
3117     case 0x00:
3118         if((c2 = (*i_getc)(f)) == 0x00){
3119             if((c2 = (*i_getc)(f)) == 0xFE){
3120                 if((c2 = (*i_getc)(f)) == 0xFF){
3121                     if(!input_encoding){
3122                         set_iconv(TRUE, w_iconv32);
3123                     }
3124                     if (iconv == w_iconv32) {
3125                         input_endian = ENDIAN_BIG;
3126                         return;
3127                     }
3128                     (*i_ungetc)(0xFF,f);
3129                 }else (*i_ungetc)(c2,f);
3130                 (*i_ungetc)(0xFE,f);
3131             }else if(c2 == 0xFF){
3132                 if((c2 = (*i_getc)(f)) == 0xFE){
3133                     if(!input_encoding){
3134                         set_iconv(TRUE, w_iconv32);
3135                     }
3136                     if (iconv == w_iconv32) {
3137                         input_endian = ENDIAN_2143;
3138                         return;
3139                     }
3140                     (*i_ungetc)(0xFF,f);
3141                 }else (*i_ungetc)(c2,f);
3142                 (*i_ungetc)(0xFF,f);
3143             }else (*i_ungetc)(c2,f);
3144             (*i_ungetc)(0x00,f);
3145         }else (*i_ungetc)(c2,f);
3146         (*i_ungetc)(0x00,f);
3147         break;
3148     case 0xEF:
3149         if((c2 = (*i_getc)(f)) == 0xBB){
3150             if((c2 = (*i_getc)(f)) == 0xBF){
3151                 if(!input_encoding){
3152                     set_iconv(TRUE, w_iconv);
3153                 }
3154                 if (iconv == w_iconv) {
3155                     return;
3156                 }
3157                 (*i_ungetc)(0xBF,f);
3158             }else (*i_ungetc)(c2,f);
3159             (*i_ungetc)(0xBB,f);
3160         }else (*i_ungetc)(c2,f);
3161         (*i_ungetc)(0xEF,f);
3162         break;
3163     case 0xFE:
3164         if((c2 = (*i_getc)(f)) == 0xFF){
3165             if((c2 = (*i_getc)(f)) == 0x00){
3166                 if((c2 = (*i_getc)(f)) == 0x00){
3167                     if(!input_encoding){
3168                         set_iconv(TRUE, w_iconv32);
3169                     }
3170                     if (iconv == w_iconv32) {
3171                         input_endian = ENDIAN_3412;
3172                         return;
3173                     }
3174                     (*i_ungetc)(0x00,f);
3175                 }else (*i_ungetc)(c2,f);
3176                 (*i_ungetc)(0x00,f);
3177             }else (*i_ungetc)(c2,f);
3178             if(!input_encoding){
3179                 set_iconv(TRUE, w_iconv16);
3180             }
3181             if (iconv == w_iconv16) {
3182                 input_endian = ENDIAN_BIG;
3183                 return;
3184             }
3185             (*i_ungetc)(0xFF,f);
3186         }else (*i_ungetc)(c2,f);
3187         (*i_ungetc)(0xFE,f);
3188         break;
3189     case 0xFF:
3190         if((c2 = (*i_getc)(f)) == 0xFE){
3191             if((c2 = (*i_getc)(f)) == 0x00){
3192                 if((c2 = (*i_getc)(f)) == 0x00){
3193                     if(!input_encoding){
3194                         set_iconv(TRUE, w_iconv32);
3195                     }
3196                     if (iconv == w_iconv32) {
3197                         input_endian = ENDIAN_LITTLE;
3198                         return;
3199                     }
3200                     (*i_ungetc)(0x00,f);
3201                 }else (*i_ungetc)(c2,f);
3202                 (*i_ungetc)(0x00,f);
3203             }else (*i_ungetc)(c2,f);
3204             if(!input_encoding){
3205                 set_iconv(TRUE, w_iconv16);
3206             }
3207             if (iconv == w_iconv16) {
3208                 input_endian = ENDIAN_LITTLE;
3209                 return;
3210             }
3211             (*i_ungetc)(0xFE,f);
3212         }else (*i_ungetc)(c2,f);
3213         (*i_ungetc)(0xFF,f);
3214         break;
3215     default:
3216         (*i_ungetc)(c2,f);
3217         break;
3218     }
3219 }
3220
3221 static struct {
3222     int count;
3223     nkf_char status;
3224     nkf_char buf[3];
3225 } broken_state;
3226
3227 static void
3228 init_broken_state(void)
3229 {
3230     memset(&broken_state, 0, sizeof(broken_state));
3231 }
3232
3233 static void
3234 push_broken_buf(c)
3235 {
3236     broken_state.buf[broken_state.count++] = c;
3237 }
3238
3239 static nkf_char
3240 pop_broken_buf(void)
3241 {
3242     return broken_state.buf[--broken_state.count];
3243 }
3244
3245 static nkf_char
3246 broken_getc(FILE *f)
3247 {
3248     nkf_char c, c1;
3249
3250     if (broken_state.count > 0) {
3251         return pop_broken_buf();
3252     }
3253     c = (*i_bgetc)(f);
3254     if (c=='$' && broken_state.status != ESC
3255         && (input_mode == ASCII || input_mode == JIS_X_0201_1976_K)) {
3256         c1= (*i_bgetc)(f);
3257         broken_state.status = 0;
3258         if (c1=='@'|| c1=='B') {
3259             push_broken_buf(c1);
3260             push_broken_buf(c);
3261             return ESC;
3262         } else {
3263             (*i_bungetc)(c1,f);
3264             return c;
3265         }
3266     } else if (c=='(' && broken_state.status != ESC
3267                && (input_mode == JIS_X_0208 || input_mode == JIS_X_0201_1976_K)) {
3268         c1= (*i_bgetc)(f);
3269         broken_state.status = 0;
3270         if (c1=='J'|| c1=='B') {
3271             push_broken_buf(c1);
3272             push_broken_buf(c);
3273             return ESC;
3274         } else {
3275             (*i_bungetc)(c1,f);
3276             return c;
3277         }
3278     } else {
3279         broken_state.status = c;
3280         return c;
3281     }
3282 }
3283
3284 static nkf_char
3285 broken_ungetc(nkf_char c, FILE *f)
3286 {
3287     if (broken_state.count < 2)
3288         push_broken_buf(c);
3289     return c;
3290 }
3291
3292 static void
3293 eol_conv(nkf_char c2, nkf_char c1)
3294 {
3295     if (guess_f && input_eol != EOF) {
3296         if (c2 == 0 && c1 == LF) {
3297             if (!input_eol) input_eol = prev_cr ? CRLF : LF;
3298             else if (input_eol != (prev_cr ? CRLF : LF)) input_eol = EOF;
3299         } else if (c2 == 0 && c1 == CR && input_eol == LF) input_eol = EOF;
3300         else if (!prev_cr);
3301         else if (!input_eol) input_eol = CR;
3302         else if (input_eol != CR) input_eol = EOF;
3303     }
3304     if (prev_cr || (c2 == 0 && c1 == LF)) {
3305         prev_cr = 0;
3306         if (eolmode_f != LF) (*o_eol_conv)(0, CR);
3307         if (eolmode_f != CR) (*o_eol_conv)(0, LF);
3308     }
3309     if (c2 == 0 && c1 == CR) prev_cr = CR;
3310     else if (c2 != 0 || c1 != LF) (*o_eol_conv)(c2, c1);
3311 }
3312
3313 /*
3314    Return value of fold_conv()
3315
3316    LF  add newline  and output char
3317    CR  add newline  and output nothing
3318    SP  space
3319    0   skip
3320    1   (or else) normal output
3321
3322    fold state in prev (previous character)
3323
3324    >0x80 Japanese (X0208/X0201)
3325    <0x80 ASCII
3326    LF    new line
3327    SP    space
3328
3329    This fold algorthm does not preserve heading space in a line.
3330    This is the main difference from fmt.
3331  */
3332
3333 #define char_size(c2,c1) (c2?2:1)
3334
3335 static void
3336 fold_conv(nkf_char c2, nkf_char c1)
3337 {
3338     nkf_char prev0;
3339     nkf_char fold_state;
3340
3341     if (c1== CR && !fold_preserve_f) {
3342         fold_state=0;  /* ignore cr */
3343     }else if (c1== LF&&f_prev==CR && fold_preserve_f) {
3344         f_prev = LF;
3345         fold_state=0;  /* ignore cr */
3346     } else if (c1== BS) {
3347         if (f_line>0) f_line--;
3348         fold_state =  1;
3349     } else if (c2==EOF && f_line != 0) {    /* close open last line */
3350         fold_state = LF;
3351     } else if ((c1==LF && !fold_preserve_f)
3352                || ((c1==CR||(c1==LF&&f_prev!=CR))
3353                    && fold_preserve_f)) {
3354         /* new line */
3355         if (fold_preserve_f) {
3356             f_prev = c1;
3357             f_line = 0;
3358             fold_state =  CR;
3359         } else if ((f_prev == c1 && !fold_preserve_f)
3360                    || (f_prev == LF && fold_preserve_f)
3361                   ) {        /* duplicate newline */
3362             if (f_line) {
3363                 f_line = 0;
3364                 fold_state =  LF;    /* output two newline */
3365             } else {
3366                 f_line = 0;
3367                 fold_state =  1;
3368             }
3369         } else  {
3370             if (f_prev&0x80) {     /* Japanese? */
3371                 f_prev = c1;
3372                 fold_state =  0;       /* ignore given single newline */
3373             } else if (f_prev==SP) {
3374                 fold_state =  0;
3375             } else {
3376                 f_prev = c1;
3377                 if (++f_line<=fold_len)
3378                     fold_state =  SP;
3379                 else {
3380                     f_line = 0;
3381                     fold_state =  CR;        /* fold and output nothing */
3382                 }
3383             }
3384         }
3385     } else if (c1=='\f') {
3386         f_prev = LF;
3387         f_line = 0;
3388         fold_state =  LF;            /* output newline and clear */
3389     } else if ( (c2==0  && c1==SP)||
3390                (c2==0  && c1==TAB)||
3391                (c2=='!'&& c1=='!')) {
3392         /* X0208 kankaku or ascii space */
3393         if (f_prev == SP) {
3394             fold_state = 0;         /* remove duplicate spaces */
3395         } else {
3396             f_prev = SP;
3397             if (++f_line<=fold_len)
3398                 fold_state = SP;         /* output ASCII space only */
3399             else {
3400                 f_prev = SP; f_line = 0;
3401                 fold_state = CR;        /* fold and output nothing */
3402             }
3403         }
3404     } else {
3405         prev0 = f_prev; /* we still need this one... , but almost done */
3406         f_prev = c1;
3407         if (c2 || c2 == JIS_X_0201_1976_K)
3408             f_prev |= 0x80;  /* this is Japanese */
3409         f_line += char_size(c2,c1);
3410         if (f_line<=fold_len) {   /* normal case */
3411             fold_state = 1;
3412         } else {
3413             if (f_line>fold_len+fold_margin) { /* too many kinsoku suspension */
3414                 f_line = char_size(c2,c1);
3415                 fold_state =  LF;       /* We can't wait, do fold now */
3416             } else if (c2 == JIS_X_0201_1976_K) {
3417                 /* simple kinsoku rules  return 1 means no folding  */
3418                 if (c1==(0xde&0x7f)) fold_state = 1; /* \e$B!+\e(B*/
3419                 else if (c1==(0xdf&0x7f)) fold_state = 1; /* \e$B!,\e(B*/
3420                 else if (c1==(0xa4&0x7f)) fold_state = 1; /* \e$B!#\e(B*/
3421                 else if (c1==(0xa3&0x7f)) fold_state = 1; /* \e$B!$\e(B*/
3422                 else if (c1==(0xa1&0x7f)) fold_state = 1; /* \e$B!W\e(B*/
3423                 else if (c1==(0xb0&0x7f)) fold_state = 1; /* - */
3424                 else if (SP<=c1 && c1<=(0xdf&0x7f)) {      /* X0201 */
3425                     f_line = 1;
3426                     fold_state = LF;/* add one new f_line before this character */
3427                 } else {
3428                     f_line = 1;
3429                     fold_state = LF;/* add one new f_line before this character */
3430                 }
3431             } else if (c2==0) {
3432                 /* kinsoku point in ASCII */
3433                 if (  c1==')'||    /* { [ ( */
3434                     c1==']'||
3435                     c1=='}'||
3436                     c1=='.'||
3437                     c1==','||
3438                     c1=='!'||
3439                     c1=='?'||
3440                     c1=='/'||
3441                     c1==':'||
3442                     c1==';') {
3443                     fold_state = 1;
3444                     /* just after special */
3445                 } else if (!is_alnum(prev0)) {
3446                     f_line = char_size(c2,c1);
3447                     fold_state = LF;
3448                 } else if ((prev0==SP) ||   /* ignored new f_line */
3449                            (prev0==LF)||        /* ignored new f_line */
3450                            (prev0&0x80)) {        /* X0208 - ASCII */
3451                     f_line = char_size(c2,c1);
3452                     fold_state = LF;/* add one new f_line before this character */
3453                 } else {
3454                     fold_state = 1;  /* default no fold in ASCII */
3455                 }
3456             } else {
3457                 if (c2=='!') {
3458                     if (c1=='"')  fold_state = 1; /* \e$B!"\e(B */
3459                     else if (c1=='#')  fold_state = 1; /* \e$B!#\e(B */
3460                     else if (c1=='W')  fold_state = 1; /* \e$B!W\e(B */
3461                     else if (c1=='K')  fold_state = 1; /* \e$B!K\e(B */
3462                     else if (c1=='$')  fold_state = 1; /* \e$B!$\e(B */
3463                     else if (c1=='%')  fold_state = 1; /* \e$B!%\e(B */
3464                     else if (c1=='\'') fold_state = 1; /* \e$B!\\e(B */
3465                     else if (c1=='(')  fold_state = 1; /* \e$B!(\e(B */
3466                     else if (c1==')')  fold_state = 1; /* \e$B!)\e(B */
3467                     else if (c1=='*')  fold_state = 1; /* \e$B!*\e(B */
3468                     else if (c1=='+')  fold_state = 1; /* \e$B!+\e(B */
3469                     else if (c1==',')  fold_state = 1; /* \e$B!,\e(B */
3470                     /* default no fold in kinsoku */
3471                     else {
3472                         fold_state = LF;
3473                         f_line = char_size(c2,c1);
3474                         /* add one new f_line before this character */
3475                     }
3476                 } else {
3477                     f_line = char_size(c2,c1);
3478                     fold_state = LF;
3479                     /* add one new f_line before this character */
3480                 }
3481             }
3482         }
3483     }
3484     /* terminator process */
3485     switch(fold_state) {
3486     case LF:
3487         OCONV_NEWLINE((*o_fconv));
3488         (*o_fconv)(c2,c1);
3489         break;
3490     case 0:
3491         return;
3492     case CR:
3493         OCONV_NEWLINE((*o_fconv));
3494         break;
3495     case TAB:
3496     case SP:
3497         (*o_fconv)(0,SP);
3498         break;
3499     default:
3500         (*o_fconv)(c2,c1);
3501     }
3502 }
3503
3504 static nkf_char z_prev2=0,z_prev1=0;
3505
3506 static void
3507 z_conv(nkf_char c2, nkf_char c1)
3508 {
3509
3510     /* if (c2) c1 &= 0x7f; assertion */
3511
3512     if (c2 == JIS_X_0201_1976_K && (c1 == 0x20 || c1 == 0x7D || c1 == 0x7E)) {
3513         (*o_zconv)(c2,c1);
3514         return;
3515     }
3516
3517     if (x0201_f) {
3518         if (z_prev2 == JIS_X_0201_1976_K) {
3519             if (c2 == JIS_X_0201_1976_K) {
3520                 if (c1 == (0xde&0x7f)) { /* \e$BByE@\e(B */
3521                     z_prev2 = 0;
3522                     (*o_zconv)(dv[(z_prev1-SP)*2], dv[(z_prev1-SP)*2+1]);
3523                     return;
3524                 } else if (c1 == (0xdf&0x7f) && ev[(z_prev1-SP)*2]) {  /* \e$BH>ByE@\e(B */
3525                     z_prev2 = 0;
3526                     (*o_zconv)(ev[(z_prev1-SP)*2], ev[(z_prev1-SP)*2+1]);
3527                     return;
3528                 }
3529             }
3530             z_prev2 = 0;
3531             (*o_zconv)(cv[(z_prev1-SP)*2], cv[(z_prev1-SP)*2+1]);
3532         }
3533         if (c2 == JIS_X_0201_1976_K) {
3534             if (dv[(c1-SP)*2] || ev[(c1-SP)*2]) {
3535                 /* wait for \e$BByE@\e(B or \e$BH>ByE@\e(B */
3536                 z_prev1 = c1;
3537                 z_prev2 = c2;
3538                 return;
3539             } else {
3540                 (*o_zconv)(cv[(c1-SP)*2], cv[(c1-SP)*2+1]);
3541                 return;
3542             }
3543         }
3544     }
3545
3546     if (c2 == EOF) {
3547         (*o_zconv)(c2, c1);
3548         return;
3549     }
3550
3551     if (alpha_f&1 && c2 == 0x23) {
3552         /* JISX0208 Alphabet */
3553         c2 = 0;
3554     } else if (c2 == 0x21) {
3555         /* JISX0208 Kigou */
3556         if (0x21==c1) {
3557             if (alpha_f&2) {
3558                 c2 = 0;
3559                 c1 = SP;
3560             } else if (alpha_f&4) {
3561                 (*o_zconv)(0, SP);
3562                 (*o_zconv)(0, SP);
3563                 return;
3564             }
3565         } else if (alpha_f&1 && 0x20<c1 && c1<0x7f && fv[c1-0x20]) {
3566             c2 =  0;
3567             c1 = fv[c1-0x20];
3568         }
3569     }
3570
3571     if (alpha_f&8 && c2 == 0) {
3572         /* HTML Entity */
3573         const char *entity = 0;
3574         switch (c1){
3575         case '>': entity = "&gt;"; break;
3576         case '<': entity = "&lt;"; break;
3577         case '\"': entity = "&quot;"; break;
3578         case '&': entity = "&amp;"; break;
3579         }
3580         if (entity){
3581             while (*entity) (*o_zconv)(0, *entity++);
3582             return;
3583         }
3584     }
3585
3586     if (alpha_f & 16) {
3587         /* JIS X 0208 Katakana to JIS X 0201 Katakana */
3588         if (c2 == 0x21) {
3589             char c = 0;
3590             switch (c1) {
3591             case 0x23:
3592                 /* U+3002 (0x8142) Ideographic Full Stop -> U+FF61 (0xA1) Halfwidth Ideographic Full Stop */
3593                 c = 0xA1;
3594                 break;
3595             case 0x56:
3596                 /* U+300C (0x8175) Left Corner Bracket -> U+FF62 (0xA2) Halfwidth Left Corner Bracket */
3597                 c = 0xA2;
3598                 break;
3599             case 0x57:
3600                 /* U+300D (0x8176) Right Corner Bracket -> U+FF63 (0xA3) Halfwidth Right Corner Bracket */
3601                 c = 0xA3;
3602                 break;
3603             case 0x22:
3604                 /* U+3001 (0x8141) Ideographic Comma -> U+FF64 (0xA4) Halfwidth Ideographic Comma */
3605                 c = 0xA4;
3606                 break;
3607             case 0x26:
3608                 /* U+30FB (0x8145) Katakana Middle Dot -> U+FF65 (0xA5) Halfwidth Katakana Middle Dot */
3609                 c = 0xA5;
3610                 break;
3611             case 0x3C:
3612                 /* U+30FC (0x815B) Katakana-Hiragana Prolonged Sound Mark -> U+FF70 (0xB0) Halfwidth Katakana-Hiragana Prolonged Sound Mark */
3613                 c = 0xB0;
3614                 break;
3615             case 0x2B:
3616                 /* U+309B (0x814A) Katakana-Hiragana Voiced Sound Mark -> U+FF9E (0xDE) Halfwidth Katakana Voiced Sound Mark */
3617                 c = 0xDE;
3618                 break;
3619             case 0x2C:
3620                 /* U+309C (0x814B) Katakana-Hiragana Semi-Voiced Sound Mark -> U+FF9F (0xDF) Halfwidth Katakana Semi-Voiced Sound Mark */
3621                 c = 0xDF;
3622                 break;
3623             }
3624             if (c) {
3625                 (*o_zconv)(JIS_X_0201_1976_K, c);
3626                 return;
3627             }
3628         } else if (c2 == 0x25) {
3629             /* JISX0208 Katakana */
3630             static const int fullwidth_to_halfwidth[] =
3631             {
3632                 0x0000, 0x2700, 0x3100, 0x2800, 0x3200, 0x2900, 0x3300, 0x2A00,
3633                 0x3400, 0x2B00, 0x3500, 0x3600, 0x365E, 0x3700, 0x375E, 0x3800,
3634                 0x385E, 0x3900, 0x395E, 0x3A00, 0x3A5E, 0x3B00, 0x3B5E, 0x3C00,
3635                 0x3C5E, 0x3D00, 0x3D5E, 0x3E00, 0x3E5E, 0x3F00, 0x3F5E, 0x4000,
3636                 0x405E, 0x4100, 0x415E, 0x2F00, 0x4200, 0x425E, 0x4300, 0x435E,
3637                 0x4400, 0x445E, 0x4500, 0x4600, 0x4700, 0x4800, 0x4900, 0x4A00,
3638                 0x4A5E, 0x4A5F, 0x4B00, 0x4B5E, 0x4B5F, 0x4C00, 0x4C5E, 0x4C5F,
3639                 0x4D00, 0x4D5E, 0x4D5F, 0x4E00, 0x4E5E, 0x4E5F, 0x4F00, 0x5000,
3640                 0x5100, 0x5200, 0x5300, 0x2C00, 0x5400, 0x2D00, 0x5500, 0x2E00,
3641                 0x5600, 0x5700, 0x5800, 0x5900, 0x5A00, 0x5B00, 0x0000, 0x5C00,
3642                 0x0000, 0x0000, 0x2600, 0x5D00, 0x335E, 0x0000, 0x0000, 0x0000,
3643                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
3644             };
3645             if (fullwidth_to_halfwidth[c1-0x20]){
3646                 c2 = fullwidth_to_halfwidth[c1-0x20];
3647                 (*o_zconv)(JIS_X_0201_1976_K, c2>>8);
3648                 if (c2 & 0xFF) {
3649                     (*o_zconv)(JIS_X_0201_1976_K, c2&0xFF);
3650                 }
3651                 return;
3652             }
3653         }
3654     }
3655     (*o_zconv)(c2,c1);
3656 }
3657
3658
3659 #define rot13(c)  ( \
3660                    ( c < 'A') ? c: \
3661                    (c <= 'M')  ? (c + 13): \
3662                    (c <= 'Z')  ? (c - 13): \
3663                    (c < 'a')   ? (c): \
3664                    (c <= 'm')  ? (c + 13): \
3665                    (c <= 'z')  ? (c - 13): \
3666                    (c) \
3667                   )
3668
3669 #define  rot47(c) ( \
3670                    ( c < '!') ? c: \
3671                    ( c <= 'O') ? (c + 47) : \
3672                    ( c <= '~') ?  (c - 47) : \
3673                    c \
3674                   )
3675
3676 static void
3677 rot_conv(nkf_char c2, nkf_char c1)
3678 {
3679     if (c2 == 0 || c2 == JIS_X_0201_1976_K || c2 == ISO_8859_1) {
3680         c1 = rot13(c1);
3681     } else if (c2) {
3682         c1 = rot47(c1);
3683         c2 = rot47(c2);
3684     }
3685     (*o_rot_conv)(c2,c1);
3686 }
3687
3688 static void
3689 hira_conv(nkf_char c2, nkf_char c1)
3690 {
3691     if (hira_f & 1) {
3692         if (c2 == 0x25) {
3693             if (0x20 < c1 && c1 < 0x74) {
3694                 c2 = 0x24;
3695                 (*o_hira_conv)(c2,c1);
3696                 return;
3697             } else if (c1 == 0x74 && nkf_enc_unicode_p(output_encoding)) {
3698                 c2 = 0;
3699                 c1 = nkf_char_unicode_new(0x3094);
3700                 (*o_hira_conv)(c2,c1);
3701                 return;
3702             }
3703         } else if (c2 == 0x21 && (c1 == 0x33 || c1 == 0x34)) {
3704             c1 += 2;
3705             (*o_hira_conv)(c2,c1);
3706             return;
3707         }
3708     }
3709     if (hira_f & 2) {
3710         if (c2 == 0 && c1 == nkf_char_unicode_new(0x3094)) {
3711             c2 = 0x25;
3712             c1 = 0x74;
3713         } else if (c2 == 0x24 && 0x20 < c1 && c1 < 0x74) {
3714             c2 = 0x25;
3715         } else if (c2 == 0x21 && (c1 == 0x35 || c1 == 0x36)) {
3716             c1 -= 2;
3717         }
3718     }
3719     (*o_hira_conv)(c2,c1);
3720 }
3721
3722
3723 static void
3724 iso2022jp_check_conv(nkf_char c2, nkf_char c1)
3725 {
3726 #define RANGE_NUM_MAX 18
3727     static const nkf_char range[RANGE_NUM_MAX][2] = {
3728         {0x222f, 0x2239,},
3729         {0x2242, 0x2249,},
3730         {0x2251, 0x225b,},
3731         {0x226b, 0x2271,},
3732         {0x227a, 0x227d,},
3733         {0x2321, 0x232f,},
3734         {0x233a, 0x2340,},
3735         {0x235b, 0x2360,},
3736         {0x237b, 0x237e,},
3737         {0x2474, 0x247e,},
3738         {0x2577, 0x257e,},
3739         {0x2639, 0x2640,},
3740         {0x2659, 0x267e,},
3741         {0x2742, 0x2750,},
3742         {0x2772, 0x277e,},
3743         {0x2841, 0x287e,},
3744         {0x4f54, 0x4f7e,},
3745         {0x7425, 0x747e},
3746     };
3747     nkf_char i;
3748     nkf_char start, end, c;
3749
3750     if(c2 >= 0x00 && c2 <= 0x20 && c1 >= 0x7f && c1 <= 0xff) {
3751         c2 = GETA1;
3752         c1 = GETA2;
3753     }
3754     if((c2 >= 0x29 && c2 <= 0x2f) || (c2 >= 0x75 && c2 <= 0x7e)) {
3755         c2 = GETA1;
3756         c1 = GETA2;
3757     }
3758
3759     for (i = 0; i < RANGE_NUM_MAX; i++) {
3760         start = range[i][0];
3761         end   = range[i][1];
3762         c     = (c2 << 8) + c1;
3763         if (c >= start && c <= end) {
3764             c2 = GETA1;
3765             c1 = GETA2;
3766         }
3767     }
3768     (*o_iso2022jp_check_conv)(c2,c1);
3769 }
3770
3771
3772 /* This converts  =?ISO-2022-JP?B?HOGE HOGE?= */
3773
3774 static const unsigned char *mime_pattern[] = {
3775     (const unsigned char *)"\075?EUC-JP?B?",
3776     (const unsigned char *)"\075?SHIFT_JIS?B?",
3777     (const unsigned char *)"\075?ISO-8859-1?Q?",
3778     (const unsigned char *)"\075?ISO-8859-1?B?",
3779     (const unsigned char *)"\075?ISO-2022-JP?B?",
3780     (const unsigned char *)"\075?ISO-2022-JP?Q?",
3781 #if defined(UTF8_INPUT_ENABLE)
3782     (const unsigned char *)"\075?UTF-8?B?",
3783     (const unsigned char *)"\075?UTF-8?Q?",
3784 #endif
3785     (const unsigned char *)"\075?US-ASCII?Q?",
3786     NULL
3787 };
3788
3789
3790 /* \e$B3:Ev$9$k%3!<%I$NM%@hEY$r>e$2$k$?$a$NL\0u\e(B */
3791 nkf_char (*mime_priority_func[])(nkf_char c2, nkf_char c1, nkf_char c0) = {
3792     e_iconv, s_iconv, 0, 0, 0, 0,
3793 #if defined(UTF8_INPUT_ENABLE)
3794     w_iconv, w_iconv,
3795 #endif
3796     0,
3797 };
3798
3799 static const nkf_char mime_encode[] = {
3800     EUC_JP, SHIFT_JIS, ISO_8859_1, ISO_8859_1, JIS_X_0208, JIS_X_0201_1976_K,
3801 #if defined(UTF8_INPUT_ENABLE)
3802     UTF_8, UTF_8,
3803 #endif
3804     ASCII,
3805     0
3806 };
3807
3808 static const nkf_char mime_encode_method[] = {
3809     'B', 'B','Q', 'B', 'B', 'Q',
3810 #if defined(UTF8_INPUT_ENABLE)
3811     'B', 'Q',
3812 #endif
3813     'Q',
3814     0
3815 };
3816
3817
3818 /* MIME preprocessor fifo */
3819
3820 #define MIME_BUF_SIZE   (1024)    /* 2^n ring buffer */
3821 #define MIME_BUF_MASK   (MIME_BUF_SIZE-1)
3822 #define mime_input_buf(n)        mime_input_state.buf[(n)&MIME_BUF_MASK]
3823 static struct {
3824     unsigned char buf[MIME_BUF_SIZE];
3825     unsigned int  top;
3826     unsigned int  last;  /* decoded */
3827     unsigned int  input; /* undecoded */
3828 } mime_input_state;
3829 static nkf_char (*mime_iconv_back)(nkf_char c2,nkf_char c1,nkf_char c0) = NULL;
3830
3831 #define MAXRECOVER 20
3832
3833 static void
3834 mime_input_buf_unshift(nkf_char c)
3835 {
3836     mime_input_buf(--mime_input_state.top) = (unsigned char)c;
3837 }
3838
3839 static nkf_char
3840 mime_ungetc(nkf_char c, FILE *f)
3841 {
3842     mime_input_buf_unshift(c);
3843     return c;
3844 }
3845
3846 static nkf_char
3847 mime_ungetc_buf(nkf_char c, FILE *f)
3848 {
3849     if (mimebuf_f)
3850         (*i_mungetc_buf)(c,f);
3851     else
3852         mime_input_buf(--mime_input_state.input) = (unsigned char)c;
3853     return c;
3854 }
3855
3856 static nkf_char
3857 mime_getc_buf(FILE *f)
3858 {
3859     /* we don't keep eof of mime_input_buf, becase it contains ?= as
3860        a terminator. It was checked in mime_integrity. */
3861     return ((mimebuf_f)?
3862             (*i_mgetc_buf)(f):mime_input_buf(mime_input_state.input++));
3863 }
3864
3865 static void
3866 switch_mime_getc(void)
3867 {
3868     if (i_getc!=mime_getc) {
3869         i_mgetc = i_getc; i_getc = mime_getc;
3870         i_mungetc = i_ungetc; i_ungetc = mime_ungetc;
3871         if(mime_f==STRICT_MIME) {
3872             i_mgetc_buf = i_mgetc; i_mgetc = mime_getc_buf;
3873             i_mungetc_buf = i_mungetc; i_mungetc = mime_ungetc_buf;
3874         }
3875     }
3876 }
3877
3878 static void
3879 unswitch_mime_getc(void)
3880 {
3881     if(mime_f==STRICT_MIME) {
3882         i_mgetc = i_mgetc_buf;
3883         i_mungetc = i_mungetc_buf;
3884     }
3885     i_getc = i_mgetc;
3886     i_ungetc = i_mungetc;
3887     if(mime_iconv_back)set_iconv(FALSE, mime_iconv_back);
3888     mime_iconv_back = NULL;
3889 }
3890
3891 static nkf_char
3892 mime_integrity(FILE *f, const unsigned char *p)
3893 {
3894     nkf_char c,d;
3895     unsigned int q;
3896     /* In buffered mode, read until =? or NL or buffer full
3897      */
3898     mime_input_state.input = mime_input_state.top;
3899     mime_input_state.last = mime_input_state.top;
3900
3901     while(*p) mime_input_buf(mime_input_state.input++) = *p++;
3902     d = 0;
3903     q = mime_input_state.input;
3904     while((c=(*i_getc)(f))!=EOF) {
3905         if (((mime_input_state.input-mime_input_state.top)&MIME_BUF_MASK)==0) {
3906             break;   /* buffer full */
3907         }
3908         if (c=='=' && d=='?') {
3909             /* checked. skip header, start decode */
3910             mime_input_buf(mime_input_state.input++) = (unsigned char)c;
3911             /* mime_last_input = mime_input_state.input; */
3912             mime_input_state.input = q;
3913             switch_mime_getc();
3914             return 1;
3915         }
3916         if (!( (c=='+'||c=='/'|| c=='=' || c=='?' || is_alnum(c))))
3917             break;
3918         /* Should we check length mod 4? */
3919         mime_input_buf(mime_input_state.input++) = (unsigned char)c;
3920         d=c;
3921     }
3922     /* In case of Incomplete MIME, no MIME decode  */
3923     mime_input_buf(mime_input_state.input++) = (unsigned char)c;
3924     mime_input_state.last = mime_input_state.input;     /* point undecoded buffer */
3925     mime_decode_mode = 1;              /* no decode on mime_input_buf last in mime_getc */
3926     switch_mime_getc();         /* anyway we need buffered getc */
3927     return 1;
3928 }
3929
3930 static nkf_char
3931 mime_begin_strict(FILE *f)
3932 {
3933     nkf_char c1 = 0;
3934     int i,j,k;
3935     const unsigned char *p,*q;
3936     nkf_char r[MAXRECOVER];    /* recovery buffer, max mime pattern length */
3937
3938     mime_decode_mode = FALSE;
3939     /* =? has been checked */
3940     j = 0;
3941     p = mime_pattern[j];
3942     r[0]='='; r[1]='?';
3943
3944     for(i=2;p[i]>SP;i++) {                   /* start at =? */
3945         if (((r[i] = c1 = (*i_getc)(f))==EOF) || nkf_toupper(c1) != p[i]) {
3946             /* pattern fails, try next one */
3947             q = p;
3948             while (mime_pattern[++j]) {
3949                 p = mime_pattern[j];
3950                 for(k=2;k<i;k++)              /* assume length(p) > i */
3951                     if (p[k]!=q[k]) break;
3952                 if (k==i && nkf_toupper(c1)==p[k]) break;
3953             }
3954             p = mime_pattern[j];
3955             if (p) continue;  /* found next one, continue */
3956             /* all fails, output from recovery buffer */
3957             (*i_ungetc)(c1,f);
3958             for(j=0;j<i;j++) {
3959                 (*oconv)(0,r[j]);
3960             }
3961             return c1;
3962         }
3963     }
3964     mime_decode_mode = p[i-2];
3965
3966     mime_iconv_back = iconv;
3967     set_iconv(FALSE, mime_priority_func[j]);
3968     clr_code_score(find_inputcode_byfunc(mime_priority_func[j]), SCORE_iMIME);
3969
3970     if (mime_decode_mode=='B') {
3971         mimebuf_f = unbuf_f;
3972         if (!unbuf_f) {
3973             /* do MIME integrity check */
3974             return mime_integrity(f,mime_pattern[j]);
3975         }
3976     }
3977     switch_mime_getc();
3978     mimebuf_f = TRUE;
3979     return c1;
3980 }
3981
3982 static nkf_char
3983 mime_begin(FILE *f)
3984 {
3985     nkf_char c1;
3986     int i,k;
3987
3988     /* In NONSTRICT mode, only =? is checked. In case of failure, we  */
3989     /* re-read and convert again from mime_buffer.  */
3990
3991     /* =? has been checked */
3992     k = mime_input_state.last;
3993     mime_input_buf(mime_input_state.last++)='='; mime_input_buf(mime_input_state.last++)='?';
3994     for(i=2;i<MAXRECOVER;i++) {                   /* start at =? */
3995         /* We accept any character type even if it is breaked by new lines */
3996         c1 = (*i_getc)(f); mime_input_buf(mime_input_state.last++) = (unsigned char)c1;
3997         if (c1==LF||c1==SP||c1==CR||
3998             c1=='-'||c1=='_'||is_alnum(c1)) continue;
3999         if (c1=='=') {
4000             /* Failed. But this could be another MIME preemble */
4001             (*i_ungetc)(c1,f);
4002             mime_input_state.last--;
4003             break;
4004         }
4005         if (c1!='?') break;
4006         else {
4007             /* c1=='?' */
4008             c1 = (*i_getc)(f); mime_input_buf(mime_input_state.last++) = (unsigned char)c1;
4009             if (!(++i<MAXRECOVER) || c1==EOF) break;
4010             if (c1=='b'||c1=='B') {
4011                 mime_decode_mode = 'B';
4012             } else if (c1=='q'||c1=='Q') {
4013                 mime_decode_mode = 'Q';
4014             } else {
4015                 break;
4016             }
4017             c1 = (*i_getc)(f); mime_input_buf(mime_input_state.last++) = (unsigned char)c1;
4018             if (!(++i<MAXRECOVER) || c1==EOF) break;
4019             if (c1!='?') {
4020                 mime_decode_mode = FALSE;
4021             }
4022             break;
4023         }
4024     }
4025     switch_mime_getc();
4026     if (!mime_decode_mode) {
4027         /* false MIME premble, restart from mime_buffer */
4028         mime_decode_mode = 1;  /* no decode, but read from the mime_buffer */
4029         /* Since we are in MIME mode until buffer becomes empty,    */
4030         /* we never go into mime_begin again for a while.           */
4031         return c1;
4032     }
4033     /* discard mime preemble, and goto MIME mode */
4034     mime_input_state.last = k;
4035     /* do no MIME integrity check */
4036     return c1;   /* used only for checking EOF */
4037 }
4038
4039 #ifdef CHECK_OPTION
4040 static void
4041 no_putc(nkf_char c)
4042 {
4043     ;
4044 }
4045
4046 static void
4047 debug(const char *str)
4048 {
4049     if (debug_f){
4050         fprintf(stderr, "%s\n", str ? str : "NULL");
4051     }
4052 }
4053 #endif
4054
4055 static void
4056 set_input_codename(const char *codename)
4057 {
4058     if (!input_codename) {
4059         input_codename = codename;
4060     } else if (strcmp(codename, input_codename) != 0) {
4061         input_codename = "";
4062     }
4063 }
4064
4065 static const char*
4066 get_guessed_code(void)
4067 {
4068     if (input_codename && !*input_codename) {
4069         input_codename = "BINARY";
4070     } else {
4071         struct input_code *p = find_inputcode_byfunc(iconv);
4072         if (!input_codename) {
4073             input_codename = "ASCII";
4074         } else if (strcmp(input_codename, "Shift_JIS") == 0) {
4075             if (p->score & (SCORE_DEPEND|SCORE_CP932))
4076                 input_codename = "CP932";
4077         } else if (strcmp(input_codename, "EUC-JP") == 0) {
4078             if (p->score & (SCORE_X0212))
4079                 input_codename = "EUCJP-MS";
4080             else if (p->score & (SCORE_DEPEND|SCORE_CP932))
4081                 input_codename = "CP51932";
4082         } else if (strcmp(input_codename, "ISO-2022-JP") == 0) {
4083             if (p->score & (SCORE_KANA))
4084                 input_codename = "CP50221";
4085             else if (p->score & (SCORE_DEPEND|SCORE_CP932))
4086                 input_codename = "CP50220";
4087         }
4088     }
4089     return input_codename;
4090 }
4091
4092 #if !defined(PERL_XS) && !defined(WIN32DLL)
4093 static void
4094 print_guessed_code(char *filename)
4095 {
4096     if (filename != NULL) printf("%s: ", filename);
4097     if (input_codename && !*input_codename) {
4098         printf("BINARY\n");
4099     } else {
4100         input_codename = get_guessed_code();
4101         if (guess_f == 1) {
4102             printf("%s\n", input_codename);
4103         } else {
4104             printf("%s%s\n",
4105                    input_codename,
4106                    input_eol == CR   ? " (CR)" :
4107                    input_eol == LF   ? " (LF)" :
4108                    input_eol == CRLF ? " (CRLF)" :
4109                    input_eol == EOF  ? " (MIXED NL)" :
4110                    "");
4111         }
4112     }
4113 }
4114 #endif /*WIN32DLL*/
4115
4116 #ifdef INPUT_OPTION
4117
4118 static nkf_char
4119 hex_getc(nkf_char ch, FILE *f, nkf_char (*g)(FILE *f), nkf_char (*u)(nkf_char c, FILE *f))
4120 {
4121     nkf_char c1, c2, c3;
4122     c1 = (*g)(f);
4123     if (c1 != ch){
4124         return c1;
4125     }
4126     c2 = (*g)(f);
4127     if (!nkf_isxdigit(c2)){
4128         (*u)(c2, f);
4129         return c1;
4130     }
4131     c3 = (*g)(f);
4132     if (!nkf_isxdigit(c3)){
4133         (*u)(c2, f);
4134         (*u)(c3, f);
4135         return c1;
4136     }
4137     return (hex2bin(c2) << 4) | hex2bin(c3);
4138 }
4139
4140 static nkf_char
4141 cap_getc(FILE *f)
4142 {
4143     return hex_getc(':', f, i_cgetc, i_cungetc);
4144 }
4145
4146 static nkf_char
4147 cap_ungetc(nkf_char c, FILE *f)
4148 {
4149     return (*i_cungetc)(c, f);
4150 }
4151
4152 static nkf_char
4153 url_getc(FILE *f)
4154 {
4155     return hex_getc('%', f, i_ugetc, i_uungetc);
4156 }
4157
4158 static nkf_char
4159 url_ungetc(nkf_char c, FILE *f)
4160 {
4161     return (*i_uungetc)(c, f);
4162 }
4163 #endif
4164
4165 #ifdef NUMCHAR_OPTION
4166 static nkf_char
4167 numchar_getc(FILE *f)
4168 {
4169     nkf_char (*g)(FILE *) = i_ngetc;
4170     nkf_char (*u)(nkf_char c ,FILE *f) = i_nungetc;
4171     int i = 0, j;
4172     nkf_char buf[12];
4173     long c = -1;
4174
4175     buf[i] = (*g)(f);
4176     if (buf[i] == '&'){
4177         buf[++i] = (*g)(f);
4178         if (buf[i] == '#'){
4179             c = 0;
4180             buf[++i] = (*g)(f);
4181             if (buf[i] == 'x' || buf[i] == 'X'){
4182                 for (j = 0; j < 7; j++){
4183                     buf[++i] = (*g)(f);
4184                     if (!nkf_isxdigit(buf[i])){
4185                         if (buf[i] != ';'){
4186                             c = -1;
4187                         }
4188                         break;
4189                     }
4190                     c <<= 4;
4191                     c |= hex2bin(buf[i]);
4192                 }
4193             }else{
4194                 for (j = 0; j < 8; j++){
4195                     if (j){
4196                         buf[++i] = (*g)(f);
4197                     }
4198                     if (!nkf_isdigit(buf[i])){
4199                         if (buf[i] != ';'){
4200                             c = -1;
4201                         }
4202                         break;
4203                     }
4204                     c *= 10;
4205                     c += hex2bin(buf[i]);
4206                 }
4207             }
4208         }
4209     }
4210     if (c != -1){
4211         return nkf_char_unicode_new(c);
4212     }
4213     while (i > 0){
4214         (*u)(buf[i], f);
4215         --i;
4216     }
4217     return buf[0];
4218 }
4219
4220 static nkf_char
4221 numchar_ungetc(nkf_char c, FILE *f)
4222 {
4223     return (*i_nungetc)(c, f);
4224 }
4225 #endif
4226
4227 #ifdef UNICODE_NORMALIZATION
4228
4229 typedef struct {
4230     unsigned char *ary;
4231     int max_length;
4232     int count;
4233 } nkf_ary;
4234
4235 static nkf_ary *
4236 nkf_ary_new(int length)
4237 {
4238     nkf_ary *ary = nkf_malloc(sizeof(nkf_ary));
4239     ary->ary = nkf_malloc(length);
4240     ary->max_length = length;
4241     ary->count = 0;
4242     return ary;
4243
4244
4245 static void
4246 nkf_ary_dispose(nkf_ary *ary)
4247 {
4248     nkf_free(ary->ary);
4249     nkf_free(ary);
4250 }
4251
4252 #define nkf_ary_length(ary) ((ary)->count)
4253 #define nkf_ary_empty_p(ary) ((ary)->count == 0)
4254
4255 static unsigned char
4256 nkf_ary_at(nkf_ary *ary, int index)
4257 {
4258     assert(index <= ary->count);
4259     return ary->ary[index];
4260 }
4261
4262 static void
4263 nkf_ary_clear(nkf_ary *ary)
4264 {
4265     ary->count = 0;
4266 }
4267
4268 static unsigned char
4269 nkf_ary_push(nkf_ary *ary, nkf_char c)
4270 {
4271     assert(ary->max_length > ary->count);
4272     ary->ary[ary->count++] = c;
4273     return ary->count;
4274 }
4275
4276 static unsigned char
4277 nkf_ary_pop(nkf_ary *ary)
4278 {
4279     assert(0 < ary->count);
4280     return ary->ary[--ary->count];
4281 }
4282
4283 /* Normalization Form C */
4284 static nkf_char
4285 nfc_getc(FILE *f)
4286 {
4287     nkf_char (*g)(FILE *f) = i_nfc_getc;
4288     nkf_char (*u)(nkf_char c ,FILE *f) = i_nfc_ungetc;
4289     nkf_ary *buf = nkf_ary_new(9);
4290     const unsigned char *array;
4291     int lower=0, upper=NORMALIZATION_TABLE_LENGTH-1;
4292     nkf_char c = (*g)(f);
4293
4294     if (c == EOF || c > 0xFF || (c & 0xc0) == 0x80) return c;
4295
4296     nkf_ary_push(buf, (unsigned char)c);
4297     do {
4298         while (lower <= upper) {
4299             int mid = (lower+upper) / 2;
4300             int len;
4301             array = normalization_table[mid].nfd;
4302             for (len=0; len < NORMALIZATION_TABLE_NFD_LENGTH && array[len]; len++) {
4303                 if (len >= nkf_ary_length(buf)) {
4304                     c = (*g)(f);
4305                     if (c == EOF) {
4306                         len = 0;
4307                         lower = 1, upper = 0;
4308                         break;
4309                     }
4310                     nkf_ary_push(buf, c);
4311                 }
4312                 if (array[len] != nkf_ary_at(buf, len)) {
4313                     if (array[len] < nkf_ary_at(buf, len)) lower = mid + 1;
4314                     else  upper = mid - 1;
4315                     len = 0;
4316                     break;
4317                 }
4318             }
4319             if (len > 0) {
4320                 int i;
4321                 array = normalization_table[mid].nfc;
4322                 nkf_ary_clear(buf);
4323                 for (i=0; i < NORMALIZATION_TABLE_NFC_LENGTH && array[i]; i++)
4324                     nkf_ary_push(buf, array[i]);
4325                 break;
4326             }
4327         }
4328     } while (lower <= upper);
4329
4330     while (nkf_ary_length(buf) > 1) (*u)(nkf_ary_pop(buf), f);
4331     c = nkf_ary_pop(buf);
4332     nkf_ary_dispose(buf);
4333
4334     return c;
4335 }
4336
4337 static nkf_char
4338 nfc_ungetc(nkf_char c, FILE *f)
4339 {
4340     return (*i_nfc_ungetc)(c, f);
4341 }
4342 #endif /* UNICODE_NORMALIZATION */
4343
4344
4345 static nkf_char
4346 base64decode(nkf_char c)
4347 {
4348     int             i;
4349     if (c > '@') {
4350         if (c < '[') {
4351             i = c - 'A';                        /* A..Z 0-25 */
4352         } else if (c == '_') {
4353             i = '?'         /* 63 */ ;          /* _  63 */
4354         } else {
4355             i = c - 'G'     /* - 'a' + 26 */ ;  /* a..z 26-51 */
4356         }
4357     } else if (c > '/') {
4358         i = c - '0' + '4'   /* - '0' + 52 */ ;  /* 0..9 52-61 */
4359     } else if (c == '+' || c == '-') {
4360         i = '>'             /* 62 */ ;          /* + and -  62 */
4361     } else {
4362         i = '?'             /* 63 */ ;          /* / 63 */
4363     }
4364     return (i);
4365 }
4366
4367 static nkf_char
4368 mime_getc(FILE *f)
4369 {
4370     nkf_char c1, c2, c3, c4, cc;
4371     nkf_char t1, t2, t3, t4, mode, exit_mode;
4372     nkf_char lwsp_count;
4373     char *lwsp_buf;
4374     char *lwsp_buf_new;
4375     nkf_char lwsp_size = 128;
4376
4377     if (mime_input_state.top != mime_input_state.last) {  /* Something is in FIFO */
4378         return  mime_input_buf(mime_input_state.top++);
4379     }
4380     if (mime_decode_mode==1 ||mime_decode_mode==FALSE) {
4381         mime_decode_mode=FALSE;
4382         unswitch_mime_getc();
4383         return (*i_getc)(f);
4384     }
4385
4386     if (mimebuf_f == FIXED_MIME)
4387         exit_mode = mime_decode_mode;
4388     else
4389         exit_mode = FALSE;
4390     if (mime_decode_mode == 'Q') {
4391         if ((c1 = (*i_mgetc)(f)) == EOF) return (EOF);
4392       restart_mime_q:
4393         if (c1=='_' && mimebuf_f != FIXED_MIME) return SP;
4394         if (c1<=SP || DEL<=c1) {
4395             mime_decode_mode = exit_mode; /* prepare for quit */
4396             return c1;
4397         }
4398         if (c1!='=' && (c1!='?' || mimebuf_f == FIXED_MIME)) {
4399             return c1;
4400         }
4401
4402         mime_decode_mode = exit_mode; /* prepare for quit */
4403         if ((c2 = (*i_mgetc)(f)) == EOF) return (EOF);
4404         if (c1=='?'&&c2=='=' && mimebuf_f != FIXED_MIME) {
4405             /* end Q encoding */
4406             input_mode = exit_mode;
4407             lwsp_count = 0;
4408             lwsp_buf = nkf_malloc((lwsp_size+5)*sizeof(char));
4409             while ((c1=(*i_getc)(f))!=EOF) {
4410                 switch (c1) {
4411                 case LF:
4412                 case CR:
4413                     if (c1==LF) {
4414                         if ((c1=(*i_getc)(f))!=EOF && (c1==SP||c1==TAB)) {
4415                             i_ungetc(SP,f);
4416                             continue;
4417                         } else {
4418                             i_ungetc(c1,f);
4419                         }
4420                         c1 = LF;
4421                     } else {
4422                         if ((c1=(*i_getc)(f))!=EOF && c1 == LF) {
4423                             if ((c1=(*i_getc)(f))!=EOF && (c1==SP||c1==TAB)) {
4424                                 i_ungetc(SP,f);
4425                                 continue;
4426                             } else {
4427                                 i_ungetc(c1,f);
4428                             }
4429                             i_ungetc(LF,f);
4430                         } else {
4431                             i_ungetc(c1,f);
4432                         }
4433                         c1 = CR;
4434                     }
4435                     break;
4436                 case SP:
4437                 case TAB:
4438                     lwsp_buf[lwsp_count] = (unsigned char)c1;
4439                     if (lwsp_count++>lwsp_size){
4440                         lwsp_size <<= 1;
4441                         lwsp_buf_new = nkf_realloc(lwsp_buf, (lwsp_size+5)*sizeof(char));
4442                         lwsp_buf = lwsp_buf_new;
4443                     }
4444                     continue;
4445                 }
4446                 break;
4447             }
4448             if (lwsp_count > 0 && (c1 != '=' || (lwsp_buf[lwsp_count-1] != SP && lwsp_buf[lwsp_count-1] != TAB))) {
4449                 i_ungetc(c1,f);
4450                 for(lwsp_count--;lwsp_count>0;lwsp_count--)
4451                     i_ungetc(lwsp_buf[lwsp_count],f);
4452                 c1 = lwsp_buf[0];
4453             }
4454             nkf_free(lwsp_buf);
4455             return c1;
4456         }
4457         if (c1=='='&&c2<SP) { /* this is soft wrap */
4458             while((c1 =  (*i_mgetc)(f)) <=SP) {
4459                 if ((c1 = (*i_mgetc)(f)) == EOF) return (EOF);
4460             }
4461             mime_decode_mode = 'Q'; /* still in MIME */
4462             goto restart_mime_q;
4463         }
4464         if (c1=='?') {
4465             mime_decode_mode = 'Q'; /* still in MIME */
4466             (*i_mungetc)(c2,f);
4467             return c1;
4468         }
4469         if ((c3 = (*i_mgetc)(f)) == EOF) return (EOF);
4470         if (c2<=SP) return c2;
4471         mime_decode_mode = 'Q'; /* still in MIME */
4472         return ((hex2bin(c2)<<4) + hex2bin(c3));
4473     }
4474
4475     if (mime_decode_mode != 'B') {
4476         mime_decode_mode = FALSE;
4477         return (*i_mgetc)(f);
4478     }
4479
4480
4481     /* Base64 encoding */
4482     /*
4483        MIME allows line break in the middle of
4484        Base64, but we are very pessimistic in decoding
4485        in unbuf mode because MIME encoded code may broken by
4486        less or editor's control sequence (such as ESC-[-K in unbuffered
4487        mode. ignore incomplete MIME.
4488      */
4489     mode = mime_decode_mode;
4490     mime_decode_mode = exit_mode;  /* prepare for quit */
4491
4492     while ((c1 = (*i_mgetc)(f))<=SP) {
4493         if (c1==EOF)
4494             return (EOF);
4495     }
4496   mime_c2_retry:
4497     if ((c2 = (*i_mgetc)(f))<=SP) {
4498         if (c2==EOF)
4499             return (EOF);
4500         if (mime_f != STRICT_MIME) goto mime_c2_retry;
4501         if (mimebuf_f!=FIXED_MIME) input_mode = ASCII;
4502         return c2;
4503     }
4504     if ((c1 == '?') && (c2 == '=')) {
4505         input_mode = ASCII;
4506         lwsp_count = 0;
4507         lwsp_buf = nkf_malloc((lwsp_size+5)*sizeof(char));
4508         while ((c1=(*i_getc)(f))!=EOF) {
4509             switch (c1) {
4510             case LF:
4511             case CR:
4512                 if (c1==LF) {
4513                     if ((c1=(*i_getc)(f))!=EOF && (c1==SP||c1==TAB)) {
4514                         i_ungetc(SP,f);
4515                         continue;
4516                     } else {
4517                         i_ungetc(c1,f);
4518                     }