OSDN Git Service

* fix some errors.
[nkf/nkf.git] / nkf.c
diff --git a/nkf.c b/nkf.c
index 571be39..505d192 100644 (file)
--- a/nkf.c
+++ b/nkf.c
@@ -30,9 +30,9 @@
  * \e$B8=:_!"\e(Bnkf \e$B$O\e(B SorceForge \e$B$K$F%a%s%F%J%s%9$,B3$1$i$l$F$$$^$9!#\e(B
  * http://sourceforge.jp/projects/nkf/
 ***********************************************************************/
-/* $Id: nkf.c,v 1.156 2007/12/19 08:57:58 naruse Exp $ */
+/* $Id: nkf.c,v 1.159 2007/12/23 07:55:20 naruse Exp $ */
 #define NKF_VERSION "2.0.8"
-#define NKF_RELEASE_DATE "2007-12-19"
+#define NKF_RELEASE_DATE "2007-12-22"
 #define COPY_RIGHT \
     "Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa),2000 S. Kono, COW\n" \
     "Copyright (C) 2002-2007 Kono, Furukawa, Naruse, mastodon"
 #define PUT_NEWLINE(func) func(0x0A)
 #define OCONV_NEWLINE(func) func(0, 0x0A)
 #endif
+#ifdef HELP_OUTPUT_STDERR
+#define HELP_OUTPUT stderr
+#else
+#define HELP_OUTPUT stdout
+#endif
 
 #if (defined(__TURBOC__) || defined(_MSC_VER) || defined(LSI_C) || defined(__MINGW32__) || defined(__EMX__) || defined(__MSDOS__) || defined(__WINDOWS__) || defined(__DOS__) || defined(__OS2__)) && !defined(MSDOS)
 #define MSDOS
@@ -228,8 +233,6 @@ void  djgpp_setbinmode(FILE *fp)
 
 enum nkf_encodings {
     ASCII,
-    JIS_X_0208,
-    JIS_X_0201,
     ISO_8859_1,
     ISO_2022_JP,
     CP50220,
@@ -262,52 +265,84 @@ enum nkf_encodings {
     UTF_32BE_BOM,
     UTF_32LE,
     UTF_32LE_BOM,
-    JIS_X_0212=0x2844,
-    JIS_X_0213_1=0x284F,
-    JIS_X_0213_2=0x2850,
+    JIS_X_0201=0x1000,
+    JIS_X_0208,
+    JIS_X_0212,
+    JIS_X_0213_1,
+    JIS_X_0213_2,
     BINARY
 };
-static const struct {
-    const int id;
-    const char *name;
-} encoding_id_to_name_table[] = {
-    {ASCII,            "ASCII"},
-    {ISO_8859_1,       "ISO-8859-1"},
-    {ISO_2022_JP,      "ISO-2022-JP"},
-    {CP50220,          "CP50220"},
-    {CP50221,          "CP50221"},
-    {CP50222,          "CP50222"},
-    {ISO_2022_JP_1,    "ISO-2022-JP-1"},
-    {ISO_2022_JP_3,    "ISO-2022-JP-3"},
-    {SHIFT_JIS,                "Shift_JIS"},
-    {WINDOWS_31J,      "WINDOWS-31J"},
-    {CP10001,          "CP10001"},
-    {EUC_JP,           "EUC-JP"},
-    {CP51932,          "CP51932"},
-    {EUCJP_MS,         "eucJP-MS"},
-    {EUCJP_ASCII,      "eucJP-ASCII"},
-    {SHIFT_JISX0213,   "Shift_JISX0213"},
-    {SHIFT_JIS_2004,   "Shift_JIS-2004"},
-    {EUC_JISX0213,     "EUC-JISX0213"},
-    {EUC_JIS_2004,     "EUC-JIS-2004"},
-    {UTF_8,            "UTF-8"},
-    {UTF_8N,           "UTF-8N"},
-    {UTF_8_BOM,                "UTF-8-BOM"},
-    {UTF8_MAC,         "UTF8-MAC"},
-    {UTF_16,           "UTF-16"},
-    {UTF_16BE,         "UTF-16BE"},
-    {UTF_16BE_BOM,     "UTF-16BE-BOM"},
-    {UTF_16LE,         "UTF-16LE"},
-    {UTF_16LE_BOM,     "UTF-16LE-BOM"},
-    {UTF_32,           "UTF-32"},
-    {UTF_32BE,         "UTF-32BE"},
-    {UTF_32BE_BOM,     "UTF-32BE-BOM"},
-    {UTF_32LE,         "UTF-32LE"},
-    {UTF_32LE_BOM,     "UTF-32LE-BOM"},
-    {BINARY,           "BINARY"},
-    {-1,                       ""}
+
+nkf_char s_iconv(nkf_char c2, nkf_char c1, nkf_char c0);
+nkf_char e_iconv(nkf_char c2, nkf_char c1, nkf_char c0);
+nkf_char w_iconv(nkf_char c2, nkf_char c1, nkf_char c0);
+nkf_char w_iconv16(nkf_char c2, nkf_char c1, nkf_char c0);
+nkf_char w_iconv32(nkf_char c2, nkf_char c1, nkf_char c0);
+void j_oconv(nkf_char c2, nkf_char c1);
+void s_oconv(nkf_char c2, nkf_char c1);
+void e_oconv(nkf_char c2, nkf_char c1);
+void w_oconv(nkf_char c2, nkf_char c1);
+void w_oconv16(nkf_char c2, nkf_char c1);
+void w_oconv32(nkf_char c2, nkf_char c1);
+
+typedef struct {
+    char *name;
+    nkf_char (*iconv_func)(nkf_char c2, nkf_char c1, nkf_char c0);
+    void (*oconv_func)(nkf_char c2, nkf_char c1);
+} nkf_native_encoding;
+
+nkf_native_encoding NkfEncodingASCII =         { "US_ASCII", e_iconv, e_oconv };
+nkf_native_encoding NkfEncodingISO_2022_JP =   { "ISO-2022-JP", e_iconv, j_oconv };
+nkf_native_encoding NkfEncodingShift_JIS =     { "Shift_JIS", s_iconv, s_oconv };
+nkf_native_encoding NkfEncodingEUC_JP =                { "EUC-JP", e_iconv, e_oconv };
+nkf_native_encoding NkfEncodingUTF_8 =         { "UTF-8", w_iconv, w_oconv };
+nkf_native_encoding NkfEncodingUTF_16 =                { "UTF-16", w_iconv16, w_oconv16 };
+nkf_native_encoding NkfEncodingUTF_32 =                { "UTF-32", w_iconv32, w_oconv32 };
+
+typedef struct {
+    int id;
+    char *name;
+    nkf_native_encoding *based_encoding;
+} nkf_encoding;
+nkf_encoding nkf_encoding_table[] = {
+    {ASCII,            "ASCII",                &NkfEncodingASCII},
+    {ISO_8859_1,       "ISO-8859-1",           &NkfEncodingASCII},
+    {ISO_2022_JP,      "ISO-2022-JP",          &NkfEncodingASCII},
+    {CP50220,          "CP50220",              &NkfEncodingISO_2022_JP},
+    {CP50221,          "CP50221",              &NkfEncodingISO_2022_JP},
+    {CP50222,          "CP50222",              &NkfEncodingISO_2022_JP},
+    {ISO_2022_JP_1,    "ISO-2022-JP-1",        &NkfEncodingISO_2022_JP},
+    {ISO_2022_JP_3,    "ISO-2022-JP-3",        &NkfEncodingISO_2022_JP},
+    {SHIFT_JIS,                "Shift_JIS",            &NkfEncodingShift_JIS},
+    {WINDOWS_31J,      "WINDOWS-31J",          &NkfEncodingShift_JIS},
+    {CP10001,          "CP10001",              &NkfEncodingShift_JIS},
+    {EUC_JP,           "EUC-JP",               &NkfEncodingEUC_JP},
+    {CP51932,          "CP51932",              &NkfEncodingEUC_JP},
+    {EUCJP_MS,         "eucJP-MS",             &NkfEncodingEUC_JP},
+    {EUCJP_ASCII,      "eucJP-ASCII",          &NkfEncodingEUC_JP},
+    {SHIFT_JISX0213,   "Shift_JISX0213",       &NkfEncodingShift_JIS},
+    {SHIFT_JIS_2004,   "Shift_JIS-2004",       &NkfEncodingShift_JIS},
+    {EUC_JISX0213,     "EUC-JISX0213",         &NkfEncodingEUC_JP},
+    {EUC_JIS_2004,     "EUC-JIS-2004",         &NkfEncodingEUC_JP},
+    {UTF_8,            "UTF-8",                &NkfEncodingUTF_8},
+    {UTF_8N,           "UTF-8N",               &NkfEncodingUTF_8},
+    {UTF_8_BOM,                "UTF-8-BOM",            &NkfEncodingUTF_8},
+    {UTF8_MAC,         "UTF8-MAC",             &NkfEncodingUTF_8},
+    {UTF_16,           "UTF-16",               &NkfEncodingUTF_16},
+    {UTF_16BE,         "UTF-16BE",             &NkfEncodingUTF_16},
+    {UTF_16BE_BOM,     "UTF-16BE-BOM",         &NkfEncodingUTF_16},
+    {UTF_16LE,         "UTF-16LE",             &NkfEncodingUTF_16},
+    {UTF_16LE_BOM,     "UTF-16LE-BOM",         &NkfEncodingUTF_16},
+    {UTF_32,           "UTF-32",               &NkfEncodingUTF_32},
+    {UTF_32BE,         "UTF-32BE",             &NkfEncodingUTF_32},
+    {UTF_32BE_BOM,     "UTF-32BE-BOM",         &NkfEncodingUTF_32},
+    {UTF_32LE,         "UTF-32LE",             &NkfEncodingUTF_32},
+    {UTF_32LE_BOM,     "UTF-32LE-BOM",         &NkfEncodingUTF_32},
+    {BINARY,           "BINARY",               &NkfEncodingASCII},
+    {-1,               NULL,                   NULL}
 };
-static const struct {
+#define NKF_ENCODING_TABLE_SIZE 34
+struct {
     const char *name;
     const int id;
 } encoding_name_to_id_table[] = {
@@ -354,7 +389,7 @@ static const struct {
     {"UTF-32LE",               UTF_32LE},
     {"UTF-32LE-BOM",           UTF_32LE_BOM},
     {"BINARY",                 BINARY},
-    {"",                       -1}
+    {NULL,                     -1}
 };
 #if defined(DEFAULT_CODE_JIS)
 #define            DEFAULT_ENCODING ISO_2022_JP
@@ -441,7 +476,7 @@ struct input_code{
 };
 
 static char *input_codename = NULL; /* NULL: unestablished, "": BINARY */
-static int output_encoding = DEFAULT_ENCODING;
+static nkf_encoding *output_encoding;
 
 #if !defined(PERL_XS) && !defined(WIN32DLL)
 static  nkf_char     noconvert(FILE *f);
@@ -451,9 +486,7 @@ static  nkf_char     kanji_convert(FILE *f);
 static  nkf_char     h_conv(FILE *f,nkf_char c2,nkf_char c1);
 static  nkf_char     push_hold_buf(nkf_char c2);
 static  void    set_iconv(nkf_char f, nkf_char (*iconv_func)(nkf_char c2,nkf_char c1,nkf_char c0));
-static  nkf_char     s_iconv(nkf_char c2,nkf_char c1,nkf_char c0);
 static  nkf_char     s2e_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1);
-static  nkf_char     e_iconv(nkf_char c2,nkf_char c1,nkf_char c0);
 #if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
 /* UCS Mapping
  * 0: Shift_JIS, eucJP-ascii
@@ -482,9 +515,6 @@ static  void    encode_fallback_perl(nkf_char c);
 static  void    encode_fallback_subchar(nkf_char c);
 static  void    (*encode_fallback)(nkf_char c) = NULL;
 static  nkf_char     w2e_conv(nkf_char c2,nkf_char c1,nkf_char c0,nkf_char *p2,nkf_char *p1);
-static  nkf_char     w_iconv(nkf_char c2,nkf_char c1,nkf_char c0);
-static  nkf_char     w_iconv16(nkf_char c2,nkf_char c1,nkf_char c0);
-static  nkf_char     w_iconv32(nkf_char c2,nkf_char c1,nkf_char c0);
 static  nkf_char       unicode_to_jis_common(nkf_char c2,nkf_char c1,nkf_char c0,nkf_char *p2,nkf_char *p1);
 static  nkf_char       w_iconv_common(nkf_char c1,nkf_char c0,const unsigned short *const *pp,nkf_char psize,nkf_char *p2,nkf_char *p1);
 static  void    w16w_conv(nkf_char val, nkf_char *p2, nkf_char *p1, nkf_char *p0);
@@ -496,14 +526,8 @@ static  void    w_status(struct input_code *, nkf_char);
 static  int     output_bom_f = FALSE;
 static  int     output_endian = ENDIAN_BIG;
 static  nkf_char     e2w_conv(nkf_char c2,nkf_char c1);
-static  void    w_oconv(nkf_char c2,nkf_char c1);
-static  void    w_oconv16(nkf_char c2,nkf_char c1);
-static  void    w_oconv32(nkf_char c2,nkf_char c1);
 #endif
-static  void    e_oconv(nkf_char c2,nkf_char c1);
 static  nkf_char     e2s_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1);
-static  void    s_oconv(nkf_char c2,nkf_char c1);
-static  void    j_oconv(nkf_char c2,nkf_char c1);
 static  void    fold_conv(nkf_char c2,nkf_char c1);
 static  void    nl_conv(nkf_char c2,nkf_char c1);
 static  void    z_conv(nkf_char c2,nkf_char c1);
@@ -886,13 +910,21 @@ char* nkf_strcpy(const char *str)
     return result;
 }
 
-static void nkf_str_upcase(const char *str, char *res, size_t length)
+static void nkf_str_upcase(const char *src, char *dest, size_t length)
 {
     int i = 0;
-    for (; i < length && str[i]; i++) {
-       res[i] = nkf_toupper(str[i]);
+    for (; i < length && dest[i]; i++) {
+       dest[i] = nkf_toupper(src[i]);
     }
-    res[i] = 0;
+    dest[i] = 0;
+}
+
+static nkf_encoding *nkf_enc_from_index(int idx)
+{
+    if (idx < 0 || NKF_ENCODING_TABLE_SIZE <= idx) {
+       return 0;
+    }
+    return &nkf_encoding_table[idx];
 }
 
 static int nkf_enc_find_index(const char *name)
@@ -906,19 +938,17 @@ static int nkf_enc_find_index(const char *name)
     return index;
 }
 
-#if defined(PERL_XS) || defined(WIN32DLL)
-static char* nkf_enc_name(const int index)
+static nkf_encoding *nkf_enc_find(const char *name)
 {
-    int i;
-    const char* name = "ASCII";
-    for (i = 0; encoding_id_to_name_table[i].id >= 0; i++) {
-       if (encoding_id_to_name_table[i].id == index) {
-           return nkf_strcpy(encoding_id_to_name_table[i].name);
-       }
-    }
-    return nkf_strcpy(name);
+    int idx = -1;
+    idx = nkf_enc_find_index(name);
+    if (idx < 0) return 0;
+    return nkf_enc_from_index(idx);
 }
-#endif
+
+#define nkf_enc_name(enc) (enc)->name
+#define nkf_enc_to_index(enc) (enc)->id
+#define nkf_enc_to_base_encoding(enc) (enc)->based_encoding
 
 #ifdef WIN32DLL
 #include "nkf32dll.c"
@@ -1031,8 +1061,7 @@ int main(int argc, char **argv)
            iconv_for_check = 0;
 #endif
           if ((fin = fopen((origfname = *argv++), "r")) == NULL) {
-              perror(*--argv);
-               *argv++;
+               perror(*(argv-1));
                is_argument_error = TRUE;
                continue;
           } else {
@@ -1327,6 +1356,7 @@ void options(unsigned char *cp)
     unsigned char *p;
     unsigned char *cp_back = NULL;
     char codeset[32];
+    nkf_encoding *enc;
 
     if (option_mode==1)
        return;
@@ -1363,9 +1393,9 @@ void options(unsigned char *cp)
                cp = (unsigned char *)long_option[i].alias;
            }else{
                 if (strcmp(long_option[i].name, "ic=") == 0){
-                   nkf_str_upcase(p, codeset, 32);
-                   i = nkf_enc_find_index(codeset);
-                   switch (i) {
+                   nkf_str_upcase((char *)p, codeset, 32);
+                   enc = nkf_enc_find(codeset);
+                   switch (nkf_enc_to_index(enc)) {
                    case ISO_2022_JP:
                        input_f = JIS_INPUT;
                        break;
@@ -1502,10 +1532,10 @@ void options(unsigned char *cp)
                     continue;
                }
                 if (strcmp(long_option[i].name, "oc=") == 0){
-                   nkf_str_upcase(p, codeset, 32);
-                   output_encoding = nkf_enc_find_index(codeset);
                    x0201_f = FALSE;
-                   switch (output_encoding) {
+                   nkf_str_upcase((char *)p, codeset, 32);
+                   output_encoding = nkf_enc_find(codeset);
+                   switch (nkf_enc_to_index(output_encoding)) {
                    case ISO_2022_JP:
                        output_conv = j_oconv;
                        break;
@@ -1864,7 +1894,7 @@ void options(unsigned char *cp)
             if (*cp=='1') {
                /* alias of -t */
                nop_f = TRUE;
-               *cp++;
+               *cp += 1;
            } else if (*cp=='2') {
                /*
                 * -t with put/get
@@ -1873,23 +1903,23 @@ void options(unsigned char *cp)
                 *
                 */
                nop_f = 2;
-               *cp++;
+               *cp += 1;
             } else
                nop_f = TRUE;
             continue;
         case 'j':           /* JIS output */
         case 'n':
             output_conv = j_oconv;
-            output_encoding = ISO_2022_JP;
+            output_encoding = nkf_enc_from_index(ISO_2022_JP);
             continue;
         case 'e':           /* AT&T EUC output */
             output_conv = e_oconv;
             cp932inv_f = FALSE;
-            output_encoding = EUC_JP;
+            output_encoding = nkf_enc_from_index(EUC_JP);
             continue;
         case 's':           /* SJIS output */
             output_conv = s_oconv;
-            output_encoding = SHIFT_JIS;
+            output_encoding = nkf_enc_from_index(SHIFT_JIS);
             continue;
         case 'l':           /* ISO8859 Latin-1 support, no conversion */
             iso8859_f = TRUE;  /* Only compatible with ISO-2022-JP */
@@ -1937,21 +1967,22 @@ void options(unsigned char *cp)
                output_conv = w_oconv; cp++;
                if (cp[0] == '0'){
                    cp++;
-                   output_encoding = UTF_8N;
+                   output_encoding = nkf_enc_from_index(UTF_8N);
                } else {
                    output_bom_f = TRUE;
-                   output_encoding = UTF_8_BOM;
+                   output_encoding = nkf_enc_from_index(UTF_8_BOM);
                }
            } else {
+               int enc_idx;
                if ('1'== cp[0] && '6'==cp[1]) {
                    output_conv = w_oconv16; cp+=2;
-                   output_encoding = UTF_16;
+                   enc_idx = UTF_16;
                } else if ('3'== cp[0] && '2'==cp[1]) {
                    output_conv = w_oconv32; cp+=2;
-                   output_encoding = UTF_32;
+                   enc_idx = UTF_32;
                } else {
                    output_conv = w_oconv;
-                   output_encoding = UTF_8;
+                   output_encoding = nkf_enc_from_index(UTF_8);
                    continue;
                }
                if (cp[0]=='L') {
@@ -1960,19 +1991,21 @@ void options(unsigned char *cp)
                } else if (cp[0] == 'B') {
                    cp++;
                 } else {
+                   output_encoding = nkf_enc_from_index(enc_idx);
                    continue;
                 }
                if (cp[0] == '0'){
                    cp++;
-                   output_encoding = output_encoding == UTF_16
+                   enc_idx = enc_idx == UTF_16
                        ? (output_endian == ENDIAN_LITTLE ? UTF_16LE : UTF_16BE)
                        : (output_endian == ENDIAN_LITTLE ? UTF_32LE : UTF_32BE);
                } else {
                    output_bom_f = TRUE;
-                   output_encoding = output_encoding == UTF_16
+                   enc_idx = enc_idx == UTF_16
                        ? (output_endian == ENDIAN_LITTLE ? UTF_16LE_BOM : UTF_16BE_BOM)
                        : (output_endian == ENDIAN_LITTLE ? UTF_32LE_BOM : UTF_32BE_BOM);
                }
+               output_encoding = nkf_enc_from_index(enc_idx);
            }
             continue;
 #endif
@@ -3028,11 +3061,11 @@ nkf_char kanji_convert(FILE *f)
                             shift_mode = FALSE;
                             NEXT;
 #endif /* X0212_ENABLE */
-                        } else if (c1 == (JIS_X_0213_1&0x7F)){
+                        } else if (c1 == 0x4F){
                             input_mode = JIS_X_0213_1;
                             shift_mode = FALSE;
                             NEXT;
-                        } else if (c1 == (JIS_X_0213_2&0x7F)){
+                        } else if (c1 == 0x50){
                             input_mode = JIS_X_0213_2;
                             shift_mode = FALSE;
                             NEXT;
@@ -4469,7 +4502,7 @@ void j_oconv(nkf_char c2, nkf_char c1)
                (*o_putc)(ESC);
                (*o_putc)('$');
                (*o_putc)('(');
-               (*o_putc)(JIS_X_0213_2&0x7F);
+               (*o_putc)(0x50);
            }
        }else{
            if(output_mode!=JIS_X_0212){
@@ -4477,7 +4510,7 @@ void j_oconv(nkf_char c2, nkf_char c1)
                (*o_putc)(ESC);
                (*o_putc)('$');
                (*o_putc)('(');
-               (*o_putc)(JIS_X_0212&0x7F);
+               (*o_putc)(0x44);
            }
         }
         (*o_putc)(c2 & 0x7f);
@@ -4515,7 +4548,7 @@ void j_oconv(nkf_char c2, nkf_char c1)
                (*o_putc)(ESC);
                (*o_putc)('$');
                (*o_putc)('(');
-               (*o_putc)(JIS_X_0213_1&0x7F);
+               (*o_putc)(0x4F);
            }
        }else if (output_mode != JIS_X_0208) {
             output_mode = JIS_X_0208;
@@ -6317,7 +6350,7 @@ void reinit(void)
     iconv_for_check = 0;
 #endif
     input_codename = NULL;
-    output_encoding = DEFAULT_ENCODING;
+    output_encoding = nkf_enc_from_index(DEFAULT_ENCODING);
 #ifdef WIN32DLL
     reinitdll();
 #endif /*WIN32DLL*/
@@ -6341,87 +6374,87 @@ nkf_char no_connection2(nkf_char c2, nkf_char c1, nkf_char c0)
 #endif
 void usage(void)
 {
-    fprintf(stderr,"USAGE:  nkf(nkf32,wnkf,nkf2) -[flags] [in file] .. [out file for -O flag]\n");
-    fprintf(stderr,"Flags:\n");
-    fprintf(stderr,"b,u      Output is buffered (DEFAULT),Output is unbuffered\n");
+    fprintf(HELP_OUTPUT,"USAGE:  nkf(nkf32,wnkf,nkf2) -[flags] [in file] .. [out file for -O flag]\n");
+    fprintf(HELP_OUTPUT,"Flags:\n");
+    fprintf(HELP_OUTPUT,"b,u      Output is buffered (DEFAULT),Output is unbuffered\n");
 #ifdef DEFAULT_CODE_SJIS
-    fprintf(stderr,"j,s,e,w  Output code is JIS 7 bit, Shift_JIS (DEFAULT), EUC-JP, UTF-8N\n");
+    fprintf(HELP_OUTPUT,"j,s,e,w  Output code is JIS 7 bit, Shift_JIS (DEFAULT), EUC-JP, UTF-8N\n");
 #endif
 #ifdef DEFAULT_CODE_JIS
-    fprintf(stderr,"j,s,e,w  Output code is JIS 7 bit (DEFAULT), Shift JIS, EUC-JP, UTF-8N\n");
+    fprintf(HELP_OUTPUT,"j,s,e,w  Output code is JIS 7 bit (DEFAULT), Shift JIS, EUC-JP, UTF-8N\n");
 #endif
 #ifdef DEFAULT_CODE_EUC
-    fprintf(stderr,"j,s,e,w  Output code is JIS 7 bit, Shift JIS, EUC-JP (DEFAULT), UTF-8N\n");
+    fprintf(HELP_OUTPUT,"j,s,e,w  Output code is JIS 7 bit, Shift JIS, EUC-JP (DEFAULT), UTF-8N\n");
 #endif
 #ifdef DEFAULT_CODE_UTF8
-    fprintf(stderr,"j,s,e,w  Output code is JIS 7 bit, Shift JIS, EUC-JP, UTF-8N (DEFAULT)\n");
+    fprintf(HELP_OUTPUT,"j,s,e,w  Output code is JIS 7 bit, Shift JIS, EUC-JP, UTF-8N (DEFAULT)\n");
 #endif
 #ifdef UTF8_OUTPUT_ENABLE
-    fprintf(stderr,"         After 'w' you can add more options. -w[ 8 [0], 16 [[BL] [0]] ]\n");
+    fprintf(HELP_OUTPUT,"         After 'w' you can add more options. -w[ 8 [0], 16 [[BL] [0]] ]\n");
 #endif
-    fprintf(stderr,"J,S,E,W  Input assumption is JIS 7 bit , Shift JIS, EUC-JP, UTF-8\n");
+    fprintf(HELP_OUTPUT,"J,S,E,W  Input assumption is JIS 7 bit , Shift JIS, EUC-JP, UTF-8\n");
 #ifdef UTF8_INPUT_ENABLE
-    fprintf(stderr,"         After 'W' you can add more options. -W[ 8, 16 [BL] ] \n");
-#endif
-    fprintf(stderr,"t        no conversion\n");
-    fprintf(stderr,"i[@B]    Specify the Esc Seq for JIS X 0208-1978/83 (DEFAULT B)\n");
-    fprintf(stderr,"o[BJH]   Specify the Esc Seq for ASCII/Roman        (DEFAULT B)\n");
-    fprintf(stderr,"r        {de/en}crypt ROT13/47\n");
-    fprintf(stderr,"h        1 katakana->hiragana, 2 hiragana->katakana, 3 both\n");
-    fprintf(stderr,"m[BQN0]  MIME decode [B:base64,Q:quoted,N:non-strict,0:no decode]\n");
-    fprintf(stderr,"M[BQ]    MIME encode [B:base64 Q:quoted]\n");
-    fprintf(stderr,"l        ISO8859-1 (Latin-1) support\n");
-    fprintf(stderr,"f/F      Folding: -f60 or -f or -f60-10 (fold margin 10) F preserve nl\n");
-    fprintf(stderr,"Z[0-4]   Default/0: Convert JISX0208 Alphabet to ASCII\n");
-    fprintf(stderr,"         1: Kankaku to one space  2: to two spaces  3: HTML Entity\n");
-    fprintf(stderr,"         4: JISX0208 Katakana to JISX0201 Katakana\n");
-    fprintf(stderr,"X,x      Assume X0201 kana in MS-Kanji, -x preserves X0201\n");
-    fprintf(stderr,"B[0-2]   Broken input  0: missing ESC,1: any X on ESC-[($]-X,2: ASCII on NL\n");
+    fprintf(HELP_OUTPUT,"         After 'W' you can add more options. -W[ 8, 16 [BL] ] \n");
+#endif
+    fprintf(HELP_OUTPUT,"t        no conversion\n");
+    fprintf(HELP_OUTPUT,"i[@B]    Specify the Esc Seq for JIS X 0208-1978/83 (DEFAULT B)\n");
+    fprintf(HELP_OUTPUT,"o[BJH]   Specify the Esc Seq for ASCII/Roman        (DEFAULT B)\n");
+    fprintf(HELP_OUTPUT,"r        {de/en}crypt ROT13/47\n");
+    fprintf(HELP_OUTPUT,"h        1 katakana->hiragana, 2 hiragana->katakana, 3 both\n");
+    fprintf(HELP_OUTPUT,"m[BQN0]  MIME decode [B:base64,Q:quoted,N:non-strict,0:no decode]\n");
+    fprintf(HELP_OUTPUT,"M[BQ]    MIME encode [B:base64 Q:quoted]\n");
+    fprintf(HELP_OUTPUT,"l        ISO8859-1 (Latin-1) support\n");
+    fprintf(HELP_OUTPUT,"f/F      Folding: -f60 or -f or -f60-10 (fold margin 10) F preserve nl\n");
+    fprintf(HELP_OUTPUT,"Z[0-4]   Default/0: Convert JISX0208 Alphabet to ASCII\n");
+    fprintf(HELP_OUTPUT,"         1: Kankaku to one space  2: to two spaces  3: HTML Entity\n");
+    fprintf(HELP_OUTPUT,"         4: JISX0208 Katakana to JISX0201 Katakana\n");
+    fprintf(HELP_OUTPUT,"X,x      Assume X0201 kana in MS-Kanji, -x preserves X0201\n");
+    fprintf(HELP_OUTPUT,"B[0-2]   Broken input  0: missing ESC,1: any X on ESC-[($]-X,2: ASCII on NL\n");
 #ifdef MSDOS
-    fprintf(stderr,"T        Text mode output\n");
-#endif
-    fprintf(stderr,"O        Output to File (DEFAULT 'nkf.out')\n");
-    fprintf(stderr,"I        Convert non ISO-2022-JP charactor to GETA\n");
-    fprintf(stderr,"d,c      Convert line breaks  -d: LF  -c: CRLF\n");
-    fprintf(stderr,"-L[uwm]  line mode u:LF w:CRLF m:CR (DEFAULT noconversion)\n");
-    fprintf(stderr,"v, V     Show this usage. V: show configuration\n");
-    fprintf(stderr,"\n");
-    fprintf(stderr,"Long name options\n");
-    fprintf(stderr," --ic=<input codeset>  --oc=<output codeset>\n");
-    fprintf(stderr,"                   Specify the input or output codeset\n");
-    fprintf(stderr," --fj  --unix --mac  --windows\n");
-    fprintf(stderr," --jis  --euc  --sjis  --utf8  --utf16  --mime  --base64\n");
-    fprintf(stderr,"                   Convert for the system or code\n");
-    fprintf(stderr," --hiragana  --katakana  --katakana-hiragana\n");
-    fprintf(stderr,"                   To Hiragana/Katakana Conversion\n");
-    fprintf(stderr," --prefix=         Insert escape before troublesome characters of Shift_JIS\n");
+    fprintf(HELP_OUTPUT,"T        Text mode output\n");
+#endif
+    fprintf(HELP_OUTPUT,"O        Output to File (DEFAULT 'nkf.out')\n");
+    fprintf(HELP_OUTPUT,"I        Convert non ISO-2022-JP charactor to GETA\n");
+    fprintf(HELP_OUTPUT,"d,c      Convert line breaks  -d: LF  -c: CRLF\n");
+    fprintf(HELP_OUTPUT,"-L[uwm]  line mode u:LF w:CRLF m:CR (DEFAULT noconversion)\n");
+    fprintf(HELP_OUTPUT,"v, V     Show this usage. V: show configuration\n");
+    fprintf(HELP_OUTPUT,"\n");
+    fprintf(HELP_OUTPUT,"Long name options\n");
+    fprintf(HELP_OUTPUT," --ic=<input codeset>  --oc=<output codeset>\n");
+    fprintf(HELP_OUTPUT,"                   Specify the input or output codeset\n");
+    fprintf(HELP_OUTPUT," --fj  --unix --mac  --windows\n");
+    fprintf(HELP_OUTPUT," --jis  --euc  --sjis  --utf8  --utf16  --mime  --base64\n");
+    fprintf(HELP_OUTPUT,"                   Convert for the system or code\n");
+    fprintf(HELP_OUTPUT," --hiragana  --katakana  --katakana-hiragana\n");
+    fprintf(HELP_OUTPUT,"                   To Hiragana/Katakana Conversion\n");
+    fprintf(HELP_OUTPUT," --prefix=         Insert escape before troublesome characters of Shift_JIS\n");
 #ifdef INPUT_OPTION
-    fprintf(stderr," --cap-input, --url-input  Convert hex after ':' or '%%'\n");
+    fprintf(HELP_OUTPUT," --cap-input, --url-input  Convert hex after ':' or '%%'\n");
 #endif
 #ifdef NUMCHAR_OPTION
-    fprintf(stderr," --numchar-input   Convert Unicode Character Reference\n");
+    fprintf(HELP_OUTPUT," --numchar-input   Convert Unicode Character Reference\n");
 #endif
 #ifdef UTF8_INPUT_ENABLE
-    fprintf(stderr," --fb-{skip, html, xml, perl, java, subchar}\n");
-    fprintf(stderr,"                   Specify how nkf handles unassigned characters\n");
+    fprintf(HELP_OUTPUT," --fb-{skip, html, xml, perl, java, subchar}\n");
+    fprintf(HELP_OUTPUT,"                   Specify how nkf handles unassigned characters\n");
 #endif
 #ifdef OVERWRITE
-    fprintf(stderr," --in-place[=SUFFIX]  --overwrite[=SUFFIX]\n");
-    fprintf(stderr,"                   Overwrite original listed files by filtered result\n");
-    fprintf(stderr,"                   --overwrite preserves timestamp of original files\n");
-#endif
-    fprintf(stderr," -g  --guess       Guess the input code\n");
-    fprintf(stderr," --help  --version Show this help/the version\n");
-    fprintf(stderr,"                   For more information, see also man nkf\n");
-    fprintf(stderr,"\n");
+    fprintf(HELP_OUTPUT," --in-place[=SUFFIX]  --overwrite[=SUFFIX]\n");
+    fprintf(HELP_OUTPUT,"                   Overwrite original listed files by filtered result\n");
+    fprintf(HELP_OUTPUT,"                   --overwrite preserves timestamp of original files\n");
+#endif
+    fprintf(HELP_OUTPUT," -g  --guess       Guess the input code\n");
+    fprintf(HELP_OUTPUT," --help  --version Show this help/the version\n");
+    fprintf(HELP_OUTPUT,"                   For more information, see also man nkf\n");
+    fprintf(HELP_OUTPUT,"\n");
     version();
 }
 
 void show_configuration(void)
 {
-    fprintf(stderr, "Summary of my nkf " NKF_VERSION " (" NKF_RELEASE_DATE ") configuration:\n");
-    fprintf(stderr, "  Compile-time options:\n");
-    fprintf(stderr, "    Default output encoding:     "
+    fprintf(HELP_OUTPUT, "Summary of my nkf " NKF_VERSION " (" NKF_RELEASE_DATE ") configuration:\n");
+    fprintf(HELP_OUTPUT, "  Compile-time options:\n");
+    fprintf(HELP_OUTPUT, "    Default output encoding:     "
 #if defined(DEFAULT_CODE_JIS)
            "ISO-2022-JP"
 #elif defined(DEFAULT_CODE_SJIS)
@@ -6432,7 +6465,7 @@ void show_configuration(void)
            "UTF-8"
 #endif
            "\n");
-    fprintf(stderr, "    Default output newline:      "
+    fprintf(HELP_OUTPUT, "    Default output newline:      "
 #if DEFAULT_NEWLINE == CR
            "CR"
 #elif DEFAULT_NEWLINE == CRLF
@@ -6441,24 +6474,31 @@ void show_configuration(void)
            "LF"
 #endif
            "\n");
-    fprintf(stderr, "    Decode MIME encoded string:  "
+    fprintf(HELP_OUTPUT, "    Decode MIME encoded string:  "
 #if MIME_DECODE_DEFAULT
            "ON"
 #else
            "OFF"
 #endif
            "\n");
-    fprintf(stderr, "    Convert JIS X 0201 Katakana: "
+    fprintf(HELP_OUTPUT, "    Convert JIS X 0201 Katakana: "
 #if X0201_DEFAULT
            "ON"
 #else
            "OFF"
 #endif
            "\n");
+fprintf(HELP_OUTPUT, " --help, --version output: "
+#if HELP_OUTPUT_HELP_OUTPUT
+"HELP_OUTPUT"
+#else
+"STDOUT"
+#endif
+"\n");
 }
 
 void version(void)
 {
-    fprintf(stderr,"Network Kanji Filter Version " NKF_VERSION " (" NKF_RELEASE_DATE ") \n" COPY_RIGHT "\n");
+    fprintf(HELP_OUTPUT,"Network Kanji Filter Version " NKF_VERSION " (" NKF_RELEASE_DATE ") \n" COPY_RIGHT "\n");
 }
 #endif /*PERL_XS*/