OSDN Git Service

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