OSDN Git Service

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