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:
22 *
23 */
24 /*
25 * The source code included in this files was separated from mbfilter_ja.c
26 * by moriyoshi koizumi <moriyoshi@php.net> on 4 dec 2002.
27 *
28 */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "mbfilter.h"
35 #include "mbfilter_jis.h"
36
37 #include "unicode_table_cp932_ext.h"
38 #include "unicode_table_jis.h"
39
40 static int mbfl_filt_ident_jis(int c, mbfl_identify_filter *filter);
41 static int mbfl_filt_ident_2022jp(int c, mbfl_identify_filter *filter);
42
43 const mbfl_encoding mbfl_encoding_jis = {
44 mbfl_no_encoding_jis,
45 "JIS",
46 "ISO-2022-JP",
47 NULL,
48 NULL,
49 MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE | MBFL_ENCTYPE_GL_UNSAFE
50 };
51
52 const mbfl_encoding mbfl_encoding_2022jp = {
53 mbfl_no_encoding_2022jp,
54 "ISO-2022-JP",
55 "ISO-2022-JP",
56 NULL,
57 NULL,
58 MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE | MBFL_ENCTYPE_GL_UNSAFE
59 };
60
61 const struct mbfl_identify_vtbl vtbl_identify_jis = {
62 mbfl_no_encoding_jis,
63 mbfl_filt_ident_common_ctor,
64 mbfl_filt_ident_common_dtor,
65 mbfl_filt_ident_jis
66 };
67
68 const struct mbfl_identify_vtbl vtbl_identify_2022jp = {
69 mbfl_no_encoding_2022jp,
70 mbfl_filt_ident_common_ctor,
71 mbfl_filt_ident_common_dtor,
72 mbfl_filt_ident_2022jp
73 };
74
75 const struct mbfl_convert_vtbl vtbl_jis_wchar = {
76 mbfl_no_encoding_jis,
77 mbfl_no_encoding_wchar,
78 mbfl_filt_conv_common_ctor,
79 mbfl_filt_conv_common_dtor,
80 mbfl_filt_conv_jis_wchar,
81 mbfl_filt_conv_common_flush
82 };
83
84 const struct mbfl_convert_vtbl vtbl_wchar_jis = {
85 mbfl_no_encoding_wchar,
86 mbfl_no_encoding_jis,
87 mbfl_filt_conv_common_ctor,
88 mbfl_filt_conv_common_dtor,
89 mbfl_filt_conv_wchar_jis,
90 mbfl_filt_conv_any_jis_flush
91 };
92
93 const struct mbfl_convert_vtbl vtbl_2022jp_wchar = {
94 mbfl_no_encoding_2022jp,
95 mbfl_no_encoding_wchar,
96 mbfl_filt_conv_common_ctor,
97 mbfl_filt_conv_common_dtor,
98 mbfl_filt_conv_jis_wchar,
99 mbfl_filt_conv_common_flush
100 };
101
102 const struct mbfl_convert_vtbl vtbl_wchar_2022jp = {
103 mbfl_no_encoding_wchar,
104 mbfl_no_encoding_2022jp,
105 mbfl_filt_conv_common_ctor,
106 mbfl_filt_conv_common_dtor,
107 mbfl_filt_conv_wchar_2022jp,
108 mbfl_filt_conv_any_jis_flush
109 };
110
111 #define CK(statement) do { if ((statement) < 0) return (-1); } while (0)
112
113 /*
114 * JIS => wchar
115 */
116 int
mbfl_filt_conv_jis_wchar(int c,mbfl_convert_filter * filter)117 mbfl_filt_conv_jis_wchar(int c, mbfl_convert_filter *filter)
118 {
119 int c1, s, w;
120
121 retry:
122 switch (filter->status & 0xf) {
123 /* case 0x00: ASCII */
124 /* case 0x10: X 0201 latin */
125 /* case 0x20: X 0201 kana */
126 /* case 0x80: X 0208 */
127 /* case 0x90: X 0212 */
128 case 0:
129 if (c == 0x1b) {
130 filter->status += 2;
131 } else if (c == 0x0e) { /* "kana in" */
132 filter->status = 0x20;
133 } else if (c == 0x0f) { /* "kana out" */
134 filter->status = 0;
135 } else if (filter->status == 0x10 && c == 0x5c) { /* YEN SIGN */
136 CK((*filter->output_function)(0xa5, filter->data));
137 } else if (filter->status == 0x10 && c == 0x7e) { /* OVER LINE */
138 CK((*filter->output_function)(0x203e, filter->data));
139 } else if (filter->status == 0x20 && c > 0x20 && c < 0x60) { /* kana */
140 CK((*filter->output_function)(0xff40 + c, filter->data));
141 } else if ((filter->status == 0x80 || filter->status == 0x90) && c > 0x20 && c < 0x7f) { /* kanji first char */
142 filter->cache = c;
143 filter->status += 1;
144 } else if (c >= 0 && c < 0x80) { /* latin, CTLs */
145 CK((*filter->output_function)(c, filter->data));
146 } else if (c > 0xa0 && c < 0xe0) { /* GR kana */
147 CK((*filter->output_function)(0xfec0 + c, filter->data));
148 } else {
149 w = c & MBFL_WCSGROUP_MASK;
150 w |= MBFL_WCSGROUP_THROUGH;
151 CK((*filter->output_function)(w, filter->data));
152 }
153 break;
154
155 /* case 0x81: X 0208 second char */
156 /* case 0x91: X 0212 second char */
157 case 1:
158 filter->status &= ~0xf;
159 c1 = filter->cache;
160 if (c > 0x20 && c < 0x7f) {
161 s = (c1 - 0x21)*94 + c - 0x21;
162 if (filter->status == 0x80) {
163 if (s >= 0 && s < jisx0208_ucs_table_size) {
164 w = jisx0208_ucs_table[s];
165 } else {
166 w = 0;
167 }
168 if (w <= 0) {
169 w = (c1 << 8) | c;
170 w &= MBFL_WCSPLANE_MASK;
171 w |= MBFL_WCSPLANE_JIS0208;
172 }
173 } else {
174 if (s >= 0 && s < jisx0212_ucs_table_size) {
175 w = jisx0212_ucs_table[s];
176 } else {
177 w = 0;
178 }
179 if (w <= 0) {
180 w = (c1 << 8) | c;
181 w &= MBFL_WCSPLANE_MASK;
182 w |= MBFL_WCSPLANE_JIS0212;
183 }
184 }
185 CK((*filter->output_function)(w, filter->data));
186 } else if (c == 0x1b) {
187 filter->status += 2;
188 } else if ((c >= 0 && c < 0x21) || c == 0x7f) { /* CTLs */
189 CK((*filter->output_function)(c, filter->data));
190 } else {
191 w = (c1 << 8) | c;
192 w &= MBFL_WCSGROUP_MASK;
193 w |= MBFL_WCSGROUP_THROUGH;
194 CK((*filter->output_function)(w, filter->data));
195 }
196 break;
197
198 /* ESC */
199 /* case 0x02: */
200 /* case 0x12: */
201 /* case 0x22: */
202 /* case 0x82: */
203 /* case 0x92: */
204 case 2:
205 if (c == 0x24) { /* '$' */
206 filter->status++;
207 } else if (c == 0x28) { /* '(' */
208 filter->status += 3;
209 } else {
210 filter->status &= ~0xf;
211 CK((*filter->output_function)(0x1b, filter->data));
212 goto retry;
213 }
214 break;
215
216 /* ESC $ */
217 /* case 0x03: */
218 /* case 0x13: */
219 /* case 0x23: */
220 /* case 0x83: */
221 /* case 0x93: */
222 case 3:
223 if (c == 0x40 || c == 0x42) { /* '@' or 'B' */
224 filter->status = 0x80;
225 } else if (c == 0x28) { /* '(' */
226 filter->status++;
227 } else {
228 filter->status &= ~0xf;
229 CK((*filter->output_function)(0x1b, filter->data));
230 CK((*filter->output_function)(0x24, filter->data));
231 goto retry;
232 }
233 break;
234
235 /* ESC $ ( */
236 /* case 0x04: */
237 /* case 0x14: */
238 /* case 0x24: */
239 /* case 0x84: */
240 /* case 0x94: */
241 case 4:
242 if (c == 0x40 || c == 0x42) { /* '@' or 'B' */
243 filter->status = 0x80;
244 } else if (c == 0x44) { /* 'D' */
245 filter->status = 0x90;
246 } else {
247 filter->status &= ~0xf;
248 CK((*filter->output_function)(0x1b, filter->data));
249 CK((*filter->output_function)(0x24, filter->data));
250 CK((*filter->output_function)(0x28, filter->data));
251 goto retry;
252 }
253 break;
254
255 /* ESC ( */
256 /* case 0x05: */
257 /* case 0x15: */
258 /* case 0x25: */
259 /* case 0x85: */
260 /* case 0x95: */
261 case 5:
262 if (c == 0x42 || c == 0x48) { /* 'B' or 'H' */
263 filter->status = 0;
264 } else if (c == 0x4a) { /* 'J' */
265 filter->status = 0x10;
266 } else if (c == 0x49) { /* 'I' */
267 filter->status = 0x20;
268 } else {
269 filter->status &= ~0xf;
270 CK((*filter->output_function)(0x1b, filter->data));
271 CK((*filter->output_function)(0x28, filter->data));
272 goto retry;
273 }
274 break;
275
276 default:
277 filter->status = 0;
278 break;
279 }
280
281 return c;
282 }
283
284 /*
285 * wchar => JIS
286 */
287 int
mbfl_filt_conv_wchar_jis(int c,mbfl_convert_filter * filter)288 mbfl_filt_conv_wchar_jis(int c, mbfl_convert_filter *filter)
289 {
290 int c1, s;
291
292 s = 0;
293 if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) {
294 s = ucs_a1_jis_table[c - ucs_a1_jis_table_min];
295 } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) {
296 s = ucs_a2_jis_table[c - ucs_a2_jis_table_min];
297 } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) {
298 s = ucs_i_jis_table[c - ucs_i_jis_table_min];
299 } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) {
300 s = ucs_r_jis_table[c - ucs_r_jis_table_min];
301 }
302 if (s <= 0) {
303 c1 = c & ~MBFL_WCSPLANE_MASK;
304 if (c1 == MBFL_WCSPLANE_JIS0208) {
305 s = c & MBFL_WCSPLANE_MASK;
306 } else if (c1 == MBFL_WCSPLANE_JIS0212) {
307 s = c & MBFL_WCSPLANE_MASK;
308 s |= 0x8080;
309 } else if (c == 0xa5) { /* YEN SIGN */
310 s = 0x1005c;
311 } else if (c == 0x203e) { /* OVER LINE */
312 s = 0x1007e;
313 } else if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */
314 s = 0x2140;
315 } else if (c == 0xff5e) { /* FULLWIDTH TILDE */
316 s = 0x2141;
317 } else if (c == 0x2225) { /* PARALLEL TO */
318 s = 0x2142;
319 } else if (c == 0xff0d) { /* FULLWIDTH HYPHEN-MINUS */
320 s = 0x215d;
321 } else if (c == 0xffe0) { /* FULLWIDTH CENT SIGN */
322 s = 0x2171;
323 } else if (c == 0xffe1) { /* FULLWIDTH POUND SIGN */
324 s = 0x2172;
325 } else if (c == 0xffe2) { /* FULLWIDTH NOT SIGN */
326 s = 0x224c;
327 }
328 if (c == 0) {
329 s = 0;
330 } else if (s <= 0) {
331 s = -1;
332 }
333 }
334 if (s >= 0) {
335 if (s < 0x80) { /* ASCII */
336 if ((filter->status & 0xff00) != 0) {
337 CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
338 CK((*filter->output_function)(0x28, filter->data)); /* '(' */
339 CK((*filter->output_function)(0x42, filter->data)); /* 'B' */
340 }
341 filter->status = 0;
342 CK((*filter->output_function)(s, filter->data));
343 } else if (s < 0x100) { /* kana */
344 if ((filter->status & 0xff00) != 0x100) {
345 CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
346 CK((*filter->output_function)(0x28, filter->data)); /* '(' */
347 CK((*filter->output_function)(0x49, filter->data)); /* 'I' */
348 }
349 filter->status = 0x100;
350 CK((*filter->output_function)(s & 0x7f, filter->data));
351 } else if (s < 0x8080) { /* X 0208 */
352 if ((filter->status & 0xff00) != 0x200) {
353 CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
354 CK((*filter->output_function)(0x24, filter->data)); /* '$' */
355 CK((*filter->output_function)(0x42, filter->data)); /* 'B' */
356 }
357 filter->status = 0x200;
358 CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
359 CK((*filter->output_function)(s & 0x7f, filter->data));
360 } else if (s < 0x10000) { /* X 0212 */
361 if ((filter->status & 0xff00) != 0x300) {
362 CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
363 CK((*filter->output_function)(0x24, filter->data)); /* '$' */
364 CK((*filter->output_function)(0x28, filter->data)); /* '(' */
365 CK((*filter->output_function)(0x44, filter->data)); /* 'D' */
366 }
367 filter->status = 0x300;
368 CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
369 CK((*filter->output_function)(s & 0x7f, filter->data));
370 } else { /* X 0201 latin */
371 if ((filter->status & 0xff00) != 0x400) {
372 CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
373 CK((*filter->output_function)(0x28, filter->data)); /* '(' */
374 CK((*filter->output_function)(0x4a, filter->data)); /* 'J' */
375 }
376 filter->status = 0x400;
377 CK((*filter->output_function)(s & 0x7f, filter->data));
378 }
379 } else {
380 if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
381 CK(mbfl_filt_conv_illegal_output(c, filter));
382 }
383 }
384
385 return c;
386 }
387
388
389 /*
390 * wchar => ISO-2022-JP
391 */
392 int
mbfl_filt_conv_wchar_2022jp(int c,mbfl_convert_filter * filter)393 mbfl_filt_conv_wchar_2022jp(int c, mbfl_convert_filter *filter)
394 {
395 int s;
396
397 s = 0;
398 if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) {
399 s = ucs_a1_jis_table[c - ucs_a1_jis_table_min];
400 } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) {
401 s = ucs_a2_jis_table[c - ucs_a2_jis_table_min];
402 } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) {
403 s = ucs_i_jis_table[c - ucs_i_jis_table_min];
404 } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) {
405 s = ucs_r_jis_table[c - ucs_r_jis_table_min];
406 }
407 if (s <= 0) {
408 if (c == 0xa5) { /* YEN SIGN */
409 s = 0x1005c;
410 } else if (c == 0x203e) { /* OVER LINE */
411 s = 0x1007e;
412 } else if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */
413 s = 0x2140;
414 } else if (c == 0xff5e) { /* FULLWIDTH TILDE */
415 s = 0x2141;
416 } else if (c == 0x2225) { /* PARALLEL TO */
417 s = 0x2142;
418 } else if (c == 0xff0d) { /* FULLWIDTH HYPHEN-MINUS */
419 s = 0x215d;
420 } else if (c == 0xffe0) { /* FULLWIDTH CENT SIGN */
421 s = 0x2171;
422 } else if (c == 0xffe1) { /* FULLWIDTH POUND SIGN */
423 s = 0x2172;
424 } else if (c == 0xffe2) { /* FULLWIDTH NOT SIGN */
425 s = 0x224c;
426 }
427 if (c == 0) {
428 s = 0;
429 } else if (s <= 0) {
430 s = -1;
431 }
432 } else if ((s >= 0x80 && s < 0x2121) || (s > 0x8080)) {
433 s = -1;
434 }
435 if (s >= 0) {
436 if (s < 0x80) { /* ASCII */
437 if ((filter->status & 0xff00) != 0) {
438 CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
439 CK((*filter->output_function)(0x28, filter->data)); /* '(' */
440 CK((*filter->output_function)(0x42, filter->data)); /* 'B' */
441 }
442 filter->status = 0;
443 CK((*filter->output_function)(s, filter->data));
444 } else if (s < 0x10000) { /* X 0208 */
445 if ((filter->status & 0xff00) != 0x200) {
446 CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
447 CK((*filter->output_function)(0x24, filter->data)); /* '$' */
448 CK((*filter->output_function)(0x42, filter->data)); /* 'B' */
449 }
450 filter->status = 0x200;
451 CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
452 CK((*filter->output_function)(s & 0x7f, filter->data));
453 } else { /* X 0201 latin */
454 if ((filter->status & 0xff00) != 0x400) {
455 CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
456 CK((*filter->output_function)(0x28, filter->data)); /* '(' */
457 CK((*filter->output_function)(0x4a, filter->data)); /* 'J' */
458 }
459 filter->status = 0x400;
460 CK((*filter->output_function)(s & 0x7f, filter->data));
461 }
462 } else {
463 if (filter->illegal_mode != MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
464 CK(mbfl_filt_conv_illegal_output(c, filter));
465 }
466 }
467
468 return c;
469 }
470
471 int
mbfl_filt_conv_any_jis_flush(mbfl_convert_filter * filter)472 mbfl_filt_conv_any_jis_flush(mbfl_convert_filter *filter)
473 {
474 /* back to latin */
475 if ((filter->status & 0xff00) != 0) {
476 CK((*filter->output_function)(0x1b, filter->data)); /* ESC */
477 CK((*filter->output_function)(0x28, filter->data)); /* '(' */
478 CK((*filter->output_function)(0x42, filter->data)); /* 'B' */
479 }
480 filter->status &= 0xff;
481
482 if (filter->flush_function != NULL) {
483 return (*filter->flush_function)(filter->data);
484 }
485
486 return 0;
487 }
488
mbfl_filt_ident_jis(int c,mbfl_identify_filter * filter)489 static int mbfl_filt_ident_jis(int c, mbfl_identify_filter *filter)
490 {
491 retry:
492 switch (filter->status & 0xf) {
493 /* case 0x00: ASCII */
494 /* case 0x10: X 0201 latin */
495 /* case 0x20: X 0201 kana */
496 /* case 0x80: X 0208 */
497 /* case 0x90: X 0212 */
498 case 0:
499 if (c == 0x1b) {
500 filter->status += 2;
501 } else if (c == 0x0e) { /* "kana in" */
502 filter->status = 0x20;
503 } else if (c == 0x0f) { /* "kana out" */
504 filter->status = 0;
505 } else if ((filter->status == 0x80 || filter->status == 0x90) && c > 0x20 && c < 0x7f) { /* kanji first char */
506 filter->status += 1;
507 } else if (c >= 0 && c < 0x80) { /* latin, CTLs */
508 ;
509 } else {
510 filter->flag = 1; /* bad */
511 }
512 break;
513
514 /* case 0x81: X 0208 second char */
515 /* case 0x91: X 0212 second char */
516 case 1:
517 filter->status &= ~0xf;
518 if (c == 0x1b) {
519 goto retry;
520 } else if (c < 0x21 || c > 0x7e) { /* bad */
521 filter->flag = 1;
522 }
523 break;
524
525 /* ESC */
526 case 2:
527 if (c == 0x24) { /* '$' */
528 filter->status++;
529 } else if (c == 0x28) { /* '(' */
530 filter->status += 3;
531 } else {
532 filter->flag = 1; /* bad */
533 filter->status &= ~0xf;
534 goto retry;
535 }
536 break;
537
538 /* ESC $ */
539 case 3:
540 if (c == 0x40 || c == 0x42) { /* '@' or 'B' */
541 filter->status = 0x80;
542 } else if (c == 0x28) { /* '(' */
543 filter->status++;
544 } else {
545 filter->flag = 1; /* bad */
546 filter->status &= ~0xf;
547 goto retry;
548 }
549 break;
550
551 /* ESC $ ( */
552 case 4:
553 if (c == 0x40 || c == 0x42) { /* '@' or 'B' */
554 filter->status = 0x80;
555 } else if (c == 0x44) { /* 'D' */
556 filter->status = 0x90;
557 } else {
558 filter->flag = 1; /* bad */
559 filter->status &= ~0xf;
560 goto retry;
561 }
562 break;
563
564 /* ESC ( */
565 case 5:
566 if (c == 0x42 || c == 0x48) { /* 'B' or 'H' */
567 filter->status = 0;
568 } else if (c == 0x4a) { /* 'J' */
569 filter->status = 0x10;
570 } else if (c == 0x49) { /* 'I' */
571 filter->status = 0x20;
572 } else {
573 filter->flag = 1; /* bad */
574 filter->status &= ~0xf;
575 goto retry;
576 }
577 break;
578
579 default:
580 filter->status = 0;
581 break;
582 }
583
584 return c;
585 }
586
mbfl_filt_ident_2022jp(int c,mbfl_identify_filter * filter)587 static int mbfl_filt_ident_2022jp(int c, mbfl_identify_filter *filter)
588 {
589 retry:
590 switch (filter->status & 0xf) {
591 /* case 0x00: ASCII */
592 /* case 0x10: X 0201 latin */
593 /* case 0x80: X 0208 */
594 case 0:
595 if (c == 0x1b) {
596 filter->status += 2;
597 } else if (filter->status == 0x80 && c > 0x20 && c < 0x7f) { /* kanji first char */
598 filter->status += 1;
599 } else if (c >= 0 && c < 0x80) { /* latin, CTLs */
600 ;
601 } else {
602 filter->flag = 1; /* bad */
603 }
604 break;
605
606 /* case 0x81: X 0208 second char */
607 case 1:
608 if (c == 0x1b) {
609 filter->status++;
610 } else {
611 filter->status &= ~0xf;
612 if (c < 0x21 || c > 0x7e) { /* bad */
613 filter->flag = 1;
614 }
615 }
616 break;
617
618 /* ESC */
619 case 2:
620 if (c == 0x24) { /* '$' */
621 filter->status++;
622 } else if (c == 0x28) { /* '(' */
623 filter->status += 3;
624 } else {
625 filter->flag = 1; /* bad */
626 filter->status &= ~0xf;
627 goto retry;
628 }
629 break;
630
631 /* ESC $ */
632 case 3:
633 if (c == 0x40 || c == 0x42) { /* '@' or 'B' */
634 filter->status = 0x80;
635 } else {
636 filter->flag = 1; /* bad */
637 filter->status &= ~0xf;
638 goto retry;
639 }
640 break;
641
642 /* ESC ( */
643 case 5:
644 if (c == 0x42) { /* 'B' */
645 filter->status = 0;
646 } else if (c == 0x4a) { /* 'J' */
647 filter->status = 0x10;
648 } else {
649 filter->flag = 1; /* bad */
650 filter->status &= ~0xf;
651 goto retry;
652 }
653 break;
654
655 default:
656 filter->status = 0;
657 break;
658 }
659
660 return c;
661 }
662