OSDN Git Service

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