OSDN Git Service

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