Annotation of embedaddon/php/ext/mbstring/oniguruma/enc/gb18030.c, revision 1.1

1.1     ! misho       1: /**********************************************************************
        !             2:   gb18030.c -  Oniguruma (regular expression library)
        !             3: **********************************************************************/
        !             4: /*-
        !             5:  * Copyright (c) 2005  KUBO Takehiro <kubo AT jiubao DOT org>
        !             6:  *                     K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
        !             7:  * All rights reserved.
        !             8:  *
        !             9:  * Redistribution and use in source and binary forms, with or without
        !            10:  * modification, are permitted provided that the following conditions
        !            11:  * are met:
        !            12:  * 1. Redistributions of source code must retain the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer.
        !            14:  * 2. Redistributions in binary form must reproduce the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer in the
        !            16:  *    documentation and/or other materials provided with the distribution.
        !            17:  *
        !            18:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
        !            19:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            20:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            21:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        !            22:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            23:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            24:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            25:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            26:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            27:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            28:  * SUCH DAMAGE.
        !            29:  */
        !            30: 
        !            31: #include "regenc.h"
        !            32: 
        !            33: #if 1
        !            34: #define DEBUG_GB18030(arg)
        !            35: #else
        !            36: #define DEBUG_GB18030(arg) printf arg
        !            37: #endif
        !            38: 
        !            39: enum {
        !            40:   C1, /* one-byte char */
        !            41:   C2, /* one-byte or second of two-byte char */
        !            42:   C4, /* one-byte or second or fourth of four-byte char */
        !            43:   CM  /* first of two- or four-byte char or second of two-byte char */
        !            44: };
        !            45: 
        !            46: static const char GB18030_MAP[] = {
        !            47:   C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1,
        !            48:   C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1,
        !            49:   C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1,
        !            50:   C4, C4, C4, C4, C4, C4, C4, C4, C4, C4, C1, C1, C1, C1, C1, C1,
        !            51:   C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2,
        !            52:   C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2,
        !            53:   C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2,
        !            54:   C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2, C1,
        !            55:   C2, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM,
        !            56:   CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM,
        !            57:   CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM,
        !            58:   CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM,
        !            59:   CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM,
        !            60:   CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM,
        !            61:   CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM,
        !            62:   CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, CM, C1
        !            63: };
        !            64: 
        !            65: static int
        !            66: gb18030_mbc_enc_len(const UChar* p)
        !            67: {
        !            68:   if (GB18030_MAP[*p] != CM)
        !            69:     return 1;
        !            70:   p++;
        !            71:   if (GB18030_MAP[*p] == C4)
        !            72:     return 4;
        !            73:   if (GB18030_MAP[*p] == C1)
        !            74:     return 1; /* illegal sequence */
        !            75:   return 2;
        !            76: }
        !            77: 
        !            78: static OnigCodePoint
        !            79: gb18030_mbc_to_code(const UChar* p, const UChar* end)
        !            80: {
        !            81:   return onigenc_mbn_mbc_to_code(ONIG_ENCODING_GB18030, p, end);
        !            82: }
        !            83: 
        !            84: static int
        !            85: gb18030_code_to_mbc(OnigCodePoint code, UChar *buf)
        !            86: {
        !            87:   return onigenc_mb4_code_to_mbc(ONIG_ENCODING_GB18030, code, buf);
        !            88: }
        !            89: 
        !            90: static int
        !            91: gb18030_mbc_to_normalize(OnigAmbigType flag, const UChar** pp, const UChar* end,
        !            92:                        UChar* lower)
        !            93: {
        !            94:   return onigenc_mbn_mbc_to_normalize(ONIG_ENCODING_GB18030, flag,
        !            95:                                       pp, end, lower);
        !            96: }
        !            97: 
        !            98: static int
        !            99: gb18030_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
        !           100: {
        !           101:   return onigenc_mbn_is_mbc_ambiguous(ONIG_ENCODING_GB18030, flag, pp, end);
        !           102: }
        !           103: 
        !           104: static int
        !           105: gb18030_is_code_ctype(OnigCodePoint code, unsigned int ctype)
        !           106: {
        !           107:   return onigenc_mb4_is_code_ctype(ONIG_ENCODING_GB18030, code, ctype);
        !           108: }
        !           109: 
        !           110: enum state {
        !           111:   S_START,
        !           112:   S_one_C2,
        !           113:   S_one_C4,
        !           114:   S_one_CM,
        !           115: 
        !           116:   S_odd_CM_one_CX,
        !           117:   S_even_CM_one_CX,
        !           118: 
        !           119:   /* CMC4 : pair of "CM C4" */
        !           120:   S_one_CMC4,
        !           121:   S_odd_CMC4,
        !           122:   S_one_C4_odd_CMC4,
        !           123:   S_even_CMC4,
        !           124:   S_one_C4_even_CMC4,
        !           125: 
        !           126:   S_odd_CM_odd_CMC4,
        !           127:   S_even_CM_odd_CMC4,
        !           128: 
        !           129:   S_odd_CM_even_CMC4,
        !           130:   S_even_CM_even_CMC4,
        !           131: 
        !           132:   /* C4CM : pair of "C4 CM" */
        !           133:   S_odd_C4CM,
        !           134:   S_one_CM_odd_C4CM,
        !           135:   S_even_C4CM,
        !           136:   S_one_CM_even_C4CM,
        !           137: 
        !           138:   S_even_CM_odd_C4CM,
        !           139:   S_odd_CM_odd_C4CM,
        !           140:   S_even_CM_even_C4CM,
        !           141:   S_odd_CM_even_C4CM,
        !           142: };
        !           143: 
        !           144: static UChar*
        !           145: gb18030_left_adjust_char_head(const UChar* start, const UChar* s)
        !           146: {
        !           147:   const UChar *p;
        !           148:   enum state state = S_START;
        !           149: 
        !           150:   DEBUG_GB18030(("----------------\n"));
        !           151:   for (p = s; p >= start; p--) {
        !           152:     DEBUG_GB18030(("state %d --(%02x)-->\n", state, *p));
        !           153:     switch (state) {
        !           154:     case S_START:
        !           155:       switch (GB18030_MAP[*p]) {
        !           156:       case C1:
        !           157:        return (UChar *)s;
        !           158:       case C2:
        !           159:        state = S_one_C2; /* C2 */
        !           160:        break;
        !           161:       case C4:
        !           162:        state = S_one_C4; /* C4 */
        !           163:        break;
        !           164:       case CM:
        !           165:        state = S_one_CM; /* CM */
        !           166:        break;
        !           167:       }
        !           168:       break;
        !           169:     case S_one_C2: /* C2 */
        !           170:       switch (GB18030_MAP[*p]) {
        !           171:       case C1:
        !           172:       case C2:
        !           173:       case C4:
        !           174:        return (UChar *)s;
        !           175:       case CM:
        !           176:        state = S_odd_CM_one_CX; /* CM C2 */
        !           177:        break;
        !           178:       }
        !           179:       break;
        !           180:     case S_one_C4: /* C4 */
        !           181:       switch (GB18030_MAP[*p]) {
        !           182:       case C1:
        !           183:       case C2:
        !           184:       case C4:
        !           185:        return (UChar *)s;
        !           186:       case CM:
        !           187:        state = S_one_CMC4;
        !           188:        break;
        !           189:       }
        !           190:       break;
        !           191:     case S_one_CM: /* CM */
        !           192:       switch (GB18030_MAP[*p]) {
        !           193:       case C1:
        !           194:       case C2:
        !           195:        return (UChar *)s;
        !           196:       case C4:
        !           197:        state = S_odd_C4CM;
        !           198:        break;
        !           199:       case CM:
        !           200:        state = S_odd_CM_one_CX; /* CM CM */
        !           201:        break;
        !           202:       }
        !           203:       break;
        !           204: 
        !           205:     case S_odd_CM_one_CX: /* CM C2 */ /* CM CM */ /* CM CM CM C4 */
        !           206:       switch (GB18030_MAP[*p]) {
        !           207:       case C1:
        !           208:       case C2:
        !           209:       case C4:
        !           210:        return (UChar *)(s - 1);
        !           211:       case CM:
        !           212:        state = S_even_CM_one_CX;
        !           213:        break;
        !           214:       }
        !           215:       break;
        !           216:     case S_even_CM_one_CX: /* CM CM C2 */ /* CM CM CM */ /* CM CM C4 */
        !           217:       switch (GB18030_MAP[*p]) {
        !           218:       case C1:
        !           219:       case C2:
        !           220:       case C4:
        !           221:        return (UChar *)s;
        !           222:       case CM:
        !           223:        state = S_odd_CM_one_CX;
        !           224:        break;
        !           225:       }
        !           226:       break;
        !           227: 
        !           228:     case S_one_CMC4: /* CM C4 */
        !           229:       switch (GB18030_MAP[*p]) {
        !           230:       case C1:
        !           231:       case C2:
        !           232:        return (UChar *)(s - 1);
        !           233:       case C4:
        !           234:        state = S_one_C4_odd_CMC4; /* C4 CM C4 */
        !           235:        break;
        !           236:       case CM:
        !           237:        state = S_even_CM_one_CX; /* CM CM C4 */
        !           238:        break;
        !           239:       }
        !           240:       break;
        !           241:     case S_odd_CMC4: /* CM C4 CM C4 CM C4 */
        !           242:       switch (GB18030_MAP[*p]) {
        !           243:       case C1:
        !           244:       case C2:
        !           245:        return (UChar *)(s - 1);
        !           246:       case C4:
        !           247:        state = S_one_C4_odd_CMC4;
        !           248:        break;
        !           249:       case CM:
        !           250:        state = S_odd_CM_odd_CMC4;
        !           251:        break;
        !           252:       }
        !           253:       break;
        !           254:     case S_one_C4_odd_CMC4: /* C4 CM C4 */
        !           255:       switch (GB18030_MAP[*p]) {
        !           256:       case C1:
        !           257:       case C2:
        !           258:       case C4:
        !           259:        return (UChar *)(s - 1);
        !           260:       case CM:
        !           261:        state = S_even_CMC4; /* CM C4 CM C4 */
        !           262:        break;
        !           263:       }
        !           264:       break;
        !           265:     case S_even_CMC4: /* CM C4 CM C4 */
        !           266:       switch (GB18030_MAP[*p]) {
        !           267:       case C1:
        !           268:       case C2:
        !           269:        return (UChar *)(s - 3);
        !           270:       case C4:
        !           271:        state = S_one_C4_even_CMC4;
        !           272:        break;
        !           273:       case CM:
        !           274:        state = S_odd_CM_even_CMC4;
        !           275:        break;
        !           276:       }
        !           277:       break;
        !           278:     case S_one_C4_even_CMC4: /* C4 CM C4 CM C4 */
        !           279:       switch (GB18030_MAP[*p]) {
        !           280:       case C1:
        !           281:       case C2:
        !           282:       case C4:
        !           283:        return (UChar *)(s - 3);
        !           284:       case CM:
        !           285:        state = S_odd_CMC4;
        !           286:        break;
        !           287:       }
        !           288:       break;
        !           289: 
        !           290:     case S_odd_CM_odd_CMC4: /* CM CM C4 CM C4 CM C4 */
        !           291:       switch (GB18030_MAP[*p]) {
        !           292:       case C1:
        !           293:       case C2:
        !           294:       case C4:
        !           295:        return (UChar *)(s - 3);
        !           296:       case CM:
        !           297:        state = S_even_CM_odd_CMC4;
        !           298:        break;
        !           299:       }
        !           300:       break;
        !           301:     case S_even_CM_odd_CMC4: /* CM CM CM C4 CM C4 CM C4 */
        !           302:       switch (GB18030_MAP[*p]) {
        !           303:       case C1:
        !           304:       case C2:
        !           305:       case C4:
        !           306:        return (UChar *)(s - 1);
        !           307:       case CM:
        !           308:        state = S_odd_CM_odd_CMC4;
        !           309:        break;
        !           310:       }
        !           311:       break;
        !           312: 
        !           313:     case S_odd_CM_even_CMC4: /* CM CM C4 CM C4 */
        !           314:       switch (GB18030_MAP[*p]) {
        !           315:       case C1:
        !           316:       case C2:
        !           317:       case C4:
        !           318:        return (UChar *)(s - 1);
        !           319:       case CM:
        !           320:        state = S_even_CM_even_CMC4;
        !           321:        break;
        !           322:       }
        !           323:       break;
        !           324:     case S_even_CM_even_CMC4: /* CM CM CM C4 CM C4 */
        !           325:       switch (GB18030_MAP[*p]) {
        !           326:       case C1:
        !           327:       case C2:
        !           328:       case C4:
        !           329:        return (UChar *)(s - 3);
        !           330:       case CM:
        !           331:        state = S_odd_CM_even_CMC4;
        !           332:        break;
        !           333:       }
        !           334:       break;
        !           335: 
        !           336:     case S_odd_C4CM: /* C4 CM */  /* C4 CM C4 CM C4 CM*/
        !           337:       switch (GB18030_MAP[*p]) {
        !           338:       case C1:
        !           339:       case C2:
        !           340:       case C4:
        !           341:        return (UChar *)s;
        !           342:       case CM:
        !           343:        state = S_one_CM_odd_C4CM; /* CM C4 CM */
        !           344:        break;
        !           345:       }
        !           346:       break;
        !           347:     case S_one_CM_odd_C4CM: /* CM C4 CM */ /* CM C4 CM C4 CM C4 CM */
        !           348:       switch (GB18030_MAP[*p]) {
        !           349:       case C1:
        !           350:       case C2:
        !           351:        return (UChar *)(s - 2); /* |CM C4 CM */
        !           352:       case C4:
        !           353:        state = S_even_C4CM;
        !           354:        break;
        !           355:       case CM:
        !           356:        state = S_even_CM_odd_C4CM;
        !           357:        break;
        !           358:       }
        !           359:       break;
        !           360:     case S_even_C4CM: /* C4 CM C4 CM */
        !           361:       switch (GB18030_MAP[*p]) {
        !           362:       case C1:
        !           363:       case C2:
        !           364:       case C4:
        !           365:        return (UChar *)(s - 2);  /* C4|CM C4 CM */
        !           366:       case CM:
        !           367:        state = S_one_CM_even_C4CM;
        !           368:        break;
        !           369:       }
        !           370:       break;
        !           371:     case S_one_CM_even_C4CM: /* CM C4 CM C4 CM */
        !           372:       switch (GB18030_MAP[*p]) {
        !           373:       case C1:
        !           374:       case C2:
        !           375:        return (UChar *)(s - 0);  /*|CM C4 CM C4|CM */
        !           376:       case C4:
        !           377:        state = S_odd_C4CM;
        !           378:        break;
        !           379:       case CM:
        !           380:        state = S_even_CM_even_C4CM;
        !           381:        break;
        !           382:       }
        !           383:       break;
        !           384: 
        !           385:     case S_even_CM_odd_C4CM: /* CM CM C4 CM */
        !           386:       switch (GB18030_MAP[*p]) {
        !           387:       case C1:
        !           388:       case C2:
        !           389:       case C4:
        !           390:        return (UChar *)(s - 0); /* |CM CM|C4|CM */
        !           391:       case CM:
        !           392:        state = S_odd_CM_odd_C4CM;
        !           393:        break;
        !           394:       }
        !           395:       break;
        !           396:     case S_odd_CM_odd_C4CM: /* CM CM CM C4 CM */
        !           397:       switch (GB18030_MAP[*p]) {
        !           398:       case C1:
        !           399:       case C2:
        !           400:       case C4:
        !           401:        return (UChar *)(s - 2); /* |CM CM|CM C4 CM */
        !           402:       case CM:
        !           403:        state = S_even_CM_odd_C4CM;
        !           404:        break;
        !           405:       }
        !           406:       break;
        !           407: 
        !           408:     case S_even_CM_even_C4CM: /* CM CM C4 CM C4 CM */
        !           409:       switch (GB18030_MAP[*p]) {
        !           410:       case C1:
        !           411:       case C2:
        !           412:       case C4:
        !           413:        return (UChar *)(s - 2); /* |CM CM|C4|CM C4 CM */
        !           414:       case CM:
        !           415:        state = S_odd_CM_even_C4CM;
        !           416:        break;
        !           417:       }
        !           418:       break;
        !           419:     case S_odd_CM_even_C4CM: /* CM CM CM C4 CM C4 CM */
        !           420:       switch (GB18030_MAP[*p]) {
        !           421:       case C1:
        !           422:       case C2:
        !           423:       case C4:
        !           424:        return (UChar *)(s - 0);  /* |CM CM|CM C4 CM C4|CM */
        !           425:       case CM:
        !           426:        state = S_even_CM_even_C4CM;
        !           427:        break;
        !           428:       }
        !           429:       break;
        !           430:     }
        !           431:   }
        !           432: 
        !           433:   DEBUG_GB18030(("state %d\n", state));
        !           434:   switch (state) {
        !           435:   case S_START:             return (UChar *)(s - 0);
        !           436:   case S_one_C2:            return (UChar *)(s - 0);
        !           437:   case S_one_C4:            return (UChar *)(s - 0);
        !           438:   case S_one_CM:            return (UChar *)(s - 0);
        !           439: 
        !           440:   case S_odd_CM_one_CX:     return (UChar *)(s - 1);
        !           441:   case S_even_CM_one_CX:    return (UChar *)(s - 0);
        !           442: 
        !           443:   case S_one_CMC4:          return (UChar *)(s - 1);
        !           444:   case S_odd_CMC4:          return (UChar *)(s - 1);
        !           445:   case S_one_C4_odd_CMC4:   return (UChar *)(s - 1);
        !           446:   case S_even_CMC4:         return (UChar *)(s - 3);
        !           447:   case S_one_C4_even_CMC4:  return (UChar *)(s - 3);
        !           448: 
        !           449:   case S_odd_CM_odd_CMC4:   return (UChar *)(s - 3);
        !           450:   case S_even_CM_odd_CMC4:  return (UChar *)(s - 1);
        !           451: 
        !           452:   case S_odd_CM_even_CMC4:  return (UChar *)(s - 1);
        !           453:   case S_even_CM_even_CMC4: return (UChar *)(s - 3);
        !           454: 
        !           455:   case S_odd_C4CM:          return (UChar *)(s - 0);
        !           456:   case S_one_CM_odd_C4CM:   return (UChar *)(s - 2);
        !           457:   case S_even_C4CM:         return (UChar *)(s - 2);
        !           458:   case S_one_CM_even_C4CM:  return (UChar *)(s - 0);
        !           459: 
        !           460:   case S_even_CM_odd_C4CM:  return (UChar *)(s - 0);
        !           461:   case S_odd_CM_odd_C4CM:   return (UChar *)(s - 2);
        !           462:   case S_even_CM_even_C4CM: return (UChar *)(s - 2);
        !           463:   case S_odd_CM_even_C4CM:  return (UChar *)(s - 0);
        !           464:   }
        !           465: 
        !           466:   return (UChar* )s;  /* never come here. (escape warning) */
        !           467: }
        !           468: 
        !           469: static int
        !           470: gb18030_is_allowed_reverse_match(const UChar* s, const UChar* end)
        !           471: {
        !           472:   return GB18030_MAP[*s] == C1 ? TRUE : FALSE;
        !           473: }
        !           474: 
        !           475: OnigEncodingType OnigEncodingGB18030 = {
        !           476:   gb18030_mbc_enc_len,
        !           477:   "GB18030",   /* name */
        !           478:   4,          /* max enc length */
        !           479:   1,          /* min enc length */
        !           480:   ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE,
        !           481:   {
        !           482:       (OnigCodePoint )'\\'                       /* esc */
        !           483:     , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.'  */
        !           484:     , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*'  */
        !           485:     , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
        !           486:     , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
        !           487:     , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
        !           488:   },
        !           489:   onigenc_is_mbc_newline_0x0a,
        !           490:   gb18030_mbc_to_code,
        !           491:   onigenc_mb4_code_to_mbclen,
        !           492:   gb18030_code_to_mbc,
        !           493:   gb18030_mbc_to_normalize,
        !           494:   gb18030_is_mbc_ambiguous,
        !           495:   onigenc_ascii_get_all_pair_ambig_codes,
        !           496:   onigenc_nothing_get_all_comp_ambig_codes,
        !           497:   gb18030_is_code_ctype,
        !           498:   onigenc_not_support_get_ctype_code_range,
        !           499:   gb18030_left_adjust_char_head,
        !           500:   gb18030_is_allowed_reverse_match
        !           501: };

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