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-06-02 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         1800073 :   while (ptr != end) {
     833         1647943 :     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         1496896 :       ptr += MINBPC(enc);
     871         1496896 :       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         5147683 :   while (ptr != end) {
    1745         4974605 :     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         4832988 :       ptr += MINBPC(enc);
    1766         4832988 :       break;
    1767                 :     }
    1768         4974605 :     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