OSDN Git Service

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