* \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.178 2008/05/21 20:41:06 naruse Exp $"
#define NKF_VERSION "2.0.8"
-#define NKF_RELEASE_DATE "2008-02-08"
+#define NKF_RELEASE_DATE "2009-01-04"
#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) 2002-2009 Kono, Furukawa, Naruse, mastodon"
#include "config.h"
#include "nkf.h"
#include "utf8tbl.h"
+#ifdef __WIN32__
+#include <windows.h>
+#include <locale.h>
+#endif
+#if defined(__OS2__)
+# define INCL_DOS
+# define INCL_DOSERRORS
+# include <os2.h>
+#endif
+#include <assert.h>
+
/* state of output_mode and input_mode
#define DEFAULT_ENCIDX ISO_2022_JP
#elif defined(DEFAULT_CODE_SJIS)
#define DEFAULT_ENCIDX SHIFT_JIS
+#elif defined(DEFAULT_CODE_WINDOWS_31J)
+#define DEFAULT_ENCIDX WINDOWS_31J
#elif defined(DEFAULT_CODE_EUC)
#define DEFAULT_ENCIDX EUC_JP
#elif defined(DEFAULT_CODE_UTF8)
#endif
struct input_code{
- char *name;
+ const char *name;
nkf_char stat;
nkf_char score;
nkf_char index;
int _file_stat;
};
-static char *input_codename = NULL; /* NULL: unestablished, "": BINARY */
+static const char *input_codename = NULL; /* NULL: unestablished, "": BINARY */
static nkf_encoding *input_encoding = NULL;
static nkf_encoding *output_encoding = NULL;
-static int kanji_convert(FILE *f);
#if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
/* UCS Mapping
* 0: Shift_JIS, eucJP-ascii
#define nkf_char_euc3_new(c) ((c) | PREFIX_EUCG3)
#define nkf_char_unicode_new(c) ((c) | CLASS_UNICODE)
#define nkf_char_unicode_p(c) ((c & CLASS_MASK) == CLASS_UNICODE)
-#define nkf_char_unicode_bmp_p(c) ((c & VALUE_MASK) <= NKF_INT32_C(UNICODE_BMP_MAX))
-#define nkf_char_unicode_value_p(c) ((c & VALUE_MASK) <= NKF_INT32_C(UNICODE_MAX))
+#define nkf_char_unicode_bmp_p(c) ((c & VALUE_MASK) <= UNICODE_BMP_MAX)
+#define nkf_char_unicode_value_p(c) ((c & VALUE_MASK) <= UNICODE_MAX)
#ifdef NUMCHAR_OPTION
static int numchar_f = FALSE;
#endif
static int guess_f = 0; /* 0: OFF, 1: ON, 2: VERBOSE */
-static void set_input_codename(char *codename);
+static void set_input_codename(const char *codename);
#ifdef EXEC_IO
static int exec_f = 0;
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__)
- return sprintf("CP%d", GetACP());
-#else
+ static char buf[16];
+ sprintf(buf, "CP%d", GetACP());
+ return buf;
+#elif defined(__OS2__)
+# if defined(INT_IS_SHORT)
+ /* OS/2 1.x */
return NULL;
+# else
+ /* OS/2 32bit */
+ static char buf[16];
+ ULONG ulCP[1], ulncp;
+ DosQueryCp(sizeof(ulCP), ulCP, &ulncp);
+ if (ulCP[0] == 932 || ulCP[0] == 943)
+ strcpy(buf, "Shift_JIS");
+ else
+ sprintf(buf, "CP%lu", ulCP[0]);
+ return buf;
+# endif
#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);
- if (enc < 0) enc = 0;
return enc;
}
#endif /* DEFAULT_CODE_LOCALE */
static nkf_encoding*
+nkf_utf8_encoding()
+{
+ return &nkf_encoding_table[UTF_8];
+}
+
+static nkf_encoding*
nkf_default_encoding()
{
nkf_encoding *enc = 0;
#ifdef DEFAULT_CODE_LOCALE
enc = nkf_locale_encoding();
-#elif DEFAULT_ENCIDX
+#elif defined(DEFAULT_ENCIDX)
enc = nkf_enc_from_index(DEFAULT_ENCIDX);
#endif
+ if (!enc) enc = nkf_utf8_encoding();
return enc;
}
{
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"
);
" Default output encoding: "
#ifdef DEFAULT_CODE_LOCALE
"LOCALE (%s)\n", nkf_enc_name(nkf_default_encoding())
-#elif DEFAULT_ENCIDX
+#elif defined(DEFAULT_ENCIDX)
"CONFIG (%s)\n", nkf_enc_name(nkf_default_encoding())
#else
"NONE\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{
- backup_filename = malloc(filename_length + strlen(suffix) + 1);
+ j = filename_length + strlen(suffix);
+ backup_filename = nkf_xmalloc(j + 1);
strcpy(backup_filename, filename);
strcat(backup_filename, suffix);
backup_filename[j] = '\0';
nkf_char val;
#endif
static const char shift_jisx0213_s1a3_table[5][2] ={ { 1, 8}, { 3, 4}, { 5,12}, {13,14}, {15, 0} };
+ if (0xFC < c1) return 1;
#ifdef SHIFTJIS_CP932
if (!cp932inv_f && is_ibmext_in_sjis(c2)){
val = shiftjis_cp932[c2 - CP932_TABLE_BEGIN][c1 - 0x40];
}
if (cp932inv_f
&& CP932INV_TABLE_BEGIN <= c2 && c2 <= CP932INV_TABLE_END){
- nkf_char c = cp932inv[c2 - CP932INV_TABLE_BEGIN][c1 - 0x40];
- if (c){
- c2 = c >> 8;
- c1 = c & 0xff;
+ val = cp932inv[c2 - CP932INV_TABLE_BEGIN][c1 - 0x40];
+ if (val){
+ c2 = val >> 8;
+ c1 = val & 0xff;
}
}
#endif /* SHIFTJIS_CP932 */
#if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
static void
-nkf_unicode_to_utf8(nkf_char val, int *p1, int *p2, int *p3, int *p4)
+nkf_unicode_to_utf8(nkf_char val, nkf_char *p1, nkf_char *p2, nkf_char *p3, nkf_char *p4)
{
val &= VALUE_MASK;
if (val < 0x80){
}
static nkf_char
-nkf_utf8_to_unicode(int c1, int c2, int c3, int c4)
+nkf_utf8_to_unicode(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4)
{
nkf_char wc;
if (c1 <= 0x7F) {
static nkf_char
w16e_conv(nkf_char val, nkf_char *p2, nkf_char *p1)
{
- int c1, c2, c3, c4;
+ nkf_char c1, c2, c3, c4;
nkf_char ret = 0;
val &= VALUE_MASK;
if (val < 0x80) {
#define NKF_ICONV_NEED_TWO_MORE_BYTES -2
#define UTF16_TO_UTF32(lead, trail) (((lead) << 10) + (trail) - NKF_INT32_C(0x35FDC00))
static size_t
-nkf_iconv_utf_16(int c1, int c2, int c3, int c4)
+nkf_iconv_utf_16(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4)
{
nkf_char wc;
}
static size_t
-nkf_iconv_utf_32(int c1, int c2, int c3, int c4)
+nkf_iconv_utf_32(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4)
{
nkf_char wc;
static void
w_oconv(nkf_char c2, nkf_char c1)
{
- int c3, c4;
+ nkf_char c3, c4;
nkf_char val;
if (output_bom_f) {
c1 = val & 0xff;
if (!val) return;
}
+
if (output_endian == ENDIAN_LITTLE){
(*o_putc)(c1);
(*o_putc)(c2);
if (alpha_f&8 && c2 == 0) {
/* HTML Entity */
- char *entity = 0;
+ const char *entity = 0;
switch (c1){
case '>': entity = ">"; break;
case '<': entity = "<"; break;
#endif
static void
-set_input_codename(char *codename)
+set_input_codename(const char *codename)
{
if (!input_codename) {
input_codename = codename;
}
}
-static char*
+static const char*
get_guessed_code(void)
{
if (input_codename && !*input_codename) {
nkf_char (*g)(FILE *) = i_ngetc;
nkf_char (*u)(nkf_char c ,FILE *f) = i_nungetc;
int i = 0, j;
- nkf_char buf[8];
+ nkf_char buf[12];
long c = -1;
buf[i] = (*g)(f);
#ifdef UNICODE_NORMALIZATION
+typedef struct {
+ unsigned char *ary;
+ int max_length;
+ int count;
+} nkf_ary;
+
+static nkf_ary *
+nkf_ary_new(int length)
+{
+ nkf_ary *ary = nkf_xmalloc(sizeof(nkf_ary));
+ ary->ary = nkf_xmalloc(length);
+ ary->max_length = length;
+ ary->count = 0;
+ return ary;
+}
+
+static void
+nkf_ary_dispose(nkf_ary *ary)
+{
+ nkf_xfree(ary->ary);
+ nkf_xfree(ary);
+}
+
+#define nkf_ary_length(ary) ((ary)->count)
+#define nkf_ary_empty_p(ary) ((ary)->count == 0)
+
+static unsigned char
+nkf_ary_at(nkf_ary *ary, int index)
+{
+ assert(index <= ary->count);
+ return ary->ary[index];
+}
+
+static void
+nkf_ary_clear(nkf_ary *ary)
+{
+ ary->count = 0;
+}
+
+static unsigned char
+nkf_ary_push(nkf_ary *ary, nkf_char c)
+{
+ assert(ary->max_length > ary->count);
+ ary->ary[ary->count++] = c;
+ return ary->count;
+}
+
+static unsigned char
+nkf_ary_pop(nkf_ary *ary)
+{
+ assert(0 < ary->count);
+ return ary->ary[--ary->count];
+}
+
/* 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_ary *buf = nkf_ary_new(9);
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_ary_push(buf, (unsigned char)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_ary_length(buf)) {
+ c = (*g)(f);
+ if (c == EOF) {
+ len = 0;
+ lower = 1, upper = 0;
+ break;
+ }
+ nkf_ary_push(buf, c);
+ }
+ if (array[len] != nkf_ary_at(buf, len)) {
+ if (array[len] < nkf_ary_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_ary_clear(buf);
for (i=0; i < NORMALIZATION_TABLE_NFC_LENGTH && array[i]; i++)
- buf[i] = (nkf_char)(array[i]);
- i--;
+ nkf_ary_push(buf, array[i]);
break;
}
}
- while (i > 0)
- (*u)(buf[i--], f);
- }
- return buf[0];
+ } while (lower <= upper);
+
+ while (nkf_ary_length(buf) > 1) (*u)(nkf_ary_pop(buf), f);
+ c = nkf_ary_pop(buf);
+ nkf_ary_dispose(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:
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 */
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:
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];
int count;
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(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;
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
{
nkf_char c1=0, c2=0, c3=0, c4=0;
int shift_mode = 0; /* 0, 1, 2, 3 */
- char g2 = 0;
+ int g2 = 0;
int is_8bit = FALSE;
if (input_encoding && !nkf_enc_asciicompat(input_encoding)) {
SEND;
}
}
+ else if (nkf_char_unicode_p(c1)) {
+ (*oconv)(0, c1);
+ NEXT;
+ }
else {
/* first byte */
if (input_mode == JIS_X_0208 && DEL <= c1 && c1 < 0x92) {
C%7 : 0 1 2 3 4 5 6
NUM : 2 0 3 4 5 X 1
*/
- static const int jphone_emoji_first_table[7] =
+ static const nkf_char jphone_emoji_first_table[7] =
{0xE1E0, 0xDFE0, 0xE2E0, 0xE3E0, 0xE4E0, 0xDFE0, 0xE0E0};
c3 = nkf_char_unicode_new(jphone_emoji_first_table[c1 % 7]);
if ((c1 = (*i_getc)(f)) == EOF) LAST;
}
if (strcmp(long_option[i].name, "oc=") == 0){
enc = nkf_enc_find((char *)p);
- if (enc <= 0) continue;
+ /* if (enc <= 0) continue; */
+ if (!enc) continue;
output_encoding = 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
cp++;
input_endian = ENDIAN_BIG;
}
- enc_idx = enc_idx == UTF_16
- ? (output_endian == ENDIAN_LITTLE ? UTF_16LE : UTF_16BE)
- : (output_endian == ENDIAN_LITTLE ? UTF_32LE : UTF_32BE);
+ enc_idx = (enc_idx == UTF_16
+ ? (input_endian == ENDIAN_LITTLE ? UTF_16LE : UTF_16BE)
+ : (input_endian == ENDIAN_LITTLE ? UTF_32LE : UTF_32BE));
input_encoding = nkf_enc_from_index(enc_idx);
}
continue;
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
}