OSDN Git Service

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