OSDN Git Service

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