Back to index

php5  5.3.10
mbfilter_jis.c
Go to the documentation of this file.
00001 /*
00002  * "streamable kanji code filter and converter"
00003  * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
00004  *
00005  * LICENSE NOTICES
00006  *
00007  * This file is part of "streamable kanji code filter and converter",
00008  * which is distributed under the terms of GNU Lesser General Public 
00009  * License (version 2) as published by the Free Software Foundation.
00010  *
00011  * This software is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with "streamable kanji code filter and converter";
00018  * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
00019  * Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  * The author of this file:
00022  *
00023  */
00024 /*
00025  * The source code included in this files was separated from mbfilter_ja.c
00026  * by moriyoshi koizumi <moriyoshi@php.net> on 4 dec 2002.
00027  * 
00028  */
00029 
00030 #ifdef HAVE_CONFIG_H
00031 #include "config.h"
00032 #endif
00033 
00034 #include "mbfilter.h"
00035 #include "mbfilter_jis.h"
00036 
00037 #include "unicode_table_cp932_ext.h"
00038 #include "unicode_table_jis.h"
00039 
00040 static int mbfl_filt_ident_jis(int c, mbfl_identify_filter *filter);
00041 static int mbfl_filt_ident_2022jp(int c, mbfl_identify_filter *filter);
00042 
00043 const mbfl_encoding mbfl_encoding_jis = {
00044        mbfl_no_encoding_jis,
00045        "JIS",
00046        "ISO-2022-JP",
00047        NULL,
00048        NULL,
00049        MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE
00050 };
00051 
00052 const mbfl_encoding mbfl_encoding_2022jp = {
00053        mbfl_no_encoding_2022jp,
00054        "ISO-2022-JP",
00055        "ISO-2022-JP",
00056        NULL,
00057        NULL,
00058        MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE
00059 };
00060 
00061 const struct mbfl_identify_vtbl vtbl_identify_jis = {
00062        mbfl_no_encoding_jis,
00063        mbfl_filt_ident_common_ctor,
00064        mbfl_filt_ident_common_dtor,
00065        mbfl_filt_ident_jis
00066 };
00067 
00068 const struct mbfl_identify_vtbl vtbl_identify_2022jp = {
00069        mbfl_no_encoding_2022jp,
00070        mbfl_filt_ident_common_ctor,
00071        mbfl_filt_ident_common_dtor,
00072        mbfl_filt_ident_2022jp
00073 };
00074 
00075 const struct mbfl_convert_vtbl vtbl_jis_wchar = {
00076        mbfl_no_encoding_jis,
00077        mbfl_no_encoding_wchar,
00078        mbfl_filt_conv_common_ctor,
00079        mbfl_filt_conv_common_dtor,
00080        mbfl_filt_conv_jis_wchar,
00081        mbfl_filt_conv_common_flush
00082 };
00083 
00084 const struct mbfl_convert_vtbl vtbl_wchar_jis = {
00085        mbfl_no_encoding_wchar,
00086        mbfl_no_encoding_jis,
00087        mbfl_filt_conv_common_ctor,
00088        mbfl_filt_conv_common_dtor,
00089        mbfl_filt_conv_wchar_jis,
00090        mbfl_filt_conv_any_jis_flush
00091 };
00092 
00093 const struct mbfl_convert_vtbl vtbl_2022jp_wchar = {
00094        mbfl_no_encoding_2022jp,
00095        mbfl_no_encoding_wchar,
00096        mbfl_filt_conv_common_ctor,
00097        mbfl_filt_conv_common_dtor,
00098        mbfl_filt_conv_jis_wchar,
00099        mbfl_filt_conv_common_flush
00100 };
00101 
00102 const struct mbfl_convert_vtbl vtbl_wchar_2022jp = {
00103        mbfl_no_encoding_wchar,
00104        mbfl_no_encoding_2022jp,
00105        mbfl_filt_conv_common_ctor,
00106        mbfl_filt_conv_common_dtor,
00107        mbfl_filt_conv_wchar_2022jp,
00108        mbfl_filt_conv_any_jis_flush
00109 };
00110 
00111 #define CK(statement)       do { if ((statement) < 0) return (-1); } while (0)
00112 
00113 /*
00114  * JIS => wchar
00115  */
00116 int
00117 mbfl_filt_conv_jis_wchar(int c, mbfl_convert_filter *filter)
00118 {
00119        int c1, s, w;
00120 
00121 retry:
00122        switch (filter->status & 0xf) {
00123 /*     case 0x00:     ASCII */
00124 /*     case 0x10:     X 0201 latin */
00125 /*     case 0x20:     X 0201 kana */
00126 /*     case 0x80:     X 0208 */
00127 /*     case 0x90:     X 0212 */
00128        case 0:
00129               if (c == 0x1b) {
00130                      filter->status += 2;
00131               } else if (c == 0x0e) {            /* "kana in" */
00132                      filter->status = 0x20;
00133               } else if (c == 0x0f) {            /* "kana out" */
00134                      filter->status = 0;
00135               } else if (filter->status == 0x10 && c == 0x5c) {       /* YEN SIGN */
00136                      CK((*filter->output_function)(0xa5, filter->data));
00137               } else if (filter->status == 0x10 && c == 0x7e) {       /* OVER LINE */
00138                      CK((*filter->output_function)(0x203e, filter->data));
00139               } else if (filter->status == 0x20 && c > 0x20 && c < 0x60) {          /* kana */
00140                      CK((*filter->output_function)(0xff40 + c, filter->data));
00141               } else if ((filter->status == 0x80 || filter->status == 0x90) && c > 0x20 && c < 0x7f) {          /* kanji first char */
00142                      filter->cache = c;
00143                      filter->status += 1;
00144               } else if (c >= 0 && c < 0x80) {          /* latin, CTLs */
00145                      CK((*filter->output_function)(c, filter->data));
00146               } else if (c > 0xa0 && c < 0xe0) { /* GR kana */
00147                      CK((*filter->output_function)(0xfec0 + c, filter->data));
00148               } else {
00149                      w = c & MBFL_WCSGROUP_MASK;
00150                      w |= MBFL_WCSGROUP_THROUGH;
00151                      CK((*filter->output_function)(w, filter->data));
00152               }
00153               break;
00154 
00155 /*     case 0x81:     X 0208 second char */
00156 /*     case 0x91:     X 0212 second char */
00157        case 1:
00158               filter->status &= ~0xf;
00159               c1 = filter->cache;
00160               if (c > 0x20 && c < 0x7f) {
00161                      s = (c1 - 0x21)*94 + c - 0x21;
00162                      if (filter->status == 0x80) {
00163                             if (s >= 0 && s < jisx0208_ucs_table_size) {
00164                                    w = jisx0208_ucs_table[s];
00165                             } else {
00166                                    w = 0;
00167                             }
00168                             if (w <= 0) {
00169                                    w = (c1 << 8) | c;
00170                                    w &= MBFL_WCSPLANE_MASK;
00171                                    w |= MBFL_WCSPLANE_JIS0208;
00172                             }
00173                      } else {
00174                             if (s >= 0 && s < jisx0212_ucs_table_size) {
00175                                    w = jisx0212_ucs_table[s];
00176                             } else {
00177                                    w = 0;
00178                             }
00179                             if (w <= 0) {
00180                                    w = (c1 << 8) | c;
00181                                    w &= MBFL_WCSPLANE_MASK;
00182                                    w |= MBFL_WCSPLANE_JIS0212;
00183                             }
00184                      }
00185                      CK((*filter->output_function)(w, filter->data));
00186               } else if (c == 0x1b) {
00187                      filter->status += 2;
00188               } else if ((c >= 0 && c < 0x21) || c == 0x7f) {         /* CTLs */
00189                      CK((*filter->output_function)(c, filter->data));
00190               } else {
00191                      w = (c1 << 8) | c;
00192                      w &= MBFL_WCSGROUP_MASK;
00193                      w |= MBFL_WCSGROUP_THROUGH;
00194                      CK((*filter->output_function)(w, filter->data));
00195               }
00196               break;
00197 
00198        /* ESC */
00199 /*     case 0x02:    */
00200 /*     case 0x12:    */
00201 /*     case 0x22:    */
00202 /*     case 0x82:    */
00203 /*     case 0x92:    */
00204        case 2:
00205               if (c == 0x24) {            /* '$' */
00206                      filter->status++;
00207               } else if (c == 0x28) {            /* '(' */
00208                      filter->status += 3;
00209               } else {
00210                      filter->status &= ~0xf;
00211                      CK((*filter->output_function)(0x1b, filter->data));
00212                      goto retry;
00213               }
00214               break;
00215 
00216        /* ESC $ */
00217 /*     case 0x03:    */
00218 /*     case 0x13:    */
00219 /*     case 0x23:    */
00220 /*     case 0x83:    */
00221 /*     case 0x93:    */
00222        case 3:
00223               if (c == 0x40 || c == 0x42) {      /* '@' or 'B' */
00224                      filter->status = 0x80;
00225               } else if (c == 0x28) {                   /* '(' */
00226                      filter->status++;
00227               } else {
00228                      filter->status &= ~0xf;
00229                      CK((*filter->output_function)(0x1b, filter->data));
00230                      CK((*filter->output_function)(0x24, filter->data));
00231                      goto retry;
00232               }
00233               break;
00234 
00235        /* ESC $ ( */
00236 /*     case 0x04:    */
00237 /*     case 0x14:    */
00238 /*     case 0x24:    */
00239 /*     case 0x84:    */
00240 /*     case 0x94:    */
00241        case 4:
00242               if (c == 0x40 || c == 0x42) {      /* '@' or 'B' */
00243                      filter->status = 0x80;
00244               } else if (c == 0x44) {                   /* 'D' */
00245                      filter->status = 0x90;
00246               } else {
00247                      filter->status &= ~0xf;
00248                      CK((*filter->output_function)(0x1b, filter->data));
00249                      CK((*filter->output_function)(0x24, filter->data));
00250                      CK((*filter->output_function)(0x28, filter->data));
00251                      goto retry;
00252               }
00253               break;
00254 
00255        /* ESC ( */
00256 /*     case 0x05:    */
00257 /*     case 0x15:    */
00258 /*     case 0x25:    */
00259 /*     case 0x85:    */
00260 /*     case 0x95:    */
00261        case 5:
00262               if (c == 0x42 || c == 0x48) {             /* 'B' or 'H' */
00263                      filter->status = 0;
00264               } else if (c == 0x4a) {            /* 'J' */
00265                      filter->status = 0x10;
00266               } else if (c == 0x49) {            /* 'I' */
00267                      filter->status = 0x20;
00268               } else {
00269                      filter->status &= ~0xf;
00270                      CK((*filter->output_function)(0x1b, filter->data));
00271                      CK((*filter->output_function)(0x28, filter->data));
00272                      goto retry;
00273               }
00274               break;
00275 
00276        default:
00277               filter->status = 0;
00278               break;
00279        }
00280 
00281        return c;
00282 }
00283 
00284 /*
00285  * wchar => JIS
00286  */
00287 int
00288 mbfl_filt_conv_wchar_jis(int c, mbfl_convert_filter *filter)
00289 {
00290        int c1, s;
00291 
00292        s = 0;
00293        if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) {
00294               s = ucs_a1_jis_table[c - ucs_a1_jis_table_min];
00295        } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) {
00296               s = ucs_a2_jis_table[c - ucs_a2_jis_table_min];
00297        } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) {
00298               s = ucs_i_jis_table[c - ucs_i_jis_table_min];
00299        } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) {
00300               s = ucs_r_jis_table[c - ucs_r_jis_table_min];
00301        }
00302        if (s <= 0) {
00303               c1 = c & ~MBFL_WCSPLANE_MASK;
00304               if (c1 == MBFL_WCSPLANE_JIS0208) {
00305                      s = c & MBFL_WCSPLANE_MASK;
00306               } else if (c1 == MBFL_WCSPLANE_JIS0212) {
00307                      s = c & MBFL_WCSPLANE_MASK;
00308                      s |= 0x8080;
00309               } else if (c == 0xa5) {            /* YEN SIGN */
00310                      s = 0x1005c;
00311               } else if (c == 0x203e) {   /* OVER LINE */
00312                      s = 0x1007e;
00313               } else if (c == 0xff3c) {   /* FULLWIDTH REVERSE SOLIDUS */
00314                      s = 0x2140;
00315               } else if (c == 0xff5e) {   /* FULLWIDTH TILDE */
00316                      s = 0x2141;
00317               } else if (c == 0x2225) {   /* PARALLEL TO */
00318                      s = 0x2142;
00319               } else if (c == 0xff0d) {   /* FULLWIDTH HYPHEN-MINUS */
00320                      s = 0x215d;
00321               } else if (c == 0xffe0) {   /* FULLWIDTH CENT SIGN */
00322                      s = 0x2171;
00323               } else if (c == 0xffe1) {   /* FULLWIDTH POUND SIGN */
00324                      s = 0x2172;
00325               } else if (c == 0xffe2) {   /* FULLWIDTH NOT SIGN */
00326                      s = 0x224c;
00327               }
00328               if (c == 0) {
00329                      s = 0;
00330               } else if (s <= 0) {
00331                      s = -1;
00332               }
00333        }
00334        if (s >= 0) {
00335               if (s < 0x80) { /* ASCII */
00336                      if ((filter->status & 0xff00) != 0) {
00337                             CK((*filter->output_function)(0x1b, filter->data));            /* ESC */
00338                             CK((*filter->output_function)(0x28, filter->data));            /* '(' */
00339                             CK((*filter->output_function)(0x42, filter->data));            /* 'B' */
00340                      }
00341                      filter->status = 0;
00342                      CK((*filter->output_function)(s, filter->data));
00343               } else if (s < 0x100) { /* kana */
00344                      if ((filter->status & 0xff00) != 0x100) {
00345                             CK((*filter->output_function)(0x1b, filter->data));            /* ESC */
00346                             CK((*filter->output_function)(0x28, filter->data));            /* '(' */
00347                             CK((*filter->output_function)(0x49, filter->data));            /* 'I' */
00348                      }
00349                      filter->status = 0x100;
00350                      CK((*filter->output_function)(s & 0x7f, filter->data));
00351               } else if (s < 0x8080) { /* X 0208 */
00352                      if ((filter->status & 0xff00) != 0x200) {
00353                             CK((*filter->output_function)(0x1b, filter->data));            /* ESC */
00354                             CK((*filter->output_function)(0x24, filter->data));            /* '$' */
00355                             CK((*filter->output_function)(0x42, filter->data));            /* 'B' */
00356                      }
00357                      filter->status = 0x200;
00358                      CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
00359                      CK((*filter->output_function)(s & 0x7f, filter->data));
00360               } else if (s < 0x10000) { /* X 0212 */
00361                      if ((filter->status & 0xff00) != 0x300) {
00362                             CK((*filter->output_function)(0x1b, filter->data));            /* ESC */
00363                             CK((*filter->output_function)(0x24, filter->data));            /* '$' */
00364                             CK((*filter->output_function)(0x28, filter->data));            /* '(' */
00365                             CK((*filter->output_function)(0x44, filter->data));            /* 'D' */
00366                      }
00367                      filter->status = 0x300;
00368                      CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
00369                      CK((*filter->output_function)(s & 0x7f, filter->data));
00370               } else { /* X 0201 latin */
00371                      if ((filter->status & 0xff00) != 0x400) {
00372                             CK((*filter->output_function)(0x1b, filter->data));            /* ESC */
00373                             CK((*filter->output_function)(0x28, filter->data));            /* '(' */
00374                             CK((*filter->output_function)(0x4a, filter->data));            /* 'J' */
00375                      }
00376                      filter->status = 0x400;
00377                      CK((*filter->output_function)(s & 0x7f, filter->data));
00378               }
00379        } else {
00380               if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
00381                      CK(mbfl_filt_conv_illegal_output(c, filter));
00382               }
00383        }
00384 
00385        return c;
00386 }
00387 
00388 
00389 /*
00390  * wchar => ISO-2022-JP
00391  */
00392 int
00393 mbfl_filt_conv_wchar_2022jp(int c, mbfl_convert_filter *filter)
00394 {
00395        int s;
00396 
00397        s = 0;
00398        if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) {
00399               s = ucs_a1_jis_table[c - ucs_a1_jis_table_min];
00400        } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) {
00401               s = ucs_a2_jis_table[c - ucs_a2_jis_table_min];
00402        } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) {
00403               s = ucs_i_jis_table[c - ucs_i_jis_table_min];
00404        } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) {
00405               s = ucs_r_jis_table[c - ucs_r_jis_table_min];
00406        }
00407        if (s <= 0) {
00408               if (c == 0xa5) {                   /* YEN SIGN */
00409                      s = 0x1005c;
00410               } else if (c == 0x203e) {   /* OVER LINE */
00411                      s = 0x1007e;
00412               } else if (c == 0xff3c) {   /* FULLWIDTH REVERSE SOLIDUS */
00413                      s = 0x2140;
00414               } else if (c == 0xff5e) {   /* FULLWIDTH TILDE */
00415                      s = 0x2141;
00416               } else if (c == 0x2225) {   /* PARALLEL TO */
00417                      s = 0x2142;
00418               } else if (c == 0xff0d) {   /* FULLWIDTH HYPHEN-MINUS */
00419                      s = 0x215d;
00420               } else if (c == 0xffe0) {   /* FULLWIDTH CENT SIGN */
00421                      s = 0x2171;
00422               } else if (c == 0xffe1) {   /* FULLWIDTH POUND SIGN */
00423                      s = 0x2172;
00424               } else if (c == 0xffe2) {   /* FULLWIDTH NOT SIGN */
00425                      s = 0x224c;
00426               }
00427               if (c == 0) {
00428                      s = 0;
00429               } else if (s <= 0) {
00430                      s = -1;
00431               }
00432        } else if ((s >= 0x80 && s < 0x2121) || (s > 0x8080)) {
00433               s = -1;
00434        }
00435        if (s >= 0) {
00436               if (s < 0x80) { /* ASCII */
00437                      if ((filter->status & 0xff00) != 0) {
00438                             CK((*filter->output_function)(0x1b, filter->data));            /* ESC */
00439                             CK((*filter->output_function)(0x28, filter->data));            /* '(' */
00440                             CK((*filter->output_function)(0x42, filter->data));            /* 'B' */
00441                      }
00442                      filter->status = 0;
00443                      CK((*filter->output_function)(s, filter->data));
00444               } else if (s < 0x10000) { /* X 0208 */
00445                      if ((filter->status & 0xff00) != 0x200) {
00446                             CK((*filter->output_function)(0x1b, filter->data));            /* ESC */
00447                             CK((*filter->output_function)(0x24, filter->data));            /* '$' */
00448                             CK((*filter->output_function)(0x42, filter->data));            /* 'B' */
00449                      }
00450                      filter->status = 0x200;
00451                      CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
00452                      CK((*filter->output_function)(s & 0x7f, filter->data));
00453               } else { /* X 0201 latin */
00454                      if ((filter->status & 0xff00) != 0x400) {
00455                             CK((*filter->output_function)(0x1b, filter->data));            /* ESC */
00456                             CK((*filter->output_function)(0x28, filter->data));            /* '(' */
00457                             CK((*filter->output_function)(0x4a, filter->data));            /* 'J' */
00458                      }
00459                      filter->status = 0x400;
00460                      CK((*filter->output_function)(s & 0x7f, filter->data));
00461               }
00462        } else {
00463               if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
00464                      CK(mbfl_filt_conv_illegal_output(c, filter));
00465               }
00466        }
00467 
00468        return c;
00469 }
00470 
00471 int
00472 mbfl_filt_conv_any_jis_flush(mbfl_convert_filter *filter)
00473 {
00474        /* back to latin */
00475        if ((filter->status & 0xff00) != 0) {
00476               CK((*filter->output_function)(0x1b, filter->data));            /* ESC */
00477               CK((*filter->output_function)(0x28, filter->data));            /* '(' */
00478               CK((*filter->output_function)(0x42, filter->data));            /* 'B' */
00479        }
00480        filter->status &= 0xff;
00481 
00482        if (filter->flush_function != NULL) {
00483               return (*filter->flush_function)(filter->data);
00484        }
00485 
00486        return 0;
00487 }
00488 
00489 static int mbfl_filt_ident_jis(int c, mbfl_identify_filter *filter)
00490 {
00491 retry:
00492        switch (filter->status & 0xf) {
00493 /*     case 0x00:     ASCII */
00494 /*     case 0x10:     X 0201 latin */
00495 /*     case 0x20:     X 0201 kana */
00496 /*     case 0x80:     X 0208 */
00497 /*     case 0x90:     X 0212 */
00498        case 0:
00499               if (c == 0x1b) {
00500                      filter->status += 2;
00501               } else if (c == 0x0e) {                   /* "kana in" */
00502                      filter->status = 0x20;
00503               } else if (c == 0x0f) {                   /* "kana out" */
00504                      filter->status = 0;
00505               } else if ((filter->status == 0x80 || filter->status == 0x90) && c > 0x20 && c < 0x7f) {          /* kanji first char */
00506                      filter->status += 1;
00507               } else if (c >= 0 && c < 0x80) {          /* latin, CTLs */
00508                      ;
00509               } else {
00510                      filter->flag = 1;    /* bad */
00511               }
00512               break;
00513 
00514 /*     case 0x81:     X 0208 second char */
00515 /*     case 0x91:     X 0212 second char */
00516        case 1:
00517               filter->status &= ~0xf;
00518               if (c == 0x1b) {
00519                      goto retry;
00520               } else if (c < 0x21 || c > 0x7e) {        /* bad */
00521                      filter->flag = 1;
00522               }
00523               break;
00524 
00525        /* ESC */
00526        case 2:
00527               if (c == 0x24) {            /* '$' */
00528                      filter->status++;
00529               } else if (c == 0x28) {            /* '(' */
00530                      filter->status += 3;
00531               } else {
00532                      filter->flag = 1;    /* bad */
00533                      filter->status &= ~0xf;
00534                      goto retry;
00535               }
00536               break;
00537 
00538        /* ESC $ */
00539        case 3:
00540               if (c == 0x40 || c == 0x42) {             /* '@' or 'B' */
00541                      filter->status = 0x80;
00542               } else if (c == 0x28) {            /* '(' */
00543                      filter->status++;
00544               } else {
00545                      filter->flag = 1;    /* bad */
00546                      filter->status &= ~0xf;
00547                      goto retry;
00548               }
00549               break;
00550 
00551        /* ESC $ ( */
00552        case 4:
00553               if (c == 0x40 || c == 0x42) {             /* '@' or 'B' */
00554                      filter->status = 0x80;
00555               } else if (c == 0x44) {            /* 'D' */
00556                      filter->status = 0x90;
00557               } else {
00558                      filter->flag = 1;    /* bad */
00559                      filter->status &= ~0xf;
00560                      goto retry;
00561               }
00562               break;
00563 
00564        /* ESC ( */
00565        case 5:
00566               if (c == 0x42 || c == 0x48) {             /* 'B' or 'H' */
00567                      filter->status = 0;
00568               } else if (c == 0x4a) {            /* 'J' */
00569                      filter->status = 0x10;
00570               } else if (c == 0x49) {            /* 'I' */
00571                      filter->status = 0x20;
00572               } else {
00573                      filter->flag = 1;    /* bad */
00574                      filter->status &= ~0xf;
00575                      goto retry;
00576               }
00577               break;
00578 
00579        default:
00580               filter->status = 0;
00581               break;
00582        }
00583 
00584        return c;
00585 }
00586 
00587 static int mbfl_filt_ident_2022jp(int c, mbfl_identify_filter *filter)
00588 {
00589 retry:
00590        switch (filter->status & 0xf) {
00591 /*     case 0x00:     ASCII */
00592 /*     case 0x10:     X 0201 latin */
00593 /*     case 0x80:     X 0208 */
00594        case 0:
00595               if (c == 0x1b) {
00596                      filter->status += 2;
00597               } else if (filter->status == 0x80 && c > 0x20 && c < 0x7f) {          /* kanji first char */
00598                      filter->status += 1;
00599               } else if (c >= 0 && c < 0x80) {          /* latin, CTLs */
00600                      ;
00601               } else {
00602                      filter->flag = 1;    /* bad */
00603               }
00604               break;
00605 
00606 /*     case 0x81:     X 0208 second char */
00607        case 1:
00608               if (c == 0x1b) {
00609                      filter->status++;
00610               } else {
00611                      filter->status &= ~0xf;
00612                      if (c < 0x21 || c > 0x7e) {        /* bad */
00613                             filter->flag = 1;
00614                      }
00615               }
00616               break;
00617 
00618        /* ESC */
00619        case 2:
00620               if (c == 0x24) {            /* '$' */
00621                      filter->status++;
00622               } else if (c == 0x28) {            /* '(' */
00623                      filter->status += 3;
00624               } else {
00625                      filter->flag = 1;    /* bad */
00626                      filter->status &= ~0xf;
00627                      goto retry;
00628               }
00629               break;
00630 
00631        /* ESC $ */
00632        case 3:
00633               if (c == 0x40 || c == 0x42) {             /* '@' or 'B' */
00634                      filter->status = 0x80;
00635               } else {
00636                      filter->flag = 1;    /* bad */
00637                      filter->status &= ~0xf;
00638                      goto retry;
00639               }
00640               break;
00641 
00642        /* ESC ( */
00643        case 5:
00644               if (c == 0x42) {            /* 'B' */
00645                      filter->status = 0;
00646               } else if (c == 0x4a) {            /* 'J' */
00647                      filter->status = 0x10;
00648               } else {
00649                      filter->flag = 1;    /* bad */
00650                      filter->status &= ~0xf;
00651                      goto retry;
00652               }
00653               break;
00654 
00655        default:
00656               filter->status = 0;
00657               break;
00658        }
00659 
00660        return c;
00661 }
00662 
00663