OSDN Git Service

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