X-Git-Url: http://git.sourceforge.jp/view?p=nkf%2Fnkf.git;a=blobdiff_plain;f=nkf.c;h=fa88403ccb597627156fd6647e842a4b946033b3;hp=e609edc74b01c0bf124363f6de87d0f46272557e;hb=5e9cdc790dfadb53b2795a696996179d2882ab93;hpb=1e755758293683429714fa89ddfc95510e44594d diff --git a/nkf.c b/nkf.c index e609edc..fa88403 100644 --- a/nkf.c +++ b/nkf.c @@ -31,9 +31,9 @@ * 現在、nkf は SorceForge にてメンテナンスが続けられています。 * http://sourceforge.jp/projects/nkf/ ***********************************************************************/ -#define NKF_IDENT "$Id: nkf.c,v 1.187 2008/11/07 02:37:21 naruse Exp $" +#define NKF_IDENT "$Id: nkf.c,v 1.192 2008/11/09 23:09:22 naruse Exp $" #define NKF_VERSION "2.0.8" -#define NKF_RELEASE_DATE "2008-10-28" +#define NKF_RELEASE_DATE "2008-11-10" #define COPY_RIGHT \ "Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa),2000 S. Kono, COW\n" \ "Copyright (C) 2002-2008 Kono, Furukawa, Naruse, mastodon" @@ -50,6 +50,7 @@ # define INCL_DOSERRORS # include #endif +#include /* state of output_mode and input_mode @@ -663,6 +664,38 @@ static int end_check; nkf_char std_gc_buf[STD_GC_BUFSIZE]; nkf_char std_gc_ndx; +static void * +nkf_malloc(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_realloc(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_free(ptr) free(ptr) + static int nkf_str_caseeql(const char *src, const char *target) { @@ -723,22 +756,15 @@ nkf_enc_find(const char *name) 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 */ @@ -754,16 +780,15 @@ nkf_locale_charmap() 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; @@ -937,12 +962,7 @@ get_backup_filename(const char *suffix, const char *filename) } 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_malloc(strlen(suffix) + (asterisk_count * (filename_length - 1)) + 1); for(i = 0, j = 0; suffix[i];){ if(suffix[i] == '*'){ backup_filename[j] = '\0'; @@ -956,7 +976,7 @@ get_backup_filename(const char *suffix, const char *filename) backup_filename[j] = '\0'; }else{ j = filename_length + strlen(suffix); - backup_filename = malloc(j + 1); + backup_filename = nkf_malloc(j + 1); strcpy(backup_filename, filename); strcat(backup_filename, suffix); backup_filename[j] = '\0'; @@ -4198,42 +4218,112 @@ numchar_ungetc(nkf_char c, FILE *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_malloc(sizeof(nkf_ary)); + ary->ary = nkf_malloc(length); + ary->max_length = length; + ary->count = 0; + return ary; +} + +static void +nkf_ary_dispose(nkf_ary *ary) +{ + nkf_free(ary->ary); + nkf_free(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 @@ -4307,11 +4397,7 @@ mime_getc(FILE *f) /* 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_malloc((lwsp_size+5)*sizeof(char)); while ((c1=(*i_getc)(f))!=EOF) { switch (c1) { case LF: @@ -4344,12 +4430,7 @@ mime_getc(FILE *f) 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_realloc(lwsp_buf, (lwsp_size+5)*sizeof(char)); lwsp_buf = lwsp_buf_new; } continue; @@ -4362,7 +4443,7 @@ mime_getc(FILE *f) i_ungetc(lwsp_buf[lwsp_count],f); c1 = lwsp_buf[0]; } - free(lwsp_buf); + nkf_free(lwsp_buf); return c1; } if (c1=='='&&c2lwsp_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_realloc(lwsp_buf, (lwsp_size+5)*sizeof(char)); lwsp_buf = lwsp_buf_new; } continue; @@ -4473,7 +4545,7 @@ mime_getc(FILE *f) i_ungetc(lwsp_buf[lwsp_count],f); c1 = lwsp_buf[0]; } - free(lwsp_buf); + nkf_free(lwsp_buf); return c1; } mime_c3_retry: @@ -4958,15 +5030,9 @@ nkf_iconv_new(char *tocode, char *fromcode) 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_malloc(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_malloc(converter->output_buffer_size); converter->cd = iconv_open(tocode, fromcode); if (converter->cd == (iconv_t)-1) { @@ -5033,8 +5099,8 @@ nkf_iconv_convert(nkf_iconv_t *converter, FILE *input) static void nkf_iconv_close(nkf_iconv_t *convert) { - free(converter->inbuf); - free(converter->outbuf); + nkf_free(converter->inbuf); + nkf_free(converter->outbuf); iconv_close(converter->cd); } #endif @@ -5811,8 +5877,7 @@ options(unsigned char *cp) 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){ @@ -5826,8 +5891,7 @@ options(unsigned char *cp) 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 @@ -6415,13 +6479,9 @@ main(int argc, char **argv) if (file_out_f == TRUE) { #ifdef OVERWRITE if (overwrite_f){ - outfname = malloc(strlen(origfname) + outfname = nkf_malloc(strlen(origfname) + strlen(".nkftmpXXXXXX") + 1); - if (!outfname){ - perror(origfname); - return -1; - } strcpy(outfname, origfname); #ifdef MSDOS { @@ -6535,7 +6595,7 @@ main(int argc, char **argv) fprintf(stderr, "Can't rename %s to %s\n", origfname, backup_filename); } - free(backup_filename); + nkf_free(backup_filename); }else{ #ifdef MSDOS if (unlink(origfname)){ @@ -6548,7 +6608,7 @@ main(int argc, char **argv) fprintf(stderr, "Can't rename %s to %s\n", outfname, origfname); } - free(outfname); + nkf_free(outfname); } #endif }