OSDN Git Service

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