OSDN Git Service

スコアによる判定が、あまり機能していなかったのを修正
[nkf/nkf.git] / nkf.c
diff --git a/nkf.c b/nkf.c
index f7f7795..e8880a5 100644 (file)
--- a/nkf.c
+++ b/nkf.c
@@ -439,7 +439,7 @@ struct input_code input_code_list[] = {
     {"EUC-JP",    0, 0, 0, {0, 0, 0}, e_status, e_iconv, 0},
     {"Shift_JIS", 0, 0, 0, {0, 0, 0}, s_status, s_iconv, 0},
     {"UTF-8",     0, 0, 0, {0, 0, 0}, w_status, w_iconv, 0},
-    {"UTF-16",     0, 0, 0, {0, 0, 0}, w16_status, w_iconv16, 0},
+    {"UTF-16",    0, 0, 0, {0, 0, 0}, w16_status, w_iconv16, 0},
     {0}
 };
 
@@ -965,7 +965,7 @@ options(cp)
 #endif
 #ifdef SHIFTJIS_CP932
                 if (strcmp(long_option[i].name, "no-cp932") == 0){
-                    cp932_f = TRUE;
+                    cp932_f = FALSE;
                     continue;
                 }
 #endif
@@ -1196,6 +1196,25 @@ options(cp)
 }
 
 #ifdef ANSI_C_PROTOTYPE
+struct input_code * find_inputcode_byfunc(int (*iconv_func)(int c2,int c1,int c0))
+#else
+struct input_code * find_inputcode_byfunc(iconv_func)
+     int (*iconv_func)();
+#endif
+{
+    if (iconv_func){
+        struct input_code *p = input_code_list;
+        while (p->name){
+            if (iconv_func == p->iconv_func){
+                return p;
+            }
+            p++;
+        }
+    }
+    return 0;
+}
+
+#ifdef ANSI_C_PROTOTYPE
 void set_iconv(int f, int (*iconv_func)(int c2,int c1,int c0))
 #else
 void set_iconv(f, iconv_func)
@@ -1222,18 +1241,17 @@ void set_iconv(f, iconv_func)
     }
 #ifdef CHECK_OPTION
     if (estab_f && iconv_for_check != iconv){
-#ifdef UTF8_INPUT_ENABLE
-        if (iconv == w_iconv) debug(input_codename = "UTF-8");
-        if (iconv == w_iconv16) debug(input_codename = "UTF-16");
-#endif
-        if (iconv == s_iconv) debug(input_codename = "Shift_JIS");
-        if (iconv == e_iconv) debug(input_codename = "EUC-JP");
+        struct input_code *p = find_inputcode_byfunc(iconv);
+        if (p){
+            debug(input_codename = p->name);
+        }
         iconv_for_check = iconv;
     }
 #endif
 }
 
-#define SCORE_KANA     (1)                   /* \e$B$$$o$f$kH>3Q%+%J\e(B */
+#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 */
 #ifdef SHIFTJIS_CP932
 #define SCORE_CP932    (SCORE_DEPEND << 1)   /* CP932 \e$B$K$h$kFI$_49$(\e(B */
@@ -1241,7 +1259,11 @@ void set_iconv(f, iconv_func)
 #else
 #define SCORE_NO_EXIST (SCORE_DEPEND << 1)   /* \e$BB8:_$7$J$$J8;z\e(B */
 #endif
-#define SCORE_ERROR    (SCORE_NO_EXIST << 1) /* \e$B%(%i!<\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_INIT (SCORE_iMIME)
+
 int score_table_A0[] = {
     0, 0, 0, 0,
     0, 0, 0, 0,
@@ -1250,8 +1272,8 @@ int score_table_A0[] = {
 };
 
 int score_table_F0[] = {
-    0, 0, 0, 0,
-    0, SCORE_DEPEND, SCORE_NO_EXIST, SCORE_NO_EXIST,
+    SCORE_L2, SCORE_L2, SCORE_L2, SCORE_L2,
+    SCORE_L2, SCORE_DEPEND, SCORE_NO_EXIST, SCORE_NO_EXIST,
     SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND,
     SCORE_DEPEND, SCORE_NO_EXIST, SCORE_NO_EXIST, SCORE_ERROR,
 };
@@ -1260,7 +1282,18 @@ void set_code_score(ptr, score)
      struct input_code *ptr;
      int score;
 {
-    ptr->score |= score;
+    if (ptr){
+        ptr->score |= score;
+    }
+}
+
+void clr_code_score(ptr, score)
+     struct input_code *ptr;
+     int score;
+{
+    if (ptr){
+        ptr->score &= ~score;
+    }
 }
 
 void code_score(ptr)
@@ -1270,18 +1303,19 @@ void code_score(ptr)
     int c1 = ptr->buf[1];
     if (c2 < 0){
         set_code_score(ptr, SCORE_ERROR);
-    }else if ((c2 & 0xf0) == 0xa0){
-        set_code_score(ptr, score_table_A0[c2 & 0x0f]);
-    }else if ((c2 & 0xf0) == 0xf0){
-        set_code_score(ptr, score_table_F0[c2 & 0x0f]);
     }else if (c2 == SSO){
         set_code_score(ptr, SCORE_KANA);
-    }
 #ifdef UTF8_OUTPUT_ENABLE
-    else if (!e2w_conv(c2, c1)){
+    }else if (!e2w_conv(c2, c1)){
         set_code_score(ptr, SCORE_NO_EXIST);
-    }
 #endif
+    }else if ((c2 & 0x70) == 0x20){
+        set_code_score(ptr, score_table_A0[c2 & 0x0f]);
+    }else if ((c2 & 0x70) == 0x70){
+        set_code_score(ptr, score_table_F0[c2 & 0x0f]);
+    }else if ((c2 & 0x70) >= 0x50){
+        set_code_score(ptr, SCORE_L2);
+    }
 }
 
 void status_disable(ptr)
@@ -1300,14 +1334,20 @@ void status_push_ch(ptr, c)
     ptr->buf[ptr->index++] = c;
 }
 
-void status_reset(ptr)
+void status_clear(ptr)
      struct input_code *ptr;
 {
     ptr->stat = 0;
-    ptr->score = 0;
     ptr->index = 0;
 }
 
+void status_reset(ptr)
+     struct input_code *ptr;
+{
+    status_clear(ptr);
+    ptr->score = SCORE_INIT;
+}
+
 void status_reinit(ptr)
      struct input_code *ptr;
 {
@@ -1343,7 +1383,7 @@ void s_status(ptr, c)
               status_push_ch(ptr, SSO);
               status_push_ch(ptr, c);
               code_score(ptr);
-              status_reset(ptr);
+              status_clear(ptr);
           }else if ((0x81 <= c && c < 0xa0) || (0xe0 <= c && c <= 0xef)){
               ptr->stat = 1;
               status_push_ch(ptr, c);
@@ -1362,7 +1402,7 @@ void s_status(ptr, c)
               status_push_ch(ptr, c);
               s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]);
               code_score(ptr);
-              status_reset(ptr);
+              status_clear(ptr);
           }else{
               status_disable(ptr);
           }
@@ -1373,7 +1413,7 @@ void s_status(ptr, c)
               status_push_ch(ptr, c);
               if (s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]) == 0){
                   set_code_score(ptr, SCORE_CP932);
-                  status_reset(ptr);
+                  status_clear(ptr);
                   break;
               }
           }
@@ -1409,7 +1449,7 @@ void e_status(ptr, c)
           if (0xa1 <= c && c <= 0xfe){
               status_push_ch(ptr, c);
               code_score(ptr);
-              status_reset(ptr);
+              status_clear(ptr);
           }else{
               status_disable(ptr);
           }
@@ -1449,7 +1489,7 @@ void w16_status(ptr, c)
               ptr->_file_stat = -1;
           }else{
               status_push_ch(ptr, c);
-              status_reset(ptr);
+              status_clear(ptr);
           }
           break;
 
@@ -1457,7 +1497,7 @@ void w16_status(ptr, c)
       case 0xff:
           if (ptr->stat != c && (c == 0xfe || c == 0xff)){
               status_push_ch(ptr, c);
-              status_reset(ptr);
+              status_clear(ptr);
           }else{
               status_disable(ptr);
               ptr->_file_stat = -1;
@@ -1499,7 +1539,7 @@ void w_status(ptr, c)
                   w2e_conv(ptr->buf[0], ptr->buf[1], ptr->buf[2],
                            &ptr->buf[0], &ptr->buf[1]);
                   code_score(ptr);
-                  status_reset(ptr);
+                  status_clear(ptr);
               }
           }else{
               status_disable(ptr);
@@ -1640,6 +1680,7 @@ module_connection()
     }
 
     i_getc = std_getc;
+    i_ungetc = std_ungetc;
     /* input redicrection */
 #ifdef INPUT_OPTION
     if (cap_f){
@@ -2011,7 +2052,7 @@ h_conv(f, c2, c1)
             }
             ++p;
         }
-        set_iconv(FALSE, p->iconv_func);
+        set_iconv(FALSE, result->iconv_func);
     }
 
 
@@ -2085,7 +2126,7 @@ int s2e_conv(c2, c1, p2, p1)
      int *p2, *p1;
 {
 #ifdef SHIFTJIS_CP932
-    if (CP932_TABLE_BEGIN <= c2 && c2 <= CP932_TABLE_END){
+    if (cp932_f && CP932_TABLE_BEGIN <= c2 && c2 <= CP932_TABLE_END){
         extern unsigned short shiftjis_cp932[3][189];
         c1 = shiftjis_cp932[c2 - CP932_TABLE_BEGIN][c1 - 0x40];
         if (c1 == 0) return 1;
@@ -2452,8 +2493,8 @@ e_oconv(c2, c1)
        output_mode = ISO8859_1;
         (*o_putc)(c1 | 0x080);
     } else {
-        if ((c1<0x20 || 0x7e<c1) ||
-           (c2<0x20 || 0x7e<c2)) {
+        if ((c1<0x21 || 0x7e<c1) ||
+           (c2<0x21 || 0x7e<c2)) {
             set_iconv(FALSE, 0);
             return; /* too late to rescue this char */
         }
@@ -3034,14 +3075,26 @@ unsigned char *mime_pattern[] = {
 #if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
    (unsigned char *)"\075?UTF-8?B?",
 #endif
+   (unsigned char *)"\075?US-ASCII?Q?",
    NULL
 };
 
+
+/* \e$B3:Ev$9$k%3!<%I$NM%@hEY$r>e$2$k$?$a$NL\0u\e(B */
+int (*mime_priority_func[])PROTO((int c2, int c1, int c0)) = {
+    e_iconv, s_iconv, 0, 0, 0, 0,
+#if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
+    w_iconv,
+#endif
+    0,
+};
+
 int      mime_encode[] = {
     JAPANESE_EUC, SHIFT_JIS,ISO8859_1, ISO8859_1, X0208, X0201,
 #if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
     UTF8,
 #endif
+    ASCII,
     0
 };
 
@@ -3050,6 +3103,7 @@ int      mime_encode_method[] = {
 #if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
     'B',
 #endif
+    'Q',
     0
 };
 
@@ -3119,6 +3173,9 @@ FILE *f;
         }
     }
     mime_decode_mode = p[i-2];
+
+    clr_code_score(find_inputcode_byfunc(mime_priority_func[j]), SCORE_iMIME);
+
     if (mime_decode_mode=='B') {
         mimebuf_f = unbuf_f;
         if (!unbuf_f) {