OSDN Git Service

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