OSDN Git Service

* add -pedantic.
[nkf/nkf.git] / nkf.c
diff --git a/nkf.c b/nkf.c
index ce68917..b9a38d9 100644 (file)
--- a/nkf.c
+++ b/nkf.c
  * \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.189 2008/11/09 18:28:52 naruse Exp $"
 #define NKF_VERSION "2.0.8"
-#define NKF_RELEASE_DATE "2008-11-10"
+#define NKF_RELEASE_DATE "2009-01-05"
 #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"
@@ -52,6 +51,7 @@
 #endif
 #include <assert.h>
 
+
 /* state of output_mode and input_mode
 
    c2           0 means ASCII
@@ -140,7 +140,7 @@ enum nkf_encodings {
     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);
@@ -664,6 +664,38 @@ static int             end_check;
 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)
 {
@@ -724,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 */
@@ -755,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;
@@ -790,6 +814,60 @@ nkf_default_encoding()
     return enc;
 }
 
+typedef struct {
+    long capa;
+    long len;
+    unsigned 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(length);
+    buf->capa = length;
+    buf->len = 0;
+    return buf;
+} 
+
+static void
+nkf_buf_dispose(nkf_buf_t *buf)
+{
+    nkf_xfree(buf->ptr);
+    nkf_xfree(buf);
+}
+
+#define nkf_buf_length(buf) ((buf)->len)
+#define nkf_buf_empty_p(buf) ((buf)->len == 0)
+
+static unsigned 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->ptr = 0;
+}
+
+static void
+nkf_buf_push(nkf_buf_t *buf, unsigned char c)
+{
+    assert(buf->capa > buf->len);
+    buf->ptr[buf->len++] = c;
+}
+
+static unsigned 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
@@ -817,6 +895,8 @@ usage(void)
            "         After 'W' you can add more options. -W[ 8, 16 [BL] ] \n"
 #endif
            "t        no conversion\n"
+           );
+    fprintf(HELP_OUTPUT,
            "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"
@@ -825,11 +905,15 @@ usage(void)
            "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"
+           );
+    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      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"
+           );
+    fprintf(HELP_OUTPUT,
 #ifdef MSDOS
            "T        Text mode output\n"
 #endif
@@ -838,7 +922,8 @@ usage(void)
            "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"
+           "\n");
+    fprintf(HELP_OUTPUT,
            "Long name options\n"
            " --ic=<input codeset>  --oc=<output codeset>\n"
            "                   Specify the input or output codeset\n"
@@ -848,6 +933,8 @@ usage(void)
            " --hiragana  --katakana  --katakana-hiragana\n"
            "                   To Hiragana/Katakana Conversion\n"
            " --prefix=         Insert escape before troublesome characters of Shift_JIS\n"
+           );
+    fprintf(HELP_OUTPUT,
 #ifdef INPUT_OPTION
            " --cap-input, --url-input  Convert hex after ':' or '%%'\n"
 #endif
@@ -858,6 +945,8 @@ usage(void)
            " --fb-{skip, html, xml, perl, java, subchar}\n"
            "                   Specify how nkf handles unassigned characters\n"
 #endif
+           );
+    fprintf(HELP_OUTPUT,
 #ifdef OVERWRITE
            " --in-place[=SUFFIX]  --overwrite[=SUFFIX]\n"
            "                   Overwrite original listed files by filtered result\n"
@@ -875,8 +964,6 @@ show_configuration(void)
 {
     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"
           );
@@ -938,12 +1025,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_xmalloc(strlen(suffix) + (asterisk_count * (filename_length - 1)) + 1);
        for(i = 0, j = 0; suffix[i];){
            if(suffix[i] == '*'){
                backup_filename[j] = '\0';
@@ -957,7 +1039,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_xmalloc(j + 1);
        strcpy(backup_filename, filename);
        strcat(backup_filename, suffix);
        backup_filename[j] = '\0';
@@ -2610,14 +2692,14 @@ w_oconv32(nkf_char c2, nkf_char c1)
 
 #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,
@@ -3559,7 +3641,7 @@ z_conv(nkf_char c2, nkf_char c1)
     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 */
@@ -4199,65 +4281,17 @@ numchar_ungetc(nkf_char c, FILE *f)
 
 #ifdef UNICODE_NORMALIZATION
 
-typedef struct {
-    unsigned char *buf;
-    int max_length;
-    int count;
-} nkf_buffer;
-
-static nkf_buffer *
-nkf_buf_new(int length)
-{
-    nkf_buffer *buf = malloc(sizeof(nkf_buffer));
-    buf->buf = malloc(length);
-    buf->max_length = length;
-    buf->count = 0;
-    return buf;
-} 
-
-#define nkf_buf_count(buf) ((buf)->count)
-#define nkf_buf_empty_p(buf) ((buf)->count == 0)
-
-static unsigned char
-nkf_buf_push(nkf_buffer *buf, nkf_char c)
-{
-    assert(buf->max_length > buf->count);
-    buf->buf[buf->count++] = c;
-    return buf->count;
-}
-
-static unsigned char
-nkf_buf_pop(nkf_buffer *buf)
-{
-    assert(0 < buf->count);
-    return buf->buf[--buf->count];
-}
-
-static unsigned char
-nkf_buf_at(nkf_buffer *buf, int index)
-{
-    assert(index <= buf->count);
-    return buf->buf[index];
-}
-
-static void
-nkf_buf_clear(nkf_buffer *buf)
-{
-    buf->count = 0;
-}
-
-/* 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;
-    nkf_buffer *buf = nkf_buf_new(9);
+    nkf_buf_t *buf = nkf_buf_new(9);
     const unsigned char *array;
     int lower=0, upper=NORMALIZATION_TABLE_LENGTH-1;
-    int c = (*g)(f);
+    nkf_char c = (*g)(f);
 
-    if (c == EOF || c > 0xFF || (c & 0xc0) != 0x80) return c;
+    if (c == EOF || c > 0xFF || (c & 0xc0) == 0x80) return c;
 
     nkf_buf_push(buf, (unsigned char)c);
     do {
@@ -4266,12 +4300,7 @@ nfc_getc(FILE *f)
            int len;
            array = normalization_table[mid].nfd;
            for (len=0; len < NORMALIZATION_TABLE_NFD_LENGTH && array[len]; len++) {
-               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 (len >= nkf_buf_count(buf)) {
+               if (len >= nkf_buf_length(buf)) {
                    c = (*g)(f);
                    if (c == EOF) {
                        len = 0;
@@ -4280,6 +4309,12 @@ nfc_getc(FILE *f)
                    }
                    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;
+               }
            }
            if (len > 0) {
                int i;
@@ -4292,9 +4327,11 @@ nfc_getc(FILE *f)
        }
     } while (lower <= upper);
 
-    while (nkf_buf_count(buf) > 1) (*u)(nkf_buf_pop(buf), f);
+    while (nkf_buf_length(buf) > 1) (*u)(nkf_buf_pop(buf), f);
+    c = nkf_buf_pop(buf);
+    nkf_buf_dispose(buf);
 
-    return nkf_buf_pop(buf);
+    return c;
 }
 
 static nkf_char
@@ -4368,11 +4405,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_xmalloc((lwsp_size+5)*sizeof(char));
            while ((c1=(*i_getc)(f))!=EOF) {
                switch (c1) {
                case LF:
@@ -4405,12 +4438,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_xrealloc(lwsp_buf, (lwsp_size+5)*sizeof(char));
                        lwsp_buf = lwsp_buf_new;
                    }
                    continue;
@@ -4423,7 +4451,7 @@ mime_getc(FILE *f)
                    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 */
@@ -4476,11 +4504,7 @@ mime_getc(FILE *f)
     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:
@@ -4516,12 +4540,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_xrealloc(lwsp_buf, (lwsp_size+5)*sizeof(char));
                    lwsp_buf = lwsp_buf_new;
                }
                continue;
@@ -4534,7 +4553,7 @@ mime_getc(FILE *f)
                i_ungetc(lwsp_buf[lwsp_count],f);
            c1 = lwsp_buf[0];
        }
-       free(lwsp_buf);
+       nkf_xfree(lwsp_buf);
        return c1;
     }
   mime_c3_retry:
@@ -4581,7 +4600,7 @@ mime_getc(FILE *f)
 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;
@@ -4891,11 +4910,36 @@ mime_putc(nkf_char c)
                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;
@@ -5019,15 +5063,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_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)
     {
@@ -5094,8 +5132,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_xfree(converter->inbuf);
+    nkf_xfree(converter->outbuf);
     iconv_close(converter->cd);
 }
 #endif
@@ -5872,8 +5910,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){
@@ -5887,8 +5924,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
@@ -6476,13 +6512,9 @@ main(int argc, char **argv)
                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
                        {
@@ -6596,7 +6628,7 @@ main(int argc, char **argv)
                            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)){
@@ -6609,7 +6641,7 @@ main(int argc, char **argv)
                        fprintf(stderr, "Can't rename %s to %s\n",
                                outfname, origfname);
                    }
-                   free(outfname);
+                   nkf_xfree(outfname);
                }
 #endif
            }