LCOV - app.info - parser/expat/lib/xmltok_impl.c

LCOV - code coverage report
| Current view: | directory - parser/expat/lib - xmltok_impl.c (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 898 | 508 | 56.6 %
| Date: | 2012-07-07 | Functions: | 87 | 26 | 29.9 %

           1                 : /* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
           2                 :    See the file COPYING for copying permission.
           3                 : */
           4                 :
           5                 : #ifndef IS_INVALID_CHAR
           6                 : #define IS_INVALID_CHAR(enc, ptr, n) (0)
           7                 : #endif
           8                 :
           9                 : #define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
          10                 :     case BT_LEAD ## n: \
          11                 :       if (end - ptr < n) \
          12                 :         return XML_TOK_PARTIAL_CHAR; \
          13                 :       if (IS_INVALID_CHAR(enc, ptr, n)) { \
          14                 :         *(nextTokPtr) = (ptr); \
          15                 :         return XML_TOK_INVALID; \
          16                 :       } \
          17                 :       ptr += n; \
          18                 :       break;
          19                 :
          20                 : #define INVALID_CASES(ptr, nextTokPtr) \
          21                 :   INVALID_LEAD_CASE(2, ptr, nextTokPtr) \
          22                 :   INVALID_LEAD_CASE(3, ptr, nextTokPtr) \
          23                 :   INVALID_LEAD_CASE(4, ptr, nextTokPtr) \
          24                 :   case BT_NONXML: \
          25                 :   case BT_MALFORM: \
          26                 :   case BT_TRAIL: \
          27                 :     *(nextTokPtr) = (ptr); \
          28                 :     return XML_TOK_INVALID;
          29                 :
          30                 : #define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \
          31                 :    case BT_LEAD ## n: \
          32                 :      if (end - ptr < n) \
          33                 :        return XML_TOK_PARTIAL_CHAR; \
          34                 :      if (!IS_NAME_CHAR(enc, ptr, n)) { \
          35                 :        *nextTokPtr = ptr; \
          36                 :        return XML_TOK_INVALID; \
          37                 :      } \
          38                 :      ptr += n; \
          39                 :      break;
          40                 :
          41                 : #define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \
          42                 :   case BT_NONASCII: \
          43                 :     if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \
          44                 :       *nextTokPtr = ptr; \
          45                 :       return XML_TOK_INVALID; \
          46                 :     } \
          47                 :   case BT_NMSTRT: \
          48                 :   case BT_HEX: \
          49                 :   case BT_DIGIT: \
          50                 :   case BT_NAME: \
          51                 :   case BT_MINUS: \
          52                 :     ptr += MINBPC(enc); \
          53                 :     break; \
          54                 :   CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \
          55                 :   CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \
          56                 :   CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr)
          57                 :
          58                 : #define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \
          59                 :    case BT_LEAD ## n: \
          60                 :      if (end - ptr < n) \
          61                 :        return XML_TOK_PARTIAL_CHAR; \
          62                 :      if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
          63                 :        *nextTokPtr = ptr; \
          64                 :        return XML_TOK_INVALID; \
          65                 :      } \
          66                 :      ptr += n; \
          67                 :      break;
          68                 :
          69                 : #define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \
          70                 :   case BT_NONASCII: \
          71                 :     if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \
          72                 :       *nextTokPtr = ptr; \
          73                 :       return XML_TOK_INVALID; \
          74                 :     } \
          75                 :   case BT_NMSTRT: \
          76                 :   case BT_HEX: \
          77                 :     ptr += MINBPC(enc); \
          78                 :     break; \
          79                 :   CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \
          80                 :   CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \
          81                 :   CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
          82                 :
          83                 : #ifndef PREFIX
          84                 : #define PREFIX(ident) ident
          85                 : #endif
          86                 :
          87                 : /* ptr points to character following "<!-" */
          88                 :
          89                 : static int PTRCALL
          90            3881 : PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
          91                 :                     const char *end, const char **nextTokPtr)
          92                 : {
          93            3881 :   if (ptr != end) {
          94            3881 :     if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
          95               0 :       *nextTokPtr = ptr;
          96               0 :       return XML_TOK_INVALID;
          97                 :     }
          98            3881 :     ptr += MINBPC(enc);
          99          265998 :     while (ptr != end) {
         100          262111 :       switch (BYTE_TYPE(enc, ptr)) {
         101               0 :       INVALID_CASES(ptr, nextTokPtr)
         102                 :       case BT_MINUS:
         103            4350 :         if ((ptr += MINBPC(enc)) == end)
         104               0 :           return XML_TOK_PARTIAL;
         105            4350 :         if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
         106            3875 :           if ((ptr += MINBPC(enc)) == end)
         107               0 :             return XML_TOK_PARTIAL;
         108            3875 :           if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
         109               0 :             *nextTokPtr = ptr;
         110               0 :             return XML_TOK_INVALID;
         111                 :           }
         112            3875 :           *nextTokPtr = ptr + MINBPC(enc);
         113            3875 :           return XML_TOK_COMMENT;
         114                 :         }
         115             475 :         break;
         116                 :       default:
         117          257761 :         ptr += MINBPC(enc);
         118          257761 :         break;
         119                 :       }
         120                 :     }
         121                 :   }
         122               6 :   return XML_TOK_PARTIAL;
         123                 : }
         124                 :
         125                 : /* ptr points to character following "<!" */
         126                 :
         127                 : static int PTRCALL
         128             757 : PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
         129                 :                  const char *end, const char **nextTokPtr)
         130                 : {
         131             757 :   if (ptr == end)
         132               0 :     return XML_TOK_PARTIAL;
         133             757 :   switch (BYTE_TYPE(enc, ptr)) {
         134                 :   case BT_MINUS:
         135             455 :     return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
         136                 :   case BT_LSQB:
         137               0 :     *nextTokPtr = ptr + MINBPC(enc);
         138               0 :     return XML_TOK_COND_SECT_OPEN;
         139                 :   case BT_NMSTRT:
         140                 :   case BT_HEX:
         141             302 :     ptr += MINBPC(enc);
         142                 :     break;
         143                 :   default:
         144               0 :     *nextTokPtr = ptr;
         145               0 :     return XML_TOK_INVALID;
         146                 :   }
         147            2174 :   while (ptr != end) {
         148            1872 :     switch (BYTE_TYPE(enc, ptr)) {
         149                 :     case BT_PERCNT:
         150               0 :       if (ptr + MINBPC(enc) == end)
         151               0 :         return XML_TOK_PARTIAL;
         152                 :       /* don't allow <!ENTITY% foo "whatever"> */
         153               0 :       switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
         154                 :       case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
         155               0 :         *nextTokPtr = ptr;
         156               0 :         return XML_TOK_INVALID;
         157                 :       }
         158                 :       /* fall through */
         159                 :     case BT_S: case BT_CR: case BT_LF:
         160             302 :       *nextTokPtr = ptr;
         161             302 :       return XML_TOK_DECL_OPEN;
         162                 :     case BT_NMSTRT:
         163                 :     case BT_HEX:
         164            1570 :       ptr += MINBPC(enc);
         165            1570 :       break;
         166                 :     default:
         167               0 :       *nextTokPtr = ptr;
         168               0 :       return XML_TOK_INVALID;
         169                 :     }
         170                 :   }
         171               0 :   return XML_TOK_PARTIAL;
         172                 : }
         173                 :
         174                 : static int PTRCALL
         175            3150 : PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr,
         176                 :                       const char *end, int *tokPtr)
         177                 : {
         178            3150 :   int upper = 0;
         179            3150 :   *tokPtr = XML_TOK_PI;
         180            3150 :   if (end - ptr != MINBPC(enc)*3)
         181              47 :     return 1;
         182            3103 :   switch (BYTE_TO_ASCII(enc, ptr)) {
         183                 :   case ASCII_x:
         184            3097 :     break;
         185                 :   case ASCII_X:
         186               0 :     upper = 1;
         187               0 :     break;
         188                 :   default:
         189               6 :     return 1;
         190                 :   }
         191            3097 :   ptr += MINBPC(enc);
         192            3097 :   switch (BYTE_TO_ASCII(enc, ptr)) {
         193                 :   case ASCII_m:
         194            3097 :     break;
         195                 :   case ASCII_M:
         196               0 :     upper = 1;
         197               0 :     break;
         198                 :   default:
         199               0 :     return 1;
         200                 :   }
         201            3097 :   ptr += MINBPC(enc);
         202            3097 :   switch (BYTE_TO_ASCII(enc, ptr)) {
         203                 :   case ASCII_l:
         204            3097 :     break;
         205                 :   case ASCII_L:
         206               0 :     upper = 1;
         207               0 :     break;
         208                 :   default:
         209               0 :     return 1;
         210                 :   }
         211            3097 :   if (upper)
         212               0 :     return 0;
         213            3097 :   *tokPtr = XML_TOK_XML_DECL;
         214            3097 :   return 1;
         215                 : }
         216                 :
         217                 : /* ptr points to character following "<?" */
         218                 :
         219                 : static int PTRCALL
         220            3150 : PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
         221                 :                const char *end, const char **nextTokPtr)
         222                 : {
         223                 :   int tok;
         224            3150 :   const char *target = ptr;
         225            3150 :   if (ptr == end)
         226               0 :     return XML_TOK_PARTIAL;
         227            3150 :   switch (BYTE_TYPE(enc, ptr)) {
         228               0 :   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
         229                 :   default:
         230               0 :     *nextTokPtr = ptr;
         231               0 :     return XML_TOK_INVALID;
         232                 :   }
         233           12661 :   while (ptr != end) {
         234            9511 :     switch (BYTE_TYPE(enc, ptr)) {
         235               0 :     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
         236                 :     case BT_S: case BT_CR: case BT_LF:
         237            3147 :       if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
         238               0 :         *nextTokPtr = ptr;
         239               0 :         return XML_TOK_INVALID;
         240                 :       }
         241            3147 :       ptr += MINBPC(enc);
         242           66370 :       while (ptr != end) {
         243           63221 :         switch (BYTE_TYPE(enc, ptr)) {
         244               0 :         INVALID_CASES(ptr, nextTokPtr)
         245                 :         case BT_QUEST:
         246            3145 :           ptr += MINBPC(enc);
         247            3145 :           if (ptr == end)
         248               0 :             return XML_TOK_PARTIAL;
         249            3145 :           if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
         250            3145 :             *nextTokPtr = ptr + MINBPC(enc);
         251            3145 :             return tok;
         252                 :           }
         253               0 :           break;
         254                 :         default:
         255           60076 :           ptr += MINBPC(enc);
         256           60076 :           break;
         257                 :         }
         258                 :       }
         259               2 :       return XML_TOK_PARTIAL;
         260                 :     case BT_QUEST:
         261               3 :       if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
         262               0 :         *nextTokPtr = ptr;
         263               0 :         return XML_TOK_INVALID;
         264                 :       }
         265               3 :       ptr += MINBPC(enc);
         266               3 :       if (ptr == end)
         267               0 :         return XML_TOK_PARTIAL;
         268               3 :       if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
         269               3 :         *nextTokPtr = ptr + MINBPC(enc);
         270               3 :         return tok;
         271                 :       }
         272                 :       /* fall through */
         273                 :     default:
         274               0 :       *nextTokPtr = ptr;
         275               0 :       return XML_TOK_INVALID;
         276                 :     }
         277                 :   }
         278               0 :   return XML_TOK_PARTIAL;
         279                 : }
         280                 :
         281                 : static int PTRCALL
         282              68 : PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr,
         283                 :                          const char *end, const char **nextTokPtr)
         284                 : {
         285                 :   static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A,
         286                 :                                      ASCII_T, ASCII_A, ASCII_LSQB };
         287                 :   int i;
         288                 :   /* CDATA[ */
         289              68 :   if (end - ptr < 6 * MINBPC(enc))
         290               0 :     return XML_TOK_PARTIAL;
         291             476 :   for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
         292             408 :     if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
         293               0 :       *nextTokPtr = ptr;
         294               0 :       return XML_TOK_INVALID;
         295                 :     }
         296                 :   }
         297              68 :   *nextTokPtr = ptr;
         298              68 :   return XML_TOK_CDATA_SECT_OPEN;
         299                 : }
         300                 :
         301                 : static int PTRCALL
         302             441 : PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
         303                 :                         const char *end, const char **nextTokPtr)
         304                 : {
         305             441 :   if (ptr == end)
         306               7 :     return XML_TOK_NONE;
         307                 :   if (MINBPC(enc) > 1) {
         308             434 :     size_t n = end - ptr;
         309             434 :     if (n & (MINBPC(enc) - 1)) {
         310               0 :       n &= ~(MINBPC(enc) - 1);
         311               0 :       if (n == 0)
         312               0 :         return XML_TOK_PARTIAL;
         313               0 :       end = ptr + n;
         314                 :     }
         315                 :   }
         316             434 :   switch (BYTE_TYPE(enc, ptr)) {
         317                 :   case BT_RSQB:
         318              67 :     ptr += MINBPC(enc);
         319              67 :     if (ptr == end)
         320               0 :       return XML_TOK_PARTIAL;
         321              67 :     if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
         322               0 :       break;
         323              67 :     ptr += MINBPC(enc);
         324              67 :     if (ptr == end)
         325               0 :       return XML_TOK_PARTIAL;
         326              67 :     if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
         327               0 :       ptr -= MINBPC(enc);
         328               0 :       break;
         329                 :     }
         330              67 :     *nextTokPtr = ptr + MINBPC(enc);
         331              67 :     return XML_TOK_CDATA_SECT_CLOSE;
         332                 :   case BT_CR:
         333               0 :     ptr += MINBPC(enc);
         334               0 :     if (ptr == end)
         335               0 :       return XML_TOK_PARTIAL;
         336               0 :     if (BYTE_TYPE(enc, ptr) == BT_LF)
         337               0 :       ptr += MINBPC(enc);
         338               0 :     *nextTokPtr = ptr;
         339               0 :     return XML_TOK_DATA_NEWLINE;
         340                 :   case BT_LF:
         341             195 :     *nextTokPtr = ptr + MINBPC(enc);
         342             195 :     return XML_TOK_DATA_NEWLINE;
         343               0 :   INVALID_CASES(ptr, nextTokPtr)
         344                 :   default:
         345             171 :     ptr += MINBPC(enc);
         346             171 :     break;
         347                 :   }
         348           29766 :   while (ptr != end) {
         349           29588 :     switch (BYTE_TYPE(enc, ptr)) {
         350                 : #define LEAD_CASE(n) \
         351                 :     case BT_LEAD ## n: \
         352                 :       if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
         353                 :         *nextTokPtr = ptr; \
         354                 :         return XML_TOK_DATA_CHARS; \
         355                 :       } \
         356                 :       ptr += n; \
         357                 :       break;
         358               0 :     LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
         359                 : #undef LEAD_CASE
         360                 :     case BT_NONXML:
         361                 :     case BT_MALFORM:
         362                 :     case BT_TRAIL:
         363                 :     case BT_CR:
         364                 :     case BT_LF:
         365                 :     case BT_RSQB:
         366             164 :       *nextTokPtr = ptr;
         367             164 :       return XML_TOK_DATA_CHARS;
         368                 :     default:
         369           29424 :       ptr += MINBPC(enc);
         370           29424 :       break;
         371                 :     }
         372                 :   }
         373               7 :   *nextTokPtr = ptr;
         374               7 :   return XML_TOK_DATA_CHARS;
         375                 : }
         376                 :
         377                 : /* ptr points to character following "</" */
         378                 :
         379                 : static int PTRCALL
         380           80864 : PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
         381                 :                    const char *end, const char **nextTokPtr)
         382                 : {
         383           80864 :   if (ptr == end)
         384               5 :     return XML_TOK_PARTIAL;
         385           80859 :   switch (BYTE_TYPE(enc, ptr)) {
         386               0 :   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
         387                 :   default:
         388               0 :     *nextTokPtr = ptr;
         389               0 :     return XML_TOK_INVALID;
         390                 :   }
         391          900218 :   while (ptr != end) {
         392          819358 :     switch (BYTE_TYPE(enc, ptr)) {
         393               0 :     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
         394                 :     case BT_S: case BT_CR: case BT_LF:
         395               4 :       for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
         396               0 :         switch (BYTE_TYPE(enc, ptr)) {
         397                 :         case BT_S: case BT_CR: case BT_LF:
         398                 :           break;
         399                 :         case BT_GT:
         400               0 :           *nextTokPtr = ptr + MINBPC(enc);
         401               0 :           return XML_TOK_END_TAG;
         402                 :         default:
         403               0 :           *nextTokPtr = ptr;
         404               0 :           return XML_TOK_INVALID;
         405                 :         }
         406                 :       }
         407               2 :       return XML_TOK_PARTIAL;
         408                 : #ifdef XML_NS
         409                 :     case BT_COLON:
         410                 :       /* no need to check qname syntax here,
         411                 :          since end-tag must match exactly */
         412           48599 :       ptr += MINBPC(enc);
         413           48599 :       break;
         414                 : #endif
         415                 :     case BT_GT:
         416           80856 :       *nextTokPtr = ptr + MINBPC(enc);
         417           80856 :       return XML_TOK_END_TAG;
         418                 :     default:
         419               0 :       *nextTokPtr = ptr;
         420               0 :       return XML_TOK_INVALID;
         421                 :     }
         422                 :   }
         423               1 :   return XML_TOK_PARTIAL;
         424                 : }
         425                 :
         426                 : /* ptr points to character following "&#X" */
         427                 :
         428                 : static int PTRCALL
         429              21 : PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
         430                 :                        const char *end, const char **nextTokPtr)
         431                 : {
         432              21 :   if (ptr != end) {
         433              21 :     switch (BYTE_TYPE(enc, ptr)) {
         434                 :     case BT_DIGIT:
         435                 :     case BT_HEX:
         436                 :       break;
         437                 :     default:
         438               0 :       *nextTokPtr = ptr;
         439               0 :       return XML_TOK_INVALID;
         440                 :     }
         441             160 :     for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
         442              79 :       switch (BYTE_TYPE(enc, ptr)) {
         443                 :       case BT_DIGIT:
         444                 :       case BT_HEX:
         445                 :         break;
         446                 :       case BT_SEMI:
         447              20 :         *nextTokPtr = ptr + MINBPC(enc);
         448              20 :         return XML_TOK_CHAR_REF;
         449                 :       default:
         450               0 :         *nextTokPtr = ptr;
         451               0 :         return XML_TOK_INVALID;
         452                 :       }
         453                 :     }
         454                 :   }
         455               1 :   return XML_TOK_PARTIAL;
         456                 : }
         457                 :
         458                 : /* ptr points to character following "&#" */
         459                 :
         460                 : static int PTRCALL
         461             708 : PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
         462                 :                     const char *end, const char **nextTokPtr)
         463                 : {
         464             708 :   if (ptr != end) {
         465             708 :     if (CHAR_MATCHES(enc, ptr, ASCII_x))
         466              21 :       return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
         467             687 :     switch (BYTE_TYPE(enc, ptr)) {
         468                 :     case BT_DIGIT:
         469                 :       break;
         470                 :     default:
         471               0 :       *nextTokPtr = ptr;
         472               0 :       return XML_TOK_INVALID;
         473                 :     }
         474            3462 :     for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
         475            1731 :       switch (BYTE_TYPE(enc, ptr)) {
         476                 :       case BT_DIGIT:
         477                 :         break;
         478                 :       case BT_SEMI:
         479             687 :         *nextTokPtr = ptr + MINBPC(enc);
         480             687 :         return XML_TOK_CHAR_REF;
         481                 :       default:
         482               0 :         *nextTokPtr = ptr;
         483               0 :         return XML_TOK_INVALID;
         484                 :       }
         485                 :     }
         486                 :   }
         487               0 :   return XML_TOK_PARTIAL;
         488                 : }
         489                 :
         490                 : /* ptr points to character following "&" */
         491                 :
         492                 : static int PTRCALL
         493            3831 : PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
         494                 :                 const char **nextTokPtr)
         495                 : {
         496            3831 :   if (ptr == end)
         497               0 :     return XML_TOK_PARTIAL;
         498            3831 :   switch (BYTE_TYPE(enc, ptr)) {
         499               0 :   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
         500                 :   case BT_NUM:
         501             708 :     return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
         502                 :   default:
         503               0 :     *nextTokPtr = ptr;
         504               0 :     return XML_TOK_INVALID;
         505                 :   }
         506           31901 :   while (ptr != end) {
         507           28778 :     switch (BYTE_TYPE(enc, ptr)) {
         508               0 :     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
         509                 :     case BT_SEMI:
         510            3123 :       *nextTokPtr = ptr + MINBPC(enc);
         511            3123 :       return XML_TOK_ENTITY_REF;
         512                 :     default:
         513               0 :       *nextTokPtr = ptr;
         514               0 :       return XML_TOK_INVALID;
         515                 :     }
         516                 :   }
         517               0 :   return XML_TOK_PARTIAL;
         518                 : }
         519                 :
         520                 : /* ptr points to character following first character of attribute name */
         521                 :
         522                 : static int PTRCALL
         523           13667 : PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
         524                 :                  const char **nextTokPtr)
         525                 : {
         526                 : #ifdef XML_NS
         527           13667 :   int hadColon = 0;
         528                 : #endif
         529          127382 :   while (ptr != end) {
         530          113692 :     switch (BYTE_TYPE(enc, ptr)) {
         531               0 :     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
         532                 : #ifdef XML_NS
         533                 :     case BT_COLON:
         534            4054 :       if (hadColon) {
         535               0 :         *nextTokPtr = ptr;
         536               0 :         return XML_TOK_INVALID;
         537                 :       }
         538            4054 :       hadColon = 1;
         539            4054 :       ptr += MINBPC(enc);
         540            4054 :       if (ptr == end)
         541               0 :         return XML_TOK_PARTIAL;
         542            4054 :       switch (BYTE_TYPE(enc, ptr)) {
         543               0 :       CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
         544                 :       default:
         545               0 :         *nextTokPtr = ptr;
         546               0 :         return XML_TOK_INVALID;
         547                 :       }
         548            4054 :       break;
         549                 : #endif
         550                 :     case BT_S: case BT_CR: case BT_LF:
         551                 :       for (;;) {
         552                 :         int t;
         553                 :
         554               0 :         ptr += MINBPC(enc);
         555               0 :         if (ptr == end)
         556               0 :           return XML_TOK_PARTIAL;
         557               0 :         t = BYTE_TYPE(enc, ptr);
         558               0 :         if (t == BT_EQUALS)
         559               0 :           break;
         560               0 :         switch (t) {
         561                 :         case BT_S:
         562                 :         case BT_LF:
         563                 :         case BT_CR:
         564                 :           break;
         565                 :         default:
         566               0 :           *nextTokPtr = ptr;
         567               0 :           return XML_TOK_INVALID;
         568                 :         }
         569               0 :       }
         570                 :     /* fall through */
         571                 :     case BT_EQUALS:
         572                 :       {
         573                 :         int open;
         574                 : #ifdef XML_NS
         575           19050 :         hadColon = 0;
         576                 : #endif
         577                 :         for (;;) {
         578           19050 :           ptr += MINBPC(enc);
         579           19050 :           if (ptr == end)
         580               1 :             return XML_TOK_PARTIAL;
         581           19049 :           open = BYTE_TYPE(enc, ptr);
         582           19049 :           if (open == BT_QUOT || open == BT_APOS)
         583                 :             break;
         584               0 :           switch (open) {
         585                 :           case BT_S:
         586                 :           case BT_LF:
         587                 :           case BT_CR:
         588                 :             break;
         589                 :           default:
         590               0 :             *nextTokPtr = ptr;
         591               0 :             return XML_TOK_INVALID;
         592                 :           }
         593               0 :         }
         594           19049 :         ptr += MINBPC(enc);
         595                 :         /* in attribute value */
         596                 :         for (;;) {
         597                 :           int t;
         598          527832 :           if (ptr == end)
         599               0 :             return XML_TOK_PARTIAL;
         600          527832 :           t = BYTE_TYPE(enc, ptr);
         601          527832 :           if (t == open)
         602                 :             break;
         603          508783 :           switch (t) {
         604               0 :           INVALID_CASES(ptr, nextTokPtr)
         605                 :           case BT_AMP:
         606                 :             {
         607             965 :               int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
         608             965 :               if (tok <= 0) {
         609               0 :                 if (tok == XML_TOK_INVALID)
         610               0 :                   *nextTokPtr = ptr;
         611               0 :                 return tok;
         612                 :               }
         613             965 :               break;
         614                 :             }
         615                 :           case BT_LT:
         616               0 :             *nextTokPtr = ptr;
         617               0 :             return XML_TOK_INVALID;
         618                 :           default:
         619          507818 :             ptr += MINBPC(enc);
         620          507818 :             break;
         621                 :           }
         622          508783 :         }
         623           19049 :         ptr += MINBPC(enc);
         624           19049 :         if (ptr == end)
         625               0 :           return XML_TOK_PARTIAL;
         626           19049 :         switch (BYTE_TYPE(enc, ptr)) {
         627                 :         case BT_S:
         628                 :         case BT_CR:
         629                 :         case BT_LF:
         630            5815 :           break;
         631                 :         case BT_SOL:
         632            1628 :           goto sol;
         633                 :         case BT_GT:
         634           11606 :           goto gt;
         635                 :         default:
         636               0 :           *nextTokPtr = ptr;
         637               0 :           return XML_TOK_INVALID;
         638                 :         }
         639                 :         /* ptr points to closing quote */
         640                 :         for (;;) {
         641           24290 :           ptr += MINBPC(enc);
         642           24290 :           if (ptr == end)
         643               0 :             return XML_TOK_PARTIAL;
         644           24290 :           switch (BYTE_TYPE(enc, ptr)) {
         645               0 :           CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
         646                 :           case BT_S: case BT_CR: case BT_LF:
         647           18475 :             continue;
         648                 :           case BT_GT:
         649                 :           gt:
         650           11704 :             *nextTokPtr = ptr + MINBPC(enc);
         651           11704 :             return XML_TOK_START_TAG_WITH_ATTS;
         652                 :           case BT_SOL:
         653                 :           sol:
         654            1939 :             ptr += MINBPC(enc);
         655            1939 :             if (ptr == end)
         656               0 :               return XML_TOK_PARTIAL;
         657            1939 :             if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
         658               0 :               *nextTokPtr = ptr;
         659               0 :               return XML_TOK_INVALID;
         660                 :             }
         661            1939 :             *nextTokPtr = ptr + MINBPC(enc);
         662            1939 :             return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
         663                 :           default:
         664               0 :             *nextTokPtr = ptr;
         665               0 :             return XML_TOK_INVALID;
         666                 :           }
         667                 :           break;
         668           18475 :         }
         669            5406 :         break;
         670                 :       }
         671                 :     default:
         672               0 :       *nextTokPtr = ptr;
         673               0 :       return XML_TOK_INVALID;
         674                 :     }
         675                 :   }
         676              23 :   return XML_TOK_PARTIAL;
         677                 : }
         678                 :
         679                 : /* ptr points to character following "<" */
         680                 :
         681                 : static int PTRCALL
         682          167416 : PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
         683                 :                const char **nextTokPtr)
         684                 : {
         685                 : #ifdef XML_NS
         686                 :   int hadColon;
         687                 : #endif
         688          167416 :   if (ptr == end)
         689               3 :     return XML_TOK_PARTIAL;
         690          167413 :   switch (BYTE_TYPE(enc, ptr)) {
         691               0 :   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
         692                 :   case BT_EXCL:
         693            3494 :     if ((ptr += MINBPC(enc)) == end)
         694               0 :       return XML_TOK_PARTIAL;
         695            3494 :     switch (BYTE_TYPE(enc, ptr)) {
         696                 :     case BT_MINUS:
         697            3426 :       return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
         698                 :     case BT_LSQB:
         699              68 :       return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc),
         700                 :                                       end, nextTokPtr);
         701                 :     }
         702               0 :     *nextTokPtr = ptr;
         703               0 :     return XML_TOK_INVALID;
         704                 :   case BT_QUEST:
         705              50 :     return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
         706                 :   case BT_SOL:
         707           80864 :     return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr);
         708                 :   default:
         709               0 :     *nextTokPtr = ptr;
         710               0 :     return XML_TOK_INVALID;
         711                 :   }
         712                 : #ifdef XML_NS
         713           83005 :   hadColon = 0;
         714                 : #endif
         715                 :   /* we have a start-tag */
         716          872962 :   while (ptr != end) {
         717          789957 :     switch (BYTE_TYPE(enc, ptr)) {
         718               0 :     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
         719                 : #ifdef XML_NS
         720                 :     case BT_COLON:
         721           48979 :       if (hadColon) {
         722               0 :         *nextTokPtr = ptr;
         723               0 :         return XML_TOK_INVALID;
         724                 :       }
         725           48979 :       hadColon = 1;
         726           48979 :       ptr += MINBPC(enc);
         727           48979 :       if (ptr == end)
         728               0 :         return XML_TOK_PARTIAL;
         729           48979 :       switch (BYTE_TYPE(enc, ptr)) {
         730               0 :       CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
         731                 :       default:
         732               0 :         *nextTokPtr = ptr;
         733               0 :         return XML_TOK_INVALID;
         734                 :       }
         735           48979 :       break;
         736                 : #endif
         737                 :     case BT_S: case BT_CR: case BT_LF:
         738                 :       {
         739           13697 :         ptr += MINBPC(enc);
         740           28299 :         while (ptr != end) {
         741           14601 :           switch (BYTE_TYPE(enc, ptr)) {
         742               0 :           CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
         743                 :           case BT_GT:
         744              19 :             goto gt;
         745                 :           case BT_SOL:
         746              10 :             goto sol;
         747                 :           case BT_S: case BT_CR: case BT_LF:
         748             905 :             ptr += MINBPC(enc);
         749             905 :             continue;
         750                 :           default:
         751               0 :             *nextTokPtr = ptr;
         752               0 :             return XML_TOK_INVALID;
         753                 :           }
         754           13667 :           return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
         755                 :         }
         756               1 :         return XML_TOK_PARTIAL;
         757                 :       }
         758                 :     case BT_GT:
         759                 :     gt:
         760           69156 :       *nextTokPtr = ptr + MINBPC(enc);
         761           69156 :       return XML_TOK_START_TAG_NO_ATTS;
         762                 :     case BT_SOL:
         763                 :     sol:
         764             181 :       ptr += MINBPC(enc);
         765             181 :       if (ptr == end)
         766               0 :         return XML_TOK_PARTIAL;
         767             181 :       if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
         768               0 :         *nextTokPtr = ptr;
         769               0 :         return XML_TOK_INVALID;
         770                 :       }
         771             181 :       *nextTokPtr = ptr + MINBPC(enc);
         772             181 :       return XML_TOK_EMPTY_ELEMENT_NO_ATTS;
         773                 :     default:
         774               0 :       *nextTokPtr = ptr;
         775               0 :       return XML_TOK_INVALID;
         776                 :     }
         777                 :   }
         778               0 :   return XML_TOK_PARTIAL;
         779                 : }
         780                 :
         781                 : static int PTRCALL
         782          450671 : PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
         783                 :                    const char **nextTokPtr)
         784                 : {
         785          450671 :   if (ptr == end)
         786             845 :     return XML_TOK_NONE;
         787                 :   if (MINBPC(enc) > 1) {
         788          449826 :     size_t n = end - ptr;
         789          449826 :     if (n & (MINBPC(enc) - 1)) {
         790               0 :       n &= ~(MINBPC(enc) - 1);
         791               0 :       if (n == 0)
         792               0 :         return XML_TOK_PARTIAL;
         793               0 :       end = ptr + n;
         794                 :     }
         795                 :   }
         796          449826 :   switch (BYTE_TYPE(enc, ptr)) {
         797                 :   case BT_LT:
         798          167416 :     return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr);
         799                 :   case BT_AMP:
         800            1841 :     return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
         801                 :   case BT_CR:
         802             140 :     ptr += MINBPC(enc);
         803             140 :     if (ptr == end)
         804               0 :       return XML_TOK_TRAILING_CR;
         805             140 :     if (BYTE_TYPE(enc, ptr) == BT_LF)
         806             140 :       ptr += MINBPC(enc);
         807             140 :     *nextTokPtr = ptr;
         808             140 :     return XML_TOK_DATA_NEWLINE;
         809                 :   case BT_LF:
         810          128848 :     *nextTokPtr = ptr + MINBPC(enc);
         811          128848 :     return XML_TOK_DATA_NEWLINE;
         812                 :   case BT_RSQB:
         813               0 :     ptr += MINBPC(enc);
         814               0 :     if (ptr == end)
         815               0 :       return XML_TOK_TRAILING_RSQB;
         816               0 :     if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
         817               0 :       break;
         818               0 :     ptr += MINBPC(enc);
         819               0 :     if (ptr == end)
         820               0 :       return XML_TOK_TRAILING_RSQB;
         821               0 :     if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
         822               0 :       ptr -= MINBPC(enc);
         823               0 :       break;
         824                 :     }
         825               0 :     *nextTokPtr = ptr;
         826               0 :     return XML_TOK_INVALID;
         827               0 :   INVALID_CASES(ptr, nextTokPtr)
         828                 :   default:
         829          151580 :     ptr += MINBPC(enc);
         830          151580 :     break;
         831                 :   }
         832         1800151 :   while (ptr != end) {
         833         1648021 :     switch (BYTE_TYPE(enc, ptr)) {
         834                 : #define LEAD_CASE(n) \
         835                 :     case BT_LEAD ## n: \
         836                 :       if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
         837                 :         *nextTokPtr = ptr; \
         838                 :         return XML_TOK_DATA_CHARS; \
         839                 :       } \
         840                 :       ptr += n; \
         841                 :       break;
         842               0 :     LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
         843                 : #undef LEAD_CASE
         844                 :     case BT_RSQB:
         845              13 :       if (ptr + MINBPC(enc) != end) {
         846              13 :          if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
         847              13 :            ptr += MINBPC(enc);
         848              13 :            break;
         849                 :          }
         850               0 :          if (ptr + 2*MINBPC(enc) != end) {
         851               0 :            if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
         852               0 :              ptr += MINBPC(enc);
         853               0 :              break;
         854                 :            }
         855               0 :            *nextTokPtr = ptr + 2*MINBPC(enc);
         856               0 :            return XML_TOK_INVALID;
         857                 :          }
         858                 :       }
         859                 :       /* fall through */
         860                 :     case BT_AMP:
         861                 :     case BT_LT:
         862                 :     case BT_NONXML:
         863                 :     case BT_MALFORM:
         864                 :     case BT_TRAIL:
         865                 :     case BT_CR:
         866                 :     case BT_LF:
         867          151032 :       *nextTokPtr = ptr;
         868          151032 :       return XML_TOK_DATA_CHARS;
         869                 :     default:
         870         1496974 :       ptr += MINBPC(enc);
         871         1496974 :       break;
         872                 :     }
         873                 :   }
         874             549 :   *nextTokPtr = ptr;
         875             549 :   return XML_TOK_DATA_CHARS;
         876                 : }
         877                 :
         878                 : /* ptr points to character following "%" */
         879                 :
         880                 : static int PTRCALL
         881               0 : PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
         882                 :                     const char **nextTokPtr)
         883                 : {
         884               0 :   if (ptr == end)
         885               0 :     return -XML_TOK_PERCENT;
         886               0 :   switch (BYTE_TYPE(enc, ptr)) {
         887               0 :   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
         888                 :   case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
         889               0 :     *nextTokPtr = ptr;
         890               0 :     return XML_TOK_PERCENT;
         891                 :   default:
         892               0 :     *nextTokPtr = ptr;
         893               0 :     return XML_TOK_INVALID;
         894                 :   }
         895               0 :   while (ptr != end) {
         896               0 :     switch (BYTE_TYPE(enc, ptr)) {
         897               0 :     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
         898                 :     case BT_SEMI:
         899               0 :       *nextTokPtr = ptr + MINBPC(enc);
         900               0 :       return XML_TOK_PARAM_ENTITY_REF;
         901                 :     default:
         902               0 :       *nextTokPtr = ptr;
         903               0 :       return XML_TOK_INVALID;
         904                 :     }
         905                 :   }
         906               0 :   return XML_TOK_PARTIAL;
         907                 : }
         908                 :
         909                 : static int PTRCALL
         910              11 : PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
         911                 :                       const char **nextTokPtr)
         912                 : {
         913              11 :   if (ptr == end)
         914               0 :     return XML_TOK_PARTIAL;
         915              11 :   switch (BYTE_TYPE(enc, ptr)) {
         916               0 :   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
         917                 :   default:
         918               0 :     *nextTokPtr = ptr;
         919               0 :     return XML_TOK_INVALID;
         920                 :   }
         921              99 :   while (ptr != end) {
         922              88 :     switch (BYTE_TYPE(enc, ptr)) {
         923               0 :     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
         924                 :     case BT_CR: case BT_LF: case BT_S:
         925                 :     case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR:
         926              11 :       *nextTokPtr = ptr;
         927              11 :       return XML_TOK_POUND_NAME;
         928                 :     default:
         929               0 :       *nextTokPtr = ptr;
         930               0 :       return XML_TOK_INVALID;
         931                 :     }
         932                 :   }
         933               0 :   return -XML_TOK_POUND_NAME;
         934                 : }
         935                 :
         936                 : static int PTRCALL
         937             260 : PREFIX(scanLit)(int open, const ENCODING *enc,
         938                 :                 const char *ptr, const char *end,
         939                 :                 const char **nextTokPtr)
         940                 : {
         941           18222 :   while (ptr != end) {
         942           17962 :     int t = BYTE_TYPE(enc, ptr);
         943           17962 :     switch (t) {
         944               0 :     INVALID_CASES(ptr, nextTokPtr)
         945                 :     case BT_QUOT:
         946                 :     case BT_APOS:
         947             304 :       ptr += MINBPC(enc);
         948             304 :       if (t != open)
         949              44 :         break;
         950             260 :       if (ptr == end)
         951               0 :         return -XML_TOK_LITERAL;
         952             260 :       *nextTokPtr = ptr;
         953             260 :       switch (BYTE_TYPE(enc, ptr)) {
         954                 :       case BT_S: case BT_CR: case BT_LF:
         955                 :       case BT_GT: case BT_PERCNT: case BT_LSQB:
         956             260 :         return XML_TOK_LITERAL;
         957                 :       default:
         958               0 :         return XML_TOK_INVALID;
         959                 :       }
         960                 :     default:
         961           17658 :       ptr += MINBPC(enc);
         962           17658 :       break;
         963                 :     }
         964                 :   }
         965               0 :   return XML_TOK_PARTIAL;
         966                 : }
         967                 :
         968                 : static int PTRCALL
         969           21795 : PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
         970                 :                   const char **nextTokPtr)
         971                 : {
         972                 :   int tok;
         973           21795 :   if (ptr == end)
         974            6499 :     return XML_TOK_NONE;
         975                 :   if (MINBPC(enc) > 1) {
         976           15296 :     size_t n = end - ptr;
         977           15296 :     if (n & (MINBPC(enc) - 1)) {
         978               0 :       n &= ~(MINBPC(enc) - 1);
         979               0 :       if (n == 0)
         980               0 :         return XML_TOK_PARTIAL;
         981               0 :       end = ptr + n;
         982                 :     }
         983                 :   }
         984           15296 :   switch (BYTE_TYPE(enc, ptr)) {
         985                 :   case BT_QUOT:
         986             258 :     return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);
         987                 :   case BT_APOS:
         988               2 :     return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);
         989                 :   case BT_LT:
         990                 :     {
         991            7118 :       ptr += MINBPC(enc);
         992            7118 :       if (ptr == end)
         993               0 :         return XML_TOK_PARTIAL;
         994            7118 :       switch (BYTE_TYPE(enc, ptr)) {
         995                 :       case BT_EXCL:
         996             757 :         return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
         997                 :       case BT_QUEST:
         998            3100 :         return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
         999                 :       case BT_NMSTRT:
        1000                 :       case BT_HEX:
        1001                 :       case BT_NONASCII:
        1002                 :       case BT_LEAD2:
        1003                 :       case BT_LEAD3:
        1004                 :       case BT_LEAD4:
        1005            3261 :         *nextTokPtr = ptr - MINBPC(enc);
        1006            3261 :         return XML_TOK_INSTANCE_START;
        1007                 :       }
        1008               0 :       *nextTokPtr = ptr;
        1009               0 :       return XML_TOK_INVALID;
        1010                 :     }
        1011                 :   case BT_CR:
        1012              16 :     if (ptr + MINBPC(enc) == end) {
        1013               0 :       *nextTokPtr = end;
        1014                 :       /* indicate that this might be part of a CR/LF pair */
        1015               0 :       return -XML_TOK_PROLOG_S;
        1016                 :     }
        1017                 :     /* fall through */
        1018                 :   case BT_S: case BT_LF:
        1019                 :     for (;;) {
        1020            9764 :       ptr += MINBPC(enc);
        1021            9764 :       if (ptr == end)
        1022                 :         break;
        1023            6941 :       switch (BYTE_TYPE(enc, ptr)) {
        1024                 :       case BT_S: case BT_LF:
        1025            2559 :         break;
        1026                 :       case BT_CR:
        1027                 :         /* don't split CR/LF pair */
        1028               8 :         if (ptr + MINBPC(enc) != end)
        1029               8 :           break;
        1030                 :         /* fall through */
        1031                 :       default:
        1032            4374 :         *nextTokPtr = ptr;
        1033            4374 :         return XML_TOK_PROLOG_S;
        1034                 :       }
        1035            2567 :     }
        1036            2823 :     *nextTokPtr = ptr;
        1037            2823 :     return XML_TOK_PROLOG_S;
        1038                 :   case BT_PERCNT:
        1039               0 :     return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
        1040                 :   case BT_COMMA:
        1041               0 :     *nextTokPtr = ptr + MINBPC(enc);
        1042               0 :     return XML_TOK_COMMA;
        1043                 :   case BT_LSQB:
        1044              37 :     *nextTokPtr = ptr + MINBPC(enc);
        1045              37 :     return XML_TOK_OPEN_BRACKET;
        1046                 :   case BT_RSQB:
        1047              37 :     ptr += MINBPC(enc);
        1048              37 :     if (ptr == end)
        1049               0 :       return -XML_TOK_CLOSE_BRACKET;
        1050              37 :     if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
        1051               0 :       if (ptr + MINBPC(enc) == end)
        1052               0 :         return XML_TOK_PARTIAL;
        1053               0 :       if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
        1054               0 :         *nextTokPtr = ptr + 2*MINBPC(enc);
        1055               0 :         return XML_TOK_COND_SECT_CLOSE;
        1056                 :       }
        1057                 :     }
        1058              37 :     *nextTokPtr = ptr;
        1059              37 :     return XML_TOK_CLOSE_BRACKET;
        1060                 :   case BT_LPAR:
        1061               0 :     *nextTokPtr = ptr + MINBPC(enc);
        1062               0 :     return XML_TOK_OPEN_PAREN;
        1063                 :   case BT_RPAR:
        1064               0 :     ptr += MINBPC(enc);
        1065               0 :     if (ptr == end)
        1066               0 :       return -XML_TOK_CLOSE_PAREN;
        1067               0 :     switch (BYTE_TYPE(enc, ptr)) {
        1068                 :     case BT_AST:
        1069               0 :       *nextTokPtr = ptr + MINBPC(enc);
        1070               0 :       return XML_TOK_CLOSE_PAREN_ASTERISK;
        1071                 :     case BT_QUEST:
        1072               0 :       *nextTokPtr = ptr + MINBPC(enc);
        1073               0 :       return XML_TOK_CLOSE_PAREN_QUESTION;
        1074                 :     case BT_PLUS:
        1075               0 :       *nextTokPtr = ptr + MINBPC(enc);
        1076               0 :       return XML_TOK_CLOSE_PAREN_PLUS;
        1077                 :     case BT_CR: case BT_LF: case BT_S:
        1078                 :     case BT_GT: case BT_COMMA: case BT_VERBAR:
        1079                 :     case BT_RPAR:
        1080               0 :       *nextTokPtr = ptr;
        1081               0 :       return XML_TOK_CLOSE_PAREN;
        1082                 :     }
        1083               0 :     *nextTokPtr = ptr;
        1084               0 :     return XML_TOK_INVALID;
        1085                 :   case BT_VERBAR:
        1086               0 :     *nextTokPtr = ptr + MINBPC(enc);
        1087               0 :     return XML_TOK_OR;
        1088                 :   case BT_GT:
        1089             302 :     *nextTokPtr = ptr + MINBPC(enc);
        1090             302 :     return XML_TOK_DECL_CLOSE;
        1091                 :   case BT_NUM:
        1092              11 :     return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr);
        1093                 : #define LEAD_CASE(n) \
        1094                 :   case BT_LEAD ## n: \
        1095                 :     if (end - ptr < n) \
        1096                 :       return XML_TOK_PARTIAL_CHAR; \
        1097                 :     if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
        1098                 :       ptr += n; \
        1099                 :       tok = XML_TOK_NAME; \
        1100                 :       break; \
        1101                 :     } \
        1102                 :     if (IS_NAME_CHAR(enc, ptr, n)) { \
        1103                 :       ptr += n; \
        1104                 :       tok = XML_TOK_NMTOKEN; \
        1105                 :       break; \
        1106                 :     } \
        1107                 :     *nextTokPtr = ptr; \
        1108                 :     return XML_TOK_INVALID;
        1109               0 :     LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
        1110                 : #undef LEAD_CASE
        1111                 :   case BT_NMSTRT:
        1112                 :   case BT_HEX:
        1113             334 :     tok = XML_TOK_NAME;
        1114             334 :     ptr += MINBPC(enc);
        1115             334 :     break;
        1116                 :   case BT_DIGIT:
        1117                 :   case BT_NAME:
        1118                 :   case BT_MINUS:
        1119                 : #ifdef XML_NS
        1120                 :   case BT_COLON:
        1121                 : #endif
        1122               0 :     tok = XML_TOK_NMTOKEN;
        1123               0 :     ptr += MINBPC(enc);
        1124               0 :     break;
        1125                 :   case BT_NONASCII:
        1126               0 :     if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) {
        1127               0 :       ptr += MINBPC(enc);
        1128               0 :       tok = XML_TOK_NAME;
        1129               0 :       break;
        1130                 :     }
        1131               0 :     if (IS_NAME_CHAR_MINBPC(enc, ptr)) {
        1132               0 :       ptr += MINBPC(enc);
        1133               0 :       tok = XML_TOK_NMTOKEN;
        1134               0 :       break;
        1135                 :     }
        1136                 :     /* fall through */
        1137                 :   default:
        1138               0 :     *nextTokPtr = ptr;
        1139               0 :     return XML_TOK_INVALID;
        1140                 :   }
        1141            3559 :   while (ptr != end) {
        1142            3225 :     switch (BYTE_TYPE(enc, ptr)) {
        1143               0 :     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
        1144                 :     case BT_GT: case BT_RPAR: case BT_COMMA:
        1145                 :     case BT_VERBAR: case BT_LSQB: case BT_PERCNT:
        1146                 :     case BT_S: case BT_CR: case BT_LF:
        1147             334 :       *nextTokPtr = ptr;
        1148             334 :       return tok;
        1149                 : #ifdef XML_NS
        1150                 :     case BT_COLON:
        1151              36 :       ptr += MINBPC(enc);
        1152              36 :       switch (tok) {
        1153                 :       case XML_TOK_NAME:
        1154              36 :         if (ptr == end)
        1155               0 :           return XML_TOK_PARTIAL;
        1156              36 :         tok = XML_TOK_PREFIXED_NAME;
        1157              36 :         switch (BYTE_TYPE(enc, ptr)) {
        1158               0 :         CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
        1159                 :         default:
        1160               0 :           tok = XML_TOK_NMTOKEN;
        1161               0 :           break;
        1162                 :         }
        1163              36 :         break;
        1164                 :       case XML_TOK_PREFIXED_NAME:
        1165               0 :         tok = XML_TOK_NMTOKEN;
        1166               0 :         break;
        1167                 :       }
        1168              36 :       break;
        1169                 : #endif
        1170                 :     case BT_PLUS:
        1171               0 :       if (tok == XML_TOK_NMTOKEN)  {
        1172               0 :         *nextTokPtr = ptr;
        1173               0 :         return XML_TOK_INVALID;
        1174                 :       }
        1175               0 :       *nextTokPtr = ptr + MINBPC(enc);
        1176               0 :       return XML_TOK_NAME_PLUS;
        1177                 :     case BT_AST:
        1178               0 :       if (tok == XML_TOK_NMTOKEN)  {
        1179               0 :         *nextTokPtr = ptr;
        1180               0 :         return XML_TOK_INVALID;
        1181                 :       }
        1182               0 :       *nextTokPtr = ptr + MINBPC(enc);
        1183               0 :       return XML_TOK_NAME_ASTERISK;
        1184                 :     case BT_QUEST:
        1185               0 :       if (tok == XML_TOK_NMTOKEN)  {
        1186               0 :         *nextTokPtr = ptr;
        1187               0 :         return XML_TOK_INVALID;
        1188                 :       }
        1189               0 :       *nextTokPtr = ptr + MINBPC(enc);
        1190               0 :       return XML_TOK_NAME_QUESTION;
        1191                 :     default:
        1192               0 :       *nextTokPtr = ptr;
        1193               0 :       return XML_TOK_INVALID;
        1194                 :     }
        1195                 :   }
        1196               0 :   return -tok;
        1197                 : }
        1198                 :
        1199                 : static int PTRCALL
        1200            5552 : PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
        1201                 :                           const char *end, const char **nextTokPtr)
        1202                 : {
        1203                 :   const char *start;
        1204            5552 :   if (ptr == end)
        1205            2039 :     return XML_TOK_NONE;
        1206            3513 :   start = ptr;
        1207           58515 :   while (ptr != end) {
        1208           53079 :     switch (BYTE_TYPE(enc, ptr)) {
        1209                 : #define LEAD_CASE(n) \
        1210                 :     case BT_LEAD ## n: ptr += n; break;
        1211               0 :     LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
        1212                 : #undef LEAD_CASE
        1213                 :     case BT_AMP:
        1214             970 :       if (ptr == start)
        1215             965 :         return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
        1216               5 :       *nextTokPtr = ptr;
        1217               5 :       return XML_TOK_DATA_CHARS;
        1218                 :     case BT_LT:
        1219                 :       /* this is for inside entity references */
        1220               0 :       *nextTokPtr = ptr;
        1221               0 :       return XML_TOK_INVALID;
        1222                 :     case BT_LF:
        1223               0 :       if (ptr == start) {
        1224               0 :         *nextTokPtr = ptr + MINBPC(enc);
        1225               0 :         return XML_TOK_DATA_NEWLINE;
        1226                 :       }
        1227               0 :       *nextTokPtr = ptr;
        1228               0 :       return XML_TOK_DATA_CHARS;
        1229                 :     case BT_CR:
        1230               0 :       if (ptr == start) {
        1231               0 :         ptr += MINBPC(enc);
        1232               0 :         if (ptr == end)
        1233               0 :           return XML_TOK_TRAILING_CR;
        1234               0 :         if (BYTE_TYPE(enc, ptr) == BT_LF)
        1235               0 :           ptr += MINBPC(enc);
        1236               0 :         *nextTokPtr = ptr;
        1237               0 :         return XML_TOK_DATA_NEWLINE;
        1238                 :       }
        1239               0 :       *nextTokPtr = ptr;
        1240               0 :       return XML_TOK_DATA_CHARS;
        1241                 :     case BT_S:
        1242             620 :       if (ptr == start) {
        1243             536 :         *nextTokPtr = ptr + MINBPC(enc);
        1244             536 :         return XML_TOK_ATTRIBUTE_VALUE_S;
        1245                 :       }
        1246              84 :       *nextTokPtr = ptr;
        1247              84 :       return XML_TOK_DATA_CHARS;
        1248                 :     default:
        1249           51489 :       ptr += MINBPC(enc);
        1250           51489 :       break;
        1251                 :     }
        1252                 :   }
        1253            1923 :   *nextTokPtr = ptr;
        1254            1923 :   return XML_TOK_DATA_CHARS;
        1255                 : }
        1256                 :
        1257                 : static int PTRCALL
        1258            1450 : PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
        1259                 :                        const char *end, const char **nextTokPtr)
        1260                 : {
        1261                 :   const char *start;
        1262            1450 :   if (ptr == end)
        1263             242 :     return XML_TOK_NONE;
        1264            1208 :   start = ptr;
        1265           18258 :   while (ptr != end) {
        1266           16810 :     switch (BYTE_TYPE(enc, ptr)) {
        1267                 : #define LEAD_CASE(n) \
        1268                 :     case BT_LEAD ## n: ptr += n; break;
        1269               0 :     LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
        1270                 : #undef LEAD_CASE
        1271                 :     case BT_AMP:
        1272             120 :       if (ptr == start)
        1273              60 :         return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
        1274              60 :       *nextTokPtr = ptr;
        1275              60 :       return XML_TOK_DATA_CHARS;
        1276                 :     case BT_PERCNT:
        1277               0 :       if (ptr == start) {
        1278               0 :         int tok =  PREFIX(scanPercent)(enc, ptr + MINBPC(enc),
        1279                 :                                        end, nextTokPtr);
        1280               0 :         return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok;
        1281                 :       }
        1282               0 :       *nextTokPtr = ptr;
        1283               0 :       return XML_TOK_DATA_CHARS;
        1284                 :     case BT_LF:
        1285             848 :       if (ptr == start) {
        1286             530 :         *nextTokPtr = ptr + MINBPC(enc);
        1287             530 :         return XML_TOK_DATA_NEWLINE;
        1288                 :       }
        1289             318 :       *nextTokPtr = ptr;
        1290             318 :       return XML_TOK_DATA_CHARS;
        1291                 :     case BT_CR:
        1292               0 :       if (ptr == start) {
        1293               0 :         ptr += MINBPC(enc);
        1294               0 :         if (ptr == end)
        1295               0 :           return XML_TOK_TRAILING_CR;
        1296               0 :         if (BYTE_TYPE(enc, ptr) == BT_LF)
        1297               0 :           ptr += MINBPC(enc);
        1298               0 :         *nextTokPtr = ptr;
        1299               0 :         return XML_TOK_DATA_NEWLINE;
        1300                 :       }
        1301               0 :       *nextTokPtr = ptr;
        1302               0 :       return XML_TOK_DATA_CHARS;
        1303                 :     default:
        1304           15842 :       ptr += MINBPC(enc);
        1305           15842 :       break;
        1306                 :     }
        1307                 :   }
        1308             240 :   *nextTokPtr = ptr;
        1309             240 :   return XML_TOK_DATA_CHARS;
        1310                 : }
        1311                 :
        1312                 : #ifdef XML_DTD
        1313                 :
        1314                 : static int PTRCALL
        1315               0 : PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,
        1316                 :                          const char *end, const char **nextTokPtr)
        1317                 : {
        1318               0 :   int level = 0;
        1319                 :   if (MINBPC(enc) > 1) {
        1320               0 :     size_t n = end - ptr;
        1321               0 :     if (n & (MINBPC(enc) - 1)) {
        1322               0 :       n &= ~(MINBPC(enc) - 1);
        1323               0 :       end = ptr + n;
        1324                 :     }
        1325                 :   }
        1326               0 :   while (ptr != end) {
        1327               0 :     switch (BYTE_TYPE(enc, ptr)) {
        1328               0 :     INVALID_CASES(ptr, nextTokPtr)
        1329                 :     case BT_LT:
        1330               0 :       if ((ptr += MINBPC(enc)) == end)
        1331               0 :         return XML_TOK_PARTIAL;
        1332               0 :       if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {
        1333               0 :         if ((ptr += MINBPC(enc)) == end)
        1334               0 :           return XML_TOK_PARTIAL;
        1335               0 :         if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
        1336               0 :           ++level;
        1337               0 :           ptr += MINBPC(enc);
        1338                 :         }
        1339                 :       }
        1340               0 :       break;
        1341                 :     case BT_RSQB:
        1342               0 :       if ((ptr += MINBPC(enc)) == end)
        1343               0 :         return XML_TOK_PARTIAL;
        1344               0 :       if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
        1345               0 :         if ((ptr += MINBPC(enc)) == end)
        1346               0 :           return XML_TOK_PARTIAL;
        1347               0 :         if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
        1348               0 :           ptr += MINBPC(enc);
        1349               0 :           if (level == 0) {
        1350               0 :             *nextTokPtr = ptr;
        1351               0 :             return XML_TOK_IGNORE_SECT;
        1352                 :           }
        1353               0 :           --level;
        1354                 :         }
        1355                 :       }
        1356               0 :       break;
        1357                 :     default:
        1358               0 :       ptr += MINBPC(enc);
        1359               0 :       break;
        1360                 :     }
        1361                 :   }
        1362               0 :   return XML_TOK_PARTIAL;
        1363                 : }
        1364                 :
        1365                 : #endif /* XML_DTD */
        1366                 :
        1367                 : static int PTRCALL
        1368               8 : PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
        1369                 :                    const char **badPtr)
        1370                 : {
        1371               8 :   ptr += MINBPC(enc);
        1372               8 :   end -= MINBPC(enc);
        1373             175 :   for (; ptr != end; ptr += MINBPC(enc)) {
        1374             167 :     switch (BYTE_TYPE(enc, ptr)) {
        1375                 :     case BT_DIGIT:
        1376                 :     case BT_HEX:
        1377                 :     case BT_MINUS:
        1378                 :     case BT_APOS:
        1379                 :     case BT_LPAR:
        1380                 :     case BT_RPAR:
        1381                 :     case BT_PLUS:
        1382                 :     case BT_COMMA:
        1383                 :     case BT_SOL:
        1384                 :     case BT_EQUALS:
        1385                 :     case BT_QUEST:
        1386                 :     case BT_CR:
        1387                 :     case BT_LF:
        1388                 :     case BT_SEMI:
        1389                 :     case BT_EXCL:
        1390                 :     case BT_AST:
        1391                 :     case BT_PERCNT:
        1392                 :     case BT_NUM:
        1393                 : #ifdef XML_NS
        1394                 :     case BT_COLON:
        1395                 : #endif
        1396              91 :       break;
        1397                 :     case BT_S:
        1398               2 :       if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) {
        1399               0 :         *badPtr = ptr;
        1400               0 :         return 0;
        1401                 :       }
        1402               2 :       break;
        1403                 :     case BT_NAME:
        1404                 :     case BT_NMSTRT:
        1405              74 :       if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f))
        1406              74 :         break;
        1407                 :     default:
        1408               0 :       switch (BYTE_TO_ASCII(enc, ptr)) {
        1409                 :       case 0x24: /* $ */
        1410                 :       case 0x40: /* @ */
        1411                 :         break;
        1412                 :       default:
        1413               0 :         *badPtr = ptr;
        1414               0 :         return 0;
        1415                 :       }
        1416               0 :       break;
        1417                 :     }
        1418                 :   }
        1419               8 :   return 1;
        1420                 : }
        1421                 :
        1422                 : /* This must only be called for a well-formed start-tag or empty
        1423                 :    element tag.  Returns the number of attributes.  Pointers to the
        1424                 :    first attsMax attributes are stored in atts.
        1425                 : */
        1426                 :
        1427                 : static int PTRCALL
        1428           82984 : PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
        1429                 :                 int attsMax, ATTRIBUTE *atts)
        1430                 : {
        1431           82984 :   enum { other, inName, inValue } state = inName;
        1432           82984 :   int nAtts = 0;
        1433           82984 :   int open = 0; /* defined when state == inValue;
        1434                 :                    initialization just to shut up compilers */
        1435                 :
        1436         1656220 :   for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) {
        1437         1656220 :     switch (BYTE_TYPE(enc, ptr)) {
        1438                 : #define START_NAME \
        1439                 :       if (state == other) { \
        1440                 :         if (nAtts < attsMax) { \
        1441                 :           atts[nAtts].name = ptr; \
        1442                 :           atts[nAtts].normalized = 1; \
        1443                 :         } \
        1444                 :         state = inName; \
        1445                 :       }
        1446                 : #define LEAD_CASE(n) \
        1447                 :     case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break;
        1448               0 :     LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
        1449                 : #undef LEAD_CASE
        1450                 :     case BT_NONASCII:
        1451                 :     case BT_NMSTRT:
        1452                 :     case BT_HEX:
        1453         1265074 :       START_NAME
        1454         1265074 :       break;
        1455                 : #undef START_NAME
        1456                 :     case BT_QUOT:
        1457           37076 :       if (state != inValue) {
        1458           18538 :         if (nAtts < attsMax)
        1459           18519 :           atts[nAtts].valuePtr = ptr + MINBPC(enc);
        1460           18538 :         state = inValue;
        1461           18538 :         open = BT_QUOT;
        1462                 :       }
        1463           18538 :       else if (open == BT_QUOT) {
        1464           18538 :         state = other;
        1465           18538 :         if (nAtts < attsMax)
        1466           18519 :           atts[nAtts].valueEnd = ptr;
        1467           18538 :         nAtts++;
        1468                 :       }
        1469           37076 :       break;
        1470                 :     case BT_APOS:
        1471            1134 :       if (state != inValue) {
        1472             566 :         if (nAtts < attsMax)
        1473             566 :           atts[nAtts].valuePtr = ptr + MINBPC(enc);
        1474             566 :         state = inValue;
        1475             566 :         open = BT_APOS;
        1476                 :       }
        1477             568 :       else if (open == BT_APOS) {
        1478             566 :         state = other;
        1479             566 :         if (nAtts < attsMax)
        1480             566 :           atts[nAtts].valueEnd = ptr;
        1481             566 :         nAtts++;
        1482                 :       }
        1483            1134 :       break;
        1484                 :     case BT_AMP:
        1485             965 :       if (nAtts < attsMax)
        1486             965 :         atts[nAtts].normalized = 0;
        1487             965 :       break;
        1488                 :     case BT_S:
        1489           36648 :       if (state == inName)
        1490           13669 :         state = other;
        1491           22979 :       else if (state == inValue
        1492             885 :                && nAtts < attsMax
        1493             880 :                && atts[nAtts].normalized
        1494             460 :                && (ptr == atts[nAtts].valuePtr
        1495             344 :                    || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE
        1496             344 :                    || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE
        1497             344 :                    || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
        1498             116 :         atts[nAtts].normalized = 0;
        1499           36648 :       break;
        1500                 :     case BT_CR: case BT_LF:
        1501                 :       /* This case ensures that the first attribute name is counted
        1502                 :          Apart from that we could just change state on the quote. */
        1503            2915 :       if (state == inName)
        1504               7 :         state = other;
        1505            2908 :       else if (state == inValue && nAtts < attsMax)
        1506               0 :         atts[nAtts].normalized = 0;
        1507            2915 :       break;
        1508                 :     case BT_GT:
        1509                 :     case BT_SOL:
        1510          110606 :       if (state != inValue)
        1511           82984 :         return nAtts;
        1512           27622 :       break;
        1513                 :     default:
        1514          201802 :       break;
        1515                 :     }
        1516         1573236 :   }
        1517                 :   /* not reached */
        1518                 : }
        1519                 :
        1520                 : static int PTRFASTCALL
        1521             707 : PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
        1522                 : {
        1523             707 :   int result = 0;
        1524                 :   /* skip &# */
        1525             707 :   ptr += 2*MINBPC(enc);
        1526             727 :   if (CHAR_MATCHES(enc, ptr, ASCII_x)) {
        1527             118 :     for (ptr += MINBPC(enc);
        1528             196 :          !CHAR_MATCHES(enc, ptr, ASCII_SEMI);
        1529              78 :          ptr += MINBPC(enc)) {
        1530              78 :       int c = BYTE_TO_ASCII(enc, ptr);
        1531              78 :       switch (c) {
        1532                 :       case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4:
        1533                 :       case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9:
        1534              70 :         result <<= 4;
        1535              70 :         result |= (c - ASCII_0);
        1536              70 :         break;
        1537                 :       case ASCII_A: case ASCII_B: case ASCII_C:
        1538                 :       case ASCII_D: case ASCII_E: case ASCII_F:
        1539               0 :         result <<= 4;
        1540               0 :         result += 10 + (c - ASCII_A);
        1541               0 :         break;
        1542                 :       case ASCII_a: case ASCII_b: case ASCII_c:
        1543                 :       case ASCII_d: case ASCII_e: case ASCII_f:
        1544               8 :         result <<= 4;
        1545               8 :         result += 10 + (c - ASCII_a);
        1546               8 :         break;
        1547                 :       }
        1548              78 :       if (result >= 0x110000)
        1549               0 :         return -1;
        1550                 :     }
        1551                 :   }
        1552                 :   else {
        1553            2418 :     for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
        1554            1731 :       int c = BYTE_TO_ASCII(enc, ptr);
        1555            1731 :       result *= 10;
        1556            1731 :       result += (c - ASCII_0);
        1557            1731 :       if (result >= 0x110000)
        1558               0 :         return -1;
        1559                 :     }
        1560                 :   }
        1561             707 :   return checkCharRefNumber(result);
        1562                 : }
        1563                 :
        1564                 : static int PTRCALL
        1565            2340 : PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,
        1566                 :                              const char *end)
        1567                 : {
        1568            2340 :   switch ((end - ptr)/MINBPC(enc)) {
        1569                 :   case 2:
        1570             285 :     if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) {
        1571             285 :       switch (BYTE_TO_ASCII(enc, ptr)) {
        1572                 :       case ASCII_l:
        1573             147 :         return ASCII_LT;
        1574                 :       case ASCII_g:
        1575             138 :         return ASCII_GT;
        1576                 :       }
        1577                 :     }
        1578               0 :     break;
        1579                 :   case 3:
        1580             147 :     if (CHAR_MATCHES(enc, ptr, ASCII_a)) {
        1581             147 :       ptr += MINBPC(enc);
        1582             147 :       if (CHAR_MATCHES(enc, ptr, ASCII_m)) {
        1583             147 :         ptr += MINBPC(enc);
        1584             147 :         if (CHAR_MATCHES(enc, ptr, ASCII_p))
        1585             147 :           return ASCII_AMP;
        1586                 :       }
        1587                 :     }
        1588               0 :     break;
        1589                 :   case 4:
        1590             242 :     switch (BYTE_TO_ASCII(enc, ptr)) {
        1591                 :     case ASCII_q:
        1592               1 :       ptr += MINBPC(enc);
        1593               1 :       if (CHAR_MATCHES(enc, ptr, ASCII_u)) {
        1594               1 :         ptr += MINBPC(enc);
        1595               1 :         if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
        1596               1 :           ptr += MINBPC(enc);
        1597               1 :           if (CHAR_MATCHES(enc, ptr, ASCII_t))
        1598               1 :             return ASCII_QUOT;
        1599                 :         }
        1600                 :       }
        1601               0 :       break;
        1602                 :     case ASCII_a:
        1603               1 :       ptr += MINBPC(enc);
        1604               1 :       if (CHAR_MATCHES(enc, ptr, ASCII_p)) {
        1605               1 :         ptr += MINBPC(enc);
        1606               1 :         if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
        1607               1 :           ptr += MINBPC(enc);
        1608               1 :           if (CHAR_MATCHES(enc, ptr, ASCII_s))
        1609               1 :             return ASCII_APOS;
        1610                 :         }
        1611                 :       }
        1612               0 :       break;
        1613                 :     }
        1614                 :   }
        1615            1906 :   return 0;
        1616                 : }
        1617                 :
        1618                 : static int PTRCALL
        1619               0 : PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
        1620                 : {
        1621                 :   for (;;) {
        1622               0 :     switch (BYTE_TYPE(enc, ptr1)) {
        1623                 : #define LEAD_CASE(n) \
        1624                 :     case BT_LEAD ## n: \
        1625                 :       if (*ptr1++ != *ptr2++) \
        1626                 :         return 0;
        1627               0 :     LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2)
        1628                 : #undef LEAD_CASE
        1629                 :       /* fall through */
        1630               0 :       if (*ptr1++ != *ptr2++)
        1631               0 :         return 0;
        1632               0 :       break;
        1633                 :     case BT_NONASCII:
        1634                 :     case BT_NMSTRT:
        1635                 : #ifdef XML_NS
        1636                 :     case BT_COLON:
        1637                 : #endif
        1638                 :     case BT_HEX:
        1639                 :     case BT_DIGIT:
        1640                 :     case BT_NAME:
        1641                 :     case BT_MINUS:
        1642               0 :       if (*ptr2++ != *ptr1++)
        1643               0 :         return 0;
        1644                 :       if (MINBPC(enc) > 1) {
        1645               0 :         if (*ptr2++ != *ptr1++)
        1646               0 :           return 0;
        1647                 :         if (MINBPC(enc) > 2) {
        1648                 :           if (*ptr2++ != *ptr1++)
        1649                 :             return 0;
        1650                 :           if (MINBPC(enc) > 3) {
        1651                 :             if (*ptr2++ != *ptr1++)
        1652                 :               return 0;
        1653                 :           }
        1654                 :         }
        1655                 :       }
        1656               0 :       break;
        1657                 :     default:
        1658               0 :       if (MINBPC(enc) == 1 && *ptr1 == *ptr2)
        1659               0 :         return 1;
        1660               0 :       switch (BYTE_TYPE(enc, ptr2)) {
        1661                 :       case BT_LEAD2:
        1662                 :       case BT_LEAD3:
        1663                 :       case BT_LEAD4:
        1664                 :       case BT_NONASCII:
        1665                 :       case BT_NMSTRT:
        1666                 : #ifdef XML_NS
        1667                 :       case BT_COLON:
        1668                 : #endif
        1669                 :       case BT_HEX:
        1670                 :       case BT_DIGIT:
        1671                 :       case BT_NAME:
        1672                 :       case BT_MINUS:
        1673               0 :         return 0;
        1674                 :       default:
        1675               0 :         return 1;
        1676                 :       }
        1677                 :     }
        1678               0 :   }
        1679                 :   /* not reached */
        1680                 : }
        1681                 :
        1682                 : static int PTRCALL
        1683            7642 : PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
        1684                 :                          const char *end1, const char *ptr2)
        1685                 : {
        1686           49250 :   for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
        1687           41649 :     if (ptr1 == end1)
        1688               0 :       return 0;
        1689           41649 :     if (!CHAR_MATCHES(enc, ptr1, *ptr2))
        1690              41 :       return 0;
        1691                 :   }
        1692            7601 :   return ptr1 == end1;
        1693                 : }
        1694                 :
        1695                 : static int PTRFASTCALL
        1696          183987 : PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
        1697                 : {
        1698          183987 :   const char *start = ptr;
        1699                 :   for (;;) {
        1700         1965799 :     switch (BYTE_TYPE(enc, ptr)) {
        1701                 : #define LEAD_CASE(n) \
        1702                 :     case BT_LEAD ## n: ptr += n; break;
        1703               0 :     LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
        1704                 : #undef LEAD_CASE
        1705                 :     case BT_NONASCII:
        1706                 :     case BT_NMSTRT:
        1707                 : #ifdef XML_NS
        1708                 :     case BT_COLON:
        1709                 : #endif
        1710                 :     case BT_HEX:
        1711                 :     case BT_DIGIT:
        1712                 :     case BT_NAME:
        1713                 :     case BT_MINUS:
        1714         1781812 :       ptr += MINBPC(enc);
        1715         1781812 :       break;
        1716                 :     default:
        1717          183987 :       return (int)(ptr - start);
        1718                 :     }
        1719         1781812 :   }
        1720                 : }
        1721                 :
        1722                 : static const char * PTRFASTCALL
        1723             145 : PREFIX(skipS)(const ENCODING *enc, const char *ptr)
        1724                 : {
        1725                 :   for (;;) {
        1726             145 :     switch (BYTE_TYPE(enc, ptr)) {
        1727                 :     case BT_LF:
        1728                 :     case BT_CR:
        1729                 :     case BT_S:
        1730              92 :       ptr += MINBPC(enc);
        1731                 :       break;
        1732                 :     default:
        1733              53 :       return ptr;
        1734                 :     }
        1735              92 :   }
        1736                 : }
        1737                 :
        1738                 : static void PTRCALL
        1739           86539 : PREFIX(updatePosition)(const ENCODING *enc,
        1740                 :                        const char *ptr,
        1741                 :                        const char *end,
        1742                 :                        POSITION *pos)
        1743                 : {
        1744         5147761 :   while (ptr != end) {
        1745         4974683 :     switch (BYTE_TYPE(enc, ptr)) {
        1746                 : #define LEAD_CASE(n) \
        1747                 :     case BT_LEAD ## n: \
        1748                 :       ptr += n; \
        1749                 :       break;
        1750               0 :     LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
        1751                 : #undef LEAD_CASE
        1752                 :     case BT_LF:
        1753          141442 :       pos->columnNumber = (XML_Size)-1;
        1754          141442 :       pos->lineNumber++;
        1755          141442 :       ptr += MINBPC(enc);
        1756          141442 :       break;
        1757                 :     case BT_CR:
        1758             172 :       pos->lineNumber++;
        1759             172 :       ptr += MINBPC(enc);
        1760             172 :       if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
        1761             172 :         ptr += MINBPC(enc);
        1762             172 :       pos->columnNumber = (XML_Size)-1;
        1763             172 :       break;
        1764                 :     default:
        1765         4833066 :       ptr += MINBPC(enc);
        1766         4833066 :       break;
        1767                 :     }
        1768         4974683 :     pos->columnNumber++;
        1769                 :   }
        1770           86539 : }
        1771                 :
        1772                 : #undef DO_LEAD_CASE
        1773                 : #undef MULTIBYTE_CASES
        1774                 : #undef INVALID_CASES
        1775                 : #undef CHECK_NAME_CASE
        1776                 : #undef CHECK_NAME_CASES
        1777                 : #undef CHECK_NMSTRT_CASE
        1778                 : #undef CHECK_NMSTRT_CASES
        1779                 :

Generated by: LCOV version 1.7