OSDN Git Service

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