OSDN Git Service

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