OSDN Git Service

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