OSDN Git Service

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