OSDN Git Service

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