OSDN Git Service

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