Annotation of embedaddon/libiconv/lib/iso2022_jp2.h, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 1999-2001, 2008 Free Software Foundation, Inc.
                      3:  * This file is part of the GNU LIBICONV Library.
                      4:  *
                      5:  * The GNU LIBICONV Library is free software; you can redistribute it
                      6:  * and/or modify it under the terms of the GNU Library General Public
                      7:  * License as published by the Free Software Foundation; either version 2
                      8:  * of the License, or (at your option) any later version.
                      9:  *
                     10:  * The GNU LIBICONV Library is distributed in the hope that it will be
                     11:  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
                     12:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     13:  * Library General Public License for more details.
                     14:  *
                     15:  * You should have received a copy of the GNU Library General Public
                     16:  * License along with the GNU LIBICONV Library; see the file COPYING.LIB.
                     17:  * If not, write to the Free Software Foundation, Inc., 51 Franklin Street,
                     18:  * Fifth Floor, Boston, MA 02110-1301, USA.
                     19:  */
                     20: 
                     21: /*
                     22:  * ISO-2022-JP-2
                     23:  */
                     24: 
                     25: /* Specification: RFC 1554 */
                     26: /* ESC '(' 'I' for JISX0201 Katakana is an extension not found in RFC 1554 or
                     27:    CJK.INF, but implemented in glibc-2.1 and qt-2.0. */
                     28: 
                     29: #define ESC 0x1b
                     30: 
                     31: /*
                     32:  * The state is composed of one of the following values
                     33:  */
                     34: #define STATE_ASCII             0
                     35: #define STATE_JISX0201ROMAN     1
                     36: #define STATE_JISX0201KATAKANA  2
                     37: #define STATE_JISX0208          3
                     38: #define STATE_JISX0212          4
                     39: #define STATE_GB2312            5
                     40: #define STATE_KSC5601           6
                     41: /*
                     42:  * and one of the following values, << 8
                     43:  */
                     44: #define STATE_G2_NONE           0
                     45: #define STATE_G2_ISO8859_1      1
                     46: #define STATE_G2_ISO8859_7      2
                     47: 
                     48: #define SPLIT_STATE \
                     49:   unsigned int state1 = state & 0xff, state2 = state >> 8
                     50: #define COMBINE_STATE \
                     51:   state = (state2 << 8) | state1
                     52: 
                     53: static int
                     54: iso2022_jp2_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n)
                     55: {
                     56:   state_t state = conv->istate;
                     57:   SPLIT_STATE;
                     58:   int count = 0;
                     59:   unsigned char c;
                     60:   for (;;) {
                     61:     c = *s;
                     62:     if (c == ESC) {
                     63:       if (n < count+3)
                     64:         goto none;
                     65:       if (s[1] == '(') {
                     66:         if (s[2] == 'B') {
                     67:           state1 = STATE_ASCII;
                     68:           s += 3; count += 3;
                     69:           if (n < count+1)
                     70:             goto none;
                     71:           continue;
                     72:         }
                     73:         if (s[2] == 'J') {
                     74:           state1 = STATE_JISX0201ROMAN;
                     75:           s += 3; count += 3;
                     76:           if (n < count+1)
                     77:             goto none;
                     78:           continue;
                     79:         }
                     80:         if (s[2] == 'I') {
                     81:           state1 = STATE_JISX0201KATAKANA;
                     82:           s += 3; count += 3;
                     83:           if (n < count+1)
                     84:             goto none;
                     85:           continue;
                     86:         }
                     87:         goto ilseq;
                     88:       }
                     89:       if (s[1] == '$') {
                     90:         if (s[2] == '@' || s[2] == 'B') {
                     91:           /* We don't distinguish JIS X 0208-1978 and JIS X 0208-1983. */
                     92:           state1 = STATE_JISX0208;
                     93:           s += 3; count += 3;
                     94:           if (n < count+1)
                     95:             goto none;
                     96:           continue;
                     97:         }
                     98:         if (s[2] == 'A') {
                     99:           state1 = STATE_GB2312;
                    100:           s += 3; count += 3;
                    101:           if (n < count+1)
                    102:             goto none;
                    103:           continue;
                    104:         }
                    105:         if (s[2] == '(') {
                    106:           if (n < count+4)
                    107:             goto none;
                    108:           if (s[3] == 'D') {
                    109:             state1 = STATE_JISX0212;
                    110:             s += 4; count += 4;
                    111:             if (n < count+1)
                    112:               goto none;
                    113:             continue;
                    114:           }
                    115:           if (s[3] == 'C') {
                    116:             state1 = STATE_KSC5601;
                    117:             s += 4; count += 4;
                    118:             if (n < count+1)
                    119:               goto none;
                    120:             continue;
                    121:           }
                    122:           goto ilseq;
                    123:         }
                    124:         goto ilseq;
                    125:       }
                    126:       if (s[1] == '.') {
                    127:         if (n < count+3)
                    128:           goto none;
                    129:         if (s[2] == 'A') {
                    130:           state2 = STATE_G2_ISO8859_1;
                    131:           s += 3; count += 3;
                    132:           if (n < count+1)
                    133:             goto none;
                    134:           continue;
                    135:         }
                    136:         if (s[2] == 'F') {
                    137:           state2 = STATE_G2_ISO8859_7;
                    138:           s += 3; count += 3;
                    139:           if (n < count+1)
                    140:             goto none;
                    141:           continue;
                    142:         }
                    143:         goto ilseq;
                    144:       }
                    145:       if (s[1] == 'N') {
                    146:         switch (state2) {
                    147:           case STATE_G2_NONE:
                    148:             goto ilseq;
                    149:           case STATE_G2_ISO8859_1:
                    150:             if (s[2] < 0x80) {
                    151:               unsigned char buf = s[2]+0x80;
                    152:               int ret = iso8859_1_mbtowc(conv,pwc,&buf,1);
                    153:               if (ret == RET_ILSEQ)
                    154:                 goto ilseq;
                    155:               if (ret != 1) abort();
                    156:               COMBINE_STATE;
                    157:               conv->istate = state;
                    158:               return count+3;
                    159:             } else
                    160:               goto ilseq;
                    161:           case STATE_G2_ISO8859_7:
                    162:             if (s[2] < 0x80) {
                    163:               unsigned char buf = s[2]+0x80;
                    164:               int ret = iso8859_7_mbtowc(conv,pwc,&buf,1);
                    165:               if (ret == RET_ILSEQ)
                    166:                 goto ilseq;
                    167:               if (ret != 1) abort();
                    168:               COMBINE_STATE;
                    169:               conv->istate = state;
                    170:               return count+3;
                    171:             } else
                    172:               goto ilseq;
                    173:           default: abort();
                    174:         }
                    175:       }
                    176:       goto ilseq;
                    177:     }
                    178:     break;
                    179:   }
                    180:   switch (state1) {
                    181:     case STATE_ASCII:
                    182:       if (c < 0x80) {
                    183:         int ret = ascii_mbtowc(conv,pwc,s,1);
                    184:         if (ret == RET_ILSEQ)
                    185:           goto ilseq;
                    186:         if (ret != 1) abort();
                    187:         if (*pwc == 0x000a || *pwc == 0x000d)
                    188:           state2 = STATE_G2_NONE;
                    189:         COMBINE_STATE;
                    190:         conv->istate = state;
                    191:         return count+1;
                    192:       } else
                    193:         goto ilseq;
                    194:     case STATE_JISX0201ROMAN:
                    195:       if (c < 0x80) {
                    196:         int ret = jisx0201_mbtowc(conv,pwc,s,1);
                    197:         if (ret == RET_ILSEQ)
                    198:           goto ilseq;
                    199:         if (ret != 1) abort();
                    200:         if (*pwc == 0x000a || *pwc == 0x000d)
                    201:           state2 = STATE_G2_NONE;
                    202:         COMBINE_STATE;
                    203:         conv->istate = state;
                    204:         return count+1;
                    205:       } else
                    206:         goto ilseq;
                    207:     case STATE_JISX0201KATAKANA:
                    208:       if (c < 0x80) {
                    209:         unsigned char buf = c+0x80;
                    210:         int ret = jisx0201_mbtowc(conv,pwc,&buf,1);
                    211:         if (ret == RET_ILSEQ)
                    212:           goto ilseq;
                    213:         if (ret != 1) abort();
                    214:         COMBINE_STATE;
                    215:         conv->istate = state;
                    216:         return count+1;
                    217:       } else
                    218:         goto ilseq;
                    219:     case STATE_JISX0208:
                    220:       if (n < count+2)
                    221:         goto none;
                    222:       if (s[0] < 0x80 && s[1] < 0x80) {
                    223:         int ret = jisx0208_mbtowc(conv,pwc,s,2);
                    224:         if (ret == RET_ILSEQ)
                    225:           goto ilseq;
                    226:         if (ret != 2) abort();
                    227:         COMBINE_STATE;
                    228:         conv->istate = state;
                    229:         return count+2;
                    230:       } else
                    231:         goto ilseq;
                    232:     case STATE_JISX0212:
                    233:       if (n < count+2)
                    234:         goto none;
                    235:       if (s[0] < 0x80 && s[1] < 0x80) {
                    236:         int ret = jisx0212_mbtowc(conv,pwc,s,2);
                    237:         if (ret == RET_ILSEQ)
                    238:           goto ilseq;
                    239:         if (ret != 2) abort();
                    240:         COMBINE_STATE;
                    241:         conv->istate = state;
                    242:         return count+2;
                    243:       } else
                    244:         goto ilseq;
                    245:     case STATE_GB2312:
                    246:       if (n < count+2)
                    247:         goto none;
                    248:       if (s[0] < 0x80 && s[1] < 0x80) {
                    249:         int ret = gb2312_mbtowc(conv,pwc,s,2);
                    250:         if (ret == RET_ILSEQ)
                    251:           goto ilseq;
                    252:         if (ret != 2) abort();
                    253:         COMBINE_STATE;
                    254:         conv->istate = state;
                    255:         return count+2;
                    256:       } else
                    257:         goto ilseq;
                    258:     case STATE_KSC5601:
                    259:       if (n < count+2)
                    260:         goto none;
                    261:       if (s[0] < 0x80 && s[1] < 0x80) {
                    262:         int ret = ksc5601_mbtowc(conv,pwc,s,2);
                    263:         if (ret == RET_ILSEQ)
                    264:           goto ilseq;
                    265:         if (ret != 2) abort();
                    266:         COMBINE_STATE;
                    267:         conv->istate = state;
                    268:         return count+2;
                    269:       } else
                    270:         goto ilseq;
                    271:     default: abort();
                    272:   }
                    273: 
                    274: none:
                    275:   COMBINE_STATE;
                    276:   conv->istate = state;
                    277:   return RET_TOOFEW(count);
                    278: 
                    279: ilseq:
                    280:   COMBINE_STATE;
                    281:   conv->istate = state;
                    282:   return RET_SHIFT_ILSEQ(count);
                    283: }
                    284: 
                    285: #undef COMBINE_STATE
                    286: #undef SPLIT_STATE
                    287: 
                    288: /*
                    289:  * The state can also contain one of the following values, << 16.
                    290:  * Values >= STATE_TAG_LANGUAGE are temporary tag parsing states.
                    291:  */
                    292: #define STATE_TAG_NONE          0
                    293: #define STATE_TAG_LANGUAGE      4
                    294: #define STATE_TAG_LANGUAGE_j    5
                    295: #define STATE_TAG_LANGUAGE_ja   1
                    296: #define STATE_TAG_LANGUAGE_k    6
                    297: #define STATE_TAG_LANGUAGE_ko   2
                    298: #define STATE_TAG_LANGUAGE_z    7
                    299: #define STATE_TAG_LANGUAGE_zh   3
                    300: 
                    301: #define SPLIT_STATE \
                    302:   unsigned int state1 = state & 0xff, state2 = (state >> 8) & 0xff, state3 = state >> 16
                    303: #define COMBINE_STATE \
                    304:   state = (state3 << 16) | (state2 << 8) | state1
                    305: 
                    306: static int
                    307: iso2022_jp2_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n)
                    308: {
                    309:   state_t state = conv->ostate;
                    310:   SPLIT_STATE;
                    311:   unsigned char buf[2];
                    312:   int ret;
                    313:   /* This defines the conversion preferences depending on the current
                    314:      langauge tag. */
                    315:   enum conversion { none = 0, european, japanese, chinese, korean, other };
                    316:   static const unsigned int conversion_lists[STATE_TAG_LANGUAGE] = {
                    317:     /* STATE_TAG_NONE */
                    318:     japanese + (european << 3) + (chinese << 6) + (korean << 9) + (other << 12),
                    319:     /* STATE_TAG_LANGUAGE_ja */
                    320:     japanese + (european << 3) + (chinese << 6) + (korean << 9) + (other << 12),
                    321:     /* STATE_TAG_LANGUAGE_ko */
                    322:     korean + (european << 3) + (japanese << 6) + (chinese << 9) + (other << 12),
                    323:     /* STATE_TAG_LANGUAGE_zh */
                    324:     chinese + (european << 3) + (japanese << 6) + (korean << 9) + (other << 12)
                    325:   };
                    326:   unsigned int conversion_list;
                    327: 
                    328:   /* Handle Unicode tag characters (range U+E0000..U+E007F). */
                    329:   if ((wc >> 7) == (0xe0000 >> 7)) {
                    330:     char c = wc & 0x7f;
                    331:     if (c >= 'A' && c <= 'Z')
                    332:       c += 'a'-'A';
                    333:     switch (c) {
                    334:       case 0x01:
                    335:         state3 = STATE_TAG_LANGUAGE;
                    336:         COMBINE_STATE;
                    337:         conv->ostate = state;
                    338:         return 0;
                    339:       case 'j':
                    340:         if (state3 == STATE_TAG_LANGUAGE) {
                    341:           state3 = STATE_TAG_LANGUAGE_j;
                    342:           COMBINE_STATE;
                    343:           conv->ostate = state;
                    344:           return 0;
                    345:         }
                    346:         break;
                    347:       case 'a':
                    348:         if (state3 == STATE_TAG_LANGUAGE_j) {
                    349:           state3 = STATE_TAG_LANGUAGE_ja;
                    350:           COMBINE_STATE;
                    351:           conv->ostate = state;
                    352:           return 0;
                    353:         }
                    354:         break;
                    355:       case 'k':
                    356:         if (state3 == STATE_TAG_LANGUAGE) {
                    357:           state3 = STATE_TAG_LANGUAGE_k;
                    358:           COMBINE_STATE;
                    359:           conv->ostate = state;
                    360:           return 0;
                    361:         }
                    362:         break;
                    363:       case 'o':
                    364:         if (state3 == STATE_TAG_LANGUAGE_k) {
                    365:           state3 = STATE_TAG_LANGUAGE_ko;
                    366:           COMBINE_STATE;
                    367:           conv->ostate = state;
                    368:           return 0;
                    369:         }
                    370:         break;
                    371:       case 'z':
                    372:         if (state3 == STATE_TAG_LANGUAGE) {
                    373:           state3 = STATE_TAG_LANGUAGE_z;
                    374:           COMBINE_STATE;
                    375:           conv->ostate = state;
                    376:           return 0;
                    377:         }
                    378:         break;
                    379:       case 'h':
                    380:         if (state3 == STATE_TAG_LANGUAGE_z) {
                    381:           state3 = STATE_TAG_LANGUAGE_zh;
                    382:           COMBINE_STATE;
                    383:           conv->ostate = state;
                    384:           return 0;
                    385:         }
                    386:         break;
                    387:       case 0x7f:
                    388:         state3 = STATE_TAG_NONE;
                    389:         COMBINE_STATE;
                    390:         conv->ostate = state;
                    391:         return 0;
                    392:       default:
                    393:         break;
                    394:     }
                    395:     /* Other tag characters reset the tag parsing state or are ignored. */
                    396:     if (state3 >= STATE_TAG_LANGUAGE)
                    397:       state3 = STATE_TAG_NONE;
                    398:     COMBINE_STATE;
                    399:     conv->ostate = state;
                    400:     return 0;
                    401:   }
                    402:   if (state3 >= STATE_TAG_LANGUAGE)
                    403:     state3 = STATE_TAG_NONE;
                    404: 
                    405:   /* Try ASCII. */
                    406:   ret = ascii_wctomb(conv,buf,wc,1);
                    407:   if (ret != RET_ILUNI) {
                    408:     if (ret != 1) abort();
                    409:     if (buf[0] < 0x80) {
                    410:       int count = (state1 == STATE_ASCII ? 1 : 4);
                    411:       if (n < count)
                    412:         return RET_TOOSMALL;
                    413:       if (state1 != STATE_ASCII) {
                    414:         r[0] = ESC;
                    415:         r[1] = '(';
                    416:         r[2] = 'B';
                    417:         r += 3;
                    418:         state1 = STATE_ASCII;
                    419:       }
                    420:       r[0] = buf[0];
                    421:       if (wc == 0x000a || wc == 0x000d)
                    422:         state2 = STATE_G2_NONE;
                    423:       COMBINE_STATE;
                    424:       conv->ostate = state;
                    425:       return count;
                    426:     }
                    427:   }
                    428: 
                    429:   conversion_list = conversion_lists[state3];
                    430: 
                    431:   do {
                    432:     switch (conversion_list & ((1 << 3) - 1)) {
                    433: 
                    434:       case european:
                    435: 
                    436:         /* Try ISO-8859-1. */
                    437:         ret = iso8859_1_wctomb(conv,buf,wc,1);
                    438:         if (ret != RET_ILUNI) {
                    439:           if (ret != 1) abort();
                    440:           if (buf[0] >= 0x80) {
                    441:             int count = (state2 == STATE_G2_ISO8859_1 ? 3 : 6);
                    442:             if (n < count)
                    443:               return RET_TOOSMALL;
                    444:             if (state2 != STATE_G2_ISO8859_1) {
                    445:               r[0] = ESC;
                    446:               r[1] = '.';
                    447:               r[2] = 'A';
                    448:               r += 3;
                    449:               state2 = STATE_G2_ISO8859_1;
                    450:             }
                    451:             r[0] = ESC;
                    452:             r[1] = 'N';
                    453:             r[2] = buf[0]-0x80;
                    454:             COMBINE_STATE;
                    455:             conv->ostate = state;
                    456:             return count;
                    457:           }
                    458:         }
                    459: 
                    460:         /* Try ISO-8859-7. */
                    461:         ret = iso8859_7_wctomb(conv,buf,wc,1);
                    462:         if (ret != RET_ILUNI) {
                    463:           if (ret != 1) abort();
                    464:           if (buf[0] >= 0x80) {
                    465:             int count = (state2 == STATE_G2_ISO8859_7 ? 3 : 6);
                    466:             if (n < count)
                    467:               return RET_TOOSMALL;
                    468:             if (state2 != STATE_G2_ISO8859_7) {
                    469:               r[0] = ESC;
                    470:               r[1] = '.';
                    471:               r[2] = 'F';
                    472:               r += 3;
                    473:               state2 = STATE_G2_ISO8859_7;
                    474:             }
                    475:             r[0] = ESC;
                    476:             r[1] = 'N';
                    477:             r[2] = buf[0]-0x80;
                    478:             COMBINE_STATE;
                    479:             conv->ostate = state;
                    480:             return count;
                    481:           }
                    482:         }
                    483: 
                    484:         break;
                    485: 
                    486:       case japanese:
                    487: 
                    488:         /* Try JIS X 0201-1976 Roman. */
                    489:         ret = jisx0201_wctomb(conv,buf,wc,1);
                    490:         if (ret != RET_ILUNI) {
                    491:           if (ret != 1) abort();
                    492:           if (buf[0] < 0x80) {
                    493:             int count = (state1 == STATE_JISX0201ROMAN ? 1 : 4);
                    494:             if (n < count)
                    495:               return RET_TOOSMALL;
                    496:             if (state1 != STATE_JISX0201ROMAN) {
                    497:               r[0] = ESC;
                    498:               r[1] = '(';
                    499:               r[2] = 'J';
                    500:               r += 3;
                    501:               state1 = STATE_JISX0201ROMAN;
                    502:             }
                    503:             r[0] = buf[0];
                    504:             if (wc == 0x000a || wc == 0x000d)
                    505:               state2 = STATE_G2_NONE;
                    506:             COMBINE_STATE;
                    507:             conv->ostate = state;
                    508:             return count;
                    509:           }
                    510:         }
                    511: 
                    512:         /* Try JIS X 0208-1990 in place of JIS X 0208-1978 and
                    513:            JIS X 0208-1983. */
                    514:         ret = jisx0208_wctomb(conv,buf,wc,2);
                    515:         if (ret != RET_ILUNI) {
                    516:           if (ret != 2) abort();
                    517:           if (buf[0] < 0x80 && buf[1] < 0x80) {
                    518:             int count = (state1 == STATE_JISX0208 ? 2 : 5);
                    519:             if (n < count)
                    520:               return RET_TOOSMALL;
                    521:             if (state1 != STATE_JISX0208) {
                    522:               r[0] = ESC;
                    523:               r[1] = '$';
                    524:               r[2] = 'B';
                    525:               r += 3;
                    526:               state1 = STATE_JISX0208;
                    527:             }
                    528:             r[0] = buf[0];
                    529:             r[1] = buf[1];
                    530:             COMBINE_STATE;
                    531:             conv->ostate = state;
                    532:             return count;
                    533:           }
                    534:         }
                    535: 
                    536:         /* Try JIS X 0212-1990. */
                    537:         ret = jisx0212_wctomb(conv,buf,wc,2);
                    538:         if (ret != RET_ILUNI) {
                    539:           if (ret != 2) abort();
                    540:           if (buf[0] < 0x80 && buf[1] < 0x80) {
                    541:             int count = (state1 == STATE_JISX0212 ? 2 : 6);
                    542:             if (n < count)
                    543:               return RET_TOOSMALL;
                    544:             if (state1 != STATE_JISX0212) {
                    545:               r[0] = ESC;
                    546:               r[1] = '$';
                    547:               r[2] = '(';
                    548:               r[3] = 'D';
                    549:               r += 4;
                    550:               state1 = STATE_JISX0212;
                    551:             }
                    552:             r[0] = buf[0];
                    553:             r[1] = buf[1];
                    554:             COMBINE_STATE;
                    555:             conv->ostate = state;
                    556:             return count;
                    557:           }
                    558:         }
                    559: 
                    560:         break;
                    561: 
                    562:       case chinese:
                    563: 
                    564:         /* Try GB 2312-1980. */
                    565:         ret = gb2312_wctomb(conv,buf,wc,2);
                    566:         if (ret != RET_ILUNI) {
                    567:           if (ret != 2) abort();
                    568:           if (buf[0] < 0x80 && buf[1] < 0x80) {
                    569:             int count = (state1 == STATE_GB2312 ? 2 : 5);
                    570:             if (n < count)
                    571:               return RET_TOOSMALL;
                    572:             if (state1 != STATE_GB2312) {
                    573:               r[0] = ESC;
                    574:               r[1] = '$';
                    575:               r[2] = 'A';
                    576:               r += 3;
                    577:               state1 = STATE_GB2312;
                    578:             }
                    579:             r[0] = buf[0];
                    580:             r[1] = buf[1];
                    581:             COMBINE_STATE;
                    582:             conv->ostate = state;
                    583:             return count;
                    584:           }
                    585:         }
                    586: 
                    587:         break;
                    588: 
                    589:       case korean:
                    590: 
                    591:         /* Try KS C 5601-1992. */
                    592:         ret = ksc5601_wctomb(conv,buf,wc,2);
                    593:         if (ret != RET_ILUNI) {
                    594:           if (ret != 2) abort();
                    595:           if (buf[0] < 0x80 && buf[1] < 0x80) {
                    596:             int count = (state1 == STATE_KSC5601 ? 2 : 6);
                    597:             if (n < count)
                    598:               return RET_TOOSMALL;
                    599:             if (state1 != STATE_KSC5601) {
                    600:               r[0] = ESC;
                    601:               r[1] = '$';
                    602:               r[2] = '(';
                    603:               r[3] = 'C';
                    604:               r += 4;
                    605:               state1 = STATE_KSC5601;
                    606:             }
                    607:             r[0] = buf[0];
                    608:             r[1] = buf[1];
                    609:             COMBINE_STATE;
                    610:             conv->ostate = state;
                    611:             return count;
                    612:           }
                    613:         }
                    614: 
                    615:         break;
                    616: 
                    617:       case other:
                    618: 
                    619:         /* Try JIS X 0201-1976 Kana. This is not officially part of
                    620:            ISO-2022-JP-2, according to RFC 1554. Therefore we try this
                    621:            only after all other attempts. */
                    622:         ret = jisx0201_wctomb(conv,buf,wc,1);
                    623:         if (ret != RET_ILUNI) {
                    624:           if (ret != 1) abort();
                    625:           if (buf[0] >= 0x80) {
                    626:             int count = (state1 == STATE_JISX0201KATAKANA ? 1 : 4);
                    627:             if (n < count)
                    628:               return RET_TOOSMALL;
                    629:             if (state1 != STATE_JISX0201KATAKANA) {
                    630:               r[0] = ESC;
                    631:               r[1] = '(';
                    632:               r[2] = 'I';
                    633:               r += 3;
                    634:               state1 = STATE_JISX0201KATAKANA;
                    635:             }
                    636:             r[0] = buf[0]-0x80;
                    637:             COMBINE_STATE;
                    638:             conv->ostate = state;
                    639:             return count;
                    640:           }
                    641:         }
                    642: 
                    643:         break;
                    644: 
                    645:       default:
                    646:         abort();
                    647:     }
                    648: 
                    649:     conversion_list = conversion_list >> 3;
                    650:   } while (conversion_list != 0);
                    651: 
                    652:   return RET_ILUNI;
                    653: }
                    654: 
                    655: static int
                    656: iso2022_jp2_reset (conv_t conv, unsigned char *r, int n)
                    657: {
                    658:   state_t state = conv->ostate;
                    659:   SPLIT_STATE;
                    660:   (void)state2;
                    661:   (void)state3;
                    662:   if (state1 != STATE_ASCII) {
                    663:     if (n < 3)
                    664:       return RET_TOOSMALL;
                    665:     r[0] = ESC;
                    666:     r[1] = '(';
                    667:     r[2] = 'B';
                    668:     /* conv->ostate = 0; will be done by the caller */
                    669:     return 3;
                    670:   } else
                    671:     return 0;
                    672: }
                    673: 
                    674: #undef COMBINE_STATE
                    675: #undef SPLIT_STATE
                    676: #undef STATE_TAG_LANGUAGE_zh
                    677: #undef STATE_TAG_LANGUAGE_z
                    678: #undef STATE_TAG_LANGUAGE_ko
                    679: #undef STATE_TAG_LANGUAGE_k
                    680: #undef STATE_TAG_LANGUAGE_ja
                    681: #undef STATE_TAG_LANGUAGE_j
                    682: #undef STATE_TAG_LANGUAGE
                    683: #undef STATE_TAG_NONE
                    684: #undef STATE_G2_ISO8859_7
                    685: #undef STATE_G2_ISO8859_1
                    686: #undef STATE_G2_NONE
                    687: #undef STATE_KSC5601
                    688: #undef STATE_GB2312
                    689: #undef STATE_JISX0212
                    690: #undef STATE_JISX0208
                    691: #undef STATE_JISX0201KATAKANA
                    692: #undef STATE_JISX0201ROMAN
                    693: #undef STATE_ASCII

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>