OSDN Git Service

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