OSDN Git Service

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