OSDN Git Service

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