OSDN Git Service

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