OSDN Git Service

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