OSDN Git Service

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