** E-Mail: furukawa@tcp-ip.or.jp
** \e$B$^$G8fO"Mm$r$*4j$$$7$^$9!#\e(B
***********************************************************************/
-/* $Id: nkf.c,v 1.69 2005/06/27 16:05:59 naruse Exp $ */
+/* $Id: nkf.c,v 1.75 2005/07/21 05:55:59 naruse Exp $ */
#define NKF_VERSION "2.0.5"
-#define NKF_RELEASE_DATE "2005-06-28"
+#define NKF_RELEASE_DATE "2005-07-22"
#include "config.h"
-static char *CopyRight =
- "Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa),2000 S. Kono, COW, 2002-2005 Kono, Furukawa, Naruse";
+#define COPY_RIGHT \
+ "Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa),2000 S. Kono, COW, 2002-2005 Kono, Furukawa, Naruse"
/*
#endif
#include <stdlib.h>
+#include <string.h>
#if defined(MSDOS) || defined(__OS2__)
#include <fcntl.h>
#ifdef OVERWRITE
/* added by satoru@isoternet.org */
-#include <string.h>
#include <sys/stat.h>
#ifndef MSDOS /* UNIX, OS/2 */
#include <unistd.h>
#define GETA2 0x2e
-#if defined( UTF8_OUTPUT_ENABLE ) || defined( UTF8_INPUT_ENABLE )
+#if defined(UTF8_OUTPUT_ENABLE) || defined(UTF8_INPUT_ENABLE)
#define sizeof_euc_utf8 94
#define sizeof_euc_to_utf8_1byte 94
#define sizeof_euc_to_utf8_2bytes 94
/* MIME preprocessor */
-
#ifdef EASYWIN /*Easy Win */
extern POINT _BufferSize;
#endif
#ifdef ANSI_C_PROTOTYPE
#define PROTO(x) x
#define STATIC static
+#define CONST const
#else
#define PROTO(x) ()
#define STATIC
+#define CONST
#endif
struct input_code{
STATIC char *input_codename = "";
+#ifndef PERL_XS
+STATIC const char *CopyRight = COPY_RIGHT;
+#endif
+#if !defined(PERL_XS) && !defined(WIN32DLL)
STATIC int noconvert PROTO((FILE *f));
+#endif
STATIC int kanji_convert PROTO((FILE *f));
STATIC int h_conv PROTO((FILE *f,int c2,int c1));
STATIC int push_hold_buf PROTO((int c2));
STATIC int w2e_conv PROTO((int c2,int c1,int c0,int *p2,int *p1));
STATIC int w_iconv PROTO((int c2,int c1,int c0));
STATIC int w_iconv16 PROTO((int c2,int c1,int c0));
-STATIC int w_iconv_common PROTO((int c1,int c0,unsigned short **pp,int psize,int *p2,int *p1));
+STATIC int w_iconv_common PROTO((int c1,int c0,const unsigned short *const *pp,int psize,int *p2,int *p1));
STATIC int ww16_conv PROTO((int c2, int c1, int c0));
#endif
#ifdef UTF8_OUTPUT_ENABLE
STATIC int mime_begin_strict PROTO((FILE *f));
STATIC int mime_getc_buf PROTO((FILE *f));
STATIC int mime_ungetc_buf PROTO((int c,FILE *f));
-STATIC int mime_integrity PROTO((FILE *f,unsigned char *p));
+STATIC int mime_integrity PROTO((FILE *f,const unsigned char *p));
STATIC int base64decode PROTO((int c));
STATIC void mime_prechar PROTO((int c2, int c1));
STATIC void mime_putc PROTO((int c));
STATIC void open_mime PROTO((int c));
STATIC void close_mime PROTO(());
+#ifndef PERL_XS
STATIC void usage PROTO(());
STATIC void version PROTO(());
+#endif
STATIC void options PROTO((unsigned char *c));
#if defined(PERL_XS) || defined(WIN32DLL)
STATIC void reinit PROTO(());
/* buffers */
-static unsigned char stdibuf[IOBUF_SIZE];
-static unsigned char stdobuf[IOBUF_SIZE];
-static unsigned char hold_buf[HOLD_SIZE*2];
-static int hold_count;
+#if !defined(PERL_XS) && !defined(WIN32DLL)
+STATIC unsigned char stdibuf[IOBUF_SIZE];
+STATIC unsigned char stdobuf[IOBUF_SIZE];
+#endif
+STATIC unsigned char hold_buf[HOLD_SIZE*2];
+STATIC int hold_count;
/* MIME preprocessor fifo */
#define MIME_BUF_SIZE (1024) /* 2^n ring buffer */
#define MIME_BUF_MASK (MIME_BUF_SIZE-1)
#define Fifo(n) mime_buf[(n)&MIME_BUF_MASK]
-static unsigned char mime_buf[MIME_BUF_SIZE];
-static unsigned int mime_top = 0;
-static unsigned int mime_last = 0; /* decoded */
-static unsigned int mime_input = 0; /* undecoded */
+STATIC unsigned char mime_buf[MIME_BUF_SIZE];
+STATIC unsigned int mime_top = 0;
+STATIC unsigned int mime_last = 0; /* decoded */
+STATIC unsigned int mime_input = 0; /* undecoded */
+STATIC int (*mime_iconv_back)PROTO((int c2,int c1,int c0)) = NULL;
/* flags */
-static int unbuf_f = FALSE;
-static int estab_f = FALSE;
-static int nop_f = FALSE;
-static int binmode_f = TRUE; /* binary mode */
-static int rot_f = FALSE; /* rot14/43 mode */
-static int hira_f = FALSE; /* hira/kata henkan */
-static int input_f = FALSE; /* non fixed input code */
-static int alpha_f = FALSE; /* convert JIx0208 alphbet to ASCII */
-static int mime_f = STRICT_MIME; /* convert MIME B base64 or Q */
-static int mime_decode_f = FALSE; /* mime decode is explicitly on */
-static int mimebuf_f = FALSE; /* MIME buffered input */
-static int broken_f = FALSE; /* convert ESC-less broken JIS */
-static int iso8859_f = FALSE; /* ISO8859 through */
-static int mimeout_f = FALSE; /* base64 mode */
+STATIC int unbuf_f = FALSE;
+STATIC int estab_f = FALSE;
+STATIC int nop_f = FALSE;
+STATIC int binmode_f = TRUE; /* binary mode */
+STATIC int rot_f = FALSE; /* rot14/43 mode */
+STATIC int hira_f = FALSE; /* hira/kata henkan */
+STATIC int input_f = FALSE; /* non fixed input code */
+STATIC int alpha_f = FALSE; /* convert JIx0208 alphbet to ASCII */
+STATIC int mime_f = STRICT_MIME; /* convert MIME B base64 or Q */
+STATIC int mime_decode_f = FALSE; /* mime decode is explicitly on */
+STATIC int mimebuf_f = FALSE; /* MIME buffered input */
+STATIC int broken_f = FALSE; /* convert ESC-less broken JIS */
+STATIC int iso8859_f = FALSE; /* ISO8859 through */
+STATIC int mimeout_f = FALSE; /* base64 mode */
#if defined(MSDOS) || defined(__OS2__)
-static int x0201_f = TRUE; /* Assume JISX0201 kana */
+STATIC int x0201_f = TRUE; /* Assume JISX0201 kana */
#else
-static int x0201_f = NO_X0201; /* Assume NO JISX0201 */
+STATIC int x0201_f = NO_X0201; /* Assume NO JISX0201 */
+#endif
+STATIC int iso2022jp_f = FALSE; /* convert ISO-2022-JP */
+#if defined(UTF8_OUTPUT_ENABLE) && defined(UTF8_INPUT_ENABLE)
+STATIC int internal_unicode_f = FALSE; /* Internal Unicode Processing */
#endif
-static int iso2022jp_f = FALSE; /* convert ISO-2022-JP */
#ifdef UTF8_OUTPUT_ENABLE
-static int unicode_bom_f= 0; /* Output Unicode BOM */
-static int w_oconv16_LE = 0; /* utf-16 little endian */
-static int ms_ucs_map_f = FALSE; /* Microsoft UCS Mapping Compatible */
+STATIC int unicode_bom_f= 0; /* Output Unicode BOM */
+STATIC int w_oconv16_LE = 0; /* utf-16 little endian */
+STATIC int ms_ucs_map_f = FALSE; /* Microsoft UCS Mapping Compatible */
#endif
-
-#ifdef NUMCHAR_OPTION
-
-#define CLASS_MASK 0x0f000000
-#define CLASS_UTF16 0x01000000
+#ifdef UNICODE_NORMALIZATION
+STATIC int nfc_f = FALSE;
+STATIC int (*i_nfc_getc)PROTO((FILE *)) = std_getc; /* input of ugetc */
+STATIC int (*i_nfc_ungetc)PROTO((int c ,FILE *f)) = std_ungetc;
+STATIC int nfc_getc PROTO((FILE *f));
+STATIC int nfc_ungetc PROTO((int c,FILE *f));
#endif
#ifdef INPUT_OPTION
-static int cap_f = FALSE;
-static int (*i_cgetc)PROTO((FILE *)) = std_getc; /* input of cgetc */
-static int (*i_cungetc)PROTO((int c ,FILE *f)) = std_ungetc;
+STATIC int cap_f = FALSE;
+STATIC int (*i_cgetc)PROTO((FILE *)) = std_getc; /* input of cgetc */
+STATIC int (*i_cungetc)PROTO((int c ,FILE *f)) = std_ungetc;
STATIC int cap_getc PROTO((FILE *f));
STATIC int cap_ungetc PROTO((int c,FILE *f));
-static int url_f = FALSE;
-static int (*i_ugetc)PROTO((FILE *)) = std_getc; /* input of ugetc */
-static int (*i_uungetc)PROTO((int c ,FILE *f)) = std_ungetc;
+STATIC int url_f = FALSE;
+STATIC int (*i_ugetc)PROTO((FILE *)) = std_getc; /* input of ugetc */
+STATIC int (*i_uungetc)PROTO((int c ,FILE *f)) = std_ungetc;
STATIC int url_getc PROTO((FILE *f));
STATIC int url_ungetc PROTO((int c,FILE *f));
+#endif
-static int numchar_f = FALSE;
-static int (*i_ngetc)PROTO((FILE *)) = std_getc; /* input of ugetc */
-static int (*i_nungetc)PROTO((int c ,FILE *f)) = std_ungetc;
+#ifdef NUMCHAR_OPTION
+#define CLASS_MASK 0x0f000000
+#define CLASS_UTF16 0x01000000
+STATIC int numchar_f = FALSE;
+STATIC int (*i_ngetc)PROTO((FILE *)) = std_getc; /* input of ugetc */
+STATIC int (*i_nungetc)PROTO((int c ,FILE *f)) = std_ungetc;
STATIC int numchar_getc PROTO((FILE *f));
STATIC int numchar_ungetc PROTO((int c,FILE *f));
#endif
#ifdef CHECK_OPTION
-static int noout_f = FALSE;
+STATIC int noout_f = FALSE;
STATIC void no_putc PROTO((int c));
-static int debug_f = FALSE;
-STATIC void debug PROTO((char *str));
+STATIC int debug_f = FALSE;
+STATIC void debug PROTO((const char *str));
+STATIC int (*iconv_for_check)() = 0;
#endif
-static int guess_f = FALSE;
+STATIC int guess_f = FALSE;
+#if !defined PERL_XS
STATIC void print_guessed_code PROTO((char *filename));
+#endif
STATIC void set_input_codename PROTO((char *codename));
-static int is_inputcode_mixed = FALSE;
-static int is_inputcode_set = FALSE;
+STATIC int is_inputcode_mixed = FALSE;
+STATIC int is_inputcode_set = FALSE;
#ifdef EXEC_IO
-static int exec_f = 0;
+STATIC int exec_f = 0;
#endif
#ifdef SHIFTJIS_CP932
#ifdef X0212_ENABLE
STATIC int x0212_f = FALSE;
-static int x0212_shift PROTO((int c));
-static int x0212_unshift PROTO((int c));
+STATIC int x0212_shift PROTO((int c));
+STATIC int x0212_unshift PROTO((int c));
#endif
STATIC unsigned char prefix_table[256];
#ifdef UTF8_INPUT_ENABLE
STATIC void w_status PROTO((struct input_code *, int));
STATIC void w16_status PROTO((struct input_code *, int));
-static int utf16_mode = UTF16BE_INPUT;
+STATIC int utf16_mode = UTF16BE_INPUT;
#endif
struct input_code input_code_list[] = {
{"EUC-JP", 0, 0, 0, {0, 0, 0}, e_status, e_iconv, 0},
{"Shift_JIS", 0, 0, 0, {0, 0, 0}, s_status, s_iconv, 0},
+#ifdef UTF8_INPUT_ENABLE
{"UTF-8", 0, 0, 0, {0, 0, 0}, w_status, w_iconv, 0},
{"UTF-16", 0, 0, 0, {0, 0, 0}, w16_status, w_iconv16, 0},
+#endif
{0}
};
-static int mimeout_mode = 0;
-static int base64_count = 0;
+STATIC int mimeout_mode = 0;
+STATIC int base64_count = 0;
/* X0208 -> ASCII converter */
/* fold parameter */
-static int f_line = 0; /* chars in line */
-static int f_prev = 0;
-static int fold_preserve_f = FALSE; /* preserve new lines */
-static int fold_f = FALSE;
-static int fold_len = 0;
+STATIC int f_line = 0; /* chars in line */
+STATIC int f_prev = 0;
+STATIC int fold_preserve_f = FALSE; /* preserve new lines */
+STATIC int fold_f = FALSE;
+STATIC int fold_len = 0;
/* options */
-static unsigned char kanji_intro = DEFAULT_J;
-static unsigned char ascii_intro = DEFAULT_R;
+STATIC unsigned char kanji_intro = DEFAULT_J;
+STATIC unsigned char ascii_intro = DEFAULT_R;
/* Folding */
#define FOLD_MARGIN 10
#define DEFAULT_FOLD 60
-static int fold_margin = FOLD_MARGIN;
+STATIC int fold_margin = FOLD_MARGIN;
/* converters */
#endif
/* process default */
-static void (*output_conv)PROTO((int c2,int c1)) = DEFAULT_CONV;
+STATIC void (*output_conv)PROTO((int c2,int c1)) = DEFAULT_CONV;
-static void (*oconv)PROTO((int c2,int c1)) = no_connection;
+STATIC void (*oconv)PROTO((int c2,int c1)) = no_connection;
/* s_iconv or oconv */
-static int (*iconv)PROTO((int c2,int c1,int c0)) = no_connection2;
+STATIC int (*iconv)PROTO((int c2,int c1,int c0)) = no_connection2;
-static void (*o_zconv)PROTO((int c2,int c1)) = no_connection;
-static void (*o_fconv)PROTO((int c2,int c1)) = no_connection;
-static void (*o_crconv)PROTO((int c2,int c1)) = no_connection;
-static void (*o_rot_conv)PROTO((int c2,int c1)) = no_connection;
-static void (*o_hira_conv)PROTO((int c2,int c1)) = no_connection;
-static void (*o_base64conv)PROTO((int c2,int c1)) = no_connection;
-static void (*o_iso2022jp_check_conv)PROTO((int c2,int c1)) = no_connection;
+STATIC void (*o_zconv)PROTO((int c2,int c1)) = no_connection;
+STATIC void (*o_fconv)PROTO((int c2,int c1)) = no_connection;
+STATIC void (*o_crconv)PROTO((int c2,int c1)) = no_connection;
+STATIC void (*o_rot_conv)PROTO((int c2,int c1)) = no_connection;
+STATIC void (*o_hira_conv)PROTO((int c2,int c1)) = no_connection;
+STATIC void (*o_base64conv)PROTO((int c2,int c1)) = no_connection;
+STATIC void (*o_iso2022jp_check_conv)PROTO((int c2,int c1)) = no_connection;
-/* static redirections */
+/* STATIC redirections */
-static void (*o_putc)PROTO((int c)) = std_putc;
+STATIC void (*o_putc)PROTO((int c)) = std_putc;
-static int (*i_getc)PROTO((FILE *f)) = std_getc; /* general input */
-static int (*i_ungetc)PROTO((int c,FILE *f)) =std_ungetc;
+STATIC int (*i_getc)PROTO((FILE *f)) = std_getc; /* general input */
+STATIC int (*i_ungetc)PROTO((int c,FILE *f)) =std_ungetc;
-static int (*i_bgetc)PROTO((FILE *)) = std_getc; /* input of mgetc */
-static int (*i_bungetc)PROTO((int c ,FILE *f)) = std_ungetc;
+STATIC int (*i_bgetc)PROTO((FILE *)) = std_getc; /* input of mgetc */
+STATIC int (*i_bungetc)PROTO((int c ,FILE *f)) = std_ungetc;
-static void (*o_mputc)PROTO((int c)) = std_putc ; /* output of mputc */
+STATIC void (*o_mputc)PROTO((int c)) = std_putc ; /* output of mputc */
-static int (*i_mgetc)PROTO((FILE *)) = std_getc; /* input of mgetc */
-static int (*i_mungetc)PROTO((int c ,FILE *f)) = std_ungetc;
+STATIC int (*i_mgetc)PROTO((FILE *)) = std_getc; /* input of mgetc */
+STATIC int (*i_mungetc)PROTO((int c ,FILE *f)) = std_ungetc;
/* for strict mime */
-static int (*i_mgetc_buf)PROTO((FILE *)) = std_getc; /* input of mgetc_buf */
-static int (*i_mungetc_buf)PROTO((int c,FILE *f)) = std_ungetc;
+STATIC int (*i_mgetc_buf)PROTO((FILE *)) = std_getc; /* input of mgetc_buf */
+STATIC int (*i_mungetc_buf)PROTO((int c,FILE *f)) = std_ungetc;
/* Global states */
-static int output_mode = ASCII, /* output kanji mode */
+STATIC int output_mode = ASCII, /* output kanji mode */
input_mode = ASCII, /* input kanji mode */
shift_mode = FALSE; /* TRUE shift out, or X0201 */
-static int mime_decode_mode = FALSE; /* MIME mode B base64, Q hex */
+STATIC int mime_decode_mode = FALSE; /* MIME mode B base64, Q hex */
/* X0201 / X0208 conversion tables */
/* X0201 kana conversion table */
/* 90-9F A0-DF */
-static
+STATIC const
unsigned char cv[]= {
0x21,0x21,0x21,0x23,0x21,0x56,0x21,0x57,
0x21,0x22,0x21,0x26,0x25,0x72,0x25,0x21,
/* X0201 kana conversion table for daguten */
/* 90-9F A0-DF */
-static
+STATIC const
unsigned char dv[]= {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* X0201 kana conversion table for han-daguten */
/* 90-9F A0-DF */
-static
+STATIC const
unsigned char ev[]= {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* X0208 kigou conversion table */
/* 0x8140 - 0x819e */
-static
+STATIC const
unsigned char fv[] = {
0x00,0x00,0x00,0x00,0x2c,0x2e,0x00,0x3a,
#define CRLF 1
-static int file_out = FALSE;
+STATIC int file_out = FALSE;
#ifdef OVERWRITE
-static int overwrite = FALSE;
+STATIC int overwrite = FALSE;
#endif
-static int crmode_f = 0; /* CR, NL, CRLF */
+STATIC int crmode_f = 0; /* CR, NL, CRLF */
#ifdef EASYWIN /*Easy Win */
-static int end_check;
+STATIC int end_check;
#endif /*Easy Win */
#define STD_GC_BUFSIZE (256)
is_inputcode_mixed = FALSE;
is_inputcode_set = FALSE;
input_codename = "";
+#ifdef CHECK_OPTION
+ iconv_for_check = 0;
+#endif
if ((fin = fopen((origfname = *argv++), "r")) == NULL) {
perror(*--argv);
return(-1);
}
#endif /* WIN32DLL */
-static
+STATIC const
struct {
- char *name;
- char *alias;
+ const char *name;
+ const char *alias;
} long_option[] = {
{"base64","jMB"},
{"euc","e"},
#ifdef X0212_ENABLE
{"x0212", ""},
#endif
+#if defined(UTF8_OUTPUT_ENABLE) && defined(UTF8_INPUT_ENABLE)
+ {"internal-unicode", ""},
+#endif
#ifdef UTF8_OUTPUT_ENABLE
{"utf8", "w"},
{"utf16", "w16"},
{"utf8-input", "W"},
{"utf16-input", "W16"},
#endif
+#ifdef UNICODE_NORMALIZATION
+ {"utf8mac-input", ""},
+#endif
#ifdef OVERWRITE
{"overwrite", ""},
#endif
{"prefix=", ""},
};
-static int option_mode = 0;
+STATIC int option_mode = 0;
void
options(cp)
return;
}
#endif
+#if defined(UTF8_OUTPUT_ENABLE) && defined(UTF8_INPUT_ENABLE)
+ if (strcmp(long_option[i].name, "internal-unicode") == 0){
+ internal_unicode_f = TRUE;
+ continue;
+ }
+#endif
#ifdef UTF8_OUTPUT_ENABLE
if (strcmp(long_option[i].name, "ms-ucs-map") == 0){
ms_ucs_map_f = TRUE;
continue;
}
#endif
+#ifdef UNICODE_NORMALIZATION
+ if (strcmp(long_option[i].name, "utf8mac-input") == 0){
+ input_f = UTF8_INPUT;
+ nfc_f = TRUE;
+ continue;
+ }
+#endif
if (strcmp(long_option[i].name, "prefix=") == 0){
if (*p == '=' && ' ' < p[1] && p[1] < 128){
for (i = 2; ' ' < p[i] && p[i] < 128; i++){
return 0;
}
-#ifdef CHECK_OPTION
-static int (*iconv_for_check)() = 0;
-#endif
-
#ifdef ANSI_C_PROTOTYPE
void set_iconv(int f, int (*iconv_func)(int c2,int c1,int c0))
#else
#define SCORE_INIT (SCORE_iMIME)
-int score_table_A0[] = {
+const int score_table_A0[] = {
0, 0, 0, 0,
0, 0, 0, 0,
0, SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND,
SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND, SCORE_NO_EXIST,
};
-int score_table_F0[] = {
+const int score_table_F0[] = {
SCORE_L2, SCORE_L2, SCORE_L2, SCORE_L2,
SCORE_L2, SCORE_DEPEND, SCORE_NO_EXIST, SCORE_NO_EXIST,
SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND,
struct input_code *ptr;
{
int c2 = ptr->buf[0];
+#ifdef UTF8_OUTPUT_ENABLE
int c1 = ptr->buf[1];
+#endif
if (c2 < 0){
set_code_score(ptr, SCORE_ERROR);
}else if (c2 == SSO){
}
#endif /*WIN32DLL*/
+#if !defined(PERL_XS) && !defined(WIN32DLL)
int
noconvert(f)
FILE *f;
(*o_putc)(c);
return 1;
}
-
+#endif
void
module_connection()
i_nungetc = i_ungetc; i_ungetc= numchar_ungetc;
}
#endif
+#ifdef UNICODE_NORMALIZATION
+ if (nfc_f && input_f == UTF8_INPUT){
+ i_nfc_getc = i_getc; i_getc = nfc_getc;
+ i_nfc_ungetc = i_ungetc; i_ungetc= nfc_ungetc;
+ }
+#endif
if (mime_f && mimebuf_f==FIXED_MIME) {
i_mgetc = i_getc; i_getc = mime_getc;
i_mungetc = i_ungetc; i_ungetc = mime_ungetc;
input_mode = X0208;
shift_mode = FALSE;
set_input_codename("ISO-2022-JP");
+#ifdef CHECK_OPTION
debug(input_codename);
+#endif
NEXT;
} else if (c1 == '(') {
if ((c1 = (*i_getc)(f)) == EOF) {
int c2, c1;
int *p2, *p1;
{
+#if defined(SHIFTJIS_CP932) || defined(X0212_ENABLE)
int val;
+#endif
#ifdef SHIFTJIS_CP932
if (cp932_f && CP932_TABLE_BEGIN <= c2 && c2 <= CP932_TABLE_END){
extern unsigned short shiftjis_cp932[3][189];
int c2, c1, c0;
int *p2, *p1;
{
- extern unsigned short * utf8_to_euc_2bytes[];
- extern unsigned short ** utf8_to_euc_3bytes[];
+ extern const unsigned short *const utf8_to_euc_2bytes[];
+ extern const unsigned short *const *const utf8_to_euc_3bytes[];
int ret = 0;
if (0xc0 <= c2 && c2 <= 0xef) {
- unsigned short **pp;
+ const unsigned short *const *pp;
if (0xe0 <= c2) {
if (c0 == 0) return -1;
int c2,
c1, c0;
{
- int ret = w2e_conv(c2, c1, c0, &c2, &c1);
+ int ret = 0;
+
+ if (c0 == 0){
+ if (c2 == 0) /* 0x00-0x7f */
+ ; /* 1byte */
+ else if ((c2 & 0xe0) == 0xc0) /* 0xc0-0xdf */
+ ; /* 2ytes */
+ else if ((c2 & 0xf0) == 0xe0) /* 0xe0-0xef */
+ return -1; /* 3bytes */
+#ifdef __COMMENT__
+ else if (0xf0 <= c2)
+ return 0; /* 4,5,6bytes */
+ else if ((c2 & 0xc0) == 0x80) /* 0x80-0xbf */
+ return 0; /* trail byte */
+#endif
+ else return 0;
+ }
+ if (c2 == EOF);
+ else if (c2 == 0xef && c1 == 0xbb && c0 == 0xbf) {
+ return 0; /* throw BOM */
+#if defined(UTF8_OUTPUT_ENABLE) && defined(UTF8_INPUT_ENABLE)
+ } else if (internal_unicode_f && (output_conv == w_oconv || output_conv == w_oconv16)){
+ unsigned short val = 0;
+ if(c2 == 0){
+ c2 = c1;
+ c1 = 0;
+ }
+ val = ww16_conv(c2, c1, c0);
+ c2 = (val >> 8) & 0xff;
+ c1 = val & 0xff;
+#endif
+ } else {
+ ret = w2e_conv(c2, c1, c0, &c2, &c1);
+ }
if (ret == 0){
(*oconv)(c2, c1);
}
unsigned short val;
int *p2, *p1;
{
- extern unsigned short * utf8_to_euc_2bytes[];
- extern unsigned short ** utf8_to_euc_3bytes[];
+ extern const unsigned short *const utf8_to_euc_2bytes[];
+ extern const unsigned short *const *const utf8_to_euc_3bytes[];
int c2, c1, c0;
- unsigned short **pp;
+ const unsigned short *const *pp;
int psize;
int ret = 0;
w_iconv16(c2, c1, c0)
int c2, c1,c0;
{
- int ret;
+ int ret = 0;
if (c2==0376 && c1==0377){
utf16_mode = UTF16BE_INPUT;
(*oconv)(c2, c1);
return 0;
}
- ret = w16e_conv(((c2<<8)&0xff00) + c1, &c2, &c1);
+#if defined(UTF8_OUTPUT_ENABLE) && defined(UTF8_INPUT_ENABLE)
+ if (internal_unicode_f && (output_conv == w_oconv || output_conv == w_oconv16));
+#endif
+ else ret = w16e_conv(((c2<<8)&0xff00) + c1, &c2, &c1);
if (ret) return ret;
(*oconv)(c2, c1);
return 0;
int
w_iconv_common(c1, c0, pp, psize, p2, p1)
int c1,c0;
- unsigned short **pp;
+ const unsigned short *const *pp;
int psize;
int *p2, *p1;
{
int c2;
- unsigned short *p ;
+ const unsigned short *p;
unsigned short val;
if (pp == 0) return 1;
e2w_conv(c2, c1)
int c2, c1;
{
- extern unsigned short euc_to_utf8_1byte[];
- extern unsigned short * euc_to_utf8_2bytes[];
- extern unsigned short * euc_to_utf8_2bytes_ms[];
- unsigned short *p;
+ extern const unsigned short euc_to_utf8_1byte[];
+ extern const unsigned short *const euc_to_utf8_2bytes[];
+ extern const unsigned short *const euc_to_utf8_2bytes_ms[];
+ const unsigned short *p;
if (c2 == X0201) {
p = euc_to_utf8_1byte;
#ifdef X0212_ENABLE
} else if (c2 >> 8 == 0x8f){
- extern unsigned short * x0212_to_utf8_2bytes[];
+ extern const unsigned short *const x0212_to_utf8_2bytes[];
c2 = (c2&0x7f) - 0x21;
if (0<=c2 && c2<sizeof_euc_to_utf8_2bytes)
p = x0212_to_utf8_2bytes[c2];
c1;
{
int c0;
+ unsigned short val;
if (c2 == EOF) {
(*o_putc)(EOF);
return;
output_mode = ISO8859_1;
(*o_putc)(c1 | 0x080);
} else {
- unsigned short val;
output_mode = UTF8;
- val = e2w_conv(c2, c1);
+ if (internal_unicode_f && (iconv == w_iconv || iconv == w_iconv16))
+ val = ((c2<<8)&0xff00) + c1;
+ else val = e2w_conv(c2, c1);
if (val){
w16w_conv(val, &c2, &c1, &c0);
(*o_putc)(c2);
unicode_bom_f=1;
}
- if (c2 == ISO8859_1) {
+ if (internal_unicode_f && (iconv == w_iconv || iconv == w_iconv16)){
+ } else if (c2 == ISO8859_1) {
c2 = 0;
c1 |= 0x80;
#ifdef NUMCHAR_OPTION
e2s_conv(c2, c1, p2, p1)
int c2, c1, *p2, *p1;
{
+#ifdef X0212_ENABLE
int val = 0;
- unsigned short *ptr;
+ const unsigned short *ptr;
int ndx;
- extern unsigned short *x0212_shiftjis[];
-#ifdef X0212_ENABLE
+ extern const unsigned short *const x0212_shiftjis[];
if ((c2 & 0xff00) == 0x8f00){
ndx = c2 & 0x7f;
if (0x21 <= ndx && ndx <= 0x7e){
#ifdef SHIFTJIS_CP932
if (cp932inv_f
&& CP932INV_TABLE_BEGIN <= c2 && c2 <= CP932INV_TABLE_END){
- extern unsigned short cp932inv[2][189];
+ extern const unsigned short cp932inv[2][189];
int c = cp932inv[c2 - CP932INV_TABLE_BEGIN][c1 - 0x40];
if (c){
c2 = c >> 8;
}
-static int broken_buf[3];
-static int broken_counter = 0;
-static int broken_last = 0;
+STATIC int broken_buf[3];
+STATIC int broken_counter = 0;
+STATIC int broken_last = 0;
int
broken_getc(f)
FILE *f;
return c;
}
-static int prev_cr = 0;
+STATIC int prev_cr = 0;
void
cr_conv(c2,c1)
iso2022jp_check_conv(c2,c1)
int c2, c1;
{
- static int range[RANGE_NUM_MAX][2] = {
+ STATIC const int range[RANGE_NUM_MAX][2] = {
{0x222f, 0x2239,},
{0x2242, 0x2249,},
{0x2251, 0x225b,},
/* This converts =?ISO-2022-JP?B?HOGE HOGE?= */
-unsigned char *mime_pattern[] = {
- (unsigned char *)"\075?EUC-JP?B?",
- (unsigned char *)"\075?SHIFT_JIS?B?",
- (unsigned char *)"\075?ISO-8859-1?Q?",
- (unsigned char *)"\075?ISO-8859-1?B?",
- (unsigned char *)"\075?ISO-2022-JP?B?",
- (unsigned char *)"\075?ISO-2022-JP?Q?",
+const unsigned char *mime_pattern[] = {
+ (const unsigned char *)"\075?EUC-JP?B?",
+ (const unsigned char *)"\075?SHIFT_JIS?B?",
+ (const unsigned char *)"\075?ISO-8859-1?Q?",
+ (const unsigned char *)"\075?ISO-8859-1?B?",
+ (const unsigned char *)"\075?ISO-2022-JP?B?",
+ (const unsigned char *)"\075?ISO-2022-JP?Q?",
#if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
- (unsigned char *)"\075?UTF-8?B?",
- (unsigned char *)"\075?UTF-8?Q?",
+ (const unsigned char *)"\075?UTF-8?B?",
+ (const unsigned char *)"\075?UTF-8?Q?",
#endif
- (unsigned char *)"\075?US-ASCII?Q?",
- NULL
+ (const unsigned char *)"\075?US-ASCII?Q?",
+ NULL
};
0,
};
-int mime_encode[] = {
+const int mime_encode[] = {
JAPANESE_EUC, SHIFT_JIS,ISO8859_1, ISO8859_1, X0208, X0201,
#if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
UTF8, UTF8,
0
};
-int mime_encode_method[] = {
+const int mime_encode_method[] = {
'B', 'B','Q', 'B', 'B', 'Q',
#if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
'B', 'Q',
}
i_getc = i_mgetc;
i_ungetc = i_mungetc;
+ if(mime_iconv_back)set_iconv(FALSE, mime_iconv_back);
+ mime_iconv_back = NULL;
}
int
{
int c1 = 0;
int i,j,k;
- unsigned char *p,*q;
+ const unsigned char *p,*q;
int r[MAXRECOVER]; /* recovery buffer, max mime pattern lenght */
mime_decode_mode = FALSE;
}
mime_decode_mode = p[i-2];
+ mime_iconv_back = iconv;
set_iconv(FALSE, mime_priority_func[j]);
clr_code_score(find_inputcode_byfunc(mime_priority_func[j]), SCORE_iMIME);
}
void debug(str)
- char *str;
+ const char *str;
{
if (debug_f){
fprintf(stderr, "%s\n", str);
is_inputcode_set = TRUE;
}
-#ifndef WIN32DLL
+#if !defined(PERL_XS) && !defined(WIN32DLL)
void
print_guessed_code (filename)
char *filename;
}
#endif
+#ifdef UNICODE_NORMALIZATION
+
+/* Normalization Form C */
+int
+nfc_getc(f)
+ FILE *f;
+{
+ int (*g)() = i_nfc_getc;
+ int (*u)() = i_nfc_ungetc;
+ int i=0, j, k=1, lower, upper;
+ int buf[9];
+ const int *array = NULL;
+ extern const struct normalization_pair normalization_table[];
+
+ buf[i] = (*g)(f);
+ while (k > 0 && ((buf[i] & 0xc0) != 0x80)){
+ lower=0, upper=NORMALIZATION_TABLE_LENGTH-1;
+ while (upper >= lower) {
+ j = (lower+upper) / 2;
+ array = normalization_table[j].nfd;
+ for (k=0; k < NORMALIZATION_TABLE_NFD_LENGTH && array[k]; k++){
+ if (array[k] != buf[k]){
+ array[k] < buf[k] ? (lower = j + 1) : (upper = j - 1);
+ k = 0;
+ break;
+ } else if (k >= i)
+ buf[++i] = (*g)(f);
+ }
+ if (k > 0){
+ array = normalization_table[j].nfc;
+ for (i=0; i < NORMALIZATION_TABLE_NFC_LENGTH && array[i]; i++)
+ buf[i] = array[i];
+ i--;
+ break;
+ }
+ }
+ while (i > 0)
+ (*u)(buf[i--], f);
+ }
+ return buf[0];
+}
+
+int
+nfc_ungetc(c, f)
+ int c;
+ FILE *f;
+{
+ return (*i_nfc_ungetc)(c, f);
+}
+#endif /* UNICODE_NORMALIZATION */
+
int
mime_getc(f)
if ((c1 = (*i_mgetc)(f)) == EOF) return (EOF);
restart_mime_q:
if (c1=='_') return ' ';
+ if (c1<=' ' || DEL<=c1) {
+ mime_decode_mode = exit_mode; /* prepare for quit */
+ return c1;
+ }
if (c1!='=' && c1!='?') {
return c1;
}
mime_decode_mode = exit_mode; /* prepare for quit */
- if (c1<=' ') return c1;
if ((c2 = (*i_mgetc)(f)) == EOF) return (EOF);
if (c1=='?'&&c2=='=' && mimebuf_f != FIXED_MIME) {
/* end Q encoding */
int
mime_integrity(f,p)
-FILE *f;
-unsigned char *p;
+ FILE *f;
+ const unsigned char *p;
{
int c,d;
unsigned int q;
*/
mime_input = mime_top;
mime_last = mime_top;
+
while(*p) Fifo(mime_input++) = *p++;
d = 0;
q = mime_input;
return (i);
}
-static char basis_64[] =
+STATIC const char basis_64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-static int b64c;
+STATIC int b64c;
#define MIMEOUT_BUF_LENGTH (60)
char mimeout_buf[MIMEOUT_BUF_LENGTH+1];
int mimeout_buf_count = 0;
open_mime(mode)
int mode;
{
- unsigned char *p;
+ const unsigned char *p;
int i;
int j;
p = mime_pattern[0];
x0201_f = NO_X0201;
#endif
iso2022jp_f = FALSE;
+#if defined(UTF8_OUTPUT_ENABLE) && defined(UTF8_INPUT_ENABLE)
+ internal_unicode_f = FALSE;
+#endif
#ifdef UTF8_OUTPUT_ENABLE
unicode_bom_f = 0;
w_oconv16_LE = 0;
ms_ucs_map_f = FALSE;
#endif
+#ifdef UNICODE_NORMALIZATION
+ nfc_f = FALSE;
+#endif
#ifdef INPUT_OPTION
cap_f = FALSE;
url_f = FALSE;
fprintf(stderr,"Flags:\n");
fprintf(stderr,"b,u Output is buffered (DEFAULT),Output is unbuffered\n");
#ifdef DEFAULT_CODE_SJIS
- fprintf(stderr,"j,s,e,w Outout code is JIS 7 bit, Shift JIS (DEFAULT), AT&T JIS (EUC), UTF-8\n");
+ fprintf(stderr,"j,s,e,w Outout code is JIS 7 bit, Shift JIS (DEFAULT), AT&T JIS (EUC), UTF-8N\n");
#endif
#ifdef DEFAULT_CODE_JIS
- fprintf(stderr,"j,s,e,w Outout code is JIS 7 bit (DEFAULT), Shift JIS, AT&T JIS (EUC), UTF-8\n");
+ fprintf(stderr,"j,s,e,w Outout code is JIS 7 bit (DEFAULT), Shift JIS, AT&T JIS (EUC), UTF-8N\n");
#endif
#ifdef DEFAULT_CODE_EUC
- fprintf(stderr,"j,s,e,w Outout code is JIS 7 bit, Shift JIS, AT&T JIS (EUC) (DEFAULT), UTF-8\n");
+ fprintf(stderr,"j,s,e,w Outout code is JIS 7 bit, Shift JIS, AT&T JIS (EUC) (DEFAULT), UTF-8N\n");
#endif
#ifdef DEFAULT_CODE_UTF8
- fprintf(stderr,"j,s,e,w Outout code is JIS 7 bit, Shift JIS, AT&T JIS (EUC), UTF-8 (DEFAULT)\n");
+ fprintf(stderr,"j,s,e,w Outout code is JIS 7 bit, Shift JIS, AT&T JIS (EUC), UTF-8N (DEFAULT)\n");
#endif
#ifdef UTF8_OUTPUT_ENABLE
fprintf(stderr," After 'w' you can add more options. (80?|16((B|L)0?)?) \n");
#ifdef NUMCHAR_OPTION
fprintf(stderr," --numchar-input Convert Unicode Character Reference\n");
#endif
+#ifdef UNICODE_NORMALIZATION
+ fprintf(stderr," --utf8mac-input UTF-8-MAC input\n");
+#endif
#ifdef UTF8_OUTPUT_ENABLE
fprintf(stderr," --ms-ucs-map Microsoft UCS Mapping Compatible\n");
#endif