-/** Network Kanji Filter. (PDS Version)
- ** -*- coding: ISO-2022-JP -*-
- ************************************************************************
- ** Copyright (C) 1987, Fujitsu LTD. (Itaru ICHIKAWA)
- ** \e$BO"Mm@h!'\e(B \e$B!J3t!KIY;NDL8&5f=j!!%=%U%H#38&!!;T@n!!;j\e(B
- ** \e$B!J\e(BE-Mail Address: ichikawa@flab.fujitsu.co.jp\e$B!K\e(B
- ** Copyright (C) 1996,1998
- ** Copyright (C) 2002
- ** \e$BO"Mm@h!'\e(B \e$BN05eBg3X>pJs9)3X2J\e(B \e$B2OLn\e(B \e$B??<#\e(B mime/X0208 support
- ** \e$B!J\e(BE-Mail Address: kono@ie.u-ryukyu.ac.jp\e$B!K\e(B
- ** \e$BO"Mm@h!'\e(B COW for DOS & Win16 & Win32 & OS/2
- ** \e$B!J\e(BE-Mail Address: GHG00637@niftyserve.or.p\e$B!K\e(B
- **
- ** \e$B$3$N%=!<%9$N$$$+$J$kJ#<L!$2~JQ!$=$@5$b5vBz$7$^$9!#$?$@$7!"\e(B
- ** \e$B$=$N:]$K$O!"C/$,9W8%$7$?$r<($9$3$NItJ,$r;D$9$3$H!#\e(B
- ** \e$B:FG[I[$d;(;o$NIUO?$J$I$NLd$$9g$o$;$bI,MW$"$j$^$;$s!#\e(B
- ** \e$B1DMxMxMQ$b>e5-$KH?$7$J$$HO0O$G5v2D$7$^$9!#\e(B
- ** \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
- ** \e$B$3$N%W%m%0%i%`$K$D$$$F$OFC$K2?$NJ]>Z$b$7$J$$!"0-$7$+$i$:!#\e(B
- **
- ** Everyone is permitted to do anything on this program
- ** including copying, modifying, improving,
- ** as long as you don't try to pretend that you wrote it.
- ** i.e., the above copyright notice has to appear in all copies.
- ** Binary distribution requires original version messages.
- ** You don't have to ask before copying, redistribution or publishing.
- ** THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
- ***********************************************************************/
-
-/***********************************************************************
- * \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/
- ***********************************************************************/
-#define NKF_IDENT "$Id: nkf.c,v 1.187 2008/11/07 02:37:21 naruse Exp $"
-#define NKF_VERSION "2.0.8"
-#define NKF_RELEASE_DATE "2008-10-28"
+/*
+ * Copyright (c) 1987, Fujitsu LTD. (Itaru ICHIKAWA).
+ * Copyright (c) 1996-2010, The nkf Project.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+#define NKF_VERSION "2.1.1"
+#define NKF_RELEASE_DATE "2011-03-25"
#define COPY_RIGHT \
- "Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa),2000 S. Kono, COW\n" \
- "Copyright (C) 2002-2008 Kono, Furukawa, Naruse, mastodon"
+ "Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa).\n" \
+ "Copyright (C) 1996-2010, The nkf Project."
#include "config.h"
#include "nkf.h"
# define INCL_DOSERRORS
# include <os2.h>
#endif
+#include <assert.h>
+
/* state of output_mode and input_mode
JIS_X_0212 = 0x1159, /* D */
/* JIS_X_0213_2000_1 = 0x1228, */ /* O */
JIS_X_0213_2 = 0x1229, /* P */
- JIS_X_0213_1 = 0x1233, /* Q */
+ JIS_X_0213_1 = 0x1233 /* Q */
};
static nkf_char s_iconv(nkf_char c2, nkf_char c1, nkf_char c0);
} encoding_name_to_id_table[] = {
{"US-ASCII", ASCII},
{"ASCII", ASCII},
+ {"646", ASCII},
+ {"ROMAN8", ASCII},
{"ISO-2022-JP", ISO_2022_JP},
{"ISO2022JP-CP932", CP50220},
{"CP50220", CP50220},
{"ISO-2022-JP-2004", ISO_2022_JP_2004},
{"SHIFT_JIS", SHIFT_JIS},
{"SJIS", SHIFT_JIS},
+ {"MS_Kanji", SHIFT_JIS},
+ {"PCK", SHIFT_JIS},
{"WINDOWS-31J", WINDOWS_31J},
{"CSWINDOWS31J", WINDOWS_31J},
{"CP932", WINDOWS_31J},
&& (c != '(') && (c != ')') && (c != '.') && (c != 0x22)))
#define is_ibmext_in_sjis(c2) (CP932_TABLE_BEGIN <= c2 && c2 <= CP932_TABLE_END)
-#define nkf_byte_jisx0201_katakana_p(c) (SP <= c && c < (0xE0&0x7F))
+#define nkf_byte_jisx0201_katakana_p(c) (SP <= c && c <= 0x5F)
#define HOLD_SIZE 1024
#if defined(INT_IS_SHORT)
static unsigned char stdobuf[IOBUF_SIZE];
#endif
+#define NKF_UNSPECIFIED (-TRUE)
+
/* flags */
static int unbuf_f = FALSE;
static int estab_f = FALSE;
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 x0201_f = X0201_DEFAULT; /* convert JIS X 0201 */
+static int x0201_f = NKF_UNSPECIFIED; /* convert JIS X 0201 */
static int iso2022jp_f = FALSE; /* replace non ISO-2022-JP with GETA */
#ifdef UNICODE_NORMALIZATION
{"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}, NULL, w_iconv16, 0},
+ {"UTF-32", 0, 0, 0, {0, 0, 0}, NULL, w_iconv32, 0},
#endif
- {0}
+ {NULL, 0, 0, 0, {0, 0, 0}, NULL, NULL, 0}
};
static int mimeout_mode = 0; /* 0, -1, 'Q', 'B', 1, 2 */
no_connection2(nkf_char c2, nkf_char c1, nkf_char c0)
{
fprintf(stderr,"nkf internal module connection failure.\n");
- exit(1);
+ exit(EXIT_FAILURE);
return 0; /* LINT */
}
static int end_check;
#endif /*Easy Win */
-#define STD_GC_BUFSIZE (256)
-nkf_char std_gc_buf[STD_GC_BUFSIZE];
-nkf_char std_gc_ndx;
+static void *
+nkf_xmalloc(size_t size)
+{
+ void *ptr;
+
+ if (size == 0) size = 1;
+
+ ptr = malloc(size);
+ if (ptr == NULL) {
+ perror("can't malloc");
+ exit(EXIT_FAILURE);
+ }
+
+ return ptr;
+}
+
+static void *
+nkf_xrealloc(void *ptr, size_t size)
+{
+ if (size == 0) size = 1;
+
+ ptr = realloc(ptr, size);
+ if (ptr == NULL) {
+ perror("can't realloc");
+ exit(EXIT_FAILURE);
+ }
+
+ return ptr;
+}
+
+#define nkf_xfree(ptr) free(ptr)
static int
nkf_str_caseeql(const char *src, const char *target)
nkf_enc_to_index(enc) == CP50222)
#ifdef DEFAULT_CODE_LOCALE
-static char*
+static const char*
nkf_locale_charmap()
{
#ifdef HAVE_LANGINFO_H
return nl_langinfo(CODESET);
#elif defined(__WIN32__)
- char buf[16];
- char *str;
- int len = sprintf(buf, "CP%d", GetACP());
- if (len > 0) {
- str = malloc(len + 1);
- strcpy(str, buf);
- str[len] = '\0';
- return str;
- }
- else return NULL;
+ static char buf[16];
+ sprintf(buf, "CP%d", GetACP());
+ return buf;
#elif defined(__OS2__)
# if defined(INT_IS_SHORT)
/* OS/2 1.x */
sprintf(buf, "CP%lu", ulCP[0]);
return buf;
# endif
-#else
- return NULL;
#endif
+ return NULL;
}
static nkf_encoding*
nkf_locale_encoding()
{
nkf_encoding *enc = 0;
- char *encname = nkf_locale_charmap();
+ const char *encname = nkf_locale_charmap();
if (encname)
enc = nkf_enc_find(encname);
return enc;
return enc;
}
+typedef struct {
+ long capa;
+ long len;
+ nkf_char *ptr;
+} nkf_buf_t;
+
+static nkf_buf_t *
+nkf_buf_new(int length)
+{
+ nkf_buf_t *buf = nkf_xmalloc(sizeof(nkf_buf_t));
+ buf->ptr = nkf_xmalloc(sizeof(nkf_char) * length);
+ buf->capa = length;
+ buf->len = 0;
+ return buf;
+}
+
+#if 0
+static void
+nkf_buf_dispose(nkf_buf_t *buf)
+{
+ nkf_xfree(buf->ptr);
+ nkf_xfree(buf);
+}
+#endif
+
+#define nkf_buf_length(buf) ((buf)->len)
+#define nkf_buf_empty_p(buf) ((buf)->len == 0)
+
+static nkf_char
+nkf_buf_at(nkf_buf_t *buf, int index)
+{
+ assert(index <= buf->len);
+ return buf->ptr[index];
+}
+
+static void
+nkf_buf_clear(nkf_buf_t *buf)
+{
+ buf->len = 0;
+}
+
+static void
+nkf_buf_push(nkf_buf_t *buf, nkf_char c)
+{
+ if (buf->capa <= buf->len) {
+ exit(EXIT_FAILURE);
+ }
+ buf->ptr[buf->len++] = c;
+}
+
+static nkf_char
+nkf_buf_pop(nkf_buf_t *buf)
+{
+ assert(!nkf_buf_empty_p(buf));
+ return buf->ptr[--buf->len];
+}
+
+/* Normalization Form C */
#ifndef PERL_XS
#ifdef WIN32DLL
#define fprintf dllprintf
usage(void)
{
fprintf(HELP_OUTPUT,
- "USAGE: nkf(nkf32,wnkf,nkf2) -[flags] [in file] .. [out file for -O flag]\n"
- "Flags:\n"
- "b,u Output is buffered (DEFAULT),Output is unbuffered\n"
- "j,s,e,w Output code is ISO-2022-JP, Shift JIS, EUC-JP, UTF-8N\n"
+ "Usage: nkf -[flags] [--] [in file] .. [out file for -O flag]\n"
#ifdef UTF8_OUTPUT_ENABLE
- " After 'w' you can add more options. -w[ 8 [0], 16 [[BL] [0]] ]\n"
+ " j/s/e/w Specify output encoding ISO-2022-JP, Shift_JIS, EUC-JP\n"
+ " UTF options is -w[8[0],{16,32}[{B,L}[0]]]\n"
+#else
#endif
- "J,S,E,W Input assumption is JIS 7 bit , Shift JIS, EUC-JP, UTF-8\n"
#ifdef UTF8_INPUT_ENABLE
- " After 'W' you can add more options. -W[ 8, 16 [BL] ] \n"
-#endif
- "t no conversion\n"
- "i[@B] Specify the Esc Seq for JIS X 0208-1978/83 (DEFAULT B)\n"
- "o[BJH] Specify the Esc Seq for ASCII/Roman (DEFAULT B)\n"
- "r {de/en}crypt ROT13/47\n"
- "h 1 katakana->hiragana, 2 hiragana->katakana, 3 both\n"
- "m[BQSN0] MIME decode [B:base64,Q:quoted,S:strict,N:non-strict,0:no decode]\n"
- "M[BQ] MIME encode [B:base64 Q:quoted]\n"
- "l ISO8859-1 (Latin-1) support\n"
- "f/F Folding: -f60 or -f or -f60-10 (fold margin 10) F preserve nl\n"
- "Z[0-4] Default/0: Convert JISX0208 Alphabet to ASCII\n"
- " 1: Kankaku to one space 2: to two spaces 3: HTML Entity\n"
- " 4: JISX0208 Katakana to JISX0201 Katakana\n"
- "X,x Assume X0201 kana in MS-Kanji, -x preserves X0201\n"
- "B[0-2] Broken input 0: missing ESC,1: any X on ESC-[($]-X,2: ASCII on NL\n"
-#ifdef MSDOS
- "T Text mode output\n"
+ " J/S/E/W Specify input encoding ISO-2022-JP, Shift_JIS, EUC-JP\n"
+ " UTF option is -W[8,[16,32][B,L]]\n"
+#else
+ " J/S/E Specify output encoding ISO-2022-JP, Shift_JIS, EUC-JP\n"
#endif
- "O Output to File (DEFAULT 'nkf.out')\n"
- "I Convert non ISO-2022-JP charactor to GETA\n"
- "d,c Convert line breaks -d: LF -c: CRLF\n"
- "-L[uwm] line mode u:LF w:CRLF m:CR (DEFAULT noconversion)\n"
- "v, V Show this usage. V: show configuration\n"
- "\n"
- "Long name options\n"
- " --ic=<input codeset> --oc=<output codeset>\n"
- " Specify the input or output codeset\n"
- " --fj --unix --mac --windows\n"
- " --jis --euc --sjis --utf8 --utf16 --mime --base64\n"
- " Convert for the system or code\n"
- " --hiragana --katakana --katakana-hiragana\n"
- " To Hiragana/Katakana Conversion\n"
- " --prefix= Insert escape before troublesome characters of Shift_JIS\n"
+ );
+ fprintf(HELP_OUTPUT,
+ " m[BQSN0] MIME decode [B:base64,Q:quoted,S:strict,N:nonstrict,0:no decode]\n"
+ " M[BQ] MIME encode [B:base64 Q:quoted]\n"
+ " 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"
+ " 1: Kankaku to one space 2: to two spaces 3: HTML Entity\n"
+ " 4: JISX0208 Katakana to JISX0201 Katakana\n"
+ " X,x Convert Halfwidth Katakana to Fullwidth or preserve it\n"
+ );
+ fprintf(HELP_OUTPUT,
+ " O Output to File (DEFAULT 'nkf.out')\n"
+ " L[uwm] Line mode u:LF w:CRLF m:CR (DEFAULT noconversion)\n"
+ );
+ fprintf(HELP_OUTPUT,
+ " --ic=<encoding> Specify the input encoding\n"
+ " --oc=<encoding> Specify the output encoding\n"
+ " --hiragana --katakana Hiragana/Katakana Conversion\n"
+ " --katakana-hiragana Converts each other\n"
+ );
+ fprintf(HELP_OUTPUT,
#ifdef INPUT_OPTION
- " --cap-input, --url-input Convert hex after ':' or '%%'\n"
+ " --{cap, url}-input Convert hex after ':' or '%%'\n"
#endif
#ifdef NUMCHAR_OPTION
- " --numchar-input Convert Unicode Character Reference\n"
+ " --numchar-input Convert Unicode Character Reference\n"
#endif
#ifdef UTF8_INPUT_ENABLE
" --fb-{skip, html, xml, perl, java, subchar}\n"
- " Specify how nkf handles unassigned characters\n"
+ " Specify unassigned character's replacement\n"
#endif
+ );
+ fprintf(HELP_OUTPUT,
#ifdef OVERWRITE
- " --in-place[=SUFFIX] --overwrite[=SUFFIX]\n"
- " Overwrite original listed files by filtered result\n"
- " --overwrite preserves timestamp of original files\n"
+ " --in-place[=SUF] Overwrite original files\n"
+ " --overwrite[=SUF] Preserve timestamp of original files\n"
#endif
- " -g --guess Guess the input code\n"
- " --help --version Show this help/the version\n"
- " For more information, see also man nkf\n"
- "\n");
+ " -g --guess Guess the input code\n"
+ " -v --version Print the version\n"
+ " --help/-V Print this help / configuration\n"
+ );
version();
}
{
fprintf(HELP_OUTPUT,
"Summary of my nkf " NKF_VERSION " (" NKF_RELEASE_DATE ") configuration:\n"
- " nkf identity:\n"
- " " NKF_IDENT "\n"
" Compile-time options:\n"
" Compiled at: " __DATE__ " " __TIME__ "\n"
);
}
if(asterisk_count){
- backup_filename = malloc(strlen(suffix) + (asterisk_count * (filename_length - 1)) + 1);
- if (!backup_filename){
- perror("Can't malloc backup filename.");
- return NULL;
- }
-
+ backup_filename = nkf_xmalloc(strlen(suffix) + (asterisk_count * (filename_length - 1)) + 1);
for(i = 0, j = 0; suffix[i];){
if(suffix[i] == '*'){
backup_filename[j] = '\0';
backup_filename[j] = '\0';
}else{
j = filename_length + strlen(suffix);
- backup_filename = malloc(j + 1);
+ backup_filename = nkf_xmalloc(j + 1);
strcpy(backup_filename, filename);
strcat(backup_filename, suffix);
backup_filename[j] = '\0';
int shift = 20;
c &= VALUE_MASK;
while(shift >= 0){
- if(c >= 1<<shift){
+ if(c >= NKF_INT32_C(1)<<shift){
while(shift >= 0){
(*f)(0, bin2hex(c>>shift));
shift -= 4;
{"euc","e"},
{"euc-input","E"},
{"fj","jm"},
- {"help","v"},
+ {"help",""},
{"jis","j"},
{"jis-input","J"},
{"mac","sLm"},
{"sjis","s"},
{"sjis-input","S"},
{"unix","eLu"},
- {"version","V"},
+ {"version","v"},
{"windows","sLw"},
{"hiragana","h1"},
{"katakana","h2"},
case ISO_8859_1:
iso8859_f = TRUE;
break;
- case CP50220:
case CP50221:
case CP50222:
+ if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */
+ case CP50220:
#ifdef SHIFTJIS_CP932
cp51932_f = TRUE;
#endif
case SHIFT_JIS:
break;
case WINDOWS_31J:
+ if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */
#ifdef SHIFTJIS_CP932
cp51932_f = TRUE;
#endif
case EUCJP_NKF:
break;
case CP51932:
+ if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */
#ifdef SHIFTJIS_CP932
cp51932_f = TRUE;
#endif
#endif
break;
case EUCJP_MS:
+ if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */
#ifdef SHIFTJIS_CP932
cp51932_f = FALSE;
#endif
#endif
break;
case EUCJP_ASCII:
+ if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */
#ifdef SHIFTJIS_CP932
cp51932_f = FALSE;
#endif
{
switch (nkf_enc_to_index(enc)) {
case CP50220:
- x0201_f = TRUE;
#ifdef SHIFTJIS_CP932
if (cp932inv_f == TRUE) cp932inv_f = FALSE;
#endif
#endif
break;
case CP50221:
+ if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */
#ifdef SHIFTJIS_CP932
if (cp932inv_f == TRUE) cp932inv_f = FALSE;
#endif
ms_ucs_map_f = UCS_MAP_CP932;
#endif
break;
+ case ISO_2022_JP:
+#ifdef SHIFTJIS_CP932
+ if (cp932inv_f == TRUE) cp932inv_f = FALSE;
+#endif
+ break;
case ISO_2022_JP_1:
x0212_f = TRUE;
#ifdef SHIFTJIS_CP932
case SHIFT_JIS:
break;
case WINDOWS_31J:
+ if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */
#ifdef UTF8_OUTPUT_ENABLE
ms_ucs_map_f = UCS_MAP_CP932;
#endif
#endif
break;
case CP51932:
+ if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */
#ifdef SHIFTJIS_CP932
if (cp932inv_f == TRUE) cp932inv_f = FALSE;
#endif
#endif
break;
case EUCJP_MS:
+ if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */
x0212_f = TRUE;
#ifdef UTF8_OUTPUT_ENABLE
ms_ucs_map_f = UCS_MAP_MS;
#endif
break;
case EUCJP_ASCII:
+ if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE; /* -x specified implicitly */
x0212_f = TRUE;
#ifdef UTF8_OUTPUT_ENABLE
ms_ucs_map_f = UCS_MAP_ASCII;
output_endian = ENDIAN_LITTLE;
output_bom_f = TRUE;
break;
+ case UTF_32:
case UTF_32BE_BOM:
output_bom_f = TRUE;
break;
*p3 = 0x80 | ( val & 0x3f);
*p4 = 0;
} else if (nkf_char_unicode_value_p(val)) {
- *p1 = 0xe0 | (val >> 16);
+ *p1 = 0xf0 | (val >> 18);
*p2 = 0x80 | ((val >> 12) & 0x3f);
*p3 = 0x80 | ((val >> 6) & 0x3f);
*p4 = 0x80 | ( val & 0x3f);
return 0;
}
-#define NKF_ICONV_NEED_ONE_MORE_BYTE -1
-#define NKF_ICONV_NEED_TWO_MORE_BYTES -2
+#define NKF_ICONV_NEED_ONE_MORE_BYTE (size_t)-1
+#define NKF_ICONV_NEED_TWO_MORE_BYTES (size_t)-2
#define UTF16_TO_UTF32(lead, trail) (((lead) << 10) + (trail) - NKF_INT32_C(0x35FDC00))
static size_t
nkf_iconv_utf_16(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4)
static nkf_char
w_iconv16(nkf_char c2, nkf_char c1, nkf_char c0)
{
- return 0;
+ (*oconv)(c2, c1);
+ return 16; /* different from w_iconv32 */
}
static nkf_char
w_iconv32(nkf_char c2, nkf_char c1, nkf_char c0)
{
- return 0;
+ (*oconv)(c2, c1);
+ return 32; /* different from w_iconv16 */
}
static size_t
}
#endif
-#define SCORE_L2 (1) /* \e$BBh\e(B2\e$B?e=`4A;z\e(B */
-#define SCORE_KANA (SCORE_L2 << 1) /* \e$B$$$o$f$kH>3Q%+%J\e(B */
-#define SCORE_DEPEND (SCORE_KANA << 1) /* \e$B5!<o0MB8J8;z\e(B */
-#define SCORE_CP932 (SCORE_DEPEND << 1) /* CP932 \e$B$K$h$kFI$_49$(\e(B (IBM extended characters) */
+#define SCORE_L2 (1) /* Kanji Level 2 */
+#define SCORE_KANA (SCORE_L2 << 1) /* Halfwidth Katakana */
+#define SCORE_DEPEND (SCORE_KANA << 1) /* MD Characters */
+#define SCORE_CP932 (SCORE_DEPEND << 1) /* IBM extended characters */
#define SCORE_X0212 (SCORE_CP932 << 1) /* JIS X 0212 */
-#define SCORE_NO_EXIST (SCORE_X0212 << 1) /* \e$BB8:_$7$J$$J8;z\e(B */
-#define SCORE_iMIME (SCORE_NO_EXIST << 1) /* MIME \e$B$K$h$k;XDj\e(B */
-#define SCORE_ERROR (SCORE_iMIME << 1) /* \e$B%(%i!<\e(B */
+#define SCORE_NO_EXIST (SCORE_X0212 << 1) /* Undefined Characters */
+#define SCORE_iMIME (SCORE_NO_EXIST << 1) /* MIME selected */
+#define SCORE_ERROR (SCORE_iMIME << 1) /* Error */
#define SCORE_INIT (SCORE_iMIME)
-static const char score_table_A0[] = {
+static const nkf_char 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,
};
-static const char score_table_F0[] = {
+static const nkf_char 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_CP932, SCORE_CP932,
}
}
+typedef struct {
+ nkf_buf_t *std_gc_buf;
+ nkf_char broken_state;
+ nkf_buf_t *broken_buf;
+ nkf_char mimeout_state;
+ nkf_buf_t *nfc_buf;
+} nkf_state_t;
+
+static nkf_state_t *nkf_state = NULL;
+
+#define STD_GC_BUFSIZE (256)
+
+static void
+nkf_state_init(void)
+{
+ if (nkf_state) {
+ nkf_buf_clear(nkf_state->std_gc_buf);
+ nkf_buf_clear(nkf_state->broken_buf);
+ nkf_buf_clear(nkf_state->nfc_buf);
+ }
+ else {
+ nkf_state = nkf_xmalloc(sizeof(nkf_state_t));
+ nkf_state->std_gc_buf = nkf_buf_new(STD_GC_BUFSIZE);
+ nkf_state->broken_buf = nkf_buf_new(3);
+ nkf_state->nfc_buf = nkf_buf_new(9);
+ }
+ nkf_state->broken_state = 0;
+ nkf_state->mimeout_state = 0;
+}
+
#ifndef WIN32DLL
static nkf_char
std_getc(FILE *f)
{
- if (std_gc_ndx){
- return std_gc_buf[--std_gc_ndx];
+ if (!nkf_buf_empty_p(nkf_state->std_gc_buf)){
+ return nkf_buf_pop(nkf_state->std_gc_buf);
}
return getc(f);
}
static nkf_char
std_ungetc(nkf_char c, FILE *f)
{
- if (std_gc_ndx == STD_GC_BUFSIZE){
- return EOF;
- }
- std_gc_buf[std_gc_ndx++] = c;
+ nkf_buf_push(nkf_state->std_gc_buf, c);
return c;
}
}
#endif /*WIN32DLL*/
-static unsigned char hold_buf[HOLD_SIZE*2];
+static nkf_char hold_buf[HOLD_SIZE*2];
static int hold_count = 0;
static nkf_char
push_hold_buf(nkf_char c2)
{
if (hold_count >= HOLD_SIZE*2)
return (EOF);
- hold_buf[hold_count++] = (unsigned char)c2;
+ hold_buf[hold_count++] = c2;
return ((hold_count >= HOLD_SIZE*2) ? EOF : hold_count);
}
static int
-h_conv(FILE *f, int c1, int c2)
+h_conv(FILE *f, nkf_char c1, nkf_char c2)
{
- int ret, c4, c3;
+ int ret;
int hold_index;
-
+ nkf_char c3, c4;
/** it must NOT be in the kanji shifte sequence */
/** it must NOT be written in JIS7 */
hold_index = 0;
while (hold_index < hold_count){
c1 = hold_buf[hold_index++];
- if (c1 <= DEL){
+ if (nkf_char_unicode_p(c1)) {
+ (*oconv)(0, c1);
+ continue;
+ }
+ else if (c1 <= DEL){
(*iconv)(0, c1, 0);
continue;
}else if (iconv == s_iconv && 0xa1 <= c1 && c1 <= 0xdf){
} else if ((c3 = (*i_getc)(f)) == EOF) {
ret = EOF;
break;
- } else {
- code_status(c3);
- if (hold_index < hold_count){
- c4 = hold_buf[hold_index++];
- } else if ((c4 = (*i_getc)(f)) == EOF) {
- c3 = ret = EOF;
- break;
- } else {
- code_status(c4);
- (*iconv)(c1, c2, (c3<<8)|c4);
- }
}
+ code_status(c3);
+ if (hold_index < hold_count){
+ c4 = hold_buf[hold_index++];
+ } else if ((c4 = (*i_getc)(f)) == EOF) {
+ c3 = ret = EOF;
+ break;
+ }
+ code_status(c4);
+ (*iconv)(c1, c2, (c3<<8)|c4);
break;
case -1:
/* 3 bytes EUC or UTF-8 */
}
}
-static struct {
- int count;
- nkf_char status;
- nkf_char buf[3];
-} broken_state;
-
-static void
-init_broken_state(void)
-{
- memset(&broken_state, 0, sizeof(broken_state));
-}
-
-static void
-push_broken_buf(c)
-{
- broken_state.buf[broken_state.count++] = c;
-}
-
-static nkf_char
-pop_broken_buf(void)
-{
- return broken_state.buf[--broken_state.count];
-}
-
static nkf_char
broken_getc(FILE *f)
{
nkf_char c, c1;
- if (broken_state.count > 0) {
- return pop_broken_buf();
+ if (!nkf_buf_empty_p(nkf_state->broken_buf)) {
+ return nkf_buf_pop(nkf_state->broken_buf);
}
c = (*i_bgetc)(f);
- if (c=='$' && broken_state.status != ESC
+ if (c=='$' && nkf_state->broken_state != ESC
&& (input_mode == ASCII || input_mode == JIS_X_0201_1976_K)) {
c1= (*i_bgetc)(f);
- broken_state.status = 0;
+ nkf_state->broken_state = 0;
if (c1=='@'|| c1=='B') {
- push_broken_buf(c1);
- push_broken_buf(c);
+ nkf_buf_push(nkf_state->broken_buf, c1);
+ nkf_buf_push(nkf_state->broken_buf, c);
return ESC;
} else {
(*i_bungetc)(c1,f);
return c;
}
- } else if (c=='(' && broken_state.status != ESC
+ } else if (c=='(' && nkf_state->broken_state != ESC
&& (input_mode == JIS_X_0208 || input_mode == JIS_X_0201_1976_K)) {
c1= (*i_bgetc)(f);
- broken_state.status = 0;
+ nkf_state->broken_state = 0;
if (c1=='J'|| c1=='B') {
- push_broken_buf(c1);
- push_broken_buf(c);
+ nkf_buf_push(nkf_state->broken_buf, c1);
+ nkf_buf_push(nkf_state->broken_buf, c);
return ESC;
} else {
(*i_bungetc)(c1,f);
return c;
}
} else {
- broken_state.status = c;
+ nkf_state->broken_state = c;
return c;
}
}
static nkf_char
broken_ungetc(nkf_char c, FILE *f)
{
- if (broken_state.count < 2)
- push_broken_buf(c);
+ if (nkf_buf_length(nkf_state->broken_buf) < 2)
+ nkf_buf_push(nkf_state->broken_buf, c);
return c;
}
else if (c2 != 0 || c1 != LF) (*o_eol_conv)(c2, c1);
}
+static void
+put_newline(void (*func)(nkf_char))
+{
+ switch (eolmode_f ? eolmode_f : DEFAULT_NEWLINE) {
+ case CRLF:
+ (*func)(0x0D);
+ (*func)(0x0A);
+ break;
+ case CR:
+ (*func)(0x0D);
+ break;
+ case LF:
+ (*func)(0x0A);
+ break;
+ }
+}
+
+static void
+oconv_newline(void (*func)(nkf_char, nkf_char))
+{
+ switch (eolmode_f ? eolmode_f : DEFAULT_NEWLINE) {
+ case CRLF:
+ (*func)(0, 0x0D);
+ (*func)(0, 0x0A);
+ break;
+ case CR:
+ (*func)(0, 0x0D);
+ break;
+ case LF:
+ (*func)(0, 0x0A);
+ break;
+ }
+}
+
/*
Return value of fold_conv()
f_prev = LF;
f_line = 0;
fold_state = LF; /* output newline and clear */
- } else if ( (c2==0 && c1==SP)||
- (c2==0 && c1==TAB)||
- (c2=='!'&& c1=='!')) {
+ } else if ((c2==0 && nkf_isblank(c1)) || (c2 == '!' && c1 == '!')) {
/* X0208 kankaku or ascii space */
if (f_prev == SP) {
fold_state = 0; /* remove duplicate spaces */
/* terminator process */
switch(fold_state) {
case LF:
- OCONV_NEWLINE((*o_fconv));
+ oconv_newline(o_fconv);
(*o_fconv)(c2,c1);
break;
case 0:
return;
case CR:
- OCONV_NEWLINE((*o_fconv));
+ oconv_newline(o_fconv);
break;
case TAB:
case SP:
if (alpha_f & 16) {
/* JIS X 0208 Katakana to JIS X 0201 Katakana */
if (c2 == 0x21) {
- char c = 0;
+ nkf_char c = 0;
switch (c1) {
case 0x23:
/* U+3002 (0x8142) Ideographic Full Stop -> U+FF61 (0xA1) Halfwidth Ideographic Full Stop */
(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?B?",
(const unsigned char *)"\075?ISO-2022-JP?Q?",
#if defined(UTF8_INPUT_ENABLE)
(const unsigned char *)"\075?UTF-8?B?",
/* \e$B3:Ev$9$k%3!<%I$NM%@hEY$r>e$2$k$?$a$NL\0u\e(B */
nkf_char (*mime_priority_func[])(nkf_char c2, nkf_char c1, nkf_char c0) = {
- e_iconv, s_iconv, 0, 0, 0, 0,
+ e_iconv, s_iconv, 0, 0, 0, 0, 0,
#if defined(UTF8_INPUT_ENABLE)
w_iconv, w_iconv,
#endif
};
static const nkf_char mime_encode[] = {
- EUC_JP, SHIFT_JIS, ISO_8859_1, ISO_8859_1, JIS_X_0208, JIS_X_0201_1976_K,
+ EUC_JP, SHIFT_JIS, ISO_8859_1, ISO_8859_1, JIS_X_0208, JIS_X_0201_1976_K, JIS_X_0201_1976_K,
#if defined(UTF8_INPUT_ENABLE)
UTF_8, UTF_8,
#endif
};
static const nkf_char mime_encode_method[] = {
- 'B', 'B','Q', 'B', 'B', 'Q',
+ 'B', 'B','Q', 'B', 'B', 'B', 'Q',
#if defined(UTF8_INPUT_ENABLE)
'B', 'Q',
#endif
nkf_char (*u)(nkf_char c ,FILE *f) = i_nungetc;
int i = 0, j;
nkf_char buf[12];
- long c = -1;
+ nkf_char c = -1;
buf[i] = (*g)(f);
if (buf[i] == '&'){
#ifdef UNICODE_NORMALIZATION
-/* Normalization Form C */
static nkf_char
nfc_getc(FILE *f)
{
nkf_char (*g)(FILE *f) = i_nfc_getc;
nkf_char (*u)(nkf_char c ,FILE *f) = i_nfc_ungetc;
- int i=0, j, k=1, lower, upper;
- nkf_char buf[9];
+ nkf_buf_t *buf = nkf_state->nfc_buf;
const unsigned char *array;
+ int lower=0, upper=NORMALIZATION_TABLE_LENGTH-1;
+ nkf_char c = (*g)(f);
- 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;
+ if (c == EOF || c > 0xFF || (c & 0xc0) == 0x80) return c;
+
+ nkf_buf_push(buf, c);
+ do {
+ while (lower <= upper) {
+ int mid = (lower+upper) / 2;
+ int len;
+ array = normalization_table[mid].nfd;
+ for (len=0; len < NORMALIZATION_TABLE_NFD_LENGTH && array[len]; len++) {
+ if (len >= nkf_buf_length(buf)) {
+ c = (*g)(f);
+ if (c == EOF) {
+ len = 0;
+ lower = 1, upper = 0;
+ break;
+ }
+ nkf_buf_push(buf, c);
+ }
+ if (array[len] != nkf_buf_at(buf, len)) {
+ if (array[len] < nkf_buf_at(buf, len)) lower = mid + 1;
+ else upper = mid - 1;
+ len = 0;
break;
- } else if (k >= i)
- buf[++i] = (*g)(f);
+ }
}
- if (k > 0){
- array = normalization_table[j].nfc;
+ if (len > 0) {
+ int i;
+ array = normalization_table[mid].nfc;
+ nkf_buf_clear(buf);
for (i=0; i < NORMALIZATION_TABLE_NFC_LENGTH && array[i]; i++)
- buf[i] = (nkf_char)(array[i]);
- i--;
+ nkf_buf_push(buf, array[i]);
break;
}
}
- while (i > 0)
- (*u)(buf[i--], f);
- }
- return buf[0];
+ } while (lower <= upper);
+
+ while (nkf_buf_length(buf) > 1) (*u)(nkf_buf_pop(buf), f);
+ c = nkf_buf_pop(buf);
+
+ return c;
}
static nkf_char
/* end Q encoding */
input_mode = exit_mode;
lwsp_count = 0;
- lwsp_buf = malloc((lwsp_size+5)*sizeof(char));
- if (lwsp_buf==NULL) {
- perror("can't malloc");
- return -1;
- }
+ lwsp_buf = nkf_xmalloc((lwsp_size+5)*sizeof(char));
while ((c1=(*i_getc)(f))!=EOF) {
switch (c1) {
case LF:
case CR:
if (c1==LF) {
- if ((c1=(*i_getc)(f))!=EOF && (c1==SP||c1==TAB)) {
+ if ((c1=(*i_getc)(f))!=EOF && nkf_isblank(c1)) {
i_ungetc(SP,f);
continue;
} else {
c1 = LF;
} else {
if ((c1=(*i_getc)(f))!=EOF && c1 == LF) {
- if ((c1=(*i_getc)(f))!=EOF && (c1==SP||c1==TAB)) {
+ if ((c1=(*i_getc)(f))!=EOF && nkf_isblank(c1)) {
i_ungetc(SP,f);
continue;
} else {
lwsp_buf[lwsp_count] = (unsigned char)c1;
if (lwsp_count++>lwsp_size){
lwsp_size <<= 1;
- lwsp_buf_new = realloc(lwsp_buf, (lwsp_size+5)*sizeof(char));
- if (lwsp_buf_new==NULL) {
- free(lwsp_buf);
- perror("can't realloc");
- return -1;
- }
+ lwsp_buf_new = nkf_xrealloc(lwsp_buf, (lwsp_size+5)*sizeof(char));
lwsp_buf = lwsp_buf_new;
}
continue;
i_ungetc(lwsp_buf[lwsp_count],f);
c1 = lwsp_buf[0];
}
- free(lwsp_buf);
+ nkf_xfree(lwsp_buf);
return c1;
}
if (c1=='='&&c2<SP) { /* this is soft wrap */
while((c1 = (*i_mgetc)(f)) <=SP) {
- if ((c1 = (*i_mgetc)(f)) == EOF) return (EOF);
+ if (c1 == EOF) return (EOF);
}
mime_decode_mode = 'Q'; /* still in MIME */
goto restart_mime_q;
if ((c1 == '?') && (c2 == '=')) {
input_mode = ASCII;
lwsp_count = 0;
- lwsp_buf = malloc((lwsp_size+5)*sizeof(char));
- if (lwsp_buf==NULL) {
- perror("can't malloc");
- return -1;
- }
+ lwsp_buf = nkf_xmalloc((lwsp_size+5)*sizeof(char));
while ((c1=(*i_getc)(f))!=EOF) {
switch (c1) {
case LF:
case CR:
if (c1==LF) {
- if ((c1=(*i_getc)(f))!=EOF && (c1==SP||c1==TAB)) {
+ if ((c1=(*i_getc)(f))!=EOF && nkf_isblank(c1)) {
i_ungetc(SP,f);
continue;
} else {
if (c1==SP) {
i_ungetc(SP,f);
continue;
- } else if ((c1=(*i_getc)(f))!=EOF && (c1==SP||c1==TAB)) {
+ } else if ((c1=(*i_getc)(f))!=EOF && nkf_isblank(c1)) {
i_ungetc(SP,f);
continue;
} else {
lwsp_buf[lwsp_count] = (unsigned char)c1;
if (lwsp_count++>lwsp_size){
lwsp_size <<= 1;
- lwsp_buf_new = realloc(lwsp_buf, (lwsp_size+5)*sizeof(char));
- if (lwsp_buf_new==NULL) {
- free(lwsp_buf);
- perror("can't realloc");
- return -1;
- }
+ lwsp_buf_new = nkf_xrealloc(lwsp_buf, (lwsp_size+5)*sizeof(char));
lwsp_buf = lwsp_buf_new;
}
continue;
i_ungetc(lwsp_buf[lwsp_count],f);
c1 = lwsp_buf[0];
}
- free(lwsp_buf);
+ nkf_xfree(lwsp_buf);
return c1;
}
mime_c3_retry:
static const char basis_64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-#define MIMEOUT_BUF_LENGTH (60)
+#define MIMEOUT_BUF_LENGTH 74
static struct {
- char buf[MIMEOUT_BUF_LENGTH+1];
+ unsigned char buf[MIMEOUT_BUF_LENGTH+1];
int count;
- nkf_char state;
} mimeout_state;
/*nkf_char mime_lastchar2, mime_lastchar1;*/
(*o_mputc)(mimeout_state.buf[i]);
i++;
}
- PUT_NEWLINE((*o_mputc));
+ put_newline(o_mputc);
(*o_mputc)(SP);
base64_count = 1;
- if (mimeout_state.count>0
- && (mimeout_state.buf[i]==SP || mimeout_state.buf[i]==TAB
- || mimeout_state.buf[i]==CR || mimeout_state.buf[i]==LF)) {
+ if (mimeout_state.count>0 && nkf_isspace(mimeout_state.buf[i])) {
i++;
}
}
for (;i<mimeout_state.count;i++) {
- if (mimeout_state.buf[i]==SP || mimeout_state.buf[i]==TAB
- || mimeout_state.buf[i]==CR || mimeout_state.buf[i]==LF) {
+ if (nkf_isspace(mimeout_state.buf[i])) {
(*o_mputc)(mimeout_state.buf[i]);
base64_count ++;
} else {
if (c2 == EOF){
if (base64_count + mimeout_state.count/3*4> 73){
(*o_base64conv)(EOF,0);
- OCONV_NEWLINE((*o_base64conv));
+ oconv_newline(o_base64conv);
(*o_base64conv)(0,SP);
base64_count = 1;
}
} else {
- if (base64_count + mimeout_state.count/3*4> 66) {
+ if ((c2 != 0 || c1 > DEL) && base64_count + mimeout_state.count/3*4> 66) {
(*o_base64conv)(EOF,0);
- OCONV_NEWLINE((*o_base64conv));
+ oconv_newline(o_base64conv);
(*o_base64conv)(0,SP);
base64_count = 1;
mimeout_mode = -1;
mimeout_mode = (output_mode==ASCII ||output_mode == ISO_8859_1) ? 'Q' : 'B';
open_mime(output_mode);
(*o_base64conv)(EOF,0);
- OCONV_NEWLINE((*o_base64conv));
+ oconv_newline(o_base64conv);
(*o_base64conv)(0,SP);
base64_count = 1;
mimeout_mode = -1;
case 'B':
break;
case 2:
- (*o_mputc)(basis_64[((mimeout_state.state & 0x3)<< 4)]);
+ (*o_mputc)(basis_64[((nkf_state->mimeout_state & 0x3)<< 4)]);
(*o_mputc)('=');
(*o_mputc)('=');
base64_count += 3;
break;
case 1:
- (*o_mputc)(basis_64[((mimeout_state.state & 0xF) << 2)]);
+ (*o_mputc)(basis_64[((nkf_state->mimeout_state & 0xF) << 2)]);
(*o_mputc)('=');
base64_count += 2;
break;
}
break;
case 'B':
- mimeout_state.state=c;
+ nkf_state->mimeout_state=c;
(*o_mputc)(basis_64[c>>2]);
mimeout_mode=2;
base64_count ++;
break;
case 2:
- (*o_mputc)(basis_64[((mimeout_state.state & 0x3)<< 4) | ((c & 0xF0) >> 4)]);
- mimeout_state.state=c;
+ (*o_mputc)(basis_64[((nkf_state->mimeout_state & 0x3)<< 4) | ((c & 0xF0) >> 4)]);
+ nkf_state->mimeout_state=c;
mimeout_mode=1;
base64_count ++;
break;
case 1:
- (*o_mputc)(basis_64[((mimeout_state.state & 0xF) << 2) | ((c & 0xC0) >>6)]);
+ (*o_mputc)(basis_64[((nkf_state->mimeout_state & 0xF) << 2) | ((c & 0xC0) >>6)]);
(*o_mputc)(basis_64[c & 0x3F]);
mimeout_mode='B';
base64_count += 2;
if (base64_count > 71){
if (c!=CR && c!=LF) {
(*o_mputc)('=');
- PUT_NEWLINE((*o_mputc));
+ put_newline(o_mputc);
}
base64_count = 0;
}
}else{
if (base64_count > 71){
eof_mime();
- PUT_NEWLINE((*o_mputc));
+ put_newline(o_mputc);
base64_count = 0;
}
if (c == EOF) { /* c==EOF */
} else if (c <= SP) {
close_mime();
if (base64_count > 70) {
- PUT_NEWLINE((*o_mputc));
+ put_newline(o_mputc);
base64_count = 0;
}
if (!nkf_isblank(c)) {
} else {
if (base64_count > 70) {
close_mime();
- PUT_NEWLINE((*o_mputc));
+ put_newline(o_mputc);
(*o_mputc)(SP);
base64_count = 1;
open_mime(output_mode);
return;
}
}
- (*o_mputc)(c);
- base64_count++;
+ if (c != 0x1B) {
+ (*o_mputc)(c);
+ base64_count++;
+ return;
+ }
}
- return;
}
if (mimeout_mode <= 0) {
- if (c <= DEL && (output_mode==ASCII ||output_mode == ISO_8859_1)) {
+ if (c <= DEL && (output_mode==ASCII || output_mode == ISO_8859_1 ||
+ output_mode == UTF_8)) {
if (nkf_isspace(c)) {
int flag = 0;
if (mimeout_mode == -1) {
if (base64_count > 1
&& base64_count + mimeout_state.count > 76
&& mimeout_state.buf[0] != CR && mimeout_state.buf[0] != LF){
- PUT_NEWLINE((*o_mputc));
- base64_count = 0;
- if (!nkf_isspace(mimeout_state.buf[0])){
- (*o_mputc)(SP);
- base64_count++;
+ static const char *str = "boundary=\"";
+ static int len = 10;
+ i = 0;
+
+ for (; i < mimeout_state.count - len; ++i) {
+ if (!strncmp((char *)(mimeout_state.buf+i), str, len)) {
+ i += len - 2;
+ break;
+ }
+ }
+
+ if (i == 0 || i == mimeout_state.count - len) {
+ put_newline(o_mputc);
+ base64_count = 0;
+ if (!nkf_isspace(mimeout_state.buf[0])){
+ (*o_mputc)(SP);
+ base64_count++;
+ }
+ }
+ else {
+ int j;
+ for (j = 0; j <= i; ++j) {
+ (*o_mputc)(mimeout_state.buf[j]);
+ }
+ put_newline(o_mputc);
+ base64_count = 1;
+ for (; j <= mimeout_state.count; ++j) {
+ mimeout_state.buf[j - i] = mimeout_state.buf[j];
+ }
+ mimeout_state.count -= i;
}
}
mimeout_state.buf[mimeout_state.count++] = (char)c;
}
}else{
/* mimeout_mode == 'B', 1, 2 */
- if ( c<=DEL && (output_mode==ASCII ||output_mode == ISO_8859_1)) {
+ if (c <= DEL && (output_mode==ASCII || output_mode == ISO_8859_1 ||
+ output_mode == UTF_8)) {
if (lastchar == CR || lastchar == LF){
if (nkf_isblank(c)) {
for (i=0;i<mimeout_state.count;i++) {
mimeout_addchar(mimeout_state.buf[i]);
}
mimeout_state.count = 0;
- } else if (SP<c && c<DEL) {
+ } else {
eof_mime();
for (i=0;i<mimeout_state.count;i++) {
(*o_mputc)(mimeout_state.buf[i]);
mimeout_state.buf[mimeout_state.count++] = (char)c;
return;
}
- if (c==SP || c==TAB || c==CR || c==LF) {
+ if (nkf_isspace(c)) {
for (i=0;i<mimeout_state.count;i++) {
if (SP<mimeout_state.buf[i] && mimeout_state.buf[i]<DEL) {
eof_mime();
nkf_iconv_t converter;
converter->input_buffer_size = IOBUF_SIZE;
- converter->input_buffer = malloc(converter->input_buffer_size);
- if (converter->input_buffer == NULL)
- perror("can't malloc");
-
+ converter->input_buffer = nkf_xmalloc(converter->input_buffer_size);
converter->output_buffer_size = IOBUF_SIZE * 2;
- converter->output_buffer = malloc(converter->output_buffer_size);
- if (converter->output_buffer == NULL)
- perror("can't malloc");
-
+ converter->output_buffer = nkf_xmalloc(converter->output_buffer_size);
converter->cd = iconv_open(tocode, fromcode);
if (converter->cd == (iconv_t)-1)
{
static void
nkf_iconv_close(nkf_iconv_t *convert)
{
- free(converter->inbuf);
- free(converter->outbuf);
+ nkf_xfree(converter->inbuf);
+ nkf_xfree(converter->outbuf);
iconv_close(converter->cd);
}
#endif
broken_f = FALSE;
iso8859_f = FALSE;
mimeout_f = FALSE;
- x0201_f = X0201_DEFAULT;
+ x0201_f = NKF_UNSPECIFIED;
iso2022jp_f = FALSE;
#if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
ms_ucs_map_f = UCS_MAP_ASCII;
input_eol = 0;
prev_cr = 0;
option_mode = 0;
- init_broken_state();
z_prev2=0,z_prev1=0;
#ifdef CHECK_OPTION
iconv_for_check = 0;
input_codename = NULL;
input_encoding = NULL;
output_encoding = NULL;
+ nkf_state_init();
#ifdef WIN32DLL
reinitdll();
#endif /*WIN32DLL*/
set_output_encoding(output_encoding);
oconv = nkf_enc_to_oconv(output_encoding);
o_putc = std_putc;
+ if (nkf_enc_unicode_p(output_encoding))
+ output_mode = UTF_8;
+
+ if (x0201_f == NKF_UNSPECIFIED) {
+ x0201_f = X0201_DEFAULT;
+ }
/* replace continucation module, from output side */
#define NEXT continue /* no output, get next */
#define SKIP c2=0;continue /* no output, get next */
#define MORE c2=c1;continue /* need one more byte */
-#define SEND ; /* output c1 and c2, get next */
+#define SEND (void)0 /* output c1 and c2, get next */
#define LAST break /* end of loop, go closing */
#define set_input_mode(mode) do { \
input_mode = mode; \
(c4 = (*i_getc)(f)) != EOF) {
nkf_iconv_utf_32(c1, c2, c3, c4);
}
- (*i_ungetc)(EOF, f);
+ goto finished;
}
else if (iconv == w_iconv16) {
while ((c1 = (*i_getc)(f)) != EOF &&
(c2 = (*i_getc)(f)) != EOF) {
- if (nkf_iconv_utf_16(c1, c2, 0, 0) == -2 &&
+ if (nkf_iconv_utf_16(c1, c2, 0, 0) == NKF_ICONV_NEED_TWO_MORE_BYTES &&
(c3 = (*i_getc)(f)) != EOF &&
(c4 = (*i_getc)(f)) != EOF) {
nkf_iconv_utf_16(c1, c2, c3, c4);
}
}
- (*i_ungetc)(EOF, f);
+ goto finished;
}
#endif
if (input_mode == JIS_X_0208 && DEL <= c1 && c1 < 0x92) {
/* CP5022x */
MORE;
+ }else if (input_codename && input_codename[0] == 'I' &&
+ 0xA1 <= c1 && c1 <= 0xDF) {
+ /* JIS X 0201 Katakana in 8bit JIS */
+ c2 = JIS_X_0201_1976_K;
+ c1 &= 0x7f;
+ SEND;
} else if (c1 > DEL) {
/* 8 bit code */
if (!estab_f && !iso8859_f) {
SKIP;
} else if (c1 == ESC && (!is_8bit || mime_decode_mode)) {
if ((c1 = (*i_getc)(f)) == EOF) {
- /* (*oconv)(0, ESC); don't send bogus code */
+ (*oconv)(0, ESC);
LAST;
}
else if (c1 == '&') {
} else if (c1 == ESC && iconv == s_iconv) {
/* ESC in Shift_JIS */
if ((c1 = (*i_getc)(f)) == EOF) {
- /* (*oconv)(0, ESC); don't send bogus code */
+ (*oconv)(0, ESC);
LAST;
} else if (c1 == '$') {
/* J-PHONE emoji */
/* goto next_word */
}
+finished:
/* epilogue */
(*iconv)(EOF, 0, 0);
if (!input_codename)
option_mode = 1;
return 0;
}
- for (i=0;i<sizeof(long_option)/sizeof(long_option[0]);i++) {
+ for (i=0;i<(int)(sizeof(long_option)/sizeof(long_option[0]));i++) {
p = (unsigned char *)long_option[i].name;
for (j=0;*p && *p != '=' && *p == cp[j];p++, j++);
if (*p == cp[j] || cp[j] == SP){
cp_back = cp;
cp = (unsigned char *)long_option[i].alias;
}else{
+#ifndef PERL_XS
+ if (strcmp(long_option[i].name, "help") == 0){
+ usage();
+ exit(EXIT_SUCCESS);
+ }
+#endif
if (strcmp(long_option[i].name, "ic=") == 0){
enc = nkf_enc_find((char *)p);
if (!enc) continue;
overwrite_f = TRUE;
preserve_time_f = TRUE;
backup_f = TRUE;
- backup_suffix = malloc(strlen((char *) p) + 1);
- strcpy(backup_suffix, (char *) p);
+ backup_suffix = (char *)p;
continue;
}
if (strcmp(long_option[i].name, "in-place") == 0){
overwrite_f = TRUE;
preserve_time_f = FALSE;
backup_f = TRUE;
- backup_suffix = malloc(strlen((char *) p) + 1);
- strcpy(backup_suffix, (char *) p);
+ backup_suffix = (char *)p;
continue;
}
#endif
output_encoding = nkf_enc_from_index(EUCJP_NKF);
continue;
case 's': /* SJIS output */
- output_encoding = nkf_enc_from_index(WINDOWS_31J);
+ 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 */
if (*cp=='@'||*cp=='B')
kanji_intro = *cp++;
continue;
- case 'o': /* ASCII IN ESC-(-J/B */
+ case 'o': /* ASCII IN ESC-(-J/B/H */
+ /* ESC ( H was used in initial JUNET messages */
if (*cp=='J'||*cp=='B'||*cp=='H')
ascii_intro = *cp++;
continue;
#ifndef PERL_XS
case 'V':
show_configuration();
- exit(1);
+ exit(EXIT_SUCCESS);
break;
case 'v':
- usage();
- exit(1);
+ version();
+ exit(EXIT_SUCCESS);
break;
#endif
#ifdef UTF8_OUTPUT_ENABLE
- case 'w': /* UTF-8 output */
+ case 'w': /* UTF-{8,16,32} output */
if (cp[0] == '8') {
cp++;
if (cp[0] == '0'){
if (cp[0]=='L') {
cp++;
output_endian = ENDIAN_LITTLE;
+ output_bom_f = TRUE;
} else if (cp[0] == 'B') {
cp++;
- } else {
- output_encoding = nkf_enc_from_index(enc_idx);
- continue;
+ output_bom_f = TRUE;
}
if (cp[0] == '0'){
+ output_bom_f = FALSE;
cp++;
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;
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);
case 'E': /* EUC-JP input */
input_encoding = nkf_enc_from_index(EUCJP_NKF);
continue;
- case 'S': /* Windows-31J input */
- input_encoding = nkf_enc_from_index(WINDOWS_31J);
+ case 'S': /* Shift_JIS input */
+ input_encoding = nkf_enc_from_index(SHIFT_JIS);
continue;
case 'Z': /* Convert X0208 alphabet to asii */
/* alpha_f
bit:3 Convert HTML Entity
bit:4 Convert JIS X 0208 Katakana to JIS X 0201 Katakana
*/
- while ('0'<= *cp && *cp <='9') {
+ while ('0'<= *cp && *cp <='4') {
alpha_f |= 1 << (*cp++ - '0');
}
- if (!alpha_f) alpha_f = 1;
+ alpha_f |= 1;
continue;
case 'x': /* Convert X0201 kana to X0208 or X0201 Conversion */
x0201_f = FALSE; /* No X0201->X0208 conversion */
#ifdef DEFAULT_CODE_LOCALE
setlocale(LC_CTYPE, "");
#endif
+ nkf_state_init();
+
for (argc--,argv++; (argc > 0) && **argv == '-'; argc--, argv++) {
cp = (unsigned char *)*argv;
options(cp);
if (file_out_f == TRUE) {
#ifdef OVERWRITE
if (overwrite_f){
- outfname = malloc(strlen(origfname)
+ outfname = nkf_xmalloc(strlen(origfname)
+ strlen(".nkftmpXXXXXX")
+ 1);
- if (!outfname){
- perror(origfname);
- return -1;
- }
strcpy(outfname, origfname);
#ifdef MSDOS
{
fprintf(stderr, "Can't rename %s to %s\n",
origfname, backup_filename);
}
- free(backup_filename);
+ nkf_xfree(backup_filename);
}else{
#ifdef MSDOS
if (unlink(origfname)){
fprintf(stderr, "Can't rename %s to %s\n",
outfname, origfname);
}
- free(outfname);
+ nkf_xfree(outfname);
}
#endif
}