OSDN Git Service

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