OSDN Git Service

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