OSDN Git Service

* Fix memory leak.
[nkf/nkf.git] / nkf.c
1 /** Network Kanji Filter. (PDS Version)
2  ** -*- coding: ISO-2022-JP -*-
3  ************************************************************************
4  ** Copyright (C) 1987, Fujitsu LTD. (Itaru ICHIKAWA)
5  ** \e$BO"Mm@h!'\e(B \e$B!J3t!KIY;NDL8&5f=j!!%=%U%H#38&!!;T@n!!;j\e(B
6  ** \e$B!J\e(BE-Mail Address: ichikawa@flab.fujitsu.co.jp\e$B!K\e(B
7  ** Copyright (C) 1996,1998
8  ** Copyright (C) 2002
9  ** \e$BO"Mm@h!'\e(B \e$BN05eBg3X>pJs9)3X2J\e(B \e$B2OLn\e(B \e$B??<#\e(B  mime/X0208 support
10  ** \e$B!J\e(BE-Mail Address: kono@ie.u-ryukyu.ac.jp\e$B!K\e(B
11  ** \e$BO"Mm@h!'\e(B COW for DOS & Win16 & Win32 & OS/2
12  ** \e$B!J\e(BE-Mail Address: GHG00637@niftyserve.or.p\e$B!K\e(B
13  **
14  **    \e$B$3$N%=!<%9$N$$$+$J$kJ#<L!$2~JQ!$=$@5$b5vBz$7$^$9!#$?$@$7!"\e(B
15  **    \e$B$=$N:]$K$O!"C/$,9W8%$7$?$r<($9$3$NItJ,$r;D$9$3$H!#\e(B
16  **    \e$B:FG[I[$d;(;o$NIUO?$J$I$NLd$$9g$o$;$bI,MW$"$j$^$;$s!#\e(B
17  **    \e$B1DMxMxMQ$b>e5-$KH?$7$J$$HO0O$G5v2D$7$^$9!#\e(B
18  **    \e$B%P%$%J%j$NG[I[$N:]$K$O\e(Bversion message\e$B$rJ]B8$9$k$3$H$r>r7o$H$7$^$9!#\e(B
19  **    \e$B$3$N%W%m%0%i%`$K$D$$$F$OFC$K2?$NJ]>Z$b$7$J$$!"0-$7$+$i$:!#\e(B
20  **
21  **    Everyone is permitted to do anything on this program
22  **    including copying, modifying, improving,
23  **    as long as you don't try to pretend that you wrote it.
24  **    i.e., the above copyright notice has to appear in all copies.
25  **    Binary distribution requires original version messages.
26  **    You don't have to ask before copying, redistribution or publishing.
27  **    THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
28  ***********************************************************************/
29
30 /***********************************************************************
31  * \e$B8=:_!"\e(Bnkf \e$B$O\e(B SorceForge \e$B$K$F%a%s%F%J%s%9$,B3$1$i$l$F$$$^$9!#\e(B
32  * http://sourceforge.jp/projects/nkf/
33  ***********************************************************************/
34 #define NKF_IDENT "$Id: nkf.c,v 1.192 2008/11/09 23:09:22 naruse Exp $"
35 #define NKF_VERSION "2.0.8"
36 #define NKF_RELEASE_DATE "2008-11-10"
37 #define COPY_RIGHT \
38     "Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa),2000 S. Kono, COW\n" \
39     "Copyright (C) 2002-2008 Kono, Furukawa, Naruse, mastodon"
40
41 #include "config.h"
42 #include "nkf.h"
43 #include "utf8tbl.h"
44 #ifdef __WIN32__
45 #include <windows.h>
46 #include <locale.h>
47 #endif
48 #if defined(__OS2__)
49 # define INCL_DOS
50 # define INCL_DOSERRORS
51 # include <os2.h>
52 #endif
53 #include <assert.h>
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_malloc(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_realloc(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_free(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             "  nkf identity:\n"
903             "    " NKF_IDENT "\n"
904             "  Compile-time options:\n"
905             "    Compiled at:                 " __DATE__ " " __TIME__ "\n"
906            );
907     fprintf(HELP_OUTPUT,
908             "    Default output encoding:     "
909 #ifdef DEFAULT_CODE_LOCALE
910             "LOCALE (%s)\n", nkf_enc_name(nkf_default_encoding())
911 #elif defined(DEFAULT_ENCIDX)
912             "CONFIG (%s)\n", nkf_enc_name(nkf_default_encoding())
913 #else
914             "NONE\n"
915 #endif
916            );
917     fprintf(HELP_OUTPUT,
918             "    Default output end of line:  "
919 #if DEFAULT_NEWLINE == CR
920             "CR"
921 #elif DEFAULT_NEWLINE == CRLF
922             "CRLF"
923 #else
924             "LF"
925 #endif
926             "\n"
927             "    Decode MIME encoded string:  "
928 #if MIME_DECODE_DEFAULT
929             "ON"
930 #else
931             "OFF"
932 #endif
933             "\n"
934             "    Convert JIS X 0201 Katakana: "
935 #if X0201_DEFAULT
936             "ON"
937 #else
938             "OFF"
939 #endif
940             "\n"
941             "    --help, --version output:    "
942 #if HELP_OUTPUT_HELP_OUTPUT
943             "HELP_OUTPUT"
944 #else
945             "STDOUT"
946 #endif
947             "\n");
948 }
949 #endif /*PERL_XS*/
950
951 #ifdef OVERWRITE
952 static char*
953 get_backup_filename(const char *suffix, const char *filename)
954 {
955     char *backup_filename;
956     int asterisk_count = 0;
957     int i, j;
958     int filename_length = strlen(filename);
959
960     for(i = 0; suffix[i]; i++){
961         if(suffix[i] == '*') asterisk_count++;
962     }
963
964     if(asterisk_count){
965         backup_filename = nkf_malloc(strlen(suffix) + (asterisk_count * (filename_length - 1)) + 1);
966         for(i = 0, j = 0; suffix[i];){
967             if(suffix[i] == '*'){
968                 backup_filename[j] = '\0';
969                 strncat(backup_filename, filename, filename_length);
970                 i++;
971                 j += filename_length;
972             }else{
973                 backup_filename[j++] = suffix[i++];
974             }
975         }
976         backup_filename[j] = '\0';
977     }else{
978         j = filename_length + strlen(suffix);
979         backup_filename = nkf_malloc(j + 1);
980         strcpy(backup_filename, filename);
981         strcat(backup_filename, suffix);
982         backup_filename[j] = '\0';
983     }
984     return backup_filename;
985 }
986 #endif
987
988 #ifdef UTF8_INPUT_ENABLE
989 static void
990 nkf_each_char_to_hex(void (*f)(nkf_char c2,nkf_char c1), nkf_char c)
991 {
992     int shift = 20;
993     c &= VALUE_MASK;
994     while(shift >= 0){
995         if(c >= 1<<shift){
996             while(shift >= 0){
997                 (*f)(0, bin2hex(c>>shift));
998                 shift -= 4;
999             }
1000         }else{
1001             shift -= 4;
1002         }
1003     }
1004     return;
1005 }
1006
1007 static void
1008 encode_fallback_html(nkf_char c)
1009 {
1010     (*oconv)(0, '&');
1011     (*oconv)(0, '#');
1012     c &= VALUE_MASK;
1013     if(c >= NKF_INT32_C(1000000))
1014         (*oconv)(0, 0x30+(c/NKF_INT32_C(1000000))%10);
1015     if(c >= NKF_INT32_C(100000))
1016         (*oconv)(0, 0x30+(c/NKF_INT32_C(100000) )%10);
1017     if(c >= 10000)
1018         (*oconv)(0, 0x30+(c/10000  )%10);
1019     if(c >= 1000)
1020         (*oconv)(0, 0x30+(c/1000   )%10);
1021     if(c >= 100)
1022         (*oconv)(0, 0x30+(c/100    )%10);
1023     if(c >= 10)
1024         (*oconv)(0, 0x30+(c/10     )%10);
1025     if(c >= 0)
1026         (*oconv)(0, 0x30+ c         %10);
1027     (*oconv)(0, ';');
1028     return;
1029 }
1030
1031 static void
1032 encode_fallback_xml(nkf_char c)
1033 {
1034     (*oconv)(0, '&');
1035     (*oconv)(0, '#');
1036     (*oconv)(0, 'x');
1037     nkf_each_char_to_hex(oconv, c);
1038     (*oconv)(0, ';');
1039     return;
1040 }
1041
1042 static void
1043 encode_fallback_java(nkf_char c)
1044 {
1045     (*oconv)(0, '\\');
1046     c &= VALUE_MASK;
1047     if(!nkf_char_unicode_bmp_p(c)){
1048         (*oconv)(0, 'U');
1049         (*oconv)(0, '0');
1050         (*oconv)(0, '0');
1051         (*oconv)(0, bin2hex(c>>20));
1052         (*oconv)(0, bin2hex(c>>16));
1053     }else{
1054         (*oconv)(0, 'u');
1055     }
1056     (*oconv)(0, bin2hex(c>>12));
1057     (*oconv)(0, bin2hex(c>> 8));
1058     (*oconv)(0, bin2hex(c>> 4));
1059     (*oconv)(0, bin2hex(c    ));
1060     return;
1061 }
1062
1063 static void
1064 encode_fallback_perl(nkf_char c)
1065 {
1066     (*oconv)(0, '\\');
1067     (*oconv)(0, 'x');
1068     (*oconv)(0, '{');
1069     nkf_each_char_to_hex(oconv, c);
1070     (*oconv)(0, '}');
1071     return;
1072 }
1073
1074 static void
1075 encode_fallback_subchar(nkf_char c)
1076 {
1077     c = unicode_subchar;
1078     (*oconv)((c>>8)&0xFF, c&0xFF);
1079     return;
1080 }
1081 #endif
1082
1083 static const struct {
1084     const char *name;
1085     const char *alias;
1086 } long_option[] = {
1087     {"ic=", ""},
1088     {"oc=", ""},
1089     {"base64","jMB"},
1090     {"euc","e"},
1091     {"euc-input","E"},
1092     {"fj","jm"},
1093     {"help","v"},
1094     {"jis","j"},
1095     {"jis-input","J"},
1096     {"mac","sLm"},
1097     {"mime","jM"},
1098     {"mime-input","m"},
1099     {"msdos","sLw"},
1100     {"sjis","s"},
1101     {"sjis-input","S"},
1102     {"unix","eLu"},
1103     {"version","V"},
1104     {"windows","sLw"},
1105     {"hiragana","h1"},
1106     {"katakana","h2"},
1107     {"katakana-hiragana","h3"},
1108     {"guess=", ""},
1109     {"guess", "g2"},
1110     {"cp932", ""},
1111     {"no-cp932", ""},
1112 #ifdef X0212_ENABLE
1113     {"x0212", ""},
1114 #endif
1115 #ifdef UTF8_OUTPUT_ENABLE
1116     {"utf8", "w"},
1117     {"utf16", "w16"},
1118     {"ms-ucs-map", ""},
1119     {"fb-skip", ""},
1120     {"fb-html", ""},
1121     {"fb-xml", ""},
1122     {"fb-perl", ""},
1123     {"fb-java", ""},
1124     {"fb-subchar", ""},
1125     {"fb-subchar=", ""},
1126 #endif
1127 #ifdef UTF8_INPUT_ENABLE
1128     {"utf8-input", "W"},
1129     {"utf16-input", "W16"},
1130     {"no-cp932ext", ""},
1131     {"no-best-fit-chars",""},
1132 #endif
1133 #ifdef UNICODE_NORMALIZATION
1134     {"utf8mac-input", ""},
1135 #endif
1136 #ifdef OVERWRITE
1137     {"overwrite", ""},
1138     {"overwrite=", ""},
1139     {"in-place", ""},
1140     {"in-place=", ""},
1141 #endif
1142 #ifdef INPUT_OPTION
1143     {"cap-input", ""},
1144     {"url-input", ""},
1145 #endif
1146 #ifdef NUMCHAR_OPTION
1147     {"numchar-input", ""},
1148 #endif
1149 #ifdef CHECK_OPTION
1150     {"no-output", ""},
1151     {"debug", ""},
1152 #endif
1153 #ifdef SHIFTJIS_CP932
1154     {"cp932inv", ""},
1155 #endif
1156 #ifdef EXEC_IO
1157     {"exec-in", ""},
1158     {"exec-out", ""},
1159 #endif
1160     {"prefix=", ""},
1161 };
1162
1163 static void
1164 set_input_encoding(nkf_encoding *enc)
1165 {
1166     switch (nkf_enc_to_index(enc)) {
1167     case ISO_8859_1:
1168         iso8859_f = TRUE;
1169         break;
1170     case CP50220:
1171     case CP50221:
1172     case CP50222:
1173 #ifdef SHIFTJIS_CP932
1174         cp51932_f = TRUE;
1175 #endif
1176 #ifdef UTF8_OUTPUT_ENABLE
1177         ms_ucs_map_f = UCS_MAP_CP932;
1178 #endif
1179         break;
1180     case ISO_2022_JP_1:
1181         x0212_f = TRUE;
1182         break;
1183     case ISO_2022_JP_3:
1184         x0212_f = TRUE;
1185         x0213_f = TRUE;
1186         break;
1187     case ISO_2022_JP_2004:
1188         x0212_f = TRUE;
1189         x0213_f = TRUE;
1190         break;
1191     case SHIFT_JIS:
1192         break;
1193     case WINDOWS_31J:
1194 #ifdef SHIFTJIS_CP932
1195         cp51932_f = TRUE;
1196 #endif
1197 #ifdef UTF8_OUTPUT_ENABLE
1198         ms_ucs_map_f = UCS_MAP_CP932;
1199 #endif
1200         break;
1201         break;
1202     case CP10001:
1203 #ifdef SHIFTJIS_CP932
1204         cp51932_f = TRUE;
1205 #endif
1206 #ifdef UTF8_OUTPUT_ENABLE
1207         ms_ucs_map_f = UCS_MAP_CP10001;
1208 #endif
1209         break;
1210     case EUC_JP:
1211         break;
1212     case EUCJP_NKF:
1213         break;
1214     case CP51932:
1215 #ifdef SHIFTJIS_CP932
1216         cp51932_f = TRUE;
1217 #endif
1218 #ifdef UTF8_OUTPUT_ENABLE
1219         ms_ucs_map_f = UCS_MAP_CP932;
1220 #endif
1221         break;
1222     case EUCJP_MS:
1223 #ifdef SHIFTJIS_CP932
1224         cp51932_f = FALSE;
1225 #endif
1226 #ifdef UTF8_OUTPUT_ENABLE
1227         ms_ucs_map_f = UCS_MAP_MS;
1228 #endif
1229         break;
1230     case EUCJP_ASCII:
1231 #ifdef SHIFTJIS_CP932
1232         cp51932_f = FALSE;
1233 #endif
1234 #ifdef UTF8_OUTPUT_ENABLE
1235         ms_ucs_map_f = UCS_MAP_ASCII;
1236 #endif
1237         break;
1238     case SHIFT_JISX0213:
1239     case SHIFT_JIS_2004:
1240         x0213_f = TRUE;
1241 #ifdef SHIFTJIS_CP932
1242         cp51932_f = FALSE;
1243 #endif
1244         break;
1245     case EUC_JISX0213:
1246     case EUC_JIS_2004:
1247         x0213_f = TRUE;
1248 #ifdef SHIFTJIS_CP932
1249         cp51932_f = FALSE;
1250 #endif
1251         break;
1252 #ifdef UTF8_INPUT_ENABLE
1253 #ifdef UNICODE_NORMALIZATION
1254     case UTF8_MAC:
1255         nfc_f = TRUE;
1256         break;
1257 #endif
1258     case UTF_16:
1259     case UTF_16BE:
1260     case UTF_16BE_BOM:
1261         input_endian = ENDIAN_BIG;
1262         break;
1263     case UTF_16LE:
1264     case UTF_16LE_BOM:
1265         input_endian = ENDIAN_LITTLE;
1266         break;
1267     case UTF_32:
1268     case UTF_32BE:
1269     case UTF_32BE_BOM:
1270         input_endian = ENDIAN_BIG;
1271         break;
1272     case UTF_32LE:
1273     case UTF_32LE_BOM:
1274         input_endian = ENDIAN_LITTLE;
1275         break;
1276 #endif
1277     }
1278 }
1279
1280 static void
1281 set_output_encoding(nkf_encoding *enc)
1282 {
1283     switch (nkf_enc_to_index(enc)) {
1284     case CP50220:
1285         x0201_f = TRUE;
1286 #ifdef SHIFTJIS_CP932
1287         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1288 #endif
1289 #ifdef UTF8_OUTPUT_ENABLE
1290         ms_ucs_map_f = UCS_MAP_CP932;
1291 #endif
1292         break;
1293     case CP50221:
1294 #ifdef SHIFTJIS_CP932
1295         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1296 #endif
1297 #ifdef UTF8_OUTPUT_ENABLE
1298         ms_ucs_map_f = UCS_MAP_CP932;
1299 #endif
1300         break;
1301     case ISO_2022_JP_1:
1302         x0212_f = TRUE;
1303 #ifdef SHIFTJIS_CP932
1304         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1305 #endif
1306         break;
1307     case ISO_2022_JP_3:
1308         x0212_f = TRUE;
1309         x0213_f = TRUE;
1310 #ifdef SHIFTJIS_CP932
1311         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1312 #endif
1313         break;
1314     case SHIFT_JIS:
1315         break;
1316     case WINDOWS_31J:
1317 #ifdef UTF8_OUTPUT_ENABLE
1318         ms_ucs_map_f = UCS_MAP_CP932;
1319 #endif
1320         break;
1321     case CP10001:
1322 #ifdef UTF8_OUTPUT_ENABLE
1323         ms_ucs_map_f = UCS_MAP_CP10001;
1324 #endif
1325         break;
1326     case EUC_JP:
1327         x0212_f = TRUE;
1328 #ifdef SHIFTJIS_CP932
1329         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1330 #endif
1331 #ifdef UTF8_OUTPUT_ENABLE
1332         ms_ucs_map_f = UCS_MAP_ASCII;
1333 #endif
1334         break;
1335     case EUCJP_NKF:
1336         x0212_f = FALSE;
1337 #ifdef SHIFTJIS_CP932
1338         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1339 #endif
1340 #ifdef UTF8_OUTPUT_ENABLE
1341         ms_ucs_map_f = UCS_MAP_ASCII;
1342 #endif
1343         break;
1344     case CP51932:
1345 #ifdef SHIFTJIS_CP932
1346         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1347 #endif
1348 #ifdef UTF8_OUTPUT_ENABLE
1349         ms_ucs_map_f = UCS_MAP_CP932;
1350 #endif
1351         break;
1352     case EUCJP_MS:
1353         x0212_f = TRUE;
1354 #ifdef UTF8_OUTPUT_ENABLE
1355         ms_ucs_map_f = UCS_MAP_MS;
1356 #endif
1357         break;
1358     case EUCJP_ASCII:
1359         x0212_f = TRUE;
1360 #ifdef UTF8_OUTPUT_ENABLE
1361         ms_ucs_map_f = UCS_MAP_ASCII;
1362 #endif
1363         break;
1364     case SHIFT_JISX0213:
1365     case SHIFT_JIS_2004:
1366         x0213_f = TRUE;
1367 #ifdef SHIFTJIS_CP932
1368         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1369 #endif
1370         break;
1371     case EUC_JISX0213:
1372     case EUC_JIS_2004:
1373         x0212_f = TRUE;
1374         x0213_f = TRUE;
1375 #ifdef SHIFTJIS_CP932
1376         if (cp932inv_f == TRUE) cp932inv_f = FALSE;
1377 #endif
1378         break;
1379 #ifdef UTF8_OUTPUT_ENABLE
1380     case UTF_8_BOM:
1381         output_bom_f = TRUE;
1382         break;
1383     case UTF_16:
1384     case UTF_16BE_BOM:
1385         output_bom_f = TRUE;
1386         break;
1387     case UTF_16LE:
1388         output_endian = ENDIAN_LITTLE;
1389         output_bom_f = FALSE;
1390         break;
1391     case UTF_16LE_BOM:
1392         output_endian = ENDIAN_LITTLE;
1393         output_bom_f = TRUE;
1394         break;
1395     case UTF_32BE_BOM:
1396         output_bom_f = TRUE;
1397         break;
1398     case UTF_32LE:
1399         output_endian = ENDIAN_LITTLE;
1400         output_bom_f = FALSE;
1401         break;
1402     case UTF_32LE_BOM:
1403         output_endian = ENDIAN_LITTLE;
1404         output_bom_f = TRUE;
1405         break;
1406 #endif
1407     }
1408 }
1409
1410 static struct input_code*
1411 find_inputcode_byfunc(nkf_char (*iconv_func)(nkf_char c2,nkf_char c1,nkf_char c0))
1412 {
1413     if (iconv_func){
1414         struct input_code *p = input_code_list;
1415         while (p->name){
1416             if (iconv_func == p->iconv_func){
1417                 return p;
1418             }
1419             p++;
1420         }
1421     }
1422     return 0;
1423 }
1424
1425 static void
1426 set_iconv(nkf_char f, nkf_char (*iconv_func)(nkf_char c2,nkf_char c1,nkf_char c0))
1427 {
1428 #ifdef INPUT_CODE_FIX
1429     if (f || !input_encoding)
1430 #endif
1431         if (estab_f != f){
1432             estab_f = f;
1433         }
1434
1435     if (iconv_func
1436 #ifdef INPUT_CODE_FIX
1437         && (f == -TRUE || !input_encoding) /* -TRUE means "FORCE" */
1438 #endif
1439        ){
1440         iconv = iconv_func;
1441     }
1442 #ifdef CHECK_OPTION
1443     if (estab_f && iconv_for_check != iconv){
1444         struct input_code *p = find_inputcode_byfunc(iconv);
1445         if (p){
1446             set_input_codename(p->name);
1447             debug(p->name);
1448         }
1449         iconv_for_check = iconv;
1450     }
1451 #endif
1452 }
1453
1454 #ifdef X0212_ENABLE
1455 static nkf_char
1456 x0212_shift(nkf_char c)
1457 {
1458     nkf_char ret = c;
1459     c &= 0x7f;
1460     if (is_eucg3(ret)){
1461         if (0x75 <= c && c <= 0x7f){
1462             ret = c + (0x109 - 0x75);
1463         }
1464     }else{
1465         if (0x75 <= c && c <= 0x7f){
1466             ret = c + (0x113 - 0x75);
1467         }
1468     }
1469     return ret;
1470 }
1471
1472
1473 static nkf_char
1474 x0212_unshift(nkf_char c)
1475 {
1476     nkf_char ret = c;
1477     if (0x7f <= c && c <= 0x88){
1478         ret = c + (0x75 - 0x7f);
1479     }else if (0x89 <= c && c <= 0x92){
1480         ret = PREFIX_EUCG3 | 0x80 | (c + (0x75 - 0x89));
1481     }
1482     return ret;
1483 }
1484 #endif /* X0212_ENABLE */
1485
1486 static nkf_char
1487 e2s_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1)
1488 {
1489     nkf_char ndx;
1490     if (is_eucg3(c2)){
1491         ndx = c2 & 0x7f;
1492         if (x0213_f){
1493             if((0x21 <= ndx && ndx <= 0x2F)){
1494                 if (p2) *p2 = ((ndx - 1) >> 1) + 0xec - ndx / 8 * 3;
1495                 if (p1) *p1 = c1 + ((ndx & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e);
1496                 return 0;
1497             }else if(0x6E <= ndx && ndx <= 0x7E){
1498                 if (p2) *p2 = ((ndx - 1) >> 1) + 0xbe;
1499                 if (p1) *p1 = c1 + ((ndx & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e);
1500                 return 0;
1501             }
1502             return 1;
1503         }
1504 #ifdef X0212_ENABLE
1505         else if(nkf_isgraph(ndx)){
1506             nkf_char val = 0;
1507             const unsigned short *ptr;
1508             ptr = x0212_shiftjis[ndx - 0x21];
1509             if (ptr){
1510                 val = ptr[(c1 & 0x7f) - 0x21];
1511             }
1512             if (val){
1513                 c2 = val >> 8;
1514                 c1 = val & 0xff;
1515                 if (p2) *p2 = c2;
1516                 if (p1) *p1 = c1;
1517                 return 0;
1518             }
1519             c2 = x0212_shift(c2);
1520         }
1521 #endif /* X0212_ENABLE */
1522     }
1523     if(0x7F < c2) return 1;
1524     if (p2) *p2 = ((c2 - 1) >> 1) + ((c2 <= 0x5e) ? 0x71 : 0xb1);
1525     if (p1) *p1 = c1 + ((c2 & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e);
1526     return 0;
1527 }
1528
1529 static nkf_char
1530 s2e_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1)
1531 {
1532 #if defined(SHIFTJIS_CP932) || defined(X0212_ENABLE)
1533     nkf_char val;
1534 #endif
1535     static const char shift_jisx0213_s1a3_table[5][2] ={ { 1, 8}, { 3, 4}, { 5,12}, {13,14}, {15, 0} };
1536     if (0xFC < c1) return 1;
1537 #ifdef SHIFTJIS_CP932
1538     if (!cp932inv_f && is_ibmext_in_sjis(c2)){
1539         val = shiftjis_cp932[c2 - CP932_TABLE_BEGIN][c1 - 0x40];
1540         if (val){
1541             c2 = val >> 8;
1542             c1 = val & 0xff;
1543         }
1544     }
1545     if (cp932inv_f
1546         && CP932INV_TABLE_BEGIN <= c2 && c2 <= CP932INV_TABLE_END){
1547         val = cp932inv[c2 - CP932INV_TABLE_BEGIN][c1 - 0x40];
1548         if (val){
1549             c2 = val >> 8;
1550             c1 = val & 0xff;
1551         }
1552     }
1553 #endif /* SHIFTJIS_CP932 */
1554 #ifdef X0212_ENABLE
1555     if (!x0213_f && is_ibmext_in_sjis(c2)){
1556         val = shiftjis_x0212[c2 - 0xfa][c1 - 0x40];
1557         if (val){
1558             if (val > 0x7FFF){
1559                 c2 = PREFIX_EUCG3 | ((val >> 8) & 0x7f);
1560                 c1 = val & 0xff;
1561             }else{
1562                 c2 = val >> 8;
1563                 c1 = val & 0xff;
1564             }
1565             if (p2) *p2 = c2;
1566             if (p1) *p1 = c1;
1567             return 0;
1568         }
1569     }
1570 #endif
1571     if(c2 >= 0x80){
1572         if(x0213_f && c2 >= 0xF0){
1573             if(c2 <= 0xF3 || (c2 == 0xF4 && c1 < 0x9F)){ /* k=1, 3<=k<=5, k=8, 12<=k<=15 */
1574                 c2 = PREFIX_EUCG3 | 0x20 | shift_jisx0213_s1a3_table[c2 - 0xF0][0x9E < c1];
1575             }else{ /* 78<=k<=94 */
1576                 c2 = PREFIX_EUCG3 | (c2 * 2 - 0x17B);
1577                 if (0x9E < c1) c2++;
1578             }
1579         }else{
1580 #define         SJ0162  0x00e1          /* 01 - 62 ku offset */
1581 #define         SJ6394  0x0161          /* 63 - 94 ku offset */
1582             c2 = c2 + c2 - ((c2 <= 0x9F) ? SJ0162 : SJ6394);
1583             if (0x9E < c1) c2++;
1584         }
1585         if (c1 < 0x9F)
1586             c1 = c1 - ((c1 > DEL) ? SP : 0x1F);
1587         else {
1588             c1 = c1 - 0x7E;
1589         }
1590     }
1591
1592 #ifdef X0212_ENABLE
1593     c2 = x0212_unshift(c2);
1594 #endif
1595     if (p2) *p2 = c2;
1596     if (p1) *p1 = c1;
1597     return 0;
1598 }
1599
1600 #if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
1601 static void
1602 nkf_unicode_to_utf8(nkf_char val, nkf_char *p1, nkf_char *p2, nkf_char *p3, nkf_char *p4)
1603 {
1604     val &= VALUE_MASK;
1605     if (val < 0x80){
1606         *p1 = val;
1607         *p2 = 0;
1608         *p3 = 0;
1609         *p4 = 0;
1610     }else if (val < 0x800){
1611         *p1 = 0xc0 | (val >> 6);
1612         *p2 = 0x80 | (val & 0x3f);
1613         *p3 = 0;
1614         *p4 = 0;
1615     } else if (nkf_char_unicode_bmp_p(val)) {
1616         *p1 = 0xe0 |  (val >> 12);
1617         *p2 = 0x80 | ((val >>  6) & 0x3f);
1618         *p3 = 0x80 | ( val        & 0x3f);
1619         *p4 = 0;
1620     } else if (nkf_char_unicode_value_p(val)) {
1621         *p1 = 0xe0 |  (val >> 16);
1622         *p2 = 0x80 | ((val >> 12) & 0x3f);
1623         *p3 = 0x80 | ((val >>  6) & 0x3f);
1624         *p4 = 0x80 | ( val        & 0x3f);
1625     } else {
1626         *p1 = 0;
1627         *p2 = 0;
1628         *p3 = 0;
1629         *p4 = 0;
1630     }
1631 }
1632
1633 static nkf_char
1634 nkf_utf8_to_unicode(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4)
1635 {
1636     nkf_char wc;
1637     if (c1 <= 0x7F) {
1638         /* single byte */
1639         wc = c1;
1640     }
1641     else if (c1 <= 0xC3) {
1642         /* trail byte or invalid */
1643         return -1;
1644     }
1645     else if (c1 <= 0xDF) {
1646         /* 2 bytes */
1647         wc  = (c1 & 0x1F) << 6;
1648         wc |= (c2 & 0x3F);
1649     }
1650     else if (c1 <= 0xEF) {
1651         /* 3 bytes */
1652         wc  = (c1 & 0x0F) << 12;
1653         wc |= (c2 & 0x3F) << 6;
1654         wc |= (c3 & 0x3F);
1655     }
1656     else if (c2 <= 0xF4) {
1657         /* 4 bytes */
1658         wc  = (c1 & 0x0F) << 18;
1659         wc |= (c2 & 0x3F) << 12;
1660         wc |= (c3 & 0x3F) << 6;
1661         wc |= (c4 & 0x3F);
1662     }
1663     else {
1664         return -1;
1665     }
1666     return wc;
1667 }
1668 #endif
1669
1670 #ifdef UTF8_INPUT_ENABLE
1671 static int
1672 unicode_to_jis_common2(nkf_char c1, nkf_char c0,
1673                        const unsigned short *const *pp, nkf_char psize,
1674                        nkf_char *p2, nkf_char *p1)
1675 {
1676     nkf_char c2;
1677     const unsigned short *p;
1678     unsigned short val;
1679
1680     if (pp == 0) return 1;
1681
1682     c1 -= 0x80;
1683     if (c1 < 0 || psize <= c1) return 1;
1684     p = pp[c1];
1685     if (p == 0)  return 1;
1686
1687     c0 -= 0x80;
1688     if (c0 < 0 || sizeof_utf8_to_euc_C2 <= c0) return 1;
1689     val = p[c0];
1690     if (val == 0) return 1;
1691     if (no_cp932ext_f && (
1692                           (val>>8) == 0x2D || /* NEC special characters */
1693                           val > NKF_INT32_C(0xF300) /* IBM extended characters */
1694                          )) return 1;
1695
1696     c2 = val >> 8;
1697     if (val > 0x7FFF){
1698         c2 &= 0x7f;
1699         c2 |= PREFIX_EUCG3;
1700     }
1701     if (c2 == SO) c2 = JIS_X_0201_1976_K;
1702     c1 = val & 0xFF;
1703     if (p2) *p2 = c2;
1704     if (p1) *p1 = c1;
1705     return 0;
1706 }
1707
1708 static int
1709 unicode_to_jis_common(nkf_char c2, nkf_char c1, nkf_char c0, nkf_char *p2, nkf_char *p1)
1710 {
1711     const unsigned short *const *pp;
1712     const unsigned short *const *const *ppp;
1713     static const char no_best_fit_chars_table_C2[] =
1714     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1715         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1716         1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 2, 1, 1, 2,
1717         0, 0, 1, 1, 0, 1, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1};
1718     static const char no_best_fit_chars_table_C2_ms[] =
1719     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1720         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1721         1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0,
1722         0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0};
1723     static const char no_best_fit_chars_table_932_C2[] =
1724     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1725         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1726         1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1,
1727         0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0};
1728     static const char no_best_fit_chars_table_932_C3[] =
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         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1732         1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1};
1733     nkf_char ret = 0;
1734
1735     if(c2 < 0x80){
1736         *p2 = 0;
1737         *p1 = c2;
1738     }else if(c2 < 0xe0){
1739         if(no_best_fit_chars_f){
1740             if(ms_ucs_map_f == UCS_MAP_CP932){
1741                 switch(c2){
1742                 case 0xC2:
1743                     if(no_best_fit_chars_table_932_C2[c1&0x3F]) return 1;
1744                     break;
1745                 case 0xC3:
1746                     if(no_best_fit_chars_table_932_C3[c1&0x3F]) return 1;
1747                     break;
1748                 }
1749             }else if(!cp932inv_f){
1750                 switch(c2){
1751                 case 0xC2:
1752                     if(no_best_fit_chars_table_C2[c1&0x3F]) return 1;
1753                     break;
1754                 case 0xC3:
1755                     if(no_best_fit_chars_table_932_C3[c1&0x3F]) return 1;
1756                     break;
1757                 }
1758             }else if(ms_ucs_map_f == UCS_MAP_MS){
1759                 if(c2 == 0xC2 && no_best_fit_chars_table_C2_ms[c1&0x3F]) return 1;
1760             }else if(ms_ucs_map_f == UCS_MAP_CP10001){
1761                 switch(c2){
1762                 case 0xC2:
1763                     switch(c1){
1764                     case 0xA2:
1765                     case 0xA3:
1766                     case 0xA5:
1767                     case 0xA6:
1768                     case 0xAC:
1769                     case 0xAF:
1770                     case 0xB8:
1771                         return 1;
1772                     }
1773                     break;
1774                 }
1775             }
1776         }
1777         pp =
1778             ms_ucs_map_f == UCS_MAP_CP932 ? utf8_to_euc_2bytes_932 :
1779             ms_ucs_map_f == UCS_MAP_MS ? utf8_to_euc_2bytes_ms :
1780             ms_ucs_map_f == UCS_MAP_CP10001 ? utf8_to_euc_2bytes_mac :
1781             utf8_to_euc_2bytes;
1782         ret =  unicode_to_jis_common2(c2, c1, pp, sizeof_utf8_to_euc_2bytes, p2, p1);
1783     }else if(c0 < 0xF0){
1784         if(no_best_fit_chars_f){
1785             if(ms_ucs_map_f == UCS_MAP_CP932){
1786                 if(c2 == 0xE3 && c1 == 0x82 && c0 == 0x94) return 1;
1787             }else if(ms_ucs_map_f == UCS_MAP_MS){
1788                 switch(c2){
1789                 case 0xE2:
1790                     switch(c1){
1791                     case 0x80:
1792                         if(c0 == 0x94 || c0 == 0x96 || c0 == 0xBE) return 1;
1793                         break;
1794                     case 0x88:
1795                         if(c0 == 0x92) return 1;
1796                         break;
1797                     }
1798                     break;
1799                 case 0xE3:
1800                     if(c1 == 0x80 || c0 == 0x9C) return 1;
1801                     break;
1802                 }
1803             }else if(ms_ucs_map_f == UCS_MAP_CP10001){
1804                 switch(c2){
1805                 case 0xE3:
1806                     switch(c1){
1807                     case 0x82:
1808                         if(c0 == 0x94) return 1;
1809                         break;
1810                     case 0x83:
1811                         if(c0 == 0xBB) return 1;
1812                         break;
1813                     }
1814                     break;
1815                 }
1816             }else{
1817                 switch(c2){
1818                 case 0xE2:
1819                     switch(c1){
1820                     case 0x80:
1821                         if(c0 == 0x95) return 1;
1822                         break;
1823                     case 0x88:
1824                         if(c0 == 0xA5) return 1;
1825                         break;
1826                     }
1827                     break;
1828                 case 0xEF:
1829                     switch(c1){
1830                     case 0xBC:
1831                         if(c0 == 0x8D) return 1;
1832                         break;
1833                     case 0xBD:
1834                         if(c0 == 0x9E && !cp932inv_f) return 1;
1835                         break;
1836                     case 0xBF:
1837                         if(0xA0 <= c0 && c0 <= 0xA5) return 1;
1838                         break;
1839                     }
1840                     break;
1841                 }
1842             }
1843         }
1844         ppp =
1845             ms_ucs_map_f == UCS_MAP_CP932 ? utf8_to_euc_3bytes_932 :
1846             ms_ucs_map_f == UCS_MAP_MS ? utf8_to_euc_3bytes_ms :
1847             ms_ucs_map_f == UCS_MAP_CP10001 ? utf8_to_euc_3bytes_mac :
1848             utf8_to_euc_3bytes;
1849         ret = unicode_to_jis_common2(c1, c0, ppp[c2 - 0xE0], sizeof_utf8_to_euc_C2, p2, p1);
1850     }else return -1;
1851 #ifdef SHIFTJIS_CP932
1852     if (!ret && !cp932inv_f && is_eucg3(*p2)) {
1853         nkf_char s2, s1;
1854         if (e2s_conv(*p2, *p1, &s2, &s1) == 0) {
1855             s2e_conv(s2, s1, p2, p1);
1856         }else{
1857             ret = 1;
1858         }
1859     }
1860 #endif
1861     return ret;
1862 }
1863
1864 #ifdef UTF8_OUTPUT_ENABLE
1865 static nkf_char
1866 e2w_conv(nkf_char c2, nkf_char c1)
1867 {
1868     const unsigned short *p;
1869
1870     if (c2 == JIS_X_0201_1976_K) {
1871         if (ms_ucs_map_f == UCS_MAP_CP10001) {
1872             switch (c1) {
1873             case 0x20:
1874                 return 0xA0;
1875             case 0x7D:
1876                 return 0xA9;
1877             }
1878         }
1879         p = euc_to_utf8_1byte;
1880 #ifdef X0212_ENABLE
1881     } else if (is_eucg3(c2)){
1882         if(ms_ucs_map_f == UCS_MAP_ASCII&& c2 == NKF_INT32_C(0x8F22) && c1 == 0x43){
1883             return 0xA6;
1884         }
1885         c2 = (c2&0x7f) - 0x21;
1886         if (0<=c2 && c2<sizeof_euc_to_utf8_2bytes)
1887             p = x0212_to_utf8_2bytes[c2];
1888         else
1889             return 0;
1890 #endif
1891     } else {
1892         c2 &= 0x7f;
1893         c2 = (c2&0x7f) - 0x21;
1894         if (0<=c2 && c2<sizeof_euc_to_utf8_2bytes)
1895             p =
1896                 ms_ucs_map_f == UCS_MAP_ASCII ? euc_to_utf8_2bytes[c2] :
1897                 ms_ucs_map_f == UCS_MAP_CP10001 ? euc_to_utf8_2bytes_mac[c2] :
1898                 euc_to_utf8_2bytes_ms[c2];
1899         else
1900             return 0;
1901     }
1902     if (!p) return 0;
1903     c1 = (c1 & 0x7f) - 0x21;
1904     if (0<=c1 && c1<sizeof_euc_to_utf8_1byte)
1905         return p[c1];
1906     return 0;
1907 }
1908 #endif
1909
1910 static nkf_char
1911 w2e_conv(nkf_char c2, nkf_char c1, nkf_char c0, nkf_char *p2, nkf_char *p1)
1912 {
1913     nkf_char ret = 0;
1914
1915     if (!c1){
1916         *p2 = 0;
1917         *p1 = c2;
1918     }else if (0xc0 <= c2 && c2 <= 0xef) {
1919         ret =  unicode_to_jis_common(c2, c1, c0, p2, p1);
1920 #ifdef NUMCHAR_OPTION
1921         if (ret > 0){
1922             if (p2) *p2 = 0;
1923             if (p1) *p1 = nkf_char_unicode_new(nkf_utf8_to_unicode(c2, c1, c0, 0));
1924             ret = 0;
1925         }
1926 #endif
1927     }
1928     return ret;
1929 }
1930
1931 #ifdef UTF8_INPUT_ENABLE
1932 static nkf_char
1933 w16e_conv(nkf_char val, nkf_char *p2, nkf_char *p1)
1934 {
1935     nkf_char c1, c2, c3, c4;
1936     nkf_char ret = 0;
1937     val &= VALUE_MASK;
1938     if (val < 0x80) {
1939         *p2 = 0;
1940         *p1 = val;
1941     }
1942     else if (nkf_char_unicode_bmp_p(val)){
1943         nkf_unicode_to_utf8(val, &c1, &c2, &c3, &c4);
1944         ret =  unicode_to_jis_common(c1, c2, c3, p2, p1);
1945         if (ret > 0){
1946             *p2 = 0;
1947             *p1 = nkf_char_unicode_new(val);
1948             ret = 0;
1949         }
1950     }
1951     else {
1952         *p2 = 0;
1953         *p1 = nkf_char_unicode_new(val);
1954     }
1955     return ret;
1956 }
1957 #endif
1958
1959 static nkf_char
1960 e_iconv(nkf_char c2, nkf_char c1, nkf_char c0)
1961 {
1962     if (c2 == JIS_X_0201_1976_K || c2 == SS2){
1963         if (iso2022jp_f && !x0201_f) {
1964             c2 = GETA1; c1 = GETA2;
1965         } else {
1966             c2 = JIS_X_0201_1976_K;
1967             c1 &= 0x7f;
1968         }
1969 #ifdef X0212_ENABLE
1970     }else if (c2 == 0x8f){
1971         if (c0 == 0){
1972             return -1;
1973         }
1974         if (!cp51932_f && !x0213_f && 0xF5 <= c1 && c1 <= 0xFE && 0xA1 <= c0 && c0 <= 0xFE) {
1975             /* encoding is eucJP-ms, so invert to Unicode Private User Area */
1976             c1 = nkf_char_unicode_new((c1 - 0xF5) * 94 + c0 - 0xA1 + 0xE3AC);
1977             c2 = 0;
1978         } else {
1979             c2 = (c2 << 8) | (c1 & 0x7f);
1980             c1 = c0 & 0x7f;
1981 #ifdef SHIFTJIS_CP932
1982             if (cp51932_f){
1983                 nkf_char s2, s1;
1984                 if (e2s_conv(c2, c1, &s2, &s1) == 0){
1985                     s2e_conv(s2, s1, &c2, &c1);
1986                     if (c2 < 0x100){
1987                         c1 &= 0x7f;
1988                         c2 &= 0x7f;
1989                     }
1990                 }
1991             }
1992 #endif /* SHIFTJIS_CP932 */
1993         }
1994 #endif /* X0212_ENABLE */
1995     } else if ((c2 == EOF) || (c2 == 0) || c2 < SP || c2 == ISO_8859_1) {
1996         /* NOP */
1997     } else {
1998         if (!cp51932_f && ms_ucs_map_f && 0xF5 <= c2 && c2 <= 0xFE && 0xA1 <= c1 && c1 <= 0xFE) {
1999             /* encoding is eucJP-ms, so invert to Unicode Private User Area */
2000             c1 = nkf_char_unicode_new((c2 - 0xF5) * 94 + c1 - 0xA1 + 0xE000);
2001             c2 = 0;
2002         } else {
2003             c1 &= 0x7f;
2004             c2 &= 0x7f;
2005 #ifdef SHIFTJIS_CP932
2006             if (cp51932_f && 0x79 <= c2 && c2 <= 0x7c){
2007                 nkf_char s2, s1;
2008                 if (e2s_conv(c2, c1, &s2, &s1) == 0){
2009                     s2e_conv(s2, s1, &c2, &c1);
2010                     if (c2 < 0x100){
2011                         c1 &= 0x7f;
2012                         c2 &= 0x7f;
2013                     }
2014                 }
2015             }
2016 #endif /* SHIFTJIS_CP932 */
2017         }
2018     }
2019     (*oconv)(c2, c1);
2020     return 0;
2021 }
2022
2023 static nkf_char
2024 s_iconv(nkf_char c2, nkf_char c1, nkf_char c0)
2025 {
2026     if (c2 == JIS_X_0201_1976_K || (0xA1 <= c2 && c2 <= 0xDF)) {
2027         if (iso2022jp_f && !x0201_f) {
2028             c2 = GETA1; c1 = GETA2;
2029         } else {
2030             c1 &= 0x7f;
2031         }
2032     } else if ((c2 == EOF) || (c2 == 0) || c2 < SP) {
2033         /* NOP */
2034     } else if (!x0213_f && 0xF0 <= c2 && c2 <= 0xF9 && 0x40 <= c1 && c1 <= 0xFC) {
2035         /* CP932 UDC */
2036         if(c1 == 0x7F) return 0;
2037         c1 = nkf_char_unicode_new((c2 - 0xF0) * 188 + (c1 - 0x40 - (0x7E < c1)) + 0xE000);
2038         c2 = 0;
2039     } else {
2040         nkf_char ret = s2e_conv(c2, c1, &c2, &c1);
2041         if (ret) return ret;
2042     }
2043     (*oconv)(c2, c1);
2044     return 0;
2045 }
2046
2047 static nkf_char
2048 w_iconv(nkf_char c1, nkf_char c2, nkf_char c3)
2049 {
2050     nkf_char ret = 0, c4 = 0;
2051     static const char w_iconv_utf8_1st_byte[] =
2052     { /* 0xC0 - 0xFF */
2053         20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
2054         21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
2055         30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 33,
2056         40, 41, 41, 41, 42, 43, 43, 43, 50, 50, 50, 50, 60, 60, 70, 70};
2057
2058     if (c3 > 0xFF) {
2059         c4 = c3 & 0xFF;
2060         c3 >>= 8;
2061     }
2062
2063     if (c1 < 0 || 0xff < c1) {
2064     }else if (c1 == 0) { /* 0 : 1 byte*/
2065         c3 = 0;
2066     } else if ((c1 & 0xC0) == 0x80) { /* 0x80-0xbf : trail byte */
2067         return 0;
2068     } else{
2069         switch (w_iconv_utf8_1st_byte[c1 - 0xC0]) {
2070         case 21:
2071             if (c2 < 0x80 || 0xBF < c2) return 0;
2072             break;
2073         case 30:
2074             if (c3 == 0) return -1;
2075             if (c2 < 0xA0 || 0xBF < c2 || (c3 & 0xC0) != 0x80)
2076                 return 0;
2077             break;
2078         case 31:
2079         case 33:
2080             if (c3 == 0) return -1;
2081             if ((c2 & 0xC0) != 0x80 || (c3 & 0xC0) != 0x80)
2082                 return 0;
2083             break;
2084         case 32:
2085             if (c3 == 0) return -1;
2086             if (c2 < 0x80 || 0x9F < c2 || (c3 & 0xC0) != 0x80)
2087                 return 0;
2088             break;
2089         case 40:
2090             if (c3 == 0) return -2;
2091             if (c2 < 0x90 || 0xBF < c2 || (c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2092                 return 0;
2093             break;
2094         case 41:
2095             if (c3 == 0) return -2;
2096             if (c2 < 0x80 || 0xBF < c2 || (c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2097                 return 0;
2098             break;
2099         case 42:
2100             if (c3 == 0) return -2;
2101             if (c2 < 0x80 || 0x8F < c2 || (c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2102                 return 0;
2103             break;
2104         default:
2105             return 0;
2106             break;
2107         }
2108     }
2109     if (c1 == 0 || c1 == EOF){
2110     } else if ((c1 & 0xf8) == 0xf0) { /* 4 bytes */
2111         c2 = nkf_char_unicode_new(nkf_utf8_to_unicode(c1, c2, c3, c4));
2112         c1 = 0;
2113     } else {
2114         ret = w2e_conv(c1, c2, c3, &c1, &c2);
2115     }
2116     if (ret == 0){
2117         (*oconv)(c1, c2);
2118     }
2119     return ret;
2120 }
2121
2122 #define NKF_ICONV_INVALID_CODE_RANGE -13
2123 static size_t
2124 unicode_iconv(nkf_char wc)
2125 {
2126     nkf_char c1, c2;
2127     int ret = 0;
2128
2129     if (wc < 0x80) {
2130         c2 = 0;
2131         c1 = wc;
2132     }else if ((wc>>11) == 27) {
2133         /* unpaired surrogate */
2134         return NKF_ICONV_INVALID_CODE_RANGE;
2135     }else if (wc < 0xFFFF) {
2136         ret = w16e_conv(wc, &c2, &c1);
2137         if (ret) return ret;
2138     }else if (wc < 0x10FFFF) {
2139         c2 = 0;
2140         c1 = nkf_char_unicode_new(wc);
2141     } else {
2142         return NKF_ICONV_INVALID_CODE_RANGE;
2143     }
2144     (*oconv)(c2, c1);
2145     return 0;
2146 }
2147
2148 #define NKF_ICONV_NEED_ONE_MORE_BYTE -1
2149 #define NKF_ICONV_NEED_TWO_MORE_BYTES -2
2150 #define UTF16_TO_UTF32(lead, trail) (((lead) << 10) + (trail) - NKF_INT32_C(0x35FDC00))
2151 static size_t
2152 nkf_iconv_utf_16(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4)
2153 {
2154     nkf_char wc;
2155
2156     if (c1 == EOF) {
2157         (*oconv)(EOF, 0);
2158         return 0;
2159     }
2160
2161     if (input_endian == ENDIAN_BIG) {
2162         if (0xD8 <= c1 && c1 <= 0xDB) {
2163             if (0xDC <= c3 && c3 <= 0xDF) {
2164                 wc = UTF16_TO_UTF32(c1 << 8 | c2, c3 << 8 | c4);
2165             } else return NKF_ICONV_NEED_TWO_MORE_BYTES;
2166         } else {
2167             wc = c1 << 8 | c2;
2168         }
2169     } else {
2170         if (0xD8 <= c2 && c2 <= 0xDB) {
2171             if (0xDC <= c4 && c4 <= 0xDF) {
2172                 wc = UTF16_TO_UTF32(c2 << 8 | c1, c4 << 8 | c3);
2173             } else return NKF_ICONV_NEED_TWO_MORE_BYTES;
2174         } else {
2175             wc = c2 << 8 | c1;
2176         }
2177     }
2178
2179     return (*unicode_iconv)(wc);
2180 }
2181
2182 static nkf_char
2183 w_iconv16(nkf_char c2, nkf_char c1, nkf_char c0)
2184 {
2185     return 0;
2186 }
2187
2188 static nkf_char
2189 w_iconv32(nkf_char c2, nkf_char c1, nkf_char c0)
2190 {
2191     return 0;
2192 }
2193
2194 static size_t
2195 nkf_iconv_utf_32(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4)
2196 {
2197     nkf_char wc;
2198
2199     if (c1 == EOF) {
2200         (*oconv)(EOF, 0);
2201         return 0;
2202     }
2203
2204     switch(input_endian){
2205     case ENDIAN_BIG:
2206         wc = c2 << 16 | c3 << 8 | c4;
2207         break;
2208     case ENDIAN_LITTLE:
2209         wc = c3 << 16 | c2 << 8 | c1;
2210         break;
2211     case ENDIAN_2143:
2212         wc = c1 << 16 | c4 << 8 | c3;
2213         break;
2214     case ENDIAN_3412:
2215         wc = c4 << 16 | c1 << 8 | c2;
2216         break;
2217     default:
2218         return NKF_ICONV_INVALID_CODE_RANGE;
2219     }
2220
2221     return (*unicode_iconv)(wc);
2222 }
2223 #endif
2224
2225 #define output_ascii_escape_sequence(mode) do { \
2226             if (output_mode != ASCII && output_mode != ISO_8859_1) { \
2227                     (*o_putc)(ESC); \
2228                     (*o_putc)('('); \
2229                     (*o_putc)(ascii_intro); \
2230                     output_mode = mode; \
2231             } \
2232     } while (0)
2233
2234 static void
2235 output_escape_sequence(int mode)
2236 {
2237     if (output_mode == mode)
2238         return;
2239     switch(mode) {
2240     case ISO_8859_1:
2241         (*o_putc)(ESC);
2242         (*o_putc)('.');
2243         (*o_putc)('A');
2244         break;
2245     case JIS_X_0201_1976_K:
2246         (*o_putc)(ESC);
2247         (*o_putc)('(');
2248         (*o_putc)('I');
2249         break;
2250     case JIS_X_0208:
2251         (*o_putc)(ESC);
2252         (*o_putc)('$');
2253         (*o_putc)(kanji_intro);
2254         break;
2255     case JIS_X_0212:
2256         (*o_putc)(ESC);
2257         (*o_putc)('$');
2258         (*o_putc)('(');
2259         (*o_putc)('D');
2260         break;
2261     case JIS_X_0213_1:
2262         (*o_putc)(ESC);
2263         (*o_putc)('$');
2264         (*o_putc)('(');
2265         (*o_putc)('Q');
2266         break;
2267     case JIS_X_0213_2:
2268         (*o_putc)(ESC);
2269         (*o_putc)('$');
2270         (*o_putc)('(');
2271         (*o_putc)('P');
2272         break;
2273     }
2274     output_mode = mode;
2275 }
2276
2277 static void
2278 j_oconv(nkf_char c2, nkf_char c1)
2279 {
2280 #ifdef NUMCHAR_OPTION
2281     if (c2 == 0 && nkf_char_unicode_p(c1)){
2282         w16e_conv(c1, &c2, &c1);
2283         if (c2 == 0 && nkf_char_unicode_p(c1)){
2284             c2 = c1 & VALUE_MASK;
2285             if (ms_ucs_map_f && 0xE000 <= c2 && c2 <= 0xE757) {
2286                 /* CP5022x UDC */
2287                 c1 &= 0xFFF;
2288                 c2 = 0x7F + c1 / 94;
2289                 c1 = 0x21 + c1 % 94;
2290             } else {
2291                 if (encode_fallback) (*encode_fallback)(c1);
2292                 return;
2293             }
2294         }
2295     }
2296 #endif
2297     if (c2 == 0) {
2298         output_ascii_escape_sequence(ASCII);
2299         (*o_putc)(c1);
2300     }
2301     else if (c2 == EOF) {
2302         output_ascii_escape_sequence(ASCII);
2303         (*o_putc)(EOF);
2304     }
2305     else if (c2 == ISO_8859_1) {
2306         output_ascii_escape_sequence(ISO_8859_1);
2307         (*o_putc)(c1|0x80);
2308     }
2309     else if (c2 == JIS_X_0201_1976_K) {
2310         output_escape_sequence(JIS_X_0201_1976_K);
2311         (*o_putc)(c1);
2312 #ifdef X0212_ENABLE
2313     } else if (is_eucg3(c2)){
2314         output_escape_sequence(x0213_f ? JIS_X_0213_2 : JIS_X_0212);
2315         (*o_putc)(c2 & 0x7f);
2316         (*o_putc)(c1);
2317 #endif
2318     } else {
2319         if(ms_ucs_map_f
2320            ? c2<0x20 || 0x92<c2 || c1<0x20 || 0x7e<c1
2321            : c2<0x20 || 0x7e<c2 || c1<0x20 || 0x7e<c1) return;
2322         output_escape_sequence(x0213_f ? JIS_X_0213_1 : JIS_X_0208);
2323         (*o_putc)(c2);
2324         (*o_putc)(c1);
2325     }
2326 }
2327
2328 static void
2329 e_oconv(nkf_char c2, nkf_char c1)
2330 {
2331     if (c2 == 0 && nkf_char_unicode_p(c1)){
2332         w16e_conv(c1, &c2, &c1);
2333         if (c2 == 0 && nkf_char_unicode_p(c1)){
2334             c2 = c1 & VALUE_MASK;
2335             if (x0212_f && 0xE000 <= c2 && c2 <= 0xE757) {
2336                 /* eucJP-ms UDC */
2337                 c1 &= 0xFFF;
2338                 c2 = c1 / 94;
2339                 c2 += c2 < 10 ? 0x75 : 0x8FEB;
2340                 c1 = 0x21 + c1 % 94;
2341                 if (is_eucg3(c2)){
2342                     (*o_putc)(0x8f);
2343                     (*o_putc)((c2 & 0x7f) | 0x080);
2344                     (*o_putc)(c1 | 0x080);
2345                 }else{
2346                     (*o_putc)((c2 & 0x7f) | 0x080);
2347                     (*o_putc)(c1 | 0x080);
2348                 }
2349                 return;
2350             } else {
2351                 if (encode_fallback) (*encode_fallback)(c1);
2352                 return;
2353             }
2354         }
2355     }
2356
2357     if (c2 == EOF) {
2358         (*o_putc)(EOF);
2359     } else if (c2 == 0) {
2360         output_mode = ASCII;
2361         (*o_putc)(c1);
2362     } else if (c2 == JIS_X_0201_1976_K) {
2363         output_mode = EUC_JP;
2364         (*o_putc)(SS2); (*o_putc)(c1|0x80);
2365     } else if (c2 == ISO_8859_1) {
2366         output_mode = ISO_8859_1;
2367         (*o_putc)(c1 | 0x080);
2368 #ifdef X0212_ENABLE
2369     } else if (is_eucg3(c2)){
2370         output_mode = EUC_JP;
2371 #ifdef SHIFTJIS_CP932
2372         if (!cp932inv_f){
2373             nkf_char s2, s1;
2374             if (e2s_conv(c2, c1, &s2, &s1) == 0){
2375                 s2e_conv(s2, s1, &c2, &c1);
2376             }
2377         }
2378 #endif
2379         if (c2 == 0) {
2380             output_mode = ASCII;
2381             (*o_putc)(c1);
2382         }else if (is_eucg3(c2)){
2383             if (x0212_f){
2384                 (*o_putc)(0x8f);
2385                 (*o_putc)((c2 & 0x7f) | 0x080);
2386                 (*o_putc)(c1 | 0x080);
2387             }
2388         }else{
2389             (*o_putc)((c2 & 0x7f) | 0x080);
2390             (*o_putc)(c1 | 0x080);
2391         }
2392 #endif
2393     } else {
2394         if (!nkf_isgraph(c1) || !nkf_isgraph(c2)) {
2395             set_iconv(FALSE, 0);
2396             return; /* too late to rescue this char */
2397         }
2398         output_mode = EUC_JP;
2399         (*o_putc)(c2 | 0x080);
2400         (*o_putc)(c1 | 0x080);
2401     }
2402 }
2403
2404 static void
2405 s_oconv(nkf_char c2, nkf_char c1)
2406 {
2407 #ifdef NUMCHAR_OPTION
2408     if (c2 == 0 && nkf_char_unicode_p(c1)){
2409         w16e_conv(c1, &c2, &c1);
2410         if (c2 == 0 && nkf_char_unicode_p(c1)){
2411             c2 = c1 & VALUE_MASK;
2412             if (!x0213_f && 0xE000 <= c2 && c2 <= 0xE757) {
2413                 /* CP932 UDC */
2414                 c1 &= 0xFFF;
2415                 c2 = c1 / 188 + (cp932inv_f ? 0xF0 : 0xEB);
2416                 c1 = c1 % 188;
2417                 c1 += 0x40 + (c1 > 0x3e);
2418                 (*o_putc)(c2);
2419                 (*o_putc)(c1);
2420                 return;
2421             } else {
2422                 if(encode_fallback)(*encode_fallback)(c1);
2423                 return;
2424             }
2425         }
2426     }
2427 #endif
2428     if (c2 == EOF) {
2429         (*o_putc)(EOF);
2430         return;
2431     } else if (c2 == 0) {
2432         output_mode = ASCII;
2433         (*o_putc)(c1);
2434     } else if (c2 == JIS_X_0201_1976_K) {
2435         output_mode = SHIFT_JIS;
2436         (*o_putc)(c1|0x80);
2437     } else if (c2 == ISO_8859_1) {
2438         output_mode = ISO_8859_1;
2439         (*o_putc)(c1 | 0x080);
2440 #ifdef X0212_ENABLE
2441     } else if (is_eucg3(c2)){
2442         output_mode = SHIFT_JIS;
2443         if (e2s_conv(c2, c1, &c2, &c1) == 0){
2444             (*o_putc)(c2);
2445             (*o_putc)(c1);
2446         }
2447 #endif
2448     } else {
2449         if (!nkf_isprint(c1) || !nkf_isprint(c2)) {
2450             set_iconv(FALSE, 0);
2451             return; /* too late to rescue this char */
2452         }
2453         output_mode = SHIFT_JIS;
2454         e2s_conv(c2, c1, &c2, &c1);
2455
2456 #ifdef SHIFTJIS_CP932
2457         if (cp932inv_f
2458             && CP932INV_TABLE_BEGIN <= c2 && c2 <= CP932INV_TABLE_END){
2459             nkf_char c = cp932inv[c2 - CP932INV_TABLE_BEGIN][c1 - 0x40];
2460             if (c){
2461                 c2 = c >> 8;
2462                 c1 = c & 0xff;
2463             }
2464         }
2465 #endif /* SHIFTJIS_CP932 */
2466
2467         (*o_putc)(c2);
2468         if (prefix_table[(unsigned char)c1]){
2469             (*o_putc)(prefix_table[(unsigned char)c1]);
2470         }
2471         (*o_putc)(c1);
2472     }
2473 }
2474
2475 #ifdef UTF8_OUTPUT_ENABLE
2476 static void
2477 w_oconv(nkf_char c2, nkf_char c1)
2478 {
2479     nkf_char c3, c4;
2480     nkf_char val;
2481
2482     if (output_bom_f) {
2483         output_bom_f = FALSE;
2484         (*o_putc)('\357');
2485         (*o_putc)('\273');
2486         (*o_putc)('\277');
2487     }
2488
2489     if (c2 == EOF) {
2490         (*o_putc)(EOF);
2491         return;
2492     }
2493
2494     if (c2 == 0 && nkf_char_unicode_p(c1)){
2495         val = c1 & VALUE_MASK;
2496         nkf_unicode_to_utf8(val, &c1, &c2, &c3, &c4);
2497         (*o_putc)(c1);
2498         if (c2) (*o_putc)(c2);
2499         if (c3) (*o_putc)(c3);
2500         if (c4) (*o_putc)(c4);
2501         return;
2502     }
2503
2504     if (c2 == 0) {
2505         (*o_putc)(c1);
2506     } else {
2507         val = e2w_conv(c2, c1);
2508         if (val){
2509             nkf_unicode_to_utf8(val, &c1, &c2, &c3, &c4);
2510             (*o_putc)(c1);
2511             if (c2) (*o_putc)(c2);
2512             if (c3) (*o_putc)(c3);
2513             if (c4) (*o_putc)(c4);
2514         }
2515     }
2516 }
2517
2518 static void
2519 w_oconv16(nkf_char c2, nkf_char c1)
2520 {
2521     if (output_bom_f) {
2522         output_bom_f = FALSE;
2523         if (output_endian == ENDIAN_LITTLE){
2524             (*o_putc)(0xFF);
2525             (*o_putc)(0xFE);
2526         }else{
2527             (*o_putc)(0xFE);
2528             (*o_putc)(0xFF);
2529         }
2530     }
2531
2532     if (c2 == EOF) {
2533         (*o_putc)(EOF);
2534         return;
2535     }
2536
2537     if (c2 == 0 && nkf_char_unicode_p(c1)) {
2538         if (nkf_char_unicode_bmp_p(c1)) {
2539             c2 = (c1 >> 8) & 0xff;
2540             c1 &= 0xff;
2541         } else {
2542             c1 &= VALUE_MASK;
2543             if (c1 <= UNICODE_MAX) {
2544                 c2 = (c1 >> 10) + NKF_INT32_C(0xD7C0);   /* high surrogate */
2545                 c1 = (c1 & 0x3FF) + NKF_INT32_C(0xDC00); /* low surrogate */
2546                 if (output_endian == ENDIAN_LITTLE){
2547                     (*o_putc)(c2 & 0xff);
2548                     (*o_putc)((c2 >> 8) & 0xff);
2549                     (*o_putc)(c1 & 0xff);
2550                     (*o_putc)((c1 >> 8) & 0xff);
2551                 }else{
2552                     (*o_putc)((c2 >> 8) & 0xff);
2553                     (*o_putc)(c2 & 0xff);
2554                     (*o_putc)((c1 >> 8) & 0xff);
2555                     (*o_putc)(c1 & 0xff);
2556                 }
2557             }
2558             return;
2559         }
2560     } else if (c2) {
2561         nkf_char val = e2w_conv(c2, c1);
2562         c2 = (val >> 8) & 0xff;
2563         c1 = val & 0xff;
2564         if (!val) return;
2565     }
2566
2567     if (output_endian == ENDIAN_LITTLE){
2568         (*o_putc)(c1);
2569         (*o_putc)(c2);
2570     }else{
2571         (*o_putc)(c2);
2572         (*o_putc)(c1);
2573     }
2574 }
2575
2576 static void
2577 w_oconv32(nkf_char c2, nkf_char c1)
2578 {
2579     if (output_bom_f) {
2580         output_bom_f = FALSE;
2581         if (output_endian == ENDIAN_LITTLE){
2582             (*o_putc)(0xFF);
2583             (*o_putc)(0xFE);
2584             (*o_putc)(0);
2585             (*o_putc)(0);
2586         }else{
2587             (*o_putc)(0);
2588             (*o_putc)(0);
2589             (*o_putc)(0xFE);
2590             (*o_putc)(0xFF);
2591         }
2592     }
2593
2594     if (c2 == EOF) {
2595         (*o_putc)(EOF);
2596         return;
2597     }
2598
2599     if (c2 == ISO_8859_1) {
2600         c1 |= 0x80;
2601     } else if (c2 == 0 && nkf_char_unicode_p(c1)) {
2602         c1 &= VALUE_MASK;
2603     } else if (c2) {
2604         c1 = e2w_conv(c2, c1);
2605         if (!c1) return;
2606     }
2607     if (output_endian == ENDIAN_LITTLE){
2608         (*o_putc)( c1        & 0xFF);
2609         (*o_putc)((c1 >>  8) & 0xFF);
2610         (*o_putc)((c1 >> 16) & 0xFF);
2611         (*o_putc)(0);
2612     }else{
2613         (*o_putc)(0);
2614         (*o_putc)((c1 >> 16) & 0xFF);
2615         (*o_putc)((c1 >>  8) & 0xFF);
2616         (*o_putc)( c1        & 0xFF);
2617     }
2618 }
2619 #endif
2620
2621 #define SCORE_L2       (1)                   /* \e$BBh\e(B2\e$B?e=`4A;z\e(B */
2622 #define SCORE_KANA     (SCORE_L2 << 1)       /* \e$B$$$o$f$kH>3Q%+%J\e(B */
2623 #define SCORE_DEPEND   (SCORE_KANA << 1)     /* \e$B5!<o0MB8J8;z\e(B */
2624 #define SCORE_CP932    (SCORE_DEPEND << 1)   /* CP932 \e$B$K$h$kFI$_49$(\e(B (IBM extended characters) */
2625 #define SCORE_X0212    (SCORE_CP932 << 1)    /* JIS X 0212 */
2626 #define SCORE_NO_EXIST (SCORE_X0212 << 1)    /* \e$BB8:_$7$J$$J8;z\e(B */
2627 #define SCORE_iMIME    (SCORE_NO_EXIST << 1) /* MIME \e$B$K$h$k;XDj\e(B */
2628 #define SCORE_ERROR    (SCORE_iMIME << 1) /* \e$B%(%i!<\e(B */
2629
2630 #define SCORE_INIT (SCORE_iMIME)
2631
2632 static const char score_table_A0[] = {
2633     0, 0, 0, 0,
2634     0, 0, 0, 0,
2635     0, SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND,
2636     SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND, SCORE_NO_EXIST,
2637 };
2638
2639 static const char score_table_F0[] = {
2640     SCORE_L2, SCORE_L2, SCORE_L2, SCORE_L2,
2641     SCORE_L2, SCORE_DEPEND, SCORE_NO_EXIST, SCORE_NO_EXIST,
2642     SCORE_DEPEND, SCORE_DEPEND, SCORE_CP932, SCORE_CP932,
2643     SCORE_CP932, SCORE_NO_EXIST, SCORE_NO_EXIST, SCORE_ERROR,
2644 };
2645
2646 static void
2647 set_code_score(struct input_code *ptr, nkf_char score)
2648 {
2649     if (ptr){
2650         ptr->score |= score;
2651     }
2652 }
2653
2654 static void
2655 clr_code_score(struct input_code *ptr, nkf_char score)
2656 {
2657     if (ptr){
2658         ptr->score &= ~score;
2659     }
2660 }
2661
2662 static void
2663 code_score(struct input_code *ptr)
2664 {
2665     nkf_char c2 = ptr->buf[0];
2666 #ifdef UTF8_OUTPUT_ENABLE
2667     nkf_char c1 = ptr->buf[1];
2668 #endif
2669     if (c2 < 0){
2670         set_code_score(ptr, SCORE_ERROR);
2671     }else if (c2 == SS2){
2672         set_code_score(ptr, SCORE_KANA);
2673     }else if (c2 == 0x8f){
2674         set_code_score(ptr, SCORE_X0212);
2675 #ifdef UTF8_OUTPUT_ENABLE
2676     }else if (!e2w_conv(c2, c1)){
2677         set_code_score(ptr, SCORE_NO_EXIST);
2678 #endif
2679     }else if ((c2 & 0x70) == 0x20){
2680         set_code_score(ptr, score_table_A0[c2 & 0x0f]);
2681     }else if ((c2 & 0x70) == 0x70){
2682         set_code_score(ptr, score_table_F0[c2 & 0x0f]);
2683     }else if ((c2 & 0x70) >= 0x50){
2684         set_code_score(ptr, SCORE_L2);
2685     }
2686 }
2687
2688 static void
2689 status_disable(struct input_code *ptr)
2690 {
2691     ptr->stat = -1;
2692     ptr->buf[0] = -1;
2693     code_score(ptr);
2694     if (iconv == ptr->iconv_func) set_iconv(FALSE, 0);
2695 }
2696
2697 static void
2698 status_push_ch(struct input_code *ptr, nkf_char c)
2699 {
2700     ptr->buf[ptr->index++] = c;
2701 }
2702
2703 static void
2704 status_clear(struct input_code *ptr)
2705 {
2706     ptr->stat = 0;
2707     ptr->index = 0;
2708 }
2709
2710 static void
2711 status_reset(struct input_code *ptr)
2712 {
2713     status_clear(ptr);
2714     ptr->score = SCORE_INIT;
2715 }
2716
2717 static void
2718 status_reinit(struct input_code *ptr)
2719 {
2720     status_reset(ptr);
2721     ptr->_file_stat = 0;
2722 }
2723
2724 static void
2725 status_check(struct input_code *ptr, nkf_char c)
2726 {
2727     if (c <= DEL && estab_f){
2728         status_reset(ptr);
2729     }
2730 }
2731
2732 static void
2733 s_status(struct input_code *ptr, nkf_char c)
2734 {
2735     switch(ptr->stat){
2736     case -1:
2737         status_check(ptr, c);
2738         break;
2739     case 0:
2740         if (c <= DEL){
2741             break;
2742         }else if (nkf_char_unicode_p(c)){
2743             break;
2744         }else if (0xa1 <= c && c <= 0xdf){
2745             status_push_ch(ptr, SS2);
2746             status_push_ch(ptr, c);
2747             code_score(ptr);
2748             status_clear(ptr);
2749         }else if ((0x81 <= c && c < 0xa0) || (0xe0 <= c && c <= 0xea)){
2750             ptr->stat = 1;
2751             status_push_ch(ptr, c);
2752         }else if (0xed <= c && c <= 0xee){
2753             ptr->stat = 3;
2754             status_push_ch(ptr, c);
2755 #ifdef SHIFTJIS_CP932
2756         }else if (is_ibmext_in_sjis(c)){
2757             ptr->stat = 2;
2758             status_push_ch(ptr, c);
2759 #endif /* SHIFTJIS_CP932 */
2760 #ifdef X0212_ENABLE
2761         }else if (0xf0 <= c && c <= 0xfc){
2762             ptr->stat = 1;
2763             status_push_ch(ptr, c);
2764 #endif /* X0212_ENABLE */
2765         }else{
2766             status_disable(ptr);
2767         }
2768         break;
2769     case 1:
2770         if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)){
2771             status_push_ch(ptr, c);
2772             s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]);
2773             code_score(ptr);
2774             status_clear(ptr);
2775         }else{
2776             status_disable(ptr);
2777         }
2778         break;
2779     case 2:
2780 #ifdef SHIFTJIS_CP932
2781         if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)) {
2782             status_push_ch(ptr, c);
2783             if (s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]) == 0) {
2784                 set_code_score(ptr, SCORE_CP932);
2785                 status_clear(ptr);
2786                 break;
2787             }
2788         }
2789 #endif /* SHIFTJIS_CP932 */
2790         status_disable(ptr);
2791         break;
2792     case 3:
2793         if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)){
2794             status_push_ch(ptr, c);
2795             s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]);
2796             set_code_score(ptr, SCORE_CP932);
2797             status_clear(ptr);
2798         }else{
2799             status_disable(ptr);
2800         }
2801         break;
2802     }
2803 }
2804
2805 static void
2806 e_status(struct input_code *ptr, nkf_char c)
2807 {
2808     switch (ptr->stat){
2809     case -1:
2810         status_check(ptr, c);
2811         break;
2812     case 0:
2813         if (c <= DEL){
2814             break;
2815         }else if (nkf_char_unicode_p(c)){
2816             break;
2817         }else if (SS2 == c || (0xa1 <= c && c <= 0xfe)){
2818             ptr->stat = 1;
2819             status_push_ch(ptr, c);
2820 #ifdef X0212_ENABLE
2821         }else if (0x8f == c){
2822             ptr->stat = 2;
2823             status_push_ch(ptr, c);
2824 #endif /* X0212_ENABLE */
2825         }else{
2826             status_disable(ptr);
2827         }
2828         break;
2829     case 1:
2830         if (0xa1 <= c && c <= 0xfe){
2831             status_push_ch(ptr, c);
2832             code_score(ptr);
2833             status_clear(ptr);
2834         }else{
2835             status_disable(ptr);
2836         }
2837         break;
2838 #ifdef X0212_ENABLE
2839     case 2:
2840         if (0xa1 <= c && c <= 0xfe){
2841             ptr->stat = 1;
2842             status_push_ch(ptr, c);
2843         }else{
2844             status_disable(ptr);
2845         }
2846 #endif /* X0212_ENABLE */
2847     }
2848 }
2849
2850 #ifdef UTF8_INPUT_ENABLE
2851 static void
2852 w_status(struct input_code *ptr, nkf_char c)
2853 {
2854     switch (ptr->stat){
2855     case -1:
2856         status_check(ptr, c);
2857         break;
2858     case 0:
2859         if (c <= DEL){
2860             break;
2861         }else if (nkf_char_unicode_p(c)){
2862             break;
2863         }else if (0xc0 <= c && c <= 0xdf){
2864             ptr->stat = 1;
2865             status_push_ch(ptr, c);
2866         }else if (0xe0 <= c && c <= 0xef){
2867             ptr->stat = 2;
2868             status_push_ch(ptr, c);
2869         }else if (0xf0 <= c && c <= 0xf4){
2870             ptr->stat = 3;
2871             status_push_ch(ptr, c);
2872         }else{
2873             status_disable(ptr);
2874         }
2875         break;
2876     case 1:
2877     case 2:
2878         if (0x80 <= c && c <= 0xbf){
2879             status_push_ch(ptr, c);
2880             if (ptr->index > ptr->stat){
2881                 int bom = (ptr->buf[0] == 0xef && ptr->buf[1] == 0xbb
2882                            && ptr->buf[2] == 0xbf);
2883                 w2e_conv(ptr->buf[0], ptr->buf[1], ptr->buf[2],
2884                          &ptr->buf[0], &ptr->buf[1]);
2885                 if (!bom){
2886                     code_score(ptr);
2887                 }
2888                 status_clear(ptr);
2889             }
2890         }else{
2891             status_disable(ptr);
2892         }
2893         break;
2894     case 3:
2895         if (0x80 <= c && c <= 0xbf){
2896             if (ptr->index < ptr->stat){
2897                 status_push_ch(ptr, c);
2898             } else {
2899                 status_clear(ptr);
2900             }
2901         }else{
2902             status_disable(ptr);
2903         }
2904         break;
2905     }
2906 }
2907 #endif
2908
2909 static void
2910 code_status(nkf_char c)
2911 {
2912     int action_flag = 1;
2913     struct input_code *result = 0;
2914     struct input_code *p = input_code_list;
2915     while (p->name){
2916         if (!p->status_func) {
2917             ++p;
2918             continue;
2919         }
2920         if (!p->status_func)
2921             continue;
2922         (p->status_func)(p, c);
2923         if (p->stat > 0){
2924             action_flag = 0;
2925         }else if(p->stat == 0){
2926             if (result){
2927                 action_flag = 0;
2928             }else{
2929                 result = p;
2930             }
2931         }
2932         ++p;
2933     }
2934
2935     if (action_flag){
2936         if (result && !estab_f){
2937             set_iconv(TRUE, result->iconv_func);
2938         }else if (c <= DEL){
2939             struct input_code *ptr = input_code_list;
2940             while (ptr->name){
2941                 status_reset(ptr);
2942                 ++ptr;
2943             }
2944         }
2945     }
2946 }
2947
2948 #ifndef WIN32DLL
2949 static nkf_char
2950 std_getc(FILE *f)
2951 {
2952     if (std_gc_ndx){
2953         return std_gc_buf[--std_gc_ndx];
2954     }
2955     return getc(f);
2956 }
2957 #endif /*WIN32DLL*/
2958
2959 static nkf_char
2960 std_ungetc(nkf_char c, FILE *f)
2961 {
2962     if (std_gc_ndx == STD_GC_BUFSIZE){
2963         return EOF;
2964     }
2965     std_gc_buf[std_gc_ndx++] = c;
2966     return c;
2967 }
2968
2969 #ifndef WIN32DLL
2970 static void
2971 std_putc(nkf_char c)
2972 {
2973     if(c!=EOF)
2974         putchar(c);
2975 }
2976 #endif /*WIN32DLL*/
2977
2978 static unsigned char   hold_buf[HOLD_SIZE*2];
2979 static int             hold_count = 0;
2980 static nkf_char
2981 push_hold_buf(nkf_char c2)
2982 {
2983     if (hold_count >= HOLD_SIZE*2)
2984         return (EOF);
2985     hold_buf[hold_count++] = (unsigned char)c2;
2986     return ((hold_count >= HOLD_SIZE*2) ? EOF : hold_count);
2987 }
2988
2989 static int
2990 h_conv(FILE *f, int c1, int c2)
2991 {
2992     int ret, c4, c3;
2993     int hold_index;
2994
2995
2996     /** it must NOT be in the kanji shifte sequence      */
2997     /** it must NOT be written in JIS7                   */
2998     /** and it must be after 2 byte 8bit code            */
2999
3000     hold_count = 0;
3001     push_hold_buf(c1);
3002     push_hold_buf(c2);
3003
3004     while ((c2 = (*i_getc)(f)) != EOF) {
3005         if (c2 == ESC){
3006             (*i_ungetc)(c2,f);
3007             break;
3008         }
3009         code_status(c2);
3010         if (push_hold_buf(c2) == EOF || estab_f) {
3011             break;
3012         }
3013     }
3014
3015     if (!estab_f) {
3016         struct input_code *p = input_code_list;
3017         struct input_code *result = p;
3018         if (c2 == EOF) {
3019             code_status(c2);
3020         }
3021         while (p->name) {
3022             if (p->status_func && p->score < result->score) {
3023                 result = p;
3024             }
3025             p++;
3026         }
3027         set_iconv(TRUE, result->iconv_func);
3028     }
3029
3030
3031     /** now,
3032      ** 1) EOF is detected, or
3033      ** 2) Code is established, or
3034      ** 3) Buffer is FULL (but last word is pushed)
3035      **
3036      ** in 1) and 3) cases, we continue to use
3037      ** Kanji codes by oconv and leave estab_f unchanged.
3038      **/
3039
3040     ret = c2;
3041     hold_index = 0;
3042     while (hold_index < hold_count){
3043         c1 = hold_buf[hold_index++];
3044         if (c1 <= DEL){
3045             (*iconv)(0, c1, 0);
3046             continue;
3047         }else if (iconv == s_iconv && 0xa1 <= c1 && c1 <= 0xdf){
3048             (*iconv)(JIS_X_0201_1976_K, c1, 0);
3049             continue;
3050         }
3051         if (hold_index < hold_count){
3052             c2 = hold_buf[hold_index++];
3053         }else{
3054             c2 = (*i_getc)(f);
3055             if (c2 == EOF){
3056                 c4 = EOF;
3057                 break;
3058             }
3059             code_status(c2);
3060         }
3061         c3 = 0;
3062         switch ((*iconv)(c1, c2, 0)) {  /* can be EUC/SJIS/UTF-8 */
3063         case -2:
3064             /* 4 bytes UTF-8 */
3065             if (hold_index < hold_count){
3066                 c3 = hold_buf[hold_index++];
3067             } else if ((c3 = (*i_getc)(f)) == EOF) {
3068                 ret = EOF;
3069                 break;
3070             } else {
3071                 code_status(c3);
3072                 if (hold_index < hold_count){
3073                     c4 = hold_buf[hold_index++];
3074                 } else if ((c4 = (*i_getc)(f)) == EOF) {
3075                     c3 = ret = EOF;
3076                     break;
3077                 } else {
3078                     code_status(c4);
3079                     (*iconv)(c1, c2, (c3<<8)|c4);
3080                 }
3081             }
3082             break;
3083         case -1:
3084             /* 3 bytes EUC or UTF-8 */
3085             if (hold_index < hold_count){
3086                 c3 = hold_buf[hold_index++];
3087             } else if ((c3 = (*i_getc)(f)) == EOF) {
3088                 ret = EOF;
3089                 break;
3090             } else {
3091                 code_status(c3);
3092             }
3093             (*iconv)(c1, c2, c3);
3094             break;
3095         }
3096         if (c3 == EOF) break;
3097     }
3098     return ret;
3099 }
3100
3101 /*
3102  * Check and Ignore BOM
3103  */
3104 static void
3105 check_bom(FILE *f)
3106 {
3107     int c2;
3108     switch(c2 = (*i_getc)(f)){
3109     case 0x00:
3110         if((c2 = (*i_getc)(f)) == 0x00){
3111             if((c2 = (*i_getc)(f)) == 0xFE){
3112                 if((c2 = (*i_getc)(f)) == 0xFF){
3113                     if(!input_encoding){
3114                         set_iconv(TRUE, w_iconv32);
3115                     }
3116                     if (iconv == w_iconv32) {
3117                         input_endian = ENDIAN_BIG;
3118                         return;
3119                     }
3120                     (*i_ungetc)(0xFF,f);
3121                 }else (*i_ungetc)(c2,f);
3122                 (*i_ungetc)(0xFE,f);
3123             }else if(c2 == 0xFF){
3124                 if((c2 = (*i_getc)(f)) == 0xFE){
3125                     if(!input_encoding){
3126                         set_iconv(TRUE, w_iconv32);
3127                     }
3128                     if (iconv == w_iconv32) {
3129                         input_endian = ENDIAN_2143;
3130                         return;
3131                     }
3132                     (*i_ungetc)(0xFF,f);
3133                 }else (*i_ungetc)(c2,f);
3134                 (*i_ungetc)(0xFF,f);
3135             }else (*i_ungetc)(c2,f);
3136             (*i_ungetc)(0x00,f);
3137         }else (*i_ungetc)(c2,f);
3138         (*i_ungetc)(0x00,f);
3139         break;
3140     case 0xEF:
3141         if((c2 = (*i_getc)(f)) == 0xBB){
3142             if((c2 = (*i_getc)(f)) == 0xBF){
3143                 if(!input_encoding){
3144                     set_iconv(TRUE, w_iconv);
3145                 }
3146                 if (iconv == w_iconv) {
3147                     return;
3148                 }
3149                 (*i_ungetc)(0xBF,f);
3150             }else (*i_ungetc)(c2,f);
3151             (*i_ungetc)(0xBB,f);
3152         }else (*i_ungetc)(c2,f);
3153         (*i_ungetc)(0xEF,f);
3154         break;
3155     case 0xFE:
3156         if((c2 = (*i_getc)(f)) == 0xFF){
3157             if((c2 = (*i_getc)(f)) == 0x00){
3158                 if((c2 = (*i_getc)(f)) == 0x00){
3159                     if(!input_encoding){
3160                         set_iconv(TRUE, w_iconv32);
3161                     }
3162                     if (iconv == w_iconv32) {
3163                         input_endian = ENDIAN_3412;
3164                         return;
3165                     }
3166                     (*i_ungetc)(0x00,f);
3167                 }else (*i_ungetc)(c2,f);
3168                 (*i_ungetc)(0x00,f);
3169             }else (*i_ungetc)(c2,f);
3170             if(!input_encoding){
3171                 set_iconv(TRUE, w_iconv16);
3172             }
3173             if (iconv == w_iconv16) {
3174                 input_endian = ENDIAN_BIG;
3175                 return;
3176             }
3177             (*i_ungetc)(0xFF,f);
3178         }else (*i_ungetc)(c2,f);
3179         (*i_ungetc)(0xFE,f);
3180         break;
3181     case 0xFF:
3182         if((c2 = (*i_getc)(f)) == 0xFE){
3183             if((c2 = (*i_getc)(f)) == 0x00){
3184                 if((c2 = (*i_getc)(f)) == 0x00){
3185                     if(!input_encoding){
3186                         set_iconv(TRUE, w_iconv32);
3187                     }
3188                     if (iconv == w_iconv32) {
3189                         input_endian = ENDIAN_LITTLE;
3190                         return;
3191                     }
3192                     (*i_ungetc)(0x00,f);
3193                 }else (*i_ungetc)(c2,f);
3194                 (*i_ungetc)(0x00,f);
3195             }else (*i_ungetc)(c2,f);
3196             if(!input_encoding){
3197                 set_iconv(TRUE, w_iconv16);
3198             }
3199             if (iconv == w_iconv16) {
3200                 input_endian = ENDIAN_LITTLE;
3201                 return;
3202             }
3203             (*i_ungetc)(0xFE,f);
3204         }else (*i_ungetc)(c2,f);
3205         (*i_ungetc)(0xFF,f);
3206         break;
3207     default:
3208         (*i_ungetc)(c2,f);
3209         break;
3210     }
3211 }
3212
3213 static struct {
3214     int count;
3215     nkf_char status;
3216     nkf_char buf[3];
3217 } broken_state;
3218
3219 static void
3220 init_broken_state(void)
3221 {
3222     memset(&broken_state, 0, sizeof(broken_state));
3223 }
3224
3225 static void
3226 push_broken_buf(c)
3227 {
3228     broken_state.buf[broken_state.count++] = c;
3229 }
3230
3231 static nkf_char
3232 pop_broken_buf(void)
3233 {
3234     return broken_state.buf[--broken_state.count];
3235 }
3236
3237 static nkf_char
3238 broken_getc(FILE *f)
3239 {
3240     nkf_char c, c1;
3241
3242     if (broken_state.count > 0) {
3243         return pop_broken_buf();
3244     }
3245     c = (*i_bgetc)(f);
3246     if (c=='$' && broken_state.status != ESC
3247         && (input_mode == ASCII || input_mode == JIS_X_0201_1976_K)) {
3248         c1= (*i_bgetc)(f);
3249         broken_state.status = 0;
3250         if (c1=='@'|| c1=='B') {
3251             push_broken_buf(c1);
3252             push_broken_buf(c);
3253             return ESC;
3254         } else {
3255             (*i_bungetc)(c1,f);
3256             return c;
3257         }
3258     } else if (c=='(' && broken_state.status != ESC
3259                && (input_mode == JIS_X_0208 || input_mode == JIS_X_0201_1976_K)) {
3260         c1= (*i_bgetc)(f);
3261         broken_state.status = 0;
3262         if (c1=='J'|| c1=='B') {
3263             push_broken_buf(c1);
3264             push_broken_buf(c);
3265             return ESC;
3266         } else {
3267             (*i_bungetc)(c1,f);
3268             return c;
3269         }
3270     } else {
3271         broken_state.status = c;
3272         return c;
3273     }
3274 }
3275
3276 static nkf_char
3277 broken_ungetc(nkf_char c, FILE *f)
3278 {
3279     if (broken_state.count < 2)
3280         push_broken_buf(c);
3281     return c;
3282 }
3283
3284 static void
3285 eol_conv(nkf_char c2, nkf_char c1)
3286 {
3287     if (guess_f && input_eol != EOF) {
3288         if (c2 == 0 && c1 == LF) {
3289             if (!input_eol) input_eol = prev_cr ? CRLF : LF;
3290             else if (input_eol != (prev_cr ? CRLF : LF)) input_eol = EOF;
3291         } else if (c2 == 0 && c1 == CR && input_eol == LF) input_eol = EOF;
3292         else if (!prev_cr);
3293         else if (!input_eol) input_eol = CR;
3294         else if (input_eol != CR) input_eol = EOF;
3295     }
3296     if (prev_cr || (c2 == 0 && c1 == LF)) {
3297         prev_cr = 0;
3298         if (eolmode_f != LF) (*o_eol_conv)(0, CR);
3299         if (eolmode_f != CR) (*o_eol_conv)(0, LF);
3300     }
3301     if (c2 == 0 && c1 == CR) prev_cr = CR;
3302     else if (c2 != 0 || c1 != LF) (*o_eol_conv)(c2, c1);
3303 }
3304
3305 /*
3306    Return value of fold_conv()
3307
3308    LF  add newline  and output char
3309    CR  add newline  and output nothing
3310    SP  space
3311    0   skip
3312    1   (or else) normal output
3313
3314    fold state in prev (previous character)
3315
3316    >0x80 Japanese (X0208/X0201)
3317    <0x80 ASCII
3318    LF    new line
3319    SP    space
3320
3321    This fold algorthm does not preserve heading space in a line.
3322    This is the main difference from fmt.
3323  */
3324
3325 #define char_size(c2,c1) (c2?2:1)
3326
3327 static void
3328 fold_conv(nkf_char c2, nkf_char c1)
3329 {
3330     nkf_char prev0;
3331     nkf_char fold_state;
3332
3333     if (c1== CR && !fold_preserve_f) {
3334         fold_state=0;  /* ignore cr */
3335     }else if (c1== LF&&f_prev==CR && fold_preserve_f) {
3336         f_prev = LF;
3337         fold_state=0;  /* ignore cr */
3338     } else if (c1== BS) {
3339         if (f_line>0) f_line--;
3340         fold_state =  1;
3341     } else if (c2==EOF && f_line != 0) {    /* close open last line */
3342         fold_state = LF;
3343     } else if ((c1==LF && !fold_preserve_f)
3344                || ((c1==CR||(c1==LF&&f_prev!=CR))
3345                    && fold_preserve_f)) {
3346         /* new line */
3347         if (fold_preserve_f) {
3348             f_prev = c1;
3349             f_line = 0;
3350             fold_state =  CR;
3351         } else if ((f_prev == c1 && !fold_preserve_f)
3352                    || (f_prev == LF && fold_preserve_f)
3353                   ) {        /* duplicate newline */
3354             if (f_line) {
3355                 f_line = 0;
3356                 fold_state =  LF;    /* output two newline */
3357             } else {
3358                 f_line = 0;
3359                 fold_state =  1;
3360             }
3361         } else  {
3362             if (f_prev&0x80) {     /* Japanese? */
3363                 f_prev = c1;
3364                 fold_state =  0;       /* ignore given single newline */
3365             } else if (f_prev==SP) {
3366                 fold_state =  0;
3367             } else {
3368                 f_prev = c1;
3369                 if (++f_line<=fold_len)
3370                     fold_state =  SP;
3371                 else {
3372                     f_line = 0;
3373                     fold_state =  CR;        /* fold and output nothing */
3374                 }
3375             }
3376         }
3377     } else if (c1=='\f') {
3378         f_prev = LF;
3379         f_line = 0;
3380         fold_state =  LF;            /* output newline and clear */
3381     } else if ( (c2==0  && c1==SP)||
3382                (c2==0  && c1==TAB)||
3383                (c2=='!'&& c1=='!')) {
3384         /* X0208 kankaku or ascii space */
3385         if (f_prev == SP) {
3386             fold_state = 0;         /* remove duplicate spaces */
3387         } else {
3388             f_prev = SP;
3389             if (++f_line<=fold_len)
3390                 fold_state = SP;         /* output ASCII space only */
3391             else {
3392                 f_prev = SP; f_line = 0;
3393                 fold_state = CR;        /* fold and output nothing */
3394             }
3395         }
3396     } else {
3397         prev0 = f_prev; /* we still need this one... , but almost done */
3398         f_prev = c1;
3399         if (c2 || c2 == JIS_X_0201_1976_K)
3400             f_prev |= 0x80;  /* this is Japanese */
3401         f_line += char_size(c2,c1);
3402         if (f_line<=fold_len) {   /* normal case */
3403             fold_state = 1;
3404         } else {
3405             if (f_line>fold_len+fold_margin) { /* too many kinsoku suspension */
3406                 f_line = char_size(c2,c1);
3407                 fold_state =  LF;       /* We can't wait, do fold now */
3408             } else if (c2 == JIS_X_0201_1976_K) {
3409                 /* simple kinsoku rules  return 1 means no folding  */
3410                 if (c1==(0xde&0x7f)) fold_state = 1; /* \e$B!+\e(B*/
3411                 else if (c1==(0xdf&0x7f)) fold_state = 1; /* \e$B!,\e(B*/
3412                 else if (c1==(0xa4&0x7f)) fold_state = 1; /* \e$B!#\e(B*/
3413                 else if (c1==(0xa3&0x7f)) fold_state = 1; /* \e$B!$\e(B*/
3414                 else if (c1==(0xa1&0x7f)) fold_state = 1; /* \e$B!W\e(B*/
3415                 else if (c1==(0xb0&0x7f)) fold_state = 1; /* - */
3416                 else if (SP<=c1 && c1<=(0xdf&0x7f)) {      /* X0201 */
3417                     f_line = 1;
3418                     fold_state = LF;/* add one new f_line before this character */
3419                 } else {
3420                     f_line = 1;
3421                     fold_state = LF;/* add one new f_line before this character */
3422                 }
3423             } else if (c2==0) {
3424                 /* kinsoku point in ASCII */
3425                 if (  c1==')'||    /* { [ ( */
3426                     c1==']'||
3427                     c1=='}'||
3428                     c1=='.'||
3429                     c1==','||
3430                     c1=='!'||
3431                     c1=='?'||
3432                     c1=='/'||
3433                     c1==':'||
3434                     c1==';') {
3435                     fold_state = 1;
3436                     /* just after special */
3437                 } else if (!is_alnum(prev0)) {
3438                     f_line = char_size(c2,c1);
3439                     fold_state = LF;
3440                 } else if ((prev0==SP) ||   /* ignored new f_line */
3441                            (prev0==LF)||        /* ignored new f_line */
3442                            (prev0&0x80)) {        /* X0208 - ASCII */
3443                     f_line = char_size(c2,c1);
3444                     fold_state = LF;/* add one new f_line before this character */
3445                 } else {
3446                     fold_state = 1;  /* default no fold in ASCII */
3447                 }
3448             } else {
3449                 if (c2=='!') {
3450                     if (c1=='"')  fold_state = 1; /* \e$B!"\e(B */
3451                     else if (c1=='#')  fold_state = 1; /* \e$B!#\e(B */
3452                     else if (c1=='W')  fold_state = 1; /* \e$B!W\e(B */
3453                     else if (c1=='K')  fold_state = 1; /* \e$B!K\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                     else if (c1=='+')  fold_state = 1; /* \e$B!+\e(B */
3461                     else if (c1==',')  fold_state = 1; /* \e$B!,\e(B */
3462                     /* default no fold in kinsoku */
3463                     else {
3464                         fold_state = LF;
3465                         f_line = char_size(c2,c1);
3466                         /* add one new f_line before this character */
3467                     }
3468                 } else {
3469                     f_line = char_size(c2,c1);
3470                     fold_state = LF;
3471                     /* add one new f_line before this character */
3472                 }
3473             }
3474         }
3475     }
3476     /* terminator process */
3477     switch(fold_state) {
3478     case LF:
3479         OCONV_NEWLINE((*o_fconv));
3480         (*o_fconv)(c2,c1);
3481         break;
3482     case 0:
3483         return;
3484     case CR:
3485         OCONV_NEWLINE((*o_fconv));
3486         break;
3487     case TAB:
3488     case SP:
3489         (*o_fconv)(0,SP);
3490         break;
3491     default:
3492         (*o_fconv)(c2,c1);
3493     }
3494 }
3495
3496 static nkf_char z_prev2=0,z_prev1=0;
3497
3498 static void
3499 z_conv(nkf_char c2, nkf_char c1)
3500 {
3501
3502     /* if (c2) c1 &= 0x7f; assertion */
3503
3504     if (c2 == JIS_X_0201_1976_K && (c1 == 0x20 || c1 == 0x7D || c1 == 0x7E)) {
3505         (*o_zconv)(c2,c1);
3506         return;
3507     }
3508
3509     if (x0201_f) {
3510         if (z_prev2 == JIS_X_0201_1976_K) {
3511             if (c2 == JIS_X_0201_1976_K) {
3512                 if (c1 == (0xde&0x7f)) { /* \e$BByE@\e(B */
3513                     z_prev2 = 0;
3514                     (*o_zconv)(dv[(z_prev1-SP)*2], dv[(z_prev1-SP)*2+1]);
3515                     return;
3516                 } else if (c1 == (0xdf&0x7f) && ev[(z_prev1-SP)*2]) {  /* \e$BH>ByE@\e(B */
3517                     z_prev2 = 0;
3518                     (*o_zconv)(ev[(z_prev1-SP)*2], ev[(z_prev1-SP)*2+1]);
3519                     return;
3520                 }
3521             }
3522             z_prev2 = 0;
3523             (*o_zconv)(cv[(z_prev1-SP)*2], cv[(z_prev1-SP)*2+1]);
3524         }
3525         if (c2 == JIS_X_0201_1976_K) {
3526             if (dv[(c1-SP)*2] || ev[(c1-SP)*2]) {
3527                 /* wait for \e$BByE@\e(B or \e$BH>ByE@\e(B */
3528                 z_prev1 = c1;
3529                 z_prev2 = c2;
3530                 return;
3531             } else {
3532                 (*o_zconv)(cv[(c1-SP)*2], cv[(c1-SP)*2+1]);
3533                 return;
3534             }
3535         }
3536     }
3537
3538     if (c2 == EOF) {
3539         (*o_zconv)(c2, c1);
3540         return;
3541     }
3542
3543     if (alpha_f&1 && c2 == 0x23) {
3544         /* JISX0208 Alphabet */
3545         c2 = 0;
3546     } else if (c2 == 0x21) {
3547         /* JISX0208 Kigou */
3548         if (0x21==c1) {
3549             if (alpha_f&2) {
3550                 c2 = 0;
3551                 c1 = SP;
3552             } else if (alpha_f&4) {
3553                 (*o_zconv)(0, SP);
3554                 (*o_zconv)(0, SP);
3555                 return;
3556             }
3557         } else if (alpha_f&1 && 0x20<c1 && c1<0x7f && fv[c1-0x20]) {
3558             c2 =  0;
3559             c1 = fv[c1-0x20];
3560         }
3561     }
3562
3563     if (alpha_f&8 && c2 == 0) {
3564         /* HTML Entity */
3565         const char *entity = 0;
3566         switch (c1){
3567         case '>': entity = "&gt;"; break;
3568         case '<': entity = "&lt;"; break;
3569         case '\"': entity = "&quot;"; break;
3570         case '&': entity = "&amp;"; break;
3571         }
3572         if (entity){
3573             while (*entity) (*o_zconv)(0, *entity++);
3574             return;
3575         }
3576     }
3577
3578     if (alpha_f & 16) {
3579         /* JIS X 0208 Katakana to JIS X 0201 Katakana */
3580         if (c2 == 0x21) {
3581             char c = 0;
3582             switch (c1) {
3583             case 0x23:
3584                 /* U+3002 (0x8142) Ideographic Full Stop -> U+FF61 (0xA1) Halfwidth Ideographic Full Stop */
3585                 c = 0xA1;
3586                 break;
3587             case 0x56:
3588                 /* U+300C (0x8175) Left Corner Bracket -> U+FF62 (0xA2) Halfwidth Left Corner Bracket */
3589                 c = 0xA2;
3590                 break;
3591             case 0x57:
3592                 /* U+300D (0x8176) Right Corner Bracket -> U+FF63 (0xA3) Halfwidth Right Corner Bracket */
3593                 c = 0xA3;
3594                 break;
3595             case 0x22:
3596                 /* U+3001 (0x8141) Ideographic Comma -> U+FF64 (0xA4) Halfwidth Ideographic Comma */
3597                 c = 0xA4;
3598                 break;
3599             case 0x26:
3600                 /* U+30FB (0x8145) Katakana Middle Dot -> U+FF65 (0xA5) Halfwidth Katakana Middle Dot */
3601                 c = 0xA5;
3602                 break;
3603             case 0x3C:
3604                 /* U+30FC (0x815B) Katakana-Hiragana Prolonged Sound Mark -> U+FF70 (0xB0) Halfwidth Katakana-Hiragana Prolonged Sound Mark */
3605                 c = 0xB0;
3606                 break;
3607             case 0x2B:
3608                 /* U+309B (0x814A) Katakana-Hiragana Voiced Sound Mark -> U+FF9E (0xDE) Halfwidth Katakana Voiced Sound Mark */
3609                 c = 0xDE;
3610                 break;
3611             case 0x2C:
3612                 /* U+309C (0x814B) Katakana-Hiragana Semi-Voiced Sound Mark -> U+FF9F (0xDF) Halfwidth Katakana Semi-Voiced Sound Mark */
3613                 c = 0xDF;
3614                 break;
3615             }
3616             if (c) {
3617                 (*o_zconv)(JIS_X_0201_1976_K, c);
3618                 return;
3619             }
3620         } else if (c2 == 0x25) {
3621             /* JISX0208 Katakana */
3622             static const int fullwidth_to_halfwidth[] =
3623             {
3624                 0x0000, 0x2700, 0x3100, 0x2800, 0x3200, 0x2900, 0x3300, 0x2A00,
3625                 0x3400, 0x2B00, 0x3500, 0x3600, 0x365E, 0x3700, 0x375E, 0x3800,
3626                 0x385E, 0x3900, 0x395E, 0x3A00, 0x3A5E, 0x3B00, 0x3B5E, 0x3C00,
3627                 0x3C5E, 0x3D00, 0x3D5E, 0x3E00, 0x3E5E, 0x3F00, 0x3F5E, 0x4000,
3628                 0x405E, 0x4100, 0x415E, 0x2F00, 0x4200, 0x425E, 0x4300, 0x435E,
3629                 0x4400, 0x445E, 0x4500, 0x4600, 0x4700, 0x4800, 0x4900, 0x4A00,
3630                 0x4A5E, 0x4A5F, 0x4B00, 0x4B5E, 0x4B5F, 0x4C00, 0x4C5E, 0x4C5F,
3631                 0x4D00, 0x4D5E, 0x4D5F, 0x4E00, 0x4E5E, 0x4E5F, 0x4F00, 0x5000,
3632                 0x5100, 0x5200, 0x5300, 0x2C00, 0x5400, 0x2D00, 0x5500, 0x2E00,
3633                 0x5600, 0x5700, 0x5800, 0x5900, 0x5A00, 0x5B00, 0x0000, 0x5C00,
3634                 0x0000, 0x0000, 0x2600, 0x5D00, 0x335E, 0x0000, 0x0000, 0x0000,
3635                 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
3636             };
3637             if (fullwidth_to_halfwidth[c1-0x20]){
3638                 c2 = fullwidth_to_halfwidth[c1-0x20];
3639                 (*o_zconv)(JIS_X_0201_1976_K, c2>>8);
3640                 if (c2 & 0xFF) {
3641                     (*o_zconv)(JIS_X_0201_1976_K, c2&0xFF);
3642                 }
3643                 return;
3644             }
3645         }
3646     }
3647     (*o_zconv)(c2,c1);
3648 }
3649
3650
3651 #define rot13(c)  ( \
3652                    ( c < 'A') ? c: \
3653                    (c <= 'M')  ? (c + 13): \
3654                    (c <= 'Z')  ? (c - 13): \
3655                    (c < 'a')   ? (c): \
3656                    (c <= 'm')  ? (c + 13): \
3657                    (c <= 'z')  ? (c - 13): \
3658                    (c) \
3659                   )
3660
3661 #define  rot47(c) ( \
3662                    ( c < '!') ? c: \
3663                    ( c <= 'O') ? (c + 47) : \
3664                    ( c <= '~') ?  (c - 47) : \
3665                    c \
3666                   )
3667
3668 static void
3669 rot_conv(nkf_char c2, nkf_char c1)
3670 {
3671     if (c2 == 0 || c2 == JIS_X_0201_1976_K || c2 == ISO_8859_1) {
3672         c1 = rot13(c1);
3673     } else if (c2) {
3674         c1 = rot47(c1);
3675         c2 = rot47(c2);
3676     }
3677     (*o_rot_conv)(c2,c1);
3678 }
3679
3680 static void
3681 hira_conv(nkf_char c2, nkf_char c1)
3682 {
3683     if (hira_f & 1) {
3684         if (c2 == 0x25) {
3685             if (0x20 < c1 && c1 < 0x74) {
3686                 c2 = 0x24;
3687                 (*o_hira_conv)(c2,c1);
3688                 return;
3689             } else if (c1 == 0x74 && nkf_enc_unicode_p(output_encoding)) {
3690                 c2 = 0;
3691                 c1 = nkf_char_unicode_new(0x3094);
3692                 (*o_hira_conv)(c2,c1);
3693                 return;
3694             }
3695         } else if (c2 == 0x21 && (c1 == 0x33 || c1 == 0x34)) {
3696             c1 += 2;
3697             (*o_hira_conv)(c2,c1);
3698             return;
3699         }
3700     }
3701     if (hira_f & 2) {
3702         if (c2 == 0 && c1 == nkf_char_unicode_new(0x3094)) {
3703             c2 = 0x25;
3704             c1 = 0x74;
3705         } else if (c2 == 0x24 && 0x20 < c1 && c1 < 0x74) {
3706             c2 = 0x25;
3707         } else if (c2 == 0x21 && (c1 == 0x35 || c1 == 0x36)) {
3708             c1 -= 2;
3709         }
3710     }
3711     (*o_hira_conv)(c2,c1);
3712 }
3713
3714
3715 static void
3716 iso2022jp_check_conv(nkf_char c2, nkf_char c1)
3717 {
3718 #define RANGE_NUM_MAX 18
3719     static const nkf_char range[RANGE_NUM_MAX][2] = {
3720         {0x222f, 0x2239,},
3721         {0x2242, 0x2249,},
3722         {0x2251, 0x225b,},
3723         {0x226b, 0x2271,},
3724         {0x227a, 0x227d,},
3725         {0x2321, 0x232f,},
3726         {0x233a, 0x2340,},
3727         {0x235b, 0x2360,},
3728         {0x237b, 0x237e,},
3729         {0x2474, 0x247e,},
3730         {0x2577, 0x257e,},
3731         {0x2639, 0x2640,},
3732         {0x2659, 0x267e,},
3733         {0x2742, 0x2750,},
3734         {0x2772, 0x277e,},
3735         {0x2841, 0x287e,},
3736         {0x4f54, 0x4f7e,},
3737         {0x7425, 0x747e},
3738     };
3739     nkf_char i;
3740     nkf_char start, end, c;
3741
3742     if(c2 >= 0x00 && c2 <= 0x20 && c1 >= 0x7f && c1 <= 0xff) {
3743         c2 = GETA1;
3744         c1 = GETA2;
3745     }
3746     if((c2 >= 0x29 && c2 <= 0x2f) || (c2 >= 0x75 && c2 <= 0x7e)) {
3747         c2 = GETA1;
3748         c1 = GETA2;
3749     }
3750
3751     for (i = 0; i < RANGE_NUM_MAX; i++) {
3752         start = range[i][0];
3753         end   = range[i][1];
3754         c     = (c2 << 8) + c1;
3755         if (c >= start && c <= end) {
3756             c2 = GETA1;
3757             c1 = GETA2;
3758         }
3759     }
3760     (*o_iso2022jp_check_conv)(c2,c1);
3761 }
3762
3763
3764 /* This converts  =?ISO-2022-JP?B?HOGE HOGE?= */
3765
3766 static const unsigned char *mime_pattern[] = {
3767     (const unsigned char *)"\075?EUC-JP?B?",
3768     (const unsigned char *)"\075?SHIFT_JIS?B?",
3769     (const unsigned char *)"\075?ISO-8859-1?Q?",
3770     (const unsigned char *)"\075?ISO-8859-1?B?",
3771     (const unsigned char *)"\075?ISO-2022-JP?B?",
3772     (const unsigned char *)"\075?ISO-2022-JP?Q?",
3773 #if defined(UTF8_INPUT_ENABLE)
3774     (const unsigned char *)"\075?UTF-8?B?",
3775     (const unsigned char *)"\075?UTF-8?Q?",
3776 #endif
3777     (const unsigned char *)"\075?US-ASCII?Q?",
3778     NULL
3779 };
3780
3781
3782 /* \e$B3:Ev$9$k%3!<%I$NM%@hEY$r>e$2$k$?$a$NL\0u\e(B */
3783 nkf_char (*mime_priority_func[])(nkf_char c2, nkf_char c1, nkf_char c0) = {
3784     e_iconv, s_iconv, 0, 0, 0, 0,
3785 #if defined(UTF8_INPUT_ENABLE)
3786     w_iconv, w_iconv,
3787 #endif
3788     0,
3789 };
3790
3791 static const nkf_char mime_encode[] = {
3792     EUC_JP, SHIFT_JIS, ISO_8859_1, ISO_8859_1, JIS_X_0208, JIS_X_0201_1976_K,
3793 #if defined(UTF8_INPUT_ENABLE)
3794     UTF_8, UTF_8,
3795 #endif
3796     ASCII,
3797     0
3798 };
3799
3800 static const nkf_char mime_encode_method[] = {
3801     'B', 'B','Q', 'B', 'B', 'Q',
3802 #if defined(UTF8_INPUT_ENABLE)
3803     'B', 'Q',
3804 #endif
3805     'Q',
3806     0
3807 };
3808
3809
3810 /* MIME preprocessor fifo */
3811
3812 #define MIME_BUF_SIZE   (1024)    /* 2^n ring buffer */
3813 #define MIME_BUF_MASK   (MIME_BUF_SIZE-1)
3814 #define mime_input_buf(n)        mime_input_state.buf[(n)&MIME_BUF_MASK]
3815 static struct {
3816     unsigned char buf[MIME_BUF_SIZE];
3817     unsigned int  top;
3818     unsigned int  last;  /* decoded */
3819     unsigned int  input; /* undecoded */
3820 } mime_input_state;
3821 static nkf_char (*mime_iconv_back)(nkf_char c2,nkf_char c1,nkf_char c0) = NULL;
3822
3823 #define MAXRECOVER 20
3824
3825 static void
3826 mime_input_buf_unshift(nkf_char c)
3827 {
3828     mime_input_buf(--mime_input_state.top) = (unsigned char)c;
3829 }
3830
3831 static nkf_char
3832 mime_ungetc(nkf_char c, FILE *f)
3833 {
3834     mime_input_buf_unshift(c);
3835     return c;
3836 }
3837
3838 static nkf_char
3839 mime_ungetc_buf(nkf_char c, FILE *f)
3840 {
3841     if (mimebuf_f)
3842         (*i_mungetc_buf)(c,f);
3843     else
3844         mime_input_buf(--mime_input_state.input) = (unsigned char)c;
3845     return c;
3846 }
3847
3848 static nkf_char
3849 mime_getc_buf(FILE *f)
3850 {
3851     /* we don't keep eof of mime_input_buf, becase it contains ?= as
3852        a terminator. It was checked in mime_integrity. */
3853     return ((mimebuf_f)?
3854             (*i_mgetc_buf)(f):mime_input_buf(mime_input_state.input++));
3855 }
3856
3857 static void
3858 switch_mime_getc(void)
3859 {
3860     if (i_getc!=mime_getc) {
3861         i_mgetc = i_getc; i_getc = mime_getc;
3862         i_mungetc = i_ungetc; i_ungetc = mime_ungetc;
3863         if(mime_f==STRICT_MIME) {
3864             i_mgetc_buf = i_mgetc; i_mgetc = mime_getc_buf;
3865             i_mungetc_buf = i_mungetc; i_mungetc = mime_ungetc_buf;
3866         }
3867     }
3868 }
3869
3870 static void
3871 unswitch_mime_getc(void)
3872 {
3873     if(mime_f==STRICT_MIME) {
3874         i_mgetc = i_mgetc_buf;
3875         i_mungetc = i_mungetc_buf;
3876     }
3877     i_getc = i_mgetc;
3878     i_ungetc = i_mungetc;
3879     if(mime_iconv_back)set_iconv(FALSE, mime_iconv_back);
3880     mime_iconv_back = NULL;
3881 }
3882
3883 static nkf_char
3884 mime_integrity(FILE *f, const unsigned char *p)
3885 {
3886     nkf_char c,d;
3887     unsigned int q;
3888     /* In buffered mode, read until =? or NL or buffer full
3889      */
3890     mime_input_state.input = mime_input_state.top;
3891     mime_input_state.last = mime_input_state.top;
3892
3893     while(*p) mime_input_buf(mime_input_state.input++) = *p++;
3894     d = 0;
3895     q = mime_input_state.input;
3896     while((c=(*i_getc)(f))!=EOF) {
3897         if (((mime_input_state.input-mime_input_state.top)&MIME_BUF_MASK)==0) {
3898             break;   /* buffer full */
3899         }
3900         if (c=='=' && d=='?') {
3901             /* checked. skip header, start decode */
3902             mime_input_buf(mime_input_state.input++) = (unsigned char)c;
3903             /* mime_last_input = mime_input_state.input; */
3904             mime_input_state.input = q;
3905             switch_mime_getc();
3906             return 1;
3907         }
3908         if (!( (c=='+'||c=='/'|| c=='=' || c=='?' || is_alnum(c))))
3909             break;
3910         /* Should we check length mod 4? */
3911         mime_input_buf(mime_input_state.input++) = (unsigned char)c;
3912         d=c;
3913     }
3914     /* In case of Incomplete MIME, no MIME decode  */
3915     mime_input_buf(mime_input_state.input++) = (unsigned char)c;
3916     mime_input_state.last = mime_input_state.input;     /* point undecoded buffer */
3917     mime_decode_mode = 1;              /* no decode on mime_input_buf last in mime_getc */
3918     switch_mime_getc();         /* anyway we need buffered getc */
3919     return 1;
3920 }
3921
3922 static nkf_char
3923 mime_begin_strict(FILE *f)
3924 {
3925     nkf_char c1 = 0;
3926     int i,j,k;
3927     const unsigned char *p,*q;
3928     nkf_char r[MAXRECOVER];    /* recovery buffer, max mime pattern length */
3929
3930     mime_decode_mode = FALSE;
3931     /* =? has been checked */
3932     j = 0;
3933     p = mime_pattern[j];
3934     r[0]='='; r[1]='?';
3935
3936     for(i=2;p[i]>SP;i++) {                   /* start at =? */
3937         if (((r[i] = c1 = (*i_getc)(f))==EOF) || nkf_toupper(c1) != p[i]) {
3938             /* pattern fails, try next one */
3939             q = p;
3940             while (mime_pattern[++j]) {
3941                 p = mime_pattern[j];
3942                 for(k=2;k<i;k++)              /* assume length(p) > i */
3943                     if (p[k]!=q[k]) break;
3944                 if (k==i && nkf_toupper(c1)==p[k]) break;
3945             }
3946             p = mime_pattern[j];
3947             if (p) continue;  /* found next one, continue */
3948             /* all fails, output from recovery buffer */
3949             (*i_ungetc)(c1,f);
3950             for(j=0;j<i;j++) {
3951                 (*oconv)(0,r[j]);
3952             }
3953             return c1;
3954         }
3955     }
3956     mime_decode_mode = p[i-2];
3957
3958     mime_iconv_back = iconv;
3959     set_iconv(FALSE, mime_priority_func[j]);
3960     clr_code_score(find_inputcode_byfunc(mime_priority_func[j]), SCORE_iMIME);
3961
3962     if (mime_decode_mode=='B') {
3963         mimebuf_f = unbuf_f;
3964         if (!unbuf_f) {
3965             /* do MIME integrity check */
3966             return mime_integrity(f,mime_pattern[j]);
3967         }
3968     }
3969     switch_mime_getc();
3970     mimebuf_f = TRUE;
3971     return c1;
3972 }
3973
3974 static nkf_char
3975 mime_begin(FILE *f)
3976 {
3977     nkf_char c1;
3978     int i,k;
3979
3980     /* In NONSTRICT mode, only =? is checked. In case of failure, we  */
3981     /* re-read and convert again from mime_buffer.  */
3982
3983     /* =? has been checked */
3984     k = mime_input_state.last;
3985     mime_input_buf(mime_input_state.last++)='='; mime_input_buf(mime_input_state.last++)='?';
3986     for(i=2;i<MAXRECOVER;i++) {                   /* start at =? */
3987         /* We accept any character type even if it is breaked by new lines */
3988         c1 = (*i_getc)(f); mime_input_buf(mime_input_state.last++) = (unsigned char)c1;
3989         if (c1==LF||c1==SP||c1==CR||
3990             c1=='-'||c1=='_'||is_alnum(c1)) continue;
3991         if (c1=='=') {
3992             /* Failed. But this could be another MIME preemble */
3993             (*i_ungetc)(c1,f);
3994             mime_input_state.last--;
3995             break;
3996         }
3997         if (c1!='?') break;
3998         else {
3999             /* c1=='?' */
4000             c1 = (*i_getc)(f); mime_input_buf(mime_input_state.last++) = (unsigned char)c1;
4001             if (!(++i<MAXRECOVER) || c1==EOF) break;
4002             if (c1=='b'||c1=='B') {
4003                 mime_decode_mode = 'B';
4004             } else if (c1=='q'||c1=='Q') {
4005                 mime_decode_mode = 'Q';
4006             } else {
4007                 break;
4008             }
4009             c1 = (*i_getc)(f); mime_input_buf(mime_input_state.last++) = (unsigned char)c1;
4010             if (!(++i<MAXRECOVER) || c1==EOF) break;
4011             if (c1!='?') {
4012                 mime_decode_mode = FALSE;
4013             }
4014             break;
4015         }
4016     }
4017     switch_mime_getc();
4018     if (!mime_decode_mode) {
4019         /* false MIME premble, restart from mime_buffer */
4020         mime_decode_mode = 1;  /* no decode, but read from the mime_buffer */
4021         /* Since we are in MIME mode until buffer becomes empty,    */
4022         /* we never go into mime_begin again for a while.           */
4023         return c1;
4024     }
4025     /* discard mime preemble, and goto MIME mode */
4026     mime_input_state.last = k;
4027     /* do no MIME integrity check */
4028     return c1;   /* used only for checking EOF */
4029 }
4030
4031 #ifdef CHECK_OPTION
4032 static void
4033 no_putc(nkf_char c)
4034 {
4035     ;
4036 }
4037
4038 static void
4039 debug(const char *str)
4040 {
4041     if (debug_f){
4042         fprintf(stderr, "%s\n", str ? str : "NULL");
4043     }
4044 }
4045 #endif
4046
4047 static void
4048 set_input_codename(const char *codename)
4049 {
4050     if (!input_codename) {
4051         input_codename = codename;
4052     } else if (strcmp(codename, input_codename) != 0) {
4053         input_codename = "";
4054     }
4055 }
4056
4057 static const char*
4058 get_guessed_code(void)
4059 {
4060     if (input_codename && !*input_codename) {
4061         input_codename = "BINARY";
4062     } else {
4063         struct input_code *p = find_inputcode_byfunc(iconv);
4064         if (!input_codename) {
4065             input_codename = "ASCII";
4066         } else if (strcmp(input_codename, "Shift_JIS") == 0) {
4067             if (p->score & (SCORE_DEPEND|SCORE_CP932))
4068                 input_codename = "CP932";
4069         } else if (strcmp(input_codename, "EUC-JP") == 0) {
4070             if (p->score & (SCORE_X0212))
4071                 input_codename = "EUCJP-MS";
4072             else if (p->score & (SCORE_DEPEND|SCORE_CP932))
4073                 input_codename = "CP51932";
4074         } else if (strcmp(input_codename, "ISO-2022-JP") == 0) {
4075             if (p->score & (SCORE_KANA))
4076                 input_codename = "CP50221";
4077             else if (p->score & (SCORE_DEPEND|SCORE_CP932))
4078                 input_codename = "CP50220";
4079         }
4080     }
4081     return input_codename;
4082 }
4083
4084 #if !defined(PERL_XS) && !defined(WIN32DLL)
4085 static void
4086 print_guessed_code(char *filename)
4087 {
4088     if (filename != NULL) printf("%s: ", filename);
4089     if (input_codename && !*input_codename) {
4090         printf("BINARY\n");
4091     } else {
4092         input_codename = get_guessed_code();
4093         if (guess_f == 1) {
4094             printf("%s\n", input_codename);
4095         } else {
4096             printf("%s%s\n",
4097                    input_codename,
4098                    input_eol == CR   ? " (CR)" :
4099                    input_eol == LF   ? " (LF)" :
4100                    input_eol == CRLF ? " (CRLF)" :
4101                    input_eol == EOF  ? " (MIXED NL)" :
4102                    "");
4103         }
4104     }
4105 }
4106 #endif /*WIN32DLL*/
4107
4108 #ifdef INPUT_OPTION
4109
4110 static nkf_char
4111 hex_getc(nkf_char ch, FILE *f, nkf_char (*g)(FILE *f), nkf_char (*u)(nkf_char c, FILE *f))
4112 {
4113     nkf_char c1, c2, c3;
4114     c1 = (*g)(f);
4115     if (c1 != ch){
4116         return c1;
4117     }
4118     c2 = (*g)(f);
4119     if (!nkf_isxdigit(c2)){
4120         (*u)(c2, f);
4121         return c1;
4122     }
4123     c3 = (*g)(f);
4124     if (!nkf_isxdigit(c3)){
4125         (*u)(c2, f);
4126         (*u)(c3, f);
4127         return c1;
4128     }
4129     return (hex2bin(c2) << 4) | hex2bin(c3);
4130 }
4131
4132 static nkf_char
4133 cap_getc(FILE *f)
4134 {
4135     return hex_getc(':', f, i_cgetc, i_cungetc);
4136 }
4137
4138 static nkf_char
4139 cap_ungetc(nkf_char c, FILE *f)
4140 {
4141     return (*i_cungetc)(c, f);
4142 }
4143
4144 static nkf_char
4145 url_getc(FILE *f)
4146 {
4147     return hex_getc('%', f, i_ugetc, i_uungetc);
4148 }
4149
4150 static nkf_char
4151 url_ungetc(nkf_char c, FILE *f)
4152 {
4153     return (*i_uungetc)(c, f);
4154 }
4155 #endif
4156
4157 #ifdef NUMCHAR_OPTION
4158 static nkf_char
4159 numchar_getc(FILE *f)
4160 {
4161     nkf_char (*g)(FILE *) = i_ngetc;
4162     nkf_char (*u)(nkf_char c ,FILE *f) = i_nungetc;
4163     int i = 0, j;
4164     nkf_char buf[12];
4165     long c = -1;
4166
4167     buf[i] = (*g)(f);
4168     if (buf[i] == '&'){
4169         buf[++i] = (*g)(f);
4170         if (buf[i] == '#'){
4171             c = 0;
4172             buf[++i] = (*g)(f);
4173             if (buf[i] == 'x' || buf[i] == 'X'){
4174                 for (j = 0; j < 7; j++){
4175                     buf[++i] = (*g)(f);
4176                     if (!nkf_isxdigit(buf[i])){
4177                         if (buf[i] != ';'){
4178                             c = -1;
4179                         }
4180                         break;
4181                     }
4182                     c <<= 4;
4183                     c |= hex2bin(buf[i]);
4184                 }
4185             }else{
4186                 for (j = 0; j < 8; j++){
4187                     if (j){
4188                         buf[++i] = (*g)(f);
4189                     }
4190                     if (!nkf_isdigit(buf[i])){
4191                         if (buf[i] != ';'){
4192                             c = -1;
4193                         }
4194                         break;
4195                     }
4196                     c *= 10;
4197                     c += hex2bin(buf[i]);
4198                 }
4199             }
4200         }
4201     }
4202     if (c != -1){
4203         return nkf_char_unicode_new(c);
4204     }
4205     while (i > 0){
4206         (*u)(buf[i], f);
4207         --i;
4208     }
4209     return buf[0];
4210 }
4211
4212 static nkf_char
4213 numchar_ungetc(nkf_char c, FILE *f)
4214 {
4215     return (*i_nungetc)(c, f);
4216 }
4217 #endif
4218
4219 #ifdef UNICODE_NORMALIZATION
4220
4221 typedef struct {
4222     unsigned char *ary;
4223     int max_length;
4224     int count;
4225 } nkf_ary;
4226
4227 static nkf_ary *
4228 nkf_ary_new(int length)
4229 {
4230     nkf_ary *ary = nkf_malloc(sizeof(nkf_ary));
4231     ary->ary = nkf_malloc(length);
4232     ary->max_length = length;
4233     ary->count = 0;
4234     return ary;
4235
4236
4237 static void
4238 nkf_ary_dispose(nkf_ary *ary)
4239 {
4240     nkf_free(ary->ary);
4241     nkf_free(ary);
4242 }
4243
4244 #define nkf_ary_length(ary) ((ary)->count)
4245 #define nkf_ary_empty_p(ary) ((ary)->count == 0)
4246
4247 static unsigned char
4248 nkf_ary_at(nkf_ary *ary, int index)
4249 {
4250     assert(index <= ary->count);
4251     return ary->ary[index];
4252 }
4253
4254 static void
4255 nkf_ary_clear(nkf_ary *ary)
4256 {
4257     ary->count = 0;
4258 }
4259
4260 static unsigned char
4261 nkf_ary_push(nkf_ary *ary, nkf_char c)
4262 {
4263     assert(ary->max_length > ary->count);
4264     ary->ary[ary->count++] = c;
4265     return ary->count;
4266 }
4267
4268 static unsigned char
4269 nkf_ary_pop(nkf_ary *ary)
4270 {
4271     assert(0 < ary->count);
4272     return ary->ary[--ary->count];
4273 }
4274
4275 /* Normalization Form C */
4276 static nkf_char
4277 nfc_getc(FILE *f)
4278 {
4279     nkf_char (*g)(FILE *f) = i_nfc_getc;
4280     nkf_char (*u)(nkf_char c ,FILE *f) = i_nfc_ungetc;
4281     nkf_ary *buf = nkf_ary_new(9);
4282     const unsigned char *array;
4283     int lower=0, upper=NORMALIZATION_TABLE_LENGTH-1;
4284     nkf_char c = (*g)(f);
4285
4286     if (c == EOF || c > 0xFF || (c & 0xc0) == 0x80) return c;
4287
4288     nkf_ary_push(buf, (unsigned char)c);
4289     do {
4290         while (lower <= upper) {
4291             int mid = (lower+upper) / 2;
4292             int len;
4293             array = normalization_table[mid].nfd;
4294             for (len=0; len < NORMALIZATION_TABLE_NFD_LENGTH && array[len]; len++) {
4295                 if (len >= nkf_ary_length(buf)) {
4296                     c = (*g)(f);
4297                     if (c == EOF) {
4298                         len = 0;
4299                         lower = 1, upper = 0;
4300                         break;
4301                     }
4302                     nkf_ary_push(buf, c);
4303                 }
4304                 if (array[len] != nkf_ary_at(buf, len)) {
4305                     if (array[len] < nkf_ary_at(buf, len)) lower = mid + 1;
4306                     else  upper = mid - 1;
4307                     len = 0;
4308                     break;
4309                 }
4310             }
4311             if (len > 0) {
4312                 int i;
4313                 array = normalization_table[mid].nfc;
4314                 nkf_ary_clear(buf);
4315                 for (i=0; i < NORMALIZATION_TABLE_NFC_LENGTH && array[i]; i++)
4316                     nkf_ary_push(buf, array[i]);
4317                 break;
4318             }
4319         }
4320     } while (lower <= upper);
4321
4322     while (nkf_ary_length(buf) > 1) (*u)(nkf_ary_pop(buf), f);
4323     c = nkf_ary_pop(buf);
4324     nkf_ary_dispose(buf);
4325
4326     return c;
4327 }
4328
4329 static nkf_char
4330 nfc_ungetc(nkf_char c, FILE *f)
4331 {
4332     return (*i_nfc_ungetc)(c, f);
4333 }
4334 #endif /* UNICODE_NORMALIZATION */
4335
4336
4337 static nkf_char
4338 base64decode(nkf_char c)
4339 {
4340     int             i;
4341     if (c > '@') {
4342         if (c < '[') {
4343             i = c - 'A';                        /* A..Z 0-25 */
4344         } else if (c == '_') {
4345             i = '?'         /* 63 */ ;          /* _  63 */
4346         } else {
4347             i = c - 'G'     /* - 'a' + 26 */ ;  /* a..z 26-51 */
4348         }
4349     } else if (c > '/') {
4350         i = c - '0' + '4'   /* - '0' + 52 */ ;  /* 0..9 52-61 */
4351     } else if (c == '+' || c == '-') {
4352         i = '>'             /* 62 */ ;          /* + and -  62 */
4353     } else {
4354         i = '?'             /* 63 */ ;          /* / 63 */
4355     }
4356     return (i);
4357 }
4358
4359 static nkf_char
4360 mime_getc(FILE *f)
4361 {
4362     nkf_char c1, c2, c3, c4, cc;
4363     nkf_char t1, t2, t3, t4, mode, exit_mode;
4364     nkf_char lwsp_count;
4365     char *lwsp_buf;
4366     char *lwsp_buf_new;
4367     nkf_char lwsp_size = 128;
4368
4369     if (mime_input_state.top != mime_input_state.last) {  /* Something is in FIFO */
4370         return  mime_input_buf(mime_input_state.top++);
4371     }
4372     if (mime_decode_mode==1 ||mime_decode_mode==FALSE) {
4373         mime_decode_mode=FALSE;
4374         unswitch_mime_getc();
4375         return (*i_getc)(f);
4376     }
4377
4378     if (mimebuf_f == FIXED_MIME)
4379         exit_mode = mime_decode_mode;
4380     else
4381         exit_mode = FALSE;
4382     if (mime_decode_mode == 'Q') {
4383         if ((c1 = (*i_mgetc)(f)) == EOF) return (EOF);
4384       restart_mime_q:
4385         if (c1=='_' && mimebuf_f != FIXED_MIME) return SP;
4386         if (c1<=SP || DEL<=c1) {
4387             mime_decode_mode = exit_mode; /* prepare for quit */
4388             return c1;
4389         }
4390         if (c1!='=' && (c1!='?' || mimebuf_f == FIXED_MIME)) {
4391             return c1;
4392         }
4393
4394         mime_decode_mode = exit_mode; /* prepare for quit */
4395         if ((c2 = (*i_mgetc)(f)) == EOF) return (EOF);
4396         if (c1=='?'&&c2=='=' && mimebuf_f != FIXED_MIME) {
4397             /* end Q encoding */
4398             input_mode = exit_mode;
4399             lwsp_count = 0;
4400             lwsp_buf = nkf_malloc((lwsp_size+5)*sizeof(char));
4401             while ((c1=(*i_getc)(f))!=EOF) {
4402                 switch (c1) {
4403                 case LF:
4404                 case CR:
4405                     if (c1==LF) {
4406                         if ((c1=(*i_getc)(f))!=EOF && (c1==SP||c1==TAB)) {
4407                             i_ungetc(SP,f);
4408                             continue;
4409                         } else {
4410                             i_ungetc(c1,f);
4411                         }
4412                         c1 = LF;
4413                     } else {
4414                         if ((c1=(*i_getc)(f))!=EOF && c1 == LF) {
4415                             if ((c1=(*i_getc)(f))!=EOF && (c1==SP||c1==TAB)) {
4416                                 i_ungetc(SP,f);
4417                                 continue;
4418                             } else {
4419                                 i_ungetc(c1,f);
4420                             }
4421                             i_ungetc(LF,f);
4422                         } else {
4423                             i_ungetc(c1,f);
4424                         }
4425                         c1 = CR;
4426                     }
4427                     break;
4428                 case SP:
4429                 case TAB:
4430                     lwsp_buf[lwsp_count] = (unsigned char)c1;
4431                     if (lwsp_count++>lwsp_size){
4432                         lwsp_size <<= 1;
4433                         lwsp_buf_new = nkf_realloc(lwsp_buf, (lwsp_size+5)*sizeof(char));
4434                         lwsp_buf = lwsp_buf_new;
4435                     }
4436                     continue;
4437                 }
4438                 break;
4439             }
4440             if (lwsp_count > 0 && (c1 != '=' || (lwsp_buf[lwsp_count-1] != SP && lwsp_buf[lwsp_count-1] != TAB))) {
4441                 i_ungetc(c1,f);
4442                 for(lwsp_count--;lwsp_count>0;lwsp_count--)
4443                     i_ungetc(lwsp_buf[lwsp_count],f);
4444                 c1 = lwsp_buf[0];
4445             }
4446             nkf_free(lwsp_buf);
4447             return c1;
4448         }
4449         if (c1=='='&&c2<SP) { /* this is soft wrap */
4450             while((c1 =  (*i_mgetc)(f)) <=SP) {
4451                 if ((c1 = (*i_mgetc)(f)) == EOF) return (EOF);
4452             }
4453             mime_decode_mode = 'Q'; /* still in MIME */
4454             goto restart_mime_q;
4455         }
4456         if (c1=='?') {
4457             mime_decode_mode = 'Q'; /* still in MIME */
4458             (*i_mungetc)(c2,f);
4459             return c1;
4460         }
4461         if ((c3 = (*i_mgetc)(f)) == EOF) return (EOF);
4462         if (c2<=SP) return c2;
4463         mime_decode_mode = 'Q'; /* still in MIME */
4464         return ((hex2bin(c2)<<4) + hex2bin(c3));
4465     }
4466
4467     if (mime_decode_mode != 'B') {
4468         mime_decode_mode = FALSE;
4469         return (*i_mgetc)(f);
4470     }
4471
4472
4473     /* Base64 encoding */
4474     /*
4475        MIME allows line break in the middle of
4476        Base64, but we are very pessimistic in decoding
4477        in unbuf mode because MIME encoded code may broken by
4478        less or editor's control sequence (such as ESC-[-K in unbuffered
4479        mode. ignore incomplete MIME.
4480      */
4481     mode = mime_decode_mode;
4482     mime_decode_mode = exit_mode;  /* prepare for quit */
4483
4484     while ((c1 = (*i_mgetc)(f))<=SP) {
4485         if (c1==EOF)
4486             return (EOF);
4487     }
4488   mime_c2_retry:
4489     if ((c2 = (*i_mgetc)(f))<=SP) {
4490         if (c2==EOF)
4491             return (EOF);
4492         if (mime_f != STRICT_MIME) goto mime_c2_retry;
4493         if (mimebuf_f!=FIXED_MIME) input_mode = ASCII;
4494         return c2;
4495     }
4496     if ((c1 == '?') && (c2 == '=')) {
4497         input_mode = ASCII;
4498         lwsp_count = 0;
4499         lwsp_buf = nkf_malloc((lwsp_size+5)*sizeof(char));
4500         while ((c1=(*i_getc)(f))!=EOF) {
4501             switch (c1) {
4502             case LF:
4503             case CR:
4504                 if (c1==LF) {
4505                     if ((c1=(*i_getc)(f))!=EOF && (c1==SP||c1==TAB)) {
4506                         i_ungetc(SP,f);
4507                         continue;
4508                     } else {
4509                         i_ungetc(c1,f);
4510                     }
4511                     c1 = LF;
4512                 } else {
4513                     if ((c1=(*i_getc)(f))!=EOF) {
4514                         if (c1==SP) {
4515                             i_ungetc(SP,f);
4516           &n