root/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mbfl_filt_conv_jis_ms_wchar
  2. mbfl_filt_conv_wchar_jis_ms
  3. mbfl_filt_conv_wchar_cp50220_ctor
  4. mbfl_filt_conv_wchar_cp50220_copy
  5. mbfl_filt_conv_wchar_cp50220_dtor
  6. mbfl_filt_conv_wchar_cp50220raw
  7. mbfl_filt_conv_wchar_cp50221
  8. mbfl_filt_conv_wchar_cp50222
  9. mbfl_filt_conv_wchar_cp50222_flush
  10. mbfl_filt_ident_jis_ms
  11. mbfl_filt_ident_cp50220
  12. mbfl_filt_ident_cp50221
  13. mbfl_filt_ident_cp50222

   1 /*
   2  * "streamable kanji code filter and converter"
   3  * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
   4  *
   5  * LICENSE NOTICES
   6  *
   7  * This file is part of "streamable kanji code filter and converter",
   8  * which is distributed under the terms of GNU Lesser General Public
   9  * License (version 2) as published by the Free Software Foundation.
  10  *
  11  * This software is distributed in the hope that it will be useful,
  12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14  * GNU Lesser General Public License for more details.
  15  *
  16  * You should have received a copy of the GNU Lesser General Public
  17  * License along with "streamable kanji code filter and converter";
  18  * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
  19  * Suite 330, Boston, MA  02111-1307  USA
  20  *
  21  * The author of this file: Moriyoshi Koizumi <koizumi@gree.co.jp>
  22  *
  23  */
  24 
  25 #ifdef HAVE_CONFIG_H
  26 #include "config.h"
  27 #endif
  28 
  29 #include "mbfilter.h"
  30 #include "mbfilter_cp5022x.h"
  31 #include "mbfilter_jis.h"
  32 #include "mbfilter_tl_jisx0201_jisx0208.h"
  33 
  34 #include "unicode_table_cp932_ext.h"
  35 #include "unicode_table_jis.h"
  36 #include "cp932_table.h"
  37 
  38 typedef struct _mbfl_filt_conv_wchar_cp50220_ctx {
  39         mbfl_filt_tl_jisx0201_jisx0208_param tl_param;
  40         mbfl_convert_filter last;
  41 } mbfl_filt_conv_wchar_cp50220_ctx;
  42 
  43 static int mbfl_filt_ident_jis_ms(int c, mbfl_identify_filter *filter);
  44 static int mbfl_filt_ident_cp50220(int c, mbfl_identify_filter *filter);
  45 static int mbfl_filt_ident_cp50221(int c, mbfl_identify_filter *filter);
  46 static int mbfl_filt_ident_cp50222(int c, mbfl_identify_filter *filter);
  47 static void mbfl_filt_conv_wchar_cp50220_ctor(mbfl_convert_filter *filt);
  48 static void mbfl_filt_conv_wchar_cp50220_dtor(mbfl_convert_filter *filt);
  49 static void mbfl_filt_conv_wchar_cp50220_copy(mbfl_convert_filter *src, mbfl_convert_filter *dest);
  50 
  51 const mbfl_encoding mbfl_encoding_jis_ms = {
  52         mbfl_no_encoding_jis_ms,
  53         "JIS-ms",
  54         "ISO-2022-JP",
  55         NULL,
  56         NULL,
  57         MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE | MBFL_ENCTYPE_GL_UNSAFE
  58 };
  59 
  60 const mbfl_encoding mbfl_encoding_cp50220 = {
  61         mbfl_no_encoding_cp50220,
  62         "CP50220",
  63         "ISO-2022-JP",
  64         (const char *(*)[])NULL,
  65         NULL,
  66         MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE | MBFL_ENCTYPE_GL_UNSAFE
  67 };
  68 
  69 const mbfl_encoding mbfl_encoding_cp50220raw = {
  70         mbfl_no_encoding_cp50220raw,
  71         "CP50220raw",
  72         "ISO-2022-JP",
  73         (const char *(*)[])NULL,
  74         NULL,
  75         MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE | MBFL_ENCTYPE_GL_UNSAFE
  76 };
  77 
  78 const mbfl_encoding mbfl_encoding_cp50221 = {
  79         mbfl_no_encoding_cp50221,
  80         "CP50221",
  81         "ISO-2022-JP",
  82         NULL,
  83         NULL,
  84         MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE | MBFL_ENCTYPE_GL_UNSAFE
  85 };
  86 
  87 const mbfl_encoding mbfl_encoding_cp50222 = {
  88         mbfl_no_encoding_cp50222,
  89         "CP50222",
  90         "ISO-2022-JP",
  91         NULL,
  92         NULL,
  93         MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE | MBFL_ENCTYPE_GL_UNSAFE
  94 };
  95 
  96 const struct mbfl_identify_vtbl vtbl_identify_jis_ms = {
  97         mbfl_no_encoding_jis_ms,
  98         mbfl_filt_ident_common_ctor,
  99         mbfl_filt_ident_common_dtor,
 100         mbfl_filt_ident_jis_ms
 101 };
 102 
 103 const struct mbfl_identify_vtbl vtbl_identify_cp50220 = {
 104         mbfl_no_encoding_cp50220,
 105         mbfl_filt_ident_common_ctor,
 106         mbfl_filt_ident_common_dtor,
 107         mbfl_filt_ident_cp50220
 108 };
 109 
 110 const struct mbfl_identify_vtbl vtbl_identify_cp50220raw = {
 111         mbfl_no_encoding_cp50220raw,
 112         mbfl_filt_ident_common_ctor,
 113         mbfl_filt_ident_common_dtor,
 114         mbfl_filt_ident_cp50220
 115 };
 116 
 117 const struct mbfl_identify_vtbl vtbl_identify_cp50221 = {
 118         mbfl_no_encoding_cp50221,
 119         mbfl_filt_ident_common_ctor,
 120         mbfl_filt_ident_common_dtor,
 121         mbfl_filt_ident_cp50221
 122 };
 123 
 124 const struct mbfl_identify_vtbl vtbl_identify_cp50222 = {
 125         mbfl_no_encoding_cp50222,
 126         mbfl_filt_ident_common_ctor,
 127         mbfl_filt_ident_common_dtor,
 128         mbfl_filt_ident_cp50222
 129 };
 130 
 131 const struct mbfl_convert_vtbl vtbl_jis_ms_wchar = {
 132         mbfl_no_encoding_jis_ms,
 133         mbfl_no_encoding_wchar,
 134         mbfl_filt_conv_common_ctor,
 135         mbfl_filt_conv_common_dtor,
 136         mbfl_filt_conv_jis_ms_wchar,
 137         mbfl_filt_conv_common_flush,
 138 };
 139 
 140 const struct mbfl_convert_vtbl vtbl_wchar_jis_ms = {
 141         mbfl_no_encoding_wchar,
 142         mbfl_no_encoding_jis_ms,
 143         mbfl_filt_conv_common_ctor,
 144         mbfl_filt_conv_common_dtor,
 145         mbfl_filt_conv_wchar_jis_ms,
 146         mbfl_filt_conv_any_jis_flush
 147 };
 148 
 149 const struct mbfl_convert_vtbl vtbl_cp50220_wchar = {
 150         mbfl_no_encoding_cp50220,
 151         mbfl_no_encoding_wchar,
 152         mbfl_filt_conv_common_ctor,
 153         mbfl_filt_conv_common_dtor,
 154         mbfl_filt_conv_jis_ms_wchar,
 155         mbfl_filt_conv_common_flush
 156 };
 157 
 158 const struct mbfl_convert_vtbl vtbl_wchar_cp50220 = {
 159         mbfl_no_encoding_wchar,
 160         mbfl_no_encoding_cp50220,
 161         mbfl_filt_conv_wchar_cp50220_ctor,
 162         mbfl_filt_conv_wchar_cp50220_dtor,
 163         mbfl_filt_conv_wchar_cp50221,
 164         mbfl_filt_conv_any_jis_flush,
 165         mbfl_filt_conv_wchar_cp50220_copy
 166 };
 167 
 168 const struct mbfl_convert_vtbl vtbl_cp50220raw_wchar = {
 169         mbfl_no_encoding_cp50220raw,
 170         mbfl_no_encoding_wchar,
 171         mbfl_filt_conv_common_ctor,
 172         mbfl_filt_conv_common_dtor,
 173         mbfl_filt_conv_jis_ms_wchar,
 174         mbfl_filt_conv_common_flush
 175 };
 176 
 177 const struct mbfl_convert_vtbl vtbl_wchar_cp50220raw = {
 178         mbfl_no_encoding_wchar,
 179         mbfl_no_encoding_cp50220raw,
 180         mbfl_filt_conv_wchar_cp50220_ctor,
 181         mbfl_filt_conv_wchar_cp50220_dtor,
 182         mbfl_filt_conv_wchar_cp50220raw,
 183         mbfl_filt_conv_any_jis_flush,
 184         mbfl_filt_conv_wchar_cp50220_copy
 185 };
 186 
 187 const struct mbfl_convert_vtbl vtbl_cp50221_wchar = {
 188         mbfl_no_encoding_cp50221,
 189         mbfl_no_encoding_wchar,
 190         mbfl_filt_conv_common_ctor,
 191         mbfl_filt_conv_common_dtor,
 192         mbfl_filt_conv_jis_ms_wchar,
 193         mbfl_filt_conv_common_flush
 194 };
 195 
 196 const struct mbfl_convert_vtbl vtbl_wchar_cp50221 = {
 197         mbfl_no_encoding_wchar,
 198         mbfl_no_encoding_cp50221,
 199         mbfl_filt_conv_common_ctor,
 200         mbfl_filt_conv_common_dtor,
 201         mbfl_filt_conv_wchar_cp50221,
 202         mbfl_filt_conv_any_jis_flush
 203 };
 204 
 205 const struct mbfl_convert_vtbl vtbl_cp50222_wchar = {
 206         mbfl_no_encoding_cp50222,
 207         mbfl_no_encoding_wchar,
 208         mbfl_filt_conv_common_ctor,
 209         mbfl_filt_conv_common_dtor,
 210         mbfl_filt_conv_jis_ms_wchar,
 211         mbfl_filt_conv_common_flush
 212 };
 213 
 214 const struct mbfl_convert_vtbl vtbl_wchar_cp50222 = {
 215         mbfl_no_encoding_wchar,
 216         mbfl_no_encoding_cp50222,
 217         mbfl_filt_conv_common_ctor,
 218         mbfl_filt_conv_common_dtor,
 219         mbfl_filt_conv_wchar_cp50222,
 220         mbfl_filt_conv_wchar_cp50222_flush
 221 };
 222 
 223 #define CK(statement)   do { if ((statement) < 0) return (-1); } while (0)
 224 
 225 /*
 226  * JIS-ms => wchar
 227  */
 228 int
 229 mbfl_filt_conv_jis_ms_wchar(int c, mbfl_convert_filter *filter)
 230 {
 231         int c1, s, w;
 232 
 233 retry:
 234         switch (filter->status & 0xf) {
 235 /*      case 0x00:       ASCII */
 236 /*      case 0x10:       X 0201 latin */
 237 /*      case 0x20:       X 0201 kana */
 238 /*      case 0x80:       X 0208 */
 239 /*      case 0x90:       X 0212 */
 240         case 0:
 241                 if (c == 0x1b) {
 242                         filter->status += 2;
 243                 } else if (c == 0x0e) {         /* "kana in" */
 244                         filter->status = 0x20;
 245                 } else if (c == 0x0f) {         /* "kana out" */
 246                         filter->status = 0;
 247                 } else if (filter->status == 0x10 && c == 0x5c) {       /* YEN SIGN */
 248                         CK((*filter->output_function)(0xa5, filter->data));
 249                 } else if (filter->status == 0x10 && c == 0x7e) {       /* OVER LINE */
 250                         CK((*filter->output_function)(0x203e, filter->data));
 251                 } else if (filter->status == 0x20 && c > 0x20 && c < 0x60) {            /* kana */
 252                         CK((*filter->output_function)(0xff40 + c, filter->data));
 253                 } else if ((filter->status == 0x80 || filter->status == 0x90) && c > 0x20 && c < 0x93) {                /* kanji first char */
 254                         filter->cache = c;
 255                         filter->status += 1;
 256                 } else if (c >= 0 && c < 0x80) {                /* latin, CTLs */
 257                         CK((*filter->output_function)(c, filter->data));
 258                 } else if (c > 0xa0 && c < 0xe0) {      /* GR kana */
 259                         CK((*filter->output_function)(0xfec0 + c, filter->data));
 260                 } else {
 261                         w = c & MBFL_WCSGROUP_MASK;
 262                         w |= MBFL_WCSGROUP_THROUGH;
 263                         CK((*filter->output_function)(w, filter->data));
 264                 }
 265                 break;
 266 
 267 /*      case 0x81:       X 0208 second char */
 268 /*      case 0x91:       X 0212 second char */
 269         case 1:
 270                 filter->status &= ~0xf;
 271                 c1 = filter->cache;
 272                 if (c > 0x20 && c < 0x7f) {
 273                         s = (c1 - 0x21)*94 + c - 0x21;
 274                         if (filter->status == 0x80) {
 275                                 if (s >= 0 && s < jisx0208_ucs_table_size) {
 276                                         w = jisx0208_ucs_table[s];
 277                                 } else if (s >= cp932ext1_ucs_table_min && s < cp932ext1_ucs_table_max) {
 278                                         w = cp932ext1_ucs_table[s - cp932ext1_ucs_table_min];
 279                                 } else if (s >= cp932ext2_ucs_table_min && s < cp932ext2_ucs_table_max) {
 280                                         w = cp932ext2_ucs_table[s - cp932ext2_ucs_table_min];
 281                                 } else if (s >= cp932ext3_ucs_table_min && s < cp932ext3_ucs_table_max) {
 282                                         w = cp932ext3_ucs_table[s - cp932ext3_ucs_table_min];
 283                                 } else if (s >= 94 * 94 && s < 114 * 94) {
 284                                         /* user-defined => PUA (Microsoft extended) */
 285                                         w = s - 94*94 + 0xe000;
 286                                 } else {
 287                                         w = 0;
 288                                 }
 289                                 if (w <= 0) {
 290                                         w = (c1 << 8) | c;
 291                                         w &= MBFL_WCSPLANE_MASK;
 292                                         w |= MBFL_WCSPLANE_JIS0208;
 293                                 }
 294                         } else {
 295                                 if (s >= 0 && s < jisx0212_ucs_table_size) {
 296                                         w = jisx0212_ucs_table[s];
 297                                 } else {
 298                                         w = 0;
 299                                 }
 300                                 if (w <= 0) {
 301                                         w = (c1 << 8) | c;
 302                                         w &= MBFL_WCSPLANE_MASK;
 303                                         w |= MBFL_WCSPLANE_JIS0212;
 304                                 }
 305                         }
 306                         CK((*filter->output_function)(w, filter->data));
 307                 } else if (c == 0x1b) {
 308                         filter->status += 2;
 309                 } else if ((c >= 0 && c < 0x21) || c == 0x7f) {         /* CTLs */
 310                         CK((*filter->output_function)(c, filter->data));
 311                 } else {
 312                         w = (c1 << 8) | c;
 313                         w &= MBFL_WCSGROUP_MASK;
 314                         w |= MBFL_WCSGROUP_THROUGH;
 315                         CK((*filter->output_function)(w, filter->data));
 316                 }
 317                 break;
 318 
 319         /* ESC */
 320 /*      case 0x02:      */
 321 /*      case 0x12:      */
 322 /*      case 0x22:      */
 323 /*      case 0x82:      */
 324 /*      case 0x92:      */
 325         case 2:
 326                 if (c == 0x24) {                /* '$' */
 327                         filter->status++;
 328                 } else if (c == 0x28) {         /* '(' */
 329                         filter->status += 3;
 330                 } else {
 331                         filter->status &= ~0xf;
 332                         CK((*filter->output_function)(0x1b, filter->data));
 333                         goto retry;
 334                 }
 335                 break;
 336 
 337         /* ESC $ */
 338 /*      case 0x03:      */
 339 /*      case 0x13:      */
 340 /*      case 0x23:      */
 341 /*      case 0x83:      */
 342 /*      case 0x93:      */
 343         case 3:
 344                 if (c == 0x40 || c == 0x42) {   /* '@' or 'B' */
 345                         filter->status = 0x80;
 346                 } else if (c == 0x28) {                 /* '(' */
 347                         filter->status++;
 348                 } else {
 349                         filter->status &= ~0xf;
 350                         CK((*filter->output_function)(0x1b, filter->data));
 351                         CK((*filter->output_function)(0x24, filter->data));
 352                         goto retry;
 353                 }
 354                 break;
 355 
 356         /* ESC $ ( */
 357 /*      case 0x04:      */
 358 /*      case 0x14:      */
 359 /*      case 0x24:      */
 360 /*      case 0x84:      */
 361 /*      case 0x94:      */
 362         case 4:
 363                 if (c == 0x40 || c == 0x42) {   /* '@' or 'B' */
 364                         filter->status = 0x80;
 365                 } else if (c == 0x44) {                 /* 'D' */
 366                         filter->status = 0x90;
 367                 } else {
 368                         filter->status &= ~0xf;
 369                         CK((*filter->output_function)(0x1b, filter->data));
 370                         CK((*filter->output_function)(0x24, filter->data));
 371                         CK((*filter->output_function)(0x28, filter->data));
 372                         goto retry;
 373                 }
 374                 break;
 375 
 376         /* ESC ( */
 377 /*      case 0x05:      */
 378 /*      case 0x15:      */
 379 /*      case 0x25:      */
 380 /*      case 0x85:      */
 381 /*      case 0x95:      */
 382         case 5:
 383                 if (c == 0x42 || c == 0x48) {           /* 'B' or 'H' */
 384                         filter->status = 0;
 385                 } else if (c == 0x4a) {         /* 'J' */
 386                         filter->status = 0x10;
 387                 } else if (c == 0x49) {         /* 'I' */
 388                         filter->status = 0x20;
 389                 } else {
 390                         filter->status &= ~0xf;
 391                         CK((*filter->output_function)(0x1b, filter->data));
 392                         CK((*filter->output_function)(0x28, filter->data));
 393                         goto retry;
 394                 }
 395                 break;
 396 
 397         default:
 398                 filter->status = 0;
 399                 break;
 400         }
 401 
 402         return c;
 403 }
 404 
 405 /*
 406  * wchar => JIS
 407  */
 408 int
 409 mbfl_filt_conv_wchar_jis_ms(int c, mbfl_convert_filter *filter)
 410 {
 411         int c1, s;
 412 
 413         s = 0;
 414         if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) {
 415                 s = ucs_a1_jis_table[c - ucs_a1_jis_table_min];
 416         } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) {
 417                 s = ucs_a2_jis_table[c - ucs_a2_jis_table_min];
 418         } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) {
 419                 s = ucs_i_jis_table[c - ucs_i_jis_table_min];
 420         } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) {
 421                 s = ucs_r_jis_table[c - ucs_r_jis_table_min];
 422         } else if (c >= 0xe000 && c < (0xe000 + 10 * 94)) {
 423                 /* PUE => Microsoft extended (pseudo 95ku - 114ku) */
 424                 /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */
 425                 s = c - 0xe000;
 426                 s = (s / 94 + 0x75) << 8 | (s % 94 + 0x21);
 427         } else if (c >= (0xe000 + 10 * 94) && c <= (0xe000 + 20 * 94)) {
 428                 /* PUE => JISX0212 user-defined (G3 85ku - 94ku) */
 429                 /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */
 430                 s = c - (0xe000 + 10 * 94);
 431                 s = (s / 94 + 0xf5) << 8 | (s % 94 + 0xa1);
 432         }
 433 
 434         /* do some transliteration */
 435         if (s <= 0) {
 436                 c1 = c & ~MBFL_WCSPLANE_MASK;
 437                 if (c1 == MBFL_WCSPLANE_JIS0208) {
 438                         s = c & MBFL_WCSPLANE_MASK;
 439                 } else if (c1 == MBFL_WCSPLANE_JIS0212) {
 440                         s = c & MBFL_WCSPLANE_MASK;
 441                         s |= 0x8080;
 442                 } else if (c == 0xa5) {         /* YEN SIGN */
 443                         s = 0x1005c;
 444                 } else if (c == 0x203e) {       /* OVER LINE */
 445                         s = 0x1007e;
 446                 } else if (c == 0xff3c) {       /* FULLWIDTH REVERSE SOLIDUS */
 447                         s = 0x2140;
 448                 } else if (c == 0xff5e) {       /* FULLWIDTH TILDE */
 449                         s = 0x2141;
 450                 } else if (c == 0x2225) {       /* PARALLEL TO */
 451                         s = 0x2142;
 452                 } else if (c == 0xff0d) {       /* FULLWIDTH HYPHEN-MINUS */
 453                         s = 0x215d;
 454                 } else if (c == 0xffe0) {       /* FULLWIDTH CENT SIGN */
 455                         s = 0x2171;
 456                 } else if (c == 0xffe1) {       /* FULLWIDTH POUND SIGN */
 457                         s = 0x2172;
 458                 } else if (c == 0xffe2) {       /* FULLWIDTH NOT SIGN */
 459                         s = 0x224c;
 460                 }
 461         }
 462         if (s <= 0 || (s >= 0x8080 && s < 0x10000)) {
 463                 int i;
 464                 s = -1;
 465 
 466                 for (i = 0;
 467                                 i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; i++) {
 468                         const int oh = cp932ext1_ucs_table_min / 94;
 469 
 470                         if (c == cp932ext1_ucs_table[i]) {
 471                                 s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21);
 472                                 break;
 473                         }
 474                 }
 475 
 476                 if (s < 0) {
 477                         const int oh = cp932ext2_ucs_table_min / 94;
 478                         const int cp932ext2_ucs_table_size =
 479                                         cp932ext2_ucs_table_max - cp932ext2_ucs_table_min;
 480                         for (i = 0; i < cp932ext2_ucs_table_size; i++) {
 481                                 if (c == cp932ext2_ucs_table[i]) {
 482                                         s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21);
 483                                         break;
 484                                 }
 485                         }
 486                 }
 487 
 488                 if (s < 0) {
 489                         const int cp932ext3_ucs_table_size =
 490                                         cp932ext3_ucs_table_max - cp932ext3_ucs_table_min;
 491                         const int limit = cp932ext3_ucs_table_size >
 492                                         cp932ext3_eucjp_table_size ?
 493                                                 cp932ext3_eucjp_table_size:
 494                                                 cp932ext3_ucs_table_size;
 495                         for (i = 0; i < limit; i++) {
 496                                 if (c == cp932ext3_ucs_table[i]) {
 497                                         s = cp932ext3_eucjp_table[i];
 498                                         break;
 499                                 }
 500                         }
 501                 }
 502 
 503                 if (c == 0) {
 504                         s = 0;
 505                 } else if (s <= 0) {
 506                         s = -1;
 507                 }
 508         }
 509 
 510         if (s >= 0) {
 511                 if (s < 0x80) { /* ASCII */
 512                         if ((filter->status & 0xff00) != 0) {
 513                                 CK((*filter->output_function)(0x1b, filter->data));             /* ESC */
 514                                 CK((*filter->output_function)(0x28, filter->data));             /* '(' */
 515                                 CK((*filter->output_function)(0x42, filter->data));             /* 'B' */
 516                         }
 517                         filter->status = 0;
 518                         CK((*filter->output_function)(s, filter->data));
 519                 } else if (s < 0x100) { /* kana */
 520                         if ((filter->status & 0xff00) != 0x100) {
 521                                 CK((*filter->output_function)(0x1b, filter->data));             /* ESC */
 522                                 CK((*filter->output_function)(0x28, filter->data));             /* '(' */
 523                                 CK((*filter->output_function)(0x49, filter->data));             /* 'I' */
 524                         }
 525                         filter->status = 0x100;
 526                         CK((*filter->output_function)(s & 0x7f, filter->data));
 527                 } else if (s < 0x8080) { /* X 0208 */
 528                         if ((filter->status & 0xff00) != 0x200) {
 529                                 CK((*filter->output_function)(0x1b, filter->data));             /* ESC */
 530                                 CK((*filter->output_function)(0x24, filter->data));             /* '$' */
 531                                 CK((*filter->output_function)(0x42, filter->data));             /* 'B' */
 532                         }
 533                         filter->status = 0x200;
 534                         CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
 535                         CK((*filter->output_function)(s & 0x7f, filter->data));
 536                 } else if (s < 0x10000) { /* X 0212 */
 537                         if ((filter->status & 0xff00) != 0x300) {
 538                                 CK((*filter->output_function)(0x1b, filter->data));             /* ESC */
 539                                 CK((*filter->output_function)(0x24, filter->data));             /* '$' */
 540                                 CK((*filter->output_function)(0x28, filter->data));             /* '(' */
 541                                 CK((*filter->output_function)(0x44, filter->data));             /* 'D' */
 542                         }
 543                         filter->status = 0x300;
 544                         CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
 545                         CK((*filter->output_function)(s & 0x7f, filter->data));
 546                 } else { /* X 0201 latin */
 547                         if ((filter->status & 0xff00) != 0x400) {
 548                                 CK((*filter->output_function)(0x1b, filter->data));             /* ESC */
 549                                 CK((*filter->output_function)(0x28, filter->data));             /* '(' */
 550                                 CK((*filter->output_function)(0x4a, filter->data));             /* 'J' */
 551                         }
 552                         filter->status = 0x400;
 553                         CK((*filter->output_function)(s & 0x7f, filter->data));
 554                 }
 555         } else {
 556                 if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
 557                         CK(mbfl_filt_conv_illegal_output(c, filter));
 558                 }
 559         }
 560 
 561         return c;
 562 }
 563 
 564 /*
 565  * wchar => CP50220
 566  */
 567 static void
 568 mbfl_filt_conv_wchar_cp50220_ctor(mbfl_convert_filter *filt)
 569 {
 570         mbfl_filt_conv_wchar_cp50220_ctx *ctx;
 571 
 572         mbfl_filt_conv_common_ctor(filt);
 573 
 574         ctx = mbfl_malloc(sizeof(mbfl_filt_conv_wchar_cp50220_ctx));
 575         if (ctx == NULL) {
 576                 mbfl_filt_conv_common_dtor(filt);
 577                 return;
 578         }
 579 
 580         ctx->tl_param.mode = MBFL_FILT_TL_HAN2ZEN_KATAKANA | MBFL_FILT_TL_HAN2ZEN_GLUE;
 581 
 582         ctx->last = *filt;
 583         ctx->last.opaque = ctx;
 584         ctx->last.data = filt->data;
 585         filt->filter_function = vtbl_tl_jisx0201_jisx0208.filter_function;
 586         filt->filter_flush = vtbl_tl_jisx0201_jisx0208.filter_flush;
 587         filt->output_function = (int(*)(int, void *))ctx->last.filter_function;
 588         filt->flush_function = (int(*)(void *))ctx->last.filter_flush;
 589         filt->data = &ctx->last;
 590         filt->opaque = ctx;
 591         vtbl_tl_jisx0201_jisx0208.filter_ctor(filt);
 592 }
 593 
 594 static void
 595 mbfl_filt_conv_wchar_cp50220_copy(mbfl_convert_filter *src, mbfl_convert_filter *dest)
 596 {
 597         mbfl_filt_conv_wchar_cp50220_ctx *ctx;
 598 
 599         *dest = *src;
 600         ctx = mbfl_malloc(sizeof(mbfl_filt_conv_wchar_cp50220_ctx));
 601         if (ctx != NULL) {
 602                 *ctx = *(mbfl_filt_conv_wchar_cp50220_ctx*)src->opaque;
 603         }
 604 
 605         dest->opaque = ctx;
 606         dest->data = &ctx->last;
 607 }
 608 
 609 static void
 610 mbfl_filt_conv_wchar_cp50220_dtor(mbfl_convert_filter *filt)
 611 {
 612         vtbl_tl_jisx0201_jisx0208.filter_dtor(filt);
 613 
 614         if (filt->opaque != NULL) {
 615                 mbfl_free(filt->opaque);
 616         }
 617 
 618         mbfl_filt_conv_common_dtor(filt);
 619 }
 620 
 621 /*
 622  * wchar => cp50220raw
 623  */
 624 int
 625 mbfl_filt_conv_wchar_cp50220raw(int c, mbfl_convert_filter *filter)
 626 {
 627         if (c & MBFL_WCSPLANE_JIS0208) {
 628                 const int s = c & MBFL_WCSPLANE_MASK;
 629 
 630                 if ((filter->status & 0xff00) != 0x200) {
 631                         CK((*filter->output_function)(0x1b, filter->data));             /* ESC */
 632                         CK((*filter->output_function)(0x24, filter->data));             /* '$' */
 633                         CK((*filter->output_function)(0x42, filter->data));             /* 'B' */
 634                         filter->status = 0x200;
 635                 }
 636                 CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
 637                 CK((*filter->output_function)(s & 0x7f, filter->data));
 638                 return c;
 639         } else {
 640                 return mbfl_filt_conv_wchar_cp50221(c, filter);
 641         }
 642 }
 643 
 644 /*
 645  * wchar => CP50221
 646  */
 647 int
 648 mbfl_filt_conv_wchar_cp50221(int c, mbfl_convert_filter *filter)
 649 {
 650         int s = 0;
 651 
 652         if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) {
 653                 s = ucs_a1_jis_table[c - ucs_a1_jis_table_min];
 654         } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) {
 655                 s = ucs_a2_jis_table[c - ucs_a2_jis_table_min];
 656         } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) {
 657                 s = ucs_i_jis_table[c - ucs_i_jis_table_min];
 658         } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) {
 659                 s = ucs_r_jis_table[c - ucs_r_jis_table_min];
 660         } else if (c >= 0xe000 && c < (0xe000 + 10 * 94)) {
 661                 /* PUE => Microsoft extended */
 662                 /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */
 663                 s = c - 0xe000;
 664                 s = (s / 94 + 0x75) << 8 | (s % 94 + 0x21);
 665         } else if (c >= (0xe000 + 10 * 94) && c <= (0xe000 + 20 * 94)) {
 666                 /* PUE => JISX0212 user-defined (G3 85ku - 94ku) */
 667                 /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */
 668                 s = c - (0xe000 + 10 * 94);
 669                 s = (s / 94 + 0xf5) << 8 | (s % 94 + 0xa1);
 670         }
 671 
 672         if (s <= 0) {
 673                 if (c == 0xa5) {                        /* YEN SIGN */
 674                         s = 0x1005c;
 675                 } else if (c == 0x203e) {       /* OVER LINE */
 676                         s = 0x1007e;
 677                 } else if (c == 0xff3c) {       /* FULLWIDTH REVERSE SOLIDUS */
 678                         s = 0x2140;
 679                 } else if (c == 0xff5e) {       /* FULLWIDTH TILDE */
 680                         s = 0x2141;
 681                 } else if (c == 0x2225) {       /* PARALLEL TO */
 682                         s = 0x2142;
 683                 } else if (c == 0xff0d) {       /* FULLWIDTH HYPHEN-MINUS */
 684                         s = 0x215d;
 685                 } else if (c == 0xffe0) {       /* FULLWIDTH CENT SIGN */
 686                         s = 0x2171;
 687                 } else if (c == 0xffe1) {       /* FULLWIDTH POUND SIGN */
 688                         s = 0x2172;
 689                 } else if (c == 0xffe2) {       /* FULLWIDTH NOT SIGN */
 690                         s = 0x224c;
 691                 }
 692         }
 693         if (s <= 0 || (s >= 0x8080 && s < 0x10000)) {
 694                 int i;
 695                 s = -1;
 696 
 697                 for (i = 0;
 698                                 i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min;
 699                                 i++) {
 700                         const int oh = cp932ext1_ucs_table_min / 94;
 701 
 702                         if (c == cp932ext1_ucs_table[i]) {
 703                                 s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21);
 704                                 break;
 705                         }
 706                 }
 707 
 708                 if (s < 0) {
 709                         const int oh = cp932ext2_ucs_table_min / 94;
 710                         const int cp932ext2_ucs_table_size =
 711                                         cp932ext2_ucs_table_max - cp932ext2_ucs_table_min;
 712                         for (i = 0; i < cp932ext2_ucs_table_size; i++) {
 713                                 if (c == cp932ext2_ucs_table[i]) {
 714                                         s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21);
 715                                         break;
 716                                 }
 717                         }
 718                 }
 719 
 720                 if (s < 0) {
 721                         const int cp932ext3_ucs_table_size =
 722                                         cp932ext3_ucs_table_max - cp932ext3_ucs_table_min;
 723                         const int limit = cp932ext3_ucs_table_size >
 724                                         cp932ext3_eucjp_table_size ?
 725                                                 cp932ext3_eucjp_table_size:
 726                                                 cp932ext3_ucs_table_size;
 727                         for (i = 0; i < limit; i++) {
 728                                 if (c == cp932ext3_ucs_table[i]) {
 729                                         s = cp932ext3_eucjp_table[i];
 730                                         break;
 731                                 }
 732                         }
 733                 }
 734 
 735                 if (c == 0) {
 736                         s = 0;
 737                 } else if (s <= 0) {
 738                         s = -1;
 739                 }
 740         }
 741 
 742         if (s >= 0) {
 743                 if (s < 0x80) { /* ASCII */
 744                         if ((filter->status & 0xff00) != 0) {
 745                                 CK((*filter->output_function)(0x1b, filter->data));             /* ESC */
 746                                 CK((*filter->output_function)(0x28, filter->data));             /* '(' */
 747                                 CK((*filter->output_function)(0x42, filter->data));             /* 'B' */
 748                                 filter->status = 0;
 749                         }
 750                         CK((*filter->output_function)(s, filter->data));
 751                 } else if (s >= 0xa0 && s < 0xe0) { /* X 0201 kana */
 752                         if ((filter->status & 0xff00) != 0x500) {
 753                                 CK((*filter->output_function)(0x1b, filter->data));             /* ESC */
 754                                 CK((*filter->output_function)(0x28, filter->data));             /* '(' */
 755                                 CK((*filter->output_function)(0x49, filter->data));             /* 'I' */
 756                                 filter->status = 0x500;
 757                         }
 758                         CK((*filter->output_function)(s - 0x80, filter->data));
 759                 } else if (s < 0x8080) { /* X 0208 */
 760                         if ((filter->status & 0xff00) != 0x200) {
 761                                 CK((*filter->output_function)(0x1b, filter->data));             /* ESC */
 762                                 CK((*filter->output_function)(0x24, filter->data));             /* '$' */
 763                                 CK((*filter->output_function)(0x42, filter->data));             /* 'B' */
 764                                 filter->status = 0x200;
 765                         }
 766                         CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
 767                         CK((*filter->output_function)(s & 0x7f, filter->data));
 768                 } else if (s < 0x10000) { /* X0212 */
 769                         if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
 770                                 CK(mbfl_filt_conv_illegal_output(c, filter));
 771                         }
 772                 } else { /* X 0201 latin */
 773                         if ((filter->status & 0xff00) != 0x400) {
 774                                 CK((*filter->output_function)(0x1b, filter->data));             /* ESC */
 775                                 CK((*filter->output_function)(0x28, filter->data));             /* '(' */
 776                                 CK((*filter->output_function)(0x4a, filter->data));             /* 'J' */
 777                         }
 778                         filter->status = 0x400;
 779                         CK((*filter->output_function)(s & 0x7f, filter->data));
 780                 }
 781         } else {
 782                 if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
 783                         CK(mbfl_filt_conv_illegal_output(c, filter));
 784                 }
 785         }
 786 
 787         return c;
 788 }
 789 
 790 /*
 791  * wchar => CP50222
 792  */
 793 int
 794 mbfl_filt_conv_wchar_cp50222(int c, mbfl_convert_filter *filter)
 795 {
 796         int s;
 797 
 798         s = 0;
 799 
 800         if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) {
 801                 s = ucs_a1_jis_table[c - ucs_a1_jis_table_min];
 802         } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) {
 803                 s = ucs_a2_jis_table[c - ucs_a2_jis_table_min];
 804         } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) {
 805                 s = ucs_i_jis_table[c - ucs_i_jis_table_min];
 806         } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) {
 807                 s = ucs_r_jis_table[c - ucs_r_jis_table_min];
 808         } else if (c >= 0xe000 && c < (0xe000 + 10 * 94)) {
 809                 /* PUE => Microsoft extended */
 810                 /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */
 811                 s = c - 0xe000;
 812                 s = (s / 94 + 0x75) << 8 | (s % 94 + 0x21);
 813         } else if (c >= (0xe000 + 10 * 94) && c <= (0xe000 + 20 * 94)) {
 814                 /* PUE => JISX0212 user-defined (G3 85ku - 94ku) */
 815                 /* See http://www.opengroup.or.jp/jvc/cde/ucs-conv.html#ch4_2 */
 816                 s = c - (0xe000 + 10 * 94);
 817                 s = (s / 94 + 0xf5) << 8 | (s % 94 + 0xa1);
 818         }
 819 
 820         if (s <= 0) {
 821                 if (c == 0xa5) {                        /* YEN SIGN */
 822                         s = 0x1005c;
 823                 } else if (c == 0x203e) {       /* OVER LINE */
 824                         s = 0x1007e;
 825                 } else if (c == 0xff3c) {       /* FULLWIDTH REVERSE SOLIDUS */
 826                         s = 0x2140;
 827                 } else if (c == 0xff5e) {       /* FULLWIDTH TILDE */
 828                         s = 0x2141;
 829                 } else if (c == 0x2225) {       /* PARALLEL TO */
 830                         s = 0x2142;
 831                 } else if (c == 0xff0d) {       /* FULLWIDTH HYPHEN-MINUS */
 832                         s = 0x215d;
 833                 } else if (c == 0xffe0) {       /* FULLWIDTH CENT SIGN */
 834                         s = 0x2171;
 835                 } else if (c == 0xffe1) {       /* FULLWIDTH POUND SIGN */
 836                         s = 0x2172;
 837                 } else if (c == 0xffe2) {       /* FULLWIDTH NOT SIGN */
 838                         s = 0x224c;
 839                 }
 840         }
 841         if (s <= 0 || (s >= 0x8080 && s < 0x10000)) {
 842                 int i;
 843                 s = -1;
 844 
 845                 for (i = 0;
 846                                 i < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; i++) {
 847                         const int oh = cp932ext1_ucs_table_min / 94;
 848 
 849                         if (c == cp932ext1_ucs_table[i]) {
 850                                 s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21);
 851                                 break;
 852                         }
 853                 }
 854 
 855                 if (s <= 0) {
 856                         const int oh = cp932ext2_ucs_table_min / 94;
 857                         const int cp932ext2_ucs_table_size =
 858                                         cp932ext2_ucs_table_max - cp932ext2_ucs_table_min;
 859                         for (i = 0; i < cp932ext2_ucs_table_size; i++) {
 860                                 if (c == cp932ext2_ucs_table[i]) {
 861                                         s = ((i / 94 + oh + 0x21) << 8) + (i % 94 + 0x21);
 862                                         break;
 863                                 }
 864                         }
 865                 }
 866 
 867                 if (s <= 0) {
 868                         const int cp932ext3_ucs_table_size =
 869                                         cp932ext3_ucs_table_max - cp932ext3_ucs_table_min;
 870                         const int limit = cp932ext3_ucs_table_size >
 871                                         cp932ext3_eucjp_table_size ?
 872                                                 cp932ext3_eucjp_table_size:
 873                                                 cp932ext3_ucs_table_size;
 874                         for (i = 0; i < limit; i++) {
 875                                 if (c == cp932ext3_ucs_table[i]) {
 876                                         s = cp932ext3_eucjp_table[i];
 877                                         break;
 878                                 }
 879                         }
 880                 }
 881 
 882                 if (c == 0) {
 883                         s = 0;
 884                 } else if (s <= 0) {
 885                         s = -1;
 886                 }
 887         }
 888 
 889         if (s >= 0) {
 890                 if (s < 0x80) { /* ASCII */
 891                         if ((filter->status & 0xff00) == 0x500) {
 892                                 CK((*filter->output_function)(0x0f, filter->data));             /* SO */
 893                                 filter->status = 0;
 894                         } else if ((filter->status & 0xff00) != 0) {
 895                                 CK((*filter->output_function)(0x1b, filter->data));             /* ESC */
 896                                 CK((*filter->output_function)(0x28, filter->data));             /* '(' */
 897                                 CK((*filter->output_function)(0x42, filter->data));             /* 'B' */
 898                                 filter->status = 0;
 899                         }
 900                         CK((*filter->output_function)(s, filter->data));
 901                 } else if (s >= 0xa0 && s < 0xe0) { /* X 0201 kana */
 902                         if ((filter->status & 0xff00) != 0x500) {
 903                                 CK((*filter->output_function)(0x0e, filter->data));             /* SI */
 904                                 filter->status = 0x500;
 905                         }
 906                         CK((*filter->output_function)(s - 0x80, filter->data));
 907                 } else if (s < 0x8080) { /* X 0208 */
 908                         if ((filter->status & 0xff00) == 0x500) {
 909                                 CK((*filter->output_function)(0x0f, filter->data));             /* SO */
 910                                 filter->status = 0;
 911                         }
 912                         if ((filter->status & 0xff00) != 0x200) {
 913                                 CK((*filter->output_function)(0x1b, filter->data));             /* ESC */
 914                                 CK((*filter->output_function)(0x24, filter->data));             /* '$' */
 915                                 CK((*filter->output_function)(0x42, filter->data));             /* 'B' */
 916                                 filter->status = 0x200;
 917                         }
 918                         CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
 919                         CK((*filter->output_function)(s & 0x7f, filter->data));
 920                 } else if (s < 0x10000) { /* X0212 */
 921                         if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
 922                                 CK(mbfl_filt_conv_illegal_output(c, filter));
 923                         }
 924                 } else { /* X 0201 latin */
 925                         if ((filter->status & 0xff00) == 0x500) {
 926                                 CK((*filter->output_function)(0x0f, filter->data));             /* SO */
 927                                 filter->status = 0;
 928                         }
 929                         if ((filter->status & 0xff00) != 0x400) {
 930                                 CK((*filter->output_function)(0x1b, filter->data));             /* ESC */
 931                                 CK((*filter->output_function)(0x28, filter->data));             /* '(' */
 932                                 CK((*filter->output_function)(0x4a, filter->data));             /* 'J' */
 933                         }
 934                         filter->status = 0x400;
 935                         CK((*filter->output_function)(s & 0x7f, filter->data));
 936                 }
 937         } else {
 938                 if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
 939                         CK(mbfl_filt_conv_illegal_output(c, filter));
 940                 }
 941         }
 942 
 943         return c;
 944 }
 945 
 946 int
 947 mbfl_filt_conv_wchar_cp50222_flush(mbfl_convert_filter *filter)
 948 {
 949         /* back to latin */
 950         if ((filter->status & 0xff00) == 0x500) {
 951                 CK((*filter->output_function)(0x0f, filter->data));             /* SO */
 952         } else if ((filter->status & 0xff00) != 0) {
 953                 CK((*filter->output_function)(0x1b, filter->data));             /* ESC */
 954                 CK((*filter->output_function)(0x28, filter->data));             /* '(' */
 955                 CK((*filter->output_function)(0x42, filter->data));             /* 'B' */
 956         }
 957         filter->status &= 0xff;
 958 
 959         if (filter->flush_function != NULL) {
 960                 return (*filter->flush_function)(filter->data);
 961         }
 962 
 963         return 0;
 964 }
 965 
 966 
 967 static int mbfl_filt_ident_jis_ms(int c, mbfl_identify_filter *filter)
 968 {
 969 retry:
 970         switch (filter->status & 0xf) {
 971 /*      case 0x00:       ASCII */
 972 /*      case 0x10:       X 0201 latin */
 973 /*      case 0x20:       X 0201 kana */
 974 /*      case 0x80:       X 0208 */
 975 /*      case 0x90:       X 0212 */
 976         case 0:
 977                 if (c == 0x1b) {
 978                         filter->status += 2;
 979                 } else if (c == 0x0e) {                 /* "kana in" */
 980                         filter->status = 0x20;
 981                 } else if (c == 0x0f) {                 /* "kana out" */
 982                         filter->status = 0;
 983                 } else if ((filter->status == 0x80 || filter->status == 0x90) && c > 0x20 && c < 0x7f) {                /* kanji first char */
 984                         filter->status += 1;
 985                 } else if (c >= 0 && c < 0x80) {                /* latin, CTLs */
 986                         ;
 987                 } else {
 988                         filter->flag = 1;       /* bad */
 989                 }
 990                 break;
 991 
 992 /*      case 0x81:       X 0208 second char */
 993 /*      case 0x91:       X 0212 second char */
 994         case 1:
 995                 filter->status &= ~0xf;
 996                 if (c == 0x1b) {
 997                         goto retry;
 998                 } else if (c < 0x21 || c > 0x7e) {              /* bad */
 999                         filter->flag = 1;
1000                 }
1001                 break;
1002 
1003         /* ESC */
1004         case 2:
1005                 if (c == 0x24) {                /* '$' */
1006                         filter->status++;
1007                 } else if (c == 0x28) {         /* '(' */
1008                         filter->status += 3;
1009                 } else {
1010                         filter->flag = 1;       /* bad */
1011                         filter->status &= ~0xf;
1012                         goto retry;
1013                 }
1014                 break;
1015 
1016         /* ESC $ */
1017         case 3:
1018                 if (c == 0x40 || c == 0x42) {           /* '@' or 'B' */
1019                         filter->status = 0x80;
1020                 } else if (c == 0x28) {         /* '(' */
1021                         filter->status++;
1022                 } else {
1023                         filter->flag = 1;       /* bad */
1024                         filter->status &= ~0xf;
1025                         goto retry;
1026                 }
1027                 break;
1028 
1029         /* ESC $ ( */
1030         case 4:
1031                 if (c == 0x40 || c == 0x42) {           /* '@' or 'B' */
1032                         filter->status = 0x80;
1033                 } else if (c == 0x44) {         /* 'D' */
1034                         filter->status = 0x90;
1035                 } else {
1036                         filter->flag = 1;       /* bad */
1037                         filter->status &= ~0xf;
1038                         goto retry;
1039                 }
1040                 break;
1041 
1042         /* ESC ( */
1043         case 5:
1044                 if (c == 0x42 || c == 0x48) {           /* 'B' or 'H' */
1045                         filter->status = 0;
1046                 } else if (c == 0x4a) {         /* 'J' */
1047                         filter->status = 0x10;
1048                 } else if (c == 0x49) {         /* 'I' */
1049                         filter->status = 0x20;
1050                 } else {
1051                         filter->flag = 1;       /* bad */
1052                         filter->status &= ~0xf;
1053                         goto retry;
1054                 }
1055                 break;
1056 
1057         default:
1058                 filter->status = 0;
1059                 break;
1060         }
1061 
1062         return c;
1063 }
1064 
1065 static int mbfl_filt_ident_cp50220(int c, mbfl_identify_filter *filter)
1066 {
1067 retry:
1068         switch (filter->status & 0xf) {
1069 /*      case 0x00:       ASCII */
1070 /*      case 0x10:       X 0201 latin */
1071 /*      case 0x80:       X 0208 */
1072         case 0:
1073                 if (c == 0x1b) {
1074                         filter->status += 2;
1075                 } else if (filter->status == 0x80 && c > 0x20 && c < 0x7f) {            /* kanji first char */
1076                         filter->status += 1;
1077                 } else if (c >= 0 && c < 0x80) {                /* latin, CTLs */
1078                         ;
1079                 } else {
1080                         filter->flag = 1;       /* bad */
1081                 }
1082                 break;
1083 
1084 /*      case 0x81:       X 0208 second char */
1085         case 1:
1086                 if (c == 0x1b) {
1087                         filter->status++;
1088                 } else {
1089                         filter->status &= ~0xf;
1090                         if (c < 0x21 || c > 0x7e) {             /* bad */
1091                                 filter->flag = 1;
1092                         }
1093                 }
1094                 break;
1095 
1096         /* ESC */
1097         case 2:
1098                 if (c == 0x24) {                /* '$' */
1099                         filter->status++;
1100                 } else if (c == 0x28) {         /* '(' */
1101                         filter->status += 3;
1102                 } else {
1103                         filter->flag = 1;       /* bad */
1104                         filter->status &= ~0xf;
1105                         goto retry;
1106                 }
1107                 break;
1108 
1109         /* ESC $ */
1110         case 3:
1111                 if (c == 0x40 || c == 0x42) {           /* '@' or 'B' */
1112                         filter->status = 0x80;
1113                 } else {
1114                         filter->flag = 1;       /* bad */
1115                         filter->status &= ~0xf;
1116                         goto retry;
1117                 }
1118                 break;
1119 
1120         /* ESC ( */
1121         case 5:
1122                 if (c == 0x42) {                /* 'B' */
1123                         filter->status = 0;
1124                 } else if (c == 0x4a) {         /* 'J' */
1125                         filter->status = 0x10;
1126                 } else {
1127                         filter->flag = 1;       /* bad */
1128                         filter->status &= ~0xf;
1129                         goto retry;
1130                 }
1131                 break;
1132 
1133         default:
1134                 filter->status = 0;
1135                 break;
1136         }
1137 
1138         return c;
1139 }
1140 
1141 static int mbfl_filt_ident_cp50221(int c, mbfl_identify_filter *filter)
1142 {
1143 retry:
1144         switch (filter->status & 0xf) {
1145 /*      case 0x00:       ASCII */
1146 /*      case 0x10:       X 0201 latin */
1147 /*      case 0x80:       X 0208 */
1148         case 0:
1149                 if (c == 0x1b) {
1150                         filter->status += 2;
1151                 } else if (filter->status == 0x80 && c > 0x20 && c < 0x7f) {            /* kanji first char */
1152                         filter->status += 1;
1153                 } else if (c >= 0 && c < 0x80) {                /* latin, CTLs */
1154                         ;
1155                 } else {
1156                         filter->flag = 1;       /* bad */
1157                 }
1158                 break;
1159 
1160 /*      case 0x81:       X 0208 second char */
1161         case 1:
1162                 if (c == 0x1b) {
1163                         filter->status++;
1164                 } else {
1165                         filter->status &= ~0xf;
1166                         if (c < 0x21 || c > 0x7e) {             /* bad */
1167                                 filter->flag = 1;
1168                         }
1169                 }
1170                 break;
1171 
1172         /* ESC */
1173         case 2:
1174                 if (c == 0x24) {                /* '$' */
1175                         filter->status++;
1176                 } else if (c == 0x28) {         /* '(' */
1177                         filter->status += 3;
1178                 } else {
1179                         filter->flag = 1;       /* bad */
1180                         filter->status &= ~0xf;
1181                         goto retry;
1182                 }
1183                 break;
1184 
1185         /* ESC $ */
1186         case 3:
1187                 if (c == 0x40 || c == 0x42) {           /* '@' or 'B' */
1188                         filter->status = 0x80;
1189                 } else {
1190                         filter->flag = 1;       /* bad */
1191                         filter->status &= ~0xf;
1192                         goto retry;
1193                 }
1194                 break;
1195 
1196         /* ESC ( */
1197         case 5:
1198                 if (c == 0x42) {                /* 'B' */
1199                         filter->status = 0;
1200                 } else if (c == 0x4a) {         /* 'J' */
1201                         filter->status = 0x10;
1202                 } else if (c == 0x49) {         /* 'I' */
1203                         filter->status = 0x20;
1204                 } else {
1205                         filter->flag = 1;       /* bad */
1206                         filter->status &= ~0xf;
1207                         goto retry;
1208                 }
1209                 break;
1210 
1211         default:
1212                 filter->status = 0;
1213                 break;
1214         }
1215 
1216         return c;
1217 }
1218 
1219 static int mbfl_filt_ident_cp50222(int c, mbfl_identify_filter *filter)
1220 {
1221 retry:
1222         switch (filter->status & 0xf) {
1223 /*      case 0x00:       ASCII */
1224 /*      case 0x10:       X 0201 latin */
1225 /*      case 0x80:       X 0208 */
1226         case 0:
1227                 if (c == 0x1b) {
1228                         filter->status += 2;
1229                 } else if (filter->status == 0x80 && c > 0x20 && c < 0x7f) {            /* kanji first char */
1230                         filter->status += 1;
1231                 } else if (c >= 0 && c < 0x80) {                /* latin, CTLs */
1232                         ;
1233                 } else {
1234                         filter->flag = 1;       /* bad */
1235                 }
1236                 break;
1237 
1238 /*      case 0x81:       X 0208 second char */
1239         case 1:
1240                 if (c == 0x1b) {
1241                         filter->status++;
1242                 } else {
1243                         filter->status &= ~0xf;
1244                         if (c < 0x21 || c > 0x7e) {             /* bad */
1245                                 filter->flag = 1;
1246                         }
1247                 }
1248                 break;
1249 
1250         /* ESC */
1251         case 2:
1252                 if (c == 0x24) {                /* '$' */
1253                         filter->status++;
1254                 } else if (c == 0x28) {         /* '(' */
1255                         filter->status += 3;
1256                 } else {
1257                         filter->flag = 1;       /* bad */
1258                         filter->status &= ~0xf;
1259                         goto retry;
1260                 }
1261                 break;
1262 
1263         /* ESC $ */
1264         case 3:
1265                 if (c == 0x40 || c == 0x42) {           /* '@' or 'B' */
1266                         filter->status = 0x80;
1267                 } else {
1268                         filter->flag = 1;       /* bad */
1269                         filter->status &= ~0xf;
1270                         goto retry;
1271                 }
1272                 break;
1273 
1274         /* ESC ( */
1275         case 5:
1276                 if (c == 0x42) {                /* 'B' */
1277                         filter->status = 0;
1278                 } else if (c == 0x4a) {         /* 'J' */
1279                         filter->status = 0x10;
1280                 } else {
1281                         filter->flag = 1;       /* bad */
1282                         filter->status &= ~0xf;
1283                         goto retry;
1284                 }
1285                 break;
1286 
1287         default:
1288                 filter->status = 0;
1289                 break;
1290         }
1291 
1292         return c;
1293 }
1294 
1295 
1296 

/* [<][>][^][v][top][bottom][index][help] */