home *** CD-ROM | disk | FTP | other *** search
/ Netrunner 2004 October / NETRUNNER0410.ISO / regular / ActivePerl-5.8.4.810-MSWin32-x86.msi / _a8310f8d2d3b346def3caa84c4cefffa < prev    next >
Encoding:
Text File  |  2004-06-01  |  45.2 KB  |  1,779 lines

  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 FASTCALL
  90. PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
  91.                     const char *end, const char **nextTokPtr)
  92. {
  93.   if (ptr != end) {
  94.     if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
  95.       *nextTokPtr = ptr;
  96.       return XML_TOK_INVALID;
  97.     }
  98.     ptr += MINBPC(enc);
  99.     while (ptr != end) {
  100.       switch (BYTE_TYPE(enc, ptr)) {
  101.       INVALID_CASES(ptr, nextTokPtr)
  102.       case BT_MINUS:
  103.         if ((ptr += MINBPC(enc)) == end)
  104.           return XML_TOK_PARTIAL;
  105.         if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
  106.           if ((ptr += MINBPC(enc)) == end)
  107.             return XML_TOK_PARTIAL;
  108.           if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
  109.             *nextTokPtr = ptr;
  110.             return XML_TOK_INVALID;
  111.           }
  112.           *nextTokPtr = ptr + MINBPC(enc);
  113.           return XML_TOK_COMMENT;
  114.         }
  115.         break;
  116.       default:
  117.         ptr += MINBPC(enc);
  118.         break;
  119.       }
  120.     }
  121.   }
  122.   return XML_TOK_PARTIAL;
  123. }
  124.  
  125. /* ptr points to character following "<!" */
  126.  
  127. static int FASTCALL
  128. PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
  129.                  const char *end, const char **nextTokPtr)
  130. {
  131.   if (ptr == end)
  132.     return XML_TOK_PARTIAL;
  133.   switch (BYTE_TYPE(enc, ptr)) {
  134.   case BT_MINUS:
  135.     return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
  136.   case BT_LSQB:
  137.     *nextTokPtr = ptr + MINBPC(enc);
  138.     return XML_TOK_COND_SECT_OPEN;
  139.   case BT_NMSTRT:
  140.   case BT_HEX:
  141.     ptr += MINBPC(enc);
  142.     break;
  143.   default:
  144.     *nextTokPtr = ptr;
  145.     return XML_TOK_INVALID;
  146.   }
  147.   while (ptr != end) {
  148.     switch (BYTE_TYPE(enc, ptr)) {
  149.     case BT_PERCNT:
  150.       if (ptr + MINBPC(enc) == end)
  151.         return XML_TOK_PARTIAL;
  152.       /* don't allow <!ENTITY% foo "whatever"> */
  153.       switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
  154.       case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
  155.         *nextTokPtr = ptr;
  156.         return XML_TOK_INVALID;
  157.       }
  158.       /* fall through */
  159.     case BT_S: case BT_CR: case BT_LF:
  160.       *nextTokPtr = ptr;
  161.       return XML_TOK_DECL_OPEN;
  162.     case BT_NMSTRT:
  163.     case BT_HEX:
  164.       ptr += MINBPC(enc);
  165.       break;
  166.     default:
  167.       *nextTokPtr = ptr;
  168.       return XML_TOK_INVALID;
  169.     }
  170.   }
  171.   return XML_TOK_PARTIAL;
  172. }
  173.  
  174. static int FASTCALL
  175. PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr,
  176.                       const char *end, int *tokPtr)
  177. {
  178.   int upper = 0;
  179.   *tokPtr = XML_TOK_PI;
  180.   if (end - ptr != MINBPC(enc)*3)
  181.     return 1;
  182.   switch (BYTE_TO_ASCII(enc, ptr)) {
  183.   case ASCII_x:
  184.     break;
  185.   case ASCII_X:
  186.     upper = 1;
  187.     break;
  188.   default:
  189.     return 1;
  190.   }
  191.   ptr += MINBPC(enc);
  192.   switch (BYTE_TO_ASCII(enc, ptr)) {
  193.   case ASCII_m:
  194.     break;
  195.   case ASCII_M:
  196.     upper = 1;
  197.     break;
  198.   default:
  199.     return 1;
  200.   }
  201.   ptr += MINBPC(enc);
  202.   switch (BYTE_TO_ASCII(enc, ptr)) {
  203.   case ASCII_l:
  204.     break;
  205.   case ASCII_L:
  206.     upper = 1;
  207.     break;
  208.   default:
  209.     return 1;
  210.   }
  211.   if (upper)
  212.     return 0;
  213.   *tokPtr = XML_TOK_XML_DECL;
  214.   return 1;
  215. }
  216.  
  217. /* ptr points to character following "<?" */
  218.  
  219. static int FASTCALL
  220. PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
  221.                const char *end, const char **nextTokPtr)
  222. {
  223.   int tok;
  224.   const char *target = ptr;
  225.   if (ptr == end)
  226.     return XML_TOK_PARTIAL;
  227.   switch (BYTE_TYPE(enc, ptr)) {
  228.   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
  229.   default:
  230.     *nextTokPtr = ptr;
  231.     return XML_TOK_INVALID;
  232.   }
  233.   while (ptr != end) {
  234.     switch (BYTE_TYPE(enc, ptr)) {
  235.     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
  236.     case BT_S: case BT_CR: case BT_LF:
  237.       if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
  238.         *nextTokPtr = ptr;
  239.         return XML_TOK_INVALID;
  240.       }
  241.       ptr += MINBPC(enc);
  242.       while (ptr != end) {
  243.         switch (BYTE_TYPE(enc, ptr)) {
  244.         INVALID_CASES(ptr, nextTokPtr)
  245.         case BT_QUEST:
  246.           ptr += MINBPC(enc);
  247.           if (ptr == end)
  248.             return XML_TOK_PARTIAL;
  249.           if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
  250.             *nextTokPtr = ptr + MINBPC(enc);
  251.             return tok;
  252.           }
  253.           break;
  254.         default:
  255.           ptr += MINBPC(enc);
  256.           break;
  257.         }
  258.       }
  259.       return XML_TOK_PARTIAL;
  260.     case BT_QUEST:
  261.       if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
  262.         *nextTokPtr = ptr;
  263.         return XML_TOK_INVALID;
  264.       }
  265.       ptr += MINBPC(enc);
  266.       if (ptr == end)
  267.         return XML_TOK_PARTIAL;
  268.       if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
  269.         *nextTokPtr = ptr + MINBPC(enc);
  270.         return tok;
  271.       }
  272.       /* fall through */
  273.     default:
  274.       *nextTokPtr = ptr;
  275.       return XML_TOK_INVALID;
  276.     }
  277.   }
  278.   return XML_TOK_PARTIAL;
  279. }
  280.  
  281. static int FASTCALL
  282. 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.   if (end - ptr < 6 * MINBPC(enc))
  290.     return XML_TOK_PARTIAL;
  291.   for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
  292.     if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
  293.       *nextTokPtr = ptr;
  294.       return XML_TOK_INVALID;
  295.     }
  296.   }
  297.   *nextTokPtr = ptr;
  298.   return XML_TOK_CDATA_SECT_OPEN;
  299. }
  300.  
  301. static int FASTCALL
  302. PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
  303.                         const char *end, const char **nextTokPtr)
  304. {
  305.   if (ptr == end)
  306.     return XML_TOK_NONE;
  307.   if (MINBPC(enc) > 1) {
  308.     size_t n = end - ptr;
  309.     if (n & (MINBPC(enc) - 1)) {
  310.       n &= ~(MINBPC(enc) - 1);
  311.       if (n == 0)
  312.         return XML_TOK_PARTIAL;
  313.       end = ptr + n;
  314.     }
  315.   }
  316.   switch (BYTE_TYPE(enc, ptr)) {
  317.   case BT_RSQB:
  318.     ptr += MINBPC(enc);
  319.     if (ptr == end)
  320.       return XML_TOK_PARTIAL;
  321.     if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
  322.       break;
  323.     ptr += MINBPC(enc);
  324.     if (ptr == end)
  325.       return XML_TOK_PARTIAL;
  326.     if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
  327.       ptr -= MINBPC(enc);
  328.       break;
  329.     }
  330.     *nextTokPtr = ptr + MINBPC(enc);
  331.     return XML_TOK_CDATA_SECT_CLOSE;
  332.   case BT_CR:
  333.     ptr += MINBPC(enc);
  334.     if (ptr == end)
  335.       return XML_TOK_PARTIAL;
  336.     if (BYTE_TYPE(enc, ptr) == BT_LF)
  337.       ptr += MINBPC(enc);
  338.     *nextTokPtr = ptr;
  339.     return XML_TOK_DATA_NEWLINE;
  340.   case BT_LF:
  341.     *nextTokPtr = ptr + MINBPC(enc);
  342.     return XML_TOK_DATA_NEWLINE;
  343.   INVALID_CASES(ptr, nextTokPtr)
  344.   default:
  345.     ptr += MINBPC(enc);
  346.     break;
  347.   }
  348.   while (ptr != end) {
  349.     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.     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.       *nextTokPtr = ptr;
  367.       return XML_TOK_DATA_CHARS;
  368.     default:
  369.       ptr += MINBPC(enc);
  370.       break;
  371.     }
  372.   }
  373.   *nextTokPtr = ptr;
  374.   return XML_TOK_DATA_CHARS;
  375. }
  376.  
  377. /* ptr points to character following "</" */
  378.  
  379. static int FASTCALL
  380. PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
  381.                    const char *end, const char **nextTokPtr)
  382. {
  383.   if (ptr == end)
  384.     return XML_TOK_PARTIAL;
  385.   switch (BYTE_TYPE(enc, ptr)) {
  386.   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
  387.   default:
  388.     *nextTokPtr = ptr;
  389.     return XML_TOK_INVALID;
  390.   }
  391.   while (ptr != end) {
  392.     switch (BYTE_TYPE(enc, ptr)) {
  393.     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
  394.     case BT_S: case BT_CR: case BT_LF:
  395.       for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
  396.         switch (BYTE_TYPE(enc, ptr)) {
  397.         case BT_S: case BT_CR: case BT_LF:
  398.           break;
  399.         case BT_GT:
  400.           *nextTokPtr = ptr + MINBPC(enc);
  401.           return XML_TOK_END_TAG;
  402.         default:
  403.           *nextTokPtr = ptr;
  404.           return XML_TOK_INVALID;
  405.         }
  406.       }
  407.       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.       ptr += MINBPC(enc);
  413.       break;
  414. #endif
  415.     case BT_GT:
  416.       *nextTokPtr = ptr + MINBPC(enc);
  417.       return XML_TOK_END_TAG;
  418.     default:
  419.       *nextTokPtr = ptr;
  420.       return XML_TOK_INVALID;
  421.     }
  422.   }
  423.   return XML_TOK_PARTIAL;
  424. }
  425.  
  426. /* ptr points to character following "&#X" */
  427.  
  428. static int FASTCALL
  429. PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
  430.                        const char *end, const char **nextTokPtr)
  431. {
  432.   if (ptr != end) {
  433.     switch (BYTE_TYPE(enc, ptr)) {
  434.     case BT_DIGIT:
  435.     case BT_HEX:
  436.       break;
  437.     default:
  438.       *nextTokPtr = ptr;
  439.       return XML_TOK_INVALID;
  440.     }
  441.     for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
  442.       switch (BYTE_TYPE(enc, ptr)) {
  443.       case BT_DIGIT:
  444.       case BT_HEX:
  445.         break;
  446.       case BT_SEMI:
  447.         *nextTokPtr = ptr + MINBPC(enc);
  448.         return XML_TOK_CHAR_REF;
  449.       default:
  450.         *nextTokPtr = ptr;
  451.         return XML_TOK_INVALID;
  452.       }
  453.     }
  454.   }
  455.   return XML_TOK_PARTIAL;
  456. }
  457.  
  458. /* ptr points to character following "&#" */
  459.  
  460. static int FASTCALL
  461. PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
  462.                     const char *end, const char **nextTokPtr)
  463. {
  464.   if (ptr != end) {
  465.     if (CHAR_MATCHES(enc, ptr, ASCII_x))
  466.       return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
  467.     switch (BYTE_TYPE(enc, ptr)) {
  468.     case BT_DIGIT:
  469.       break;
  470.     default:
  471.       *nextTokPtr = ptr;
  472.       return XML_TOK_INVALID;
  473.     }
  474.     for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
  475.       switch (BYTE_TYPE(enc, ptr)) {
  476.       case BT_DIGIT:
  477.         break;
  478.       case BT_SEMI:
  479.         *nextTokPtr = ptr + MINBPC(enc);
  480.         return XML_TOK_CHAR_REF;
  481.       default:
  482.         *nextTokPtr = ptr;
  483.         return XML_TOK_INVALID;
  484.       }
  485.     }
  486.   }
  487.   return XML_TOK_PARTIAL;
  488. }
  489.  
  490. /* ptr points to character following "&" */
  491.  
  492. static int FASTCALL
  493. PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
  494.                 const char **nextTokPtr)
  495. {
  496.   if (ptr == end)
  497.     return XML_TOK_PARTIAL;
  498.   switch (BYTE_TYPE(enc, ptr)) {
  499.   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
  500.   case BT_NUM:
  501.     return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
  502.   default:
  503.     *nextTokPtr = ptr;
  504.     return XML_TOK_INVALID;
  505.   }
  506.   while (ptr != end) {
  507.     switch (BYTE_TYPE(enc, ptr)) {
  508.     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
  509.     case BT_SEMI:
  510.       *nextTokPtr = ptr + MINBPC(enc);
  511.       return XML_TOK_ENTITY_REF;
  512.     default:
  513.       *nextTokPtr = ptr;
  514.       return XML_TOK_INVALID;
  515.     }
  516.   }
  517.   return XML_TOK_PARTIAL;
  518. }
  519.  
  520. /* ptr points to character following first character of attribute name */
  521.  
  522. static int FASTCALL
  523. PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
  524.                  const char **nextTokPtr)
  525. {
  526. #ifdef XML_NS
  527.   int hadColon = 0;
  528. #endif
  529.   while (ptr != end) {
  530.     switch (BYTE_TYPE(enc, ptr)) {
  531.     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
  532. #ifdef XML_NS
  533.     case BT_COLON:
  534.       if (hadColon) {
  535.         *nextTokPtr = ptr;
  536.         return XML_TOK_INVALID;
  537.       }
  538.       hadColon = 1;
  539.       ptr += MINBPC(enc);
  540.       if (ptr == end)
  541.         return XML_TOK_PARTIAL;
  542.       switch (BYTE_TYPE(enc, ptr)) {
  543.       CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
  544.       default:
  545.         *nextTokPtr = ptr;
  546.         return XML_TOK_INVALID;
  547.       }
  548.       break;
  549. #endif
  550.     case BT_S: case BT_CR: case BT_LF:
  551.       for (;;) {
  552.         int t;
  553.  
  554.         ptr += MINBPC(enc);
  555.         if (ptr == end)
  556.           return XML_TOK_PARTIAL;
  557.         t = BYTE_TYPE(enc, ptr);
  558.         if (t == BT_EQUALS)
  559.           break;
  560.         switch (t) {
  561.         case BT_S:
  562.         case BT_LF:
  563.         case BT_CR:
  564.           break;
  565.         default:
  566.           *nextTokPtr = ptr;
  567.           return XML_TOK_INVALID;
  568.         }
  569.       }
  570.     /* fall through */
  571.     case BT_EQUALS:
  572.       {
  573.         int open;
  574. #ifdef XML_NS
  575.         hadColon = 0;
  576. #endif
  577.         for (;;) {
  578.           ptr += MINBPC(enc);
  579.           if (ptr == end)
  580.             return XML_TOK_PARTIAL;
  581.           open = BYTE_TYPE(enc, ptr);
  582.           if (open == BT_QUOT || open == BT_APOS)
  583.             break;
  584.           switch (open) {
  585.           case BT_S:
  586.           case BT_LF:
  587.           case BT_CR:
  588.             break;
  589.           default:
  590.             *nextTokPtr = ptr;
  591.             return XML_TOK_INVALID;
  592.           }
  593.         }
  594.         ptr += MINBPC(enc);
  595.         /* in attribute value */
  596.         for (;;) {
  597.           int t;
  598.           if (ptr == end)
  599.             return XML_TOK_PARTIAL;
  600.           t = BYTE_TYPE(enc, ptr);
  601.           if (t == open)
  602.             break;
  603.           switch (t) {
  604.           INVALID_CASES(ptr, nextTokPtr)
  605.           case BT_AMP:
  606.             {
  607.               int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
  608.               if (tok <= 0) {
  609.                 if (tok == XML_TOK_INVALID)
  610.                   *nextTokPtr = ptr;
  611.                 return tok;
  612.               }
  613.               break;
  614.             }
  615.           case BT_LT:
  616.             *nextTokPtr = ptr;
  617.             return XML_TOK_INVALID;
  618.           default:
  619.             ptr += MINBPC(enc);
  620.             break;
  621.           }
  622.         }
  623.         ptr += MINBPC(enc);
  624.         if (ptr == end)
  625.           return XML_TOK_PARTIAL;
  626.         switch (BYTE_TYPE(enc, ptr)) {
  627.         case BT_S:
  628.         case BT_CR:
  629.         case BT_LF:
  630.           break;
  631.         case BT_SOL:
  632.           goto sol;
  633.         case BT_GT:
  634.           goto gt;
  635.         default:
  636.           *nextTokPtr = ptr;
  637.           return XML_TOK_INVALID;
  638.         }
  639.         /* ptr points to closing quote */
  640.         for (;;) {
  641.           ptr += MINBPC(enc);
  642.           if (ptr == end)
  643.             return XML_TOK_PARTIAL;
  644.           switch (BYTE_TYPE(enc, ptr)) {
  645.           CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
  646.           case BT_S: case BT_CR: case BT_LF:
  647.             continue;
  648.           case BT_GT:
  649.           gt:
  650.             *nextTokPtr = ptr + MINBPC(enc);
  651.             return XML_TOK_START_TAG_WITH_ATTS;
  652.           case BT_SOL:
  653.           sol:
  654.             ptr += MINBPC(enc);
  655.             if (ptr == end)
  656.               return XML_TOK_PARTIAL;
  657.             if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
  658.               *nextTokPtr = ptr;
  659.               return XML_TOK_INVALID;
  660.             }
  661.             *nextTokPtr = ptr + MINBPC(enc);
  662.             return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
  663.           default:
  664.             *nextTokPtr = ptr;
  665.             return XML_TOK_INVALID;
  666.           }
  667.           break;
  668.         }
  669.         break;
  670.       }
  671.     default:
  672.       *nextTokPtr = ptr;
  673.       return XML_TOK_INVALID;
  674.     }
  675.   }
  676.   return XML_TOK_PARTIAL;
  677. }
  678.  
  679. /* ptr points to character following "<" */
  680.  
  681. static int FASTCALL
  682. 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.   if (ptr == end)
  689.     return XML_TOK_PARTIAL;
  690.   switch (BYTE_TYPE(enc, ptr)) {
  691.   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
  692.   case BT_EXCL:
  693.     if ((ptr += MINBPC(enc)) == end)
  694.       return XML_TOK_PARTIAL;
  695.     switch (BYTE_TYPE(enc, ptr)) {
  696.     case BT_MINUS:
  697.       return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
  698.     case BT_LSQB:
  699.       return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc),
  700.                                       end, nextTokPtr);
  701.     }
  702.     *nextTokPtr = ptr;
  703.     return XML_TOK_INVALID;
  704.   case BT_QUEST:
  705.     return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
  706.   case BT_SOL:
  707.     return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr);
  708.   default:
  709.     *nextTokPtr = ptr;
  710.     return XML_TOK_INVALID;
  711.   }
  712. #ifdef XML_NS
  713.   hadColon = 0;
  714. #endif
  715.   /* we have a start-tag */
  716.   while (ptr != end) {
  717.     switch (BYTE_TYPE(enc, ptr)) {
  718.     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
  719. #ifdef XML_NS
  720.     case BT_COLON:
  721.       if (hadColon) {
  722.         *nextTokPtr = ptr;
  723.         return XML_TOK_INVALID;
  724.       }
  725.       hadColon = 1;
  726.       ptr += MINBPC(enc);
  727.       if (ptr == end)
  728.         return XML_TOK_PARTIAL;
  729.       switch (BYTE_TYPE(enc, ptr)) {
  730.       CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
  731.       default:
  732.         *nextTokPtr = ptr;
  733.         return XML_TOK_INVALID;
  734.       }
  735.       break;
  736. #endif
  737.     case BT_S: case BT_CR: case BT_LF:
  738.       {
  739.         ptr += MINBPC(enc);
  740.         while (ptr != end) {
  741.           switch (BYTE_TYPE(enc, ptr)) {
  742.           CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
  743.           case BT_GT:
  744.             goto gt;
  745.           case BT_SOL:
  746.             goto sol;
  747.           case BT_S: case BT_CR: case BT_LF:
  748.             ptr += MINBPC(enc);
  749.             continue;
  750.           default:
  751.             *nextTokPtr = ptr;
  752.             return XML_TOK_INVALID;
  753.           }
  754.           return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
  755.         }
  756.         return XML_TOK_PARTIAL;
  757.       }
  758.     case BT_GT:
  759.     gt:
  760.       *nextTokPtr = ptr + MINBPC(enc);
  761.       return XML_TOK_START_TAG_NO_ATTS;
  762.     case BT_SOL:
  763.     sol:
  764.       ptr += MINBPC(enc);
  765.       if (ptr == end)
  766.         return XML_TOK_PARTIAL;
  767.       if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
  768.         *nextTokPtr = ptr;
  769.         return XML_TOK_INVALID;
  770.       }
  771.       *nextTokPtr = ptr + MINBPC(enc);
  772.       return XML_TOK_EMPTY_ELEMENT_NO_ATTS;
  773.     default:
  774.       *nextTokPtr = ptr;
  775.       return XML_TOK_INVALID;
  776.     }
  777.   }
  778.   return XML_TOK_PARTIAL;
  779. }
  780.  
  781. static int FASTCALL
  782. PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
  783.                    const char **nextTokPtr)
  784. {
  785.   if (ptr == end)
  786.     return XML_TOK_NONE;
  787.   if (MINBPC(enc) > 1) {
  788.     size_t n = end - ptr;
  789.     if (n & (MINBPC(enc) - 1)) {
  790.       n &= ~(MINBPC(enc) - 1);
  791.       if (n == 0)
  792.         return XML_TOK_PARTIAL;
  793.       end = ptr + n;
  794.     }
  795.   }
  796.   switch (BYTE_TYPE(enc, ptr)) {
  797.   case BT_LT:
  798.     return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr);
  799.   case BT_AMP:
  800.     return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
  801.   case BT_CR:
  802.     ptr += MINBPC(enc);
  803.     if (ptr == end)
  804.       return XML_TOK_TRAILING_CR;
  805.     if (BYTE_TYPE(enc, ptr) == BT_LF)
  806.       ptr += MINBPC(enc);
  807.     *nextTokPtr = ptr;
  808.     return XML_TOK_DATA_NEWLINE;
  809.   case BT_LF:
  810.     *nextTokPtr = ptr + MINBPC(enc);
  811.     return XML_TOK_DATA_NEWLINE;
  812.   case BT_RSQB:
  813.     ptr += MINBPC(enc);
  814.     if (ptr == end)
  815.       return XML_TOK_TRAILING_RSQB;
  816.     if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
  817.       break;
  818.     ptr += MINBPC(enc);
  819.     if (ptr == end)
  820.       return XML_TOK_TRAILING_RSQB;
  821.     if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
  822.       ptr -= MINBPC(enc);
  823.       break;
  824.     }
  825.     *nextTokPtr = ptr;
  826.     return XML_TOK_INVALID;
  827.   INVALID_CASES(ptr, nextTokPtr)
  828.   default:
  829.     ptr += MINBPC(enc);
  830.     break;
  831.   }
  832.   while (ptr != end) {
  833.     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.     LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
  843. #undef LEAD_CASE
  844.     case BT_RSQB:
  845.       if (ptr + MINBPC(enc) != end) {
  846.          if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
  847.            ptr += MINBPC(enc);
  848.            break;
  849.          }
  850.          if (ptr + 2*MINBPC(enc) != end) {
  851.            if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
  852.              ptr += MINBPC(enc);
  853.              break;
  854.            }
  855.            *nextTokPtr = ptr + 2*MINBPC(enc);
  856.            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.       *nextTokPtr = ptr;
  868.       return XML_TOK_DATA_CHARS;
  869.     default:
  870.       ptr += MINBPC(enc);
  871.       break;
  872.     }
  873.   }
  874.   *nextTokPtr = ptr;
  875.   return XML_TOK_DATA_CHARS;
  876. }
  877.  
  878. /* ptr points to character following "%" */
  879.  
  880. static int FASTCALL
  881. PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
  882.                     const char **nextTokPtr)
  883. {
  884.   if (ptr == end)
  885.     return XML_TOK_PARTIAL;
  886.   switch (BYTE_TYPE(enc, ptr)) {
  887.   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
  888.   case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
  889.     *nextTokPtr = ptr;
  890.     return XML_TOK_PERCENT;
  891.   default:
  892.     *nextTokPtr = ptr;
  893.     return XML_TOK_INVALID;
  894.   }
  895.   while (ptr != end) {
  896.     switch (BYTE_TYPE(enc, ptr)) {
  897.     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
  898.     case BT_SEMI:
  899.       *nextTokPtr = ptr + MINBPC(enc);
  900.       return XML_TOK_PARAM_ENTITY_REF;
  901.     default:
  902.       *nextTokPtr = ptr;
  903.       return XML_TOK_INVALID;
  904.     }
  905.   }
  906.   return XML_TOK_PARTIAL;
  907. }
  908.  
  909. static int FASTCALL
  910. PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
  911.                       const char **nextTokPtr)
  912. {
  913.   if (ptr == end)
  914.     return XML_TOK_PARTIAL;
  915.   switch (BYTE_TYPE(enc, ptr)) {
  916.   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
  917.   default:
  918.     *nextTokPtr = ptr;
  919.     return XML_TOK_INVALID;
  920.   }
  921.   while (ptr != end) {
  922.     switch (BYTE_TYPE(enc, ptr)) {
  923.     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.       *nextTokPtr = ptr;
  927.       return XML_TOK_POUND_NAME;
  928.     default:
  929.       *nextTokPtr = ptr;
  930.       return XML_TOK_INVALID;
  931.     }
  932.   }
  933.   return -XML_TOK_POUND_NAME;
  934. }
  935.  
  936. static int FASTCALL
  937. PREFIX(scanLit)(int open, const ENCODING *enc,
  938.                 const char *ptr, const char *end,
  939.                 const char **nextTokPtr)
  940. {
  941.   while (ptr != end) {
  942.     int t = BYTE_TYPE(enc, ptr);
  943.     switch (t) {
  944.     INVALID_CASES(ptr, nextTokPtr)
  945.     case BT_QUOT:
  946.     case BT_APOS:
  947.       ptr += MINBPC(enc);
  948.       if (t != open)
  949.         break;
  950.       if (ptr == end)
  951.         return -XML_TOK_LITERAL;
  952.       *nextTokPtr = ptr;
  953.       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.         return XML_TOK_LITERAL;
  957.       default:
  958.         return XML_TOK_INVALID;
  959.       }
  960.     default:
  961.       ptr += MINBPC(enc);
  962.       break;
  963.     }
  964.   }
  965.   return XML_TOK_PARTIAL;
  966. }
  967.  
  968. static int FASTCALL
  969. PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
  970.                   const char **nextTokPtr)
  971. {
  972.   int tok;
  973.   if (ptr == end)
  974.     return XML_TOK_NONE;
  975.   if (MINBPC(enc) > 1) {
  976.     size_t n = end - ptr;
  977.     if (n & (MINBPC(enc) - 1)) {
  978.       n &= ~(MINBPC(enc) - 1);
  979.       if (n == 0)
  980.         return XML_TOK_PARTIAL;
  981.       end = ptr + n;
  982.     }
  983.   }
  984.   switch (BYTE_TYPE(enc, ptr)) {
  985.   case BT_QUOT:
  986.     return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);
  987.   case BT_APOS:
  988.     return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);
  989.   case BT_LT:
  990.     {
  991.       ptr += MINBPC(enc);
  992.       if (ptr == end)
  993.         return XML_TOK_PARTIAL;
  994.       switch (BYTE_TYPE(enc, ptr)) {
  995.       case BT_EXCL:
  996.         return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
  997.       case BT_QUEST:
  998.         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.         *nextTokPtr = ptr - MINBPC(enc);
  1006.         return XML_TOK_INSTANCE_START;
  1007.       }
  1008.       *nextTokPtr = ptr;
  1009.       return XML_TOK_INVALID;
  1010.     }
  1011.   case BT_CR:
  1012.     if (ptr + MINBPC(enc) == end) {
  1013.       *nextTokPtr = end;
  1014.       /* indicate that this might be part of a CR/LF pair */
  1015.       return -XML_TOK_PROLOG_S;
  1016.     }
  1017.     /* fall through */
  1018.   case BT_S: case BT_LF:
  1019.     for (;;) {
  1020.       ptr += MINBPC(enc);
  1021.       if (ptr == end)
  1022.         break;
  1023.       switch (BYTE_TYPE(enc, ptr)) {
  1024.       case BT_S: case BT_LF:
  1025.         break;
  1026.       case BT_CR:
  1027.         /* don't split CR/LF pair */
  1028.         if (ptr + MINBPC(enc) != end)
  1029.           break;
  1030.         /* fall through */
  1031.       default:
  1032.         *nextTokPtr = ptr;
  1033.         return XML_TOK_PROLOG_S;
  1034.       }
  1035.     }
  1036.     *nextTokPtr = ptr;
  1037.     return XML_TOK_PROLOG_S;
  1038.   case BT_PERCNT:
  1039.     return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
  1040.   case BT_COMMA:
  1041.     *nextTokPtr = ptr + MINBPC(enc);
  1042.     return XML_TOK_COMMA;
  1043.   case BT_LSQB:
  1044.     *nextTokPtr = ptr + MINBPC(enc);
  1045.     return XML_TOK_OPEN_BRACKET;
  1046.   case BT_RSQB:
  1047.     ptr += MINBPC(enc);
  1048.     if (ptr == end)
  1049.       return -XML_TOK_CLOSE_BRACKET;
  1050.     if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
  1051.       if (ptr + MINBPC(enc) == end)
  1052.         return XML_TOK_PARTIAL;
  1053.       if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
  1054.         *nextTokPtr = ptr + 2*MINBPC(enc);
  1055.         return XML_TOK_COND_SECT_CLOSE;
  1056.       }
  1057.     }
  1058.     *nextTokPtr = ptr;
  1059.     return XML_TOK_CLOSE_BRACKET;
  1060.   case BT_LPAR:
  1061.     *nextTokPtr = ptr + MINBPC(enc);
  1062.     return XML_TOK_OPEN_PAREN;
  1063.   case BT_RPAR:
  1064.     ptr += MINBPC(enc);
  1065.     if (ptr == end)
  1066.       return -XML_TOK_CLOSE_PAREN;
  1067.     switch (BYTE_TYPE(enc, ptr)) {
  1068.     case BT_AST:
  1069.       *nextTokPtr = ptr + MINBPC(enc);
  1070.       return XML_TOK_CLOSE_PAREN_ASTERISK;
  1071.     case BT_QUEST:
  1072.       *nextTokPtr = ptr + MINBPC(enc);
  1073.       return XML_TOK_CLOSE_PAREN_QUESTION;
  1074.     case BT_PLUS:
  1075.       *nextTokPtr = ptr + MINBPC(enc);
  1076.       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.       *nextTokPtr = ptr;
  1081.       return XML_TOK_CLOSE_PAREN;
  1082.     }
  1083.     *nextTokPtr = ptr;
  1084.     return XML_TOK_INVALID;
  1085.   case BT_VERBAR:
  1086.     *nextTokPtr = ptr + MINBPC(enc);
  1087.     return XML_TOK_OR;
  1088.   case BT_GT:
  1089.     *nextTokPtr = ptr + MINBPC(enc);
  1090.     return XML_TOK_DECL_CLOSE;
  1091.   case BT_NUM:
  1092.     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.     LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
  1110. #undef LEAD_CASE
  1111.   case BT_NMSTRT:
  1112.   case BT_HEX:
  1113.     tok = XML_TOK_NAME;
  1114.     ptr += MINBPC(enc);
  1115.     break;
  1116.   case BT_DIGIT:
  1117.   case BT_NAME:
  1118.   case BT_MINUS:
  1119. #ifdef XML_NS
  1120.   case BT_COLON:
  1121. #endif
  1122.     tok = XML_TOK_NMTOKEN;
  1123.     ptr += MINBPC(enc);
  1124.     break;
  1125.   case BT_NONASCII:
  1126.     if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) {
  1127.       ptr += MINBPC(enc);
  1128.       tok = XML_TOK_NAME;
  1129.       break;
  1130.     }
  1131.     if (IS_NAME_CHAR_MINBPC(enc, ptr)) {
  1132.       ptr += MINBPC(enc);
  1133.       tok = XML_TOK_NMTOKEN;
  1134.       break;
  1135.     }
  1136.     /* fall through */
  1137.   default:
  1138.     *nextTokPtr = ptr;
  1139.     return XML_TOK_INVALID;
  1140.   }
  1141.   while (ptr != end) {
  1142.     switch (BYTE_TYPE(enc, ptr)) {
  1143.     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.       *nextTokPtr = ptr;
  1148.       return tok;
  1149. #ifdef XML_NS
  1150.     case BT_COLON:
  1151.       ptr += MINBPC(enc);
  1152.       switch (tok) {
  1153.       case XML_TOK_NAME:
  1154.         if (ptr == end)
  1155.           return XML_TOK_PARTIAL;
  1156.         tok = XML_TOK_PREFIXED_NAME;
  1157.         switch (BYTE_TYPE(enc, ptr)) {
  1158.         CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
  1159.         default:
  1160.           tok = XML_TOK_NMTOKEN;
  1161.           break;
  1162.         }
  1163.         break;
  1164.       case XML_TOK_PREFIXED_NAME:
  1165.         tok = XML_TOK_NMTOKEN;
  1166.         break;
  1167.       }
  1168.       break;
  1169. #endif
  1170.     case BT_PLUS:
  1171.       if (tok == XML_TOK_NMTOKEN)  {
  1172.         *nextTokPtr = ptr;
  1173.         return XML_TOK_INVALID;
  1174.       }
  1175.       *nextTokPtr = ptr + MINBPC(enc);
  1176.       return XML_TOK_NAME_PLUS;
  1177.     case BT_AST:
  1178.       if (tok == XML_TOK_NMTOKEN)  {
  1179.         *nextTokPtr = ptr;
  1180.         return XML_TOK_INVALID;
  1181.       }
  1182.       *nextTokPtr = ptr + MINBPC(enc);
  1183.       return XML_TOK_NAME_ASTERISK;
  1184.     case BT_QUEST:
  1185.       if (tok == XML_TOK_NMTOKEN)  {
  1186.         *nextTokPtr = ptr;
  1187.         return XML_TOK_INVALID;
  1188.       }
  1189.       *nextTokPtr = ptr + MINBPC(enc);
  1190.       return XML_TOK_NAME_QUESTION;
  1191.     default:
  1192.       *nextTokPtr = ptr;
  1193.       return XML_TOK_INVALID;
  1194.     }
  1195.   }
  1196.   return -tok;
  1197. }
  1198.  
  1199. static int FASTCALL
  1200. PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
  1201.                           const char *end, const char **nextTokPtr)
  1202. {
  1203.   const char *start;
  1204.   if (ptr == end)
  1205.     return XML_TOK_NONE;
  1206.   start = ptr;
  1207.   while (ptr != end) {
  1208.     switch (BYTE_TYPE(enc, ptr)) {
  1209. #define LEAD_CASE(n) \
  1210.     case BT_LEAD ## n: ptr += n; break;
  1211.     LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
  1212. #undef LEAD_CASE
  1213.     case BT_AMP:
  1214.       if (ptr == start)
  1215.         return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
  1216.       *nextTokPtr = ptr;
  1217.       return XML_TOK_DATA_CHARS;
  1218.     case BT_LT:
  1219.       /* this is for inside entity references */
  1220.       *nextTokPtr = ptr;
  1221.       return XML_TOK_INVALID;
  1222.     case BT_LF:
  1223.       if (ptr == start) {
  1224.         *nextTokPtr = ptr + MINBPC(enc);
  1225.         return XML_TOK_DATA_NEWLINE;
  1226.       }
  1227.       *nextTokPtr = ptr;
  1228.       return XML_TOK_DATA_CHARS;
  1229.     case BT_CR:
  1230.       if (ptr == start) {
  1231.         ptr += MINBPC(enc);
  1232.         if (ptr == end)
  1233.           return XML_TOK_TRAILING_CR;
  1234.         if (BYTE_TYPE(enc, ptr) == BT_LF)
  1235.           ptr += MINBPC(enc);
  1236.         *nextTokPtr = ptr;
  1237.         return XML_TOK_DATA_NEWLINE;
  1238.       }
  1239.       *nextTokPtr = ptr;
  1240.       return XML_TOK_DATA_CHARS;
  1241.     case BT_S:
  1242.       if (ptr == start) {
  1243.         *nextTokPtr = ptr + MINBPC(enc);
  1244.         return XML_TOK_ATTRIBUTE_VALUE_S;
  1245.       }
  1246.       *nextTokPtr = ptr;
  1247.       return XML_TOK_DATA_CHARS;
  1248.     default:
  1249.       ptr += MINBPC(enc);
  1250.       break;
  1251.     }
  1252.   }
  1253.   *nextTokPtr = ptr;
  1254.   return XML_TOK_DATA_CHARS;
  1255. }
  1256.  
  1257. static int FASTCALL
  1258. PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
  1259.                        const char *end, const char **nextTokPtr)
  1260. {
  1261.   const char *start;
  1262.   if (ptr == end)
  1263.     return XML_TOK_NONE;
  1264.   start = ptr;
  1265.   while (ptr != end) {
  1266.     switch (BYTE_TYPE(enc, ptr)) {
  1267. #define LEAD_CASE(n) \
  1268.     case BT_LEAD ## n: ptr += n; break;
  1269.     LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
  1270. #undef LEAD_CASE
  1271.     case BT_AMP:
  1272.       if (ptr == start)
  1273.         return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
  1274.       *nextTokPtr = ptr;
  1275.       return XML_TOK_DATA_CHARS;
  1276.     case BT_PERCNT:
  1277.       if (ptr == start) {
  1278.         int tok =  PREFIX(scanPercent)(enc, ptr + MINBPC(enc),
  1279.                                        end, nextTokPtr);
  1280.         return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok;
  1281.       }
  1282.       *nextTokPtr = ptr;
  1283.       return XML_TOK_DATA_CHARS;
  1284.     case BT_LF:
  1285.       if (ptr == start) {
  1286.         *nextTokPtr = ptr + MINBPC(enc);
  1287.         return XML_TOK_DATA_NEWLINE;
  1288.       }
  1289.       *nextTokPtr = ptr;
  1290.       return XML_TOK_DATA_CHARS;
  1291.     case BT_CR:
  1292.       if (ptr == start) {
  1293.         ptr += MINBPC(enc);
  1294.         if (ptr == end)
  1295.           return XML_TOK_TRAILING_CR;
  1296.         if (BYTE_TYPE(enc, ptr) == BT_LF)
  1297.           ptr += MINBPC(enc);
  1298.         *nextTokPtr = ptr;
  1299.         return XML_TOK_DATA_NEWLINE;
  1300.       }
  1301.       *nextTokPtr = ptr;
  1302.       return XML_TOK_DATA_CHARS;
  1303.     default:
  1304.       ptr += MINBPC(enc);
  1305.       break;
  1306.     }
  1307.   }
  1308.   *nextTokPtr = ptr;
  1309.   return XML_TOK_DATA_CHARS;
  1310. }
  1311.  
  1312. #ifdef XML_DTD
  1313.  
  1314. static int FASTCALL
  1315. PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,
  1316.                          const char *end, const char **nextTokPtr)
  1317. {
  1318.   int level = 0;
  1319.   if (MINBPC(enc) > 1) {
  1320.     size_t n = end - ptr;
  1321.     if (n & (MINBPC(enc) - 1)) {
  1322.       n &= ~(MINBPC(enc) - 1);
  1323.       end = ptr + n;
  1324.     }
  1325.   }
  1326.   while (ptr != end) {
  1327.     switch (BYTE_TYPE(enc, ptr)) {
  1328.     INVALID_CASES(ptr, nextTokPtr)
  1329.     case BT_LT:
  1330.       if ((ptr += MINBPC(enc)) == end)
  1331.         return XML_TOK_PARTIAL;
  1332.       if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {
  1333.         if ((ptr += MINBPC(enc)) == end)
  1334.           return XML_TOK_PARTIAL;
  1335.         if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
  1336.           ++level;
  1337.           ptr += MINBPC(enc);
  1338.         }
  1339.       }
  1340.       break;
  1341.     case BT_RSQB:
  1342.       if ((ptr += MINBPC(enc)) == end)
  1343.         return XML_TOK_PARTIAL;
  1344.       if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
  1345.         if ((ptr += MINBPC(enc)) == end)
  1346.           return XML_TOK_PARTIAL;
  1347.         if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
  1348.           ptr += MINBPC(enc);
  1349.           if (level == 0) {
  1350.             *nextTokPtr = ptr;
  1351.             return XML_TOK_IGNORE_SECT;
  1352.           }
  1353.           --level;
  1354.         }
  1355.       }
  1356.       break;
  1357.     default:
  1358.       ptr += MINBPC(enc);
  1359.       break;
  1360.     }
  1361.   }
  1362.   return XML_TOK_PARTIAL;
  1363. }
  1364.  
  1365. #endif /* XML_DTD */
  1366.  
  1367. static int FASTCALL
  1368. PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
  1369.                    const char **badPtr)
  1370. {
  1371.   ptr += MINBPC(enc);
  1372.   end -= MINBPC(enc);
  1373.   for (; ptr != end; ptr += MINBPC(enc)) {
  1374.     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.       break;
  1397.     case BT_S:
  1398.       if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) {
  1399.         *badPtr = ptr;
  1400.         return 0;
  1401.       }
  1402.       break;
  1403.     case BT_NAME:
  1404.     case BT_NMSTRT:
  1405.       if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f))
  1406.         break;
  1407.     default:
  1408.       switch (BYTE_TO_ASCII(enc, ptr)) {
  1409.       case 0x24: /* $ */
  1410.       case 0x40: /* @ */
  1411.         break;
  1412.       default:
  1413.         *badPtr = ptr;
  1414.         return 0;
  1415.       }
  1416.       break;
  1417.     }
  1418.   }
  1419.   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 FASTCALL
  1428. PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
  1429.                 int attsMax, ATTRIBUTE *atts)
  1430. {
  1431.   enum { other, inName, inValue } state = inName;
  1432.   int nAtts = 0;
  1433.   int open = 0; /* defined when state == inValue;
  1434.                    initialization just to shut up compilers */
  1435.  
  1436.   for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) {
  1437.     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.     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.       START_NAME
  1454.       break;
  1455. #undef START_NAME
  1456.     case BT_QUOT:
  1457.       if (state != inValue) {
  1458.         if (nAtts < attsMax)
  1459.           atts[nAtts].valuePtr = ptr + MINBPC(enc);
  1460.         state = inValue;
  1461.         open = BT_QUOT;
  1462.       }
  1463.       else if (open == BT_QUOT) {
  1464.         state = other;
  1465.         if (nAtts < attsMax)
  1466.           atts[nAtts].valueEnd = ptr;
  1467.         nAtts++;
  1468.       }
  1469.       break;
  1470.     case BT_APOS:
  1471.       if (state != inValue) {
  1472.         if (nAtts < attsMax)
  1473.           atts[nAtts].valuePtr = ptr + MINBPC(enc);
  1474.         state = inValue;
  1475.         open = BT_APOS;
  1476.       }
  1477.       else if (open == BT_APOS) {
  1478.         state = other;
  1479.         if (nAtts < attsMax)
  1480.           atts[nAtts].valueEnd = ptr;
  1481.         nAtts++;
  1482.       }
  1483.       break;
  1484.     case BT_AMP:
  1485.       if (nAtts < attsMax)
  1486.         atts[nAtts].normalized = 0;
  1487.       break;
  1488.     case BT_S:
  1489.       if (state == inName)
  1490.         state = other;
  1491.       else if (state == inValue
  1492.                && nAtts < attsMax
  1493.                && atts[nAtts].normalized
  1494.                && (ptr == atts[nAtts].valuePtr
  1495.                    || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE
  1496.                    || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE
  1497.                    || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
  1498.         atts[nAtts].normalized = 0;
  1499.       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.       if (state == inName)
  1504.         state = other;
  1505.       else if (state == inValue && nAtts < attsMax)
  1506.         atts[nAtts].normalized = 0;
  1507.       break;
  1508.     case BT_GT:
  1509.     case BT_SOL:
  1510.       if (state != inValue)
  1511.         return nAtts;
  1512.       break;
  1513.     default:
  1514.       break;
  1515.     }
  1516.   }
  1517.   /* not reached */
  1518. }
  1519.  
  1520. static int FASTCALL
  1521. PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
  1522. {
  1523.   int result = 0;
  1524.   /* skip &# */
  1525.   ptr += 2*MINBPC(enc);
  1526.   if (CHAR_MATCHES(enc, ptr, ASCII_x)) {
  1527.     for (ptr += MINBPC(enc);
  1528.          !CHAR_MATCHES(enc, ptr, ASCII_SEMI);
  1529.          ptr += MINBPC(enc)) {
  1530.       int c = BYTE_TO_ASCII(enc, ptr);
  1531.       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.         result <<= 4;
  1535.         result |= (c - ASCII_0);
  1536.         break;
  1537.       case ASCII_A: case ASCII_B: case ASCII_C:
  1538.       case ASCII_D: case ASCII_E: case ASCII_F:
  1539.         result <<= 4;
  1540.         result += 10 + (c - ASCII_A);
  1541.         break;
  1542.       case ASCII_a: case ASCII_b: case ASCII_c:
  1543.       case ASCII_d: case ASCII_e: case ASCII_f:
  1544.         result <<= 4;
  1545.         result += 10 + (c - ASCII_a);
  1546.         break;
  1547.       }
  1548.       if (result >= 0x110000)
  1549.         return -1;
  1550.     }
  1551.   }
  1552.   else {
  1553.     for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
  1554.       int c = BYTE_TO_ASCII(enc, ptr);
  1555.       result *= 10;
  1556.       result += (c - ASCII_0);
  1557.       if (result >= 0x110000)
  1558.         return -1;
  1559.     }
  1560.   }
  1561.   return checkCharRefNumber(result);
  1562. }
  1563.  
  1564. static int FASTCALL
  1565. PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,
  1566.                              const char *end)
  1567. {
  1568.   switch ((end - ptr)/MINBPC(enc)) {
  1569.   case 2:
  1570.     if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) {
  1571.       switch (BYTE_TO_ASCII(enc, ptr)) {
  1572.       case ASCII_l:
  1573.         return ASCII_LT;
  1574.       case ASCII_g:
  1575.         return ASCII_GT;
  1576.       }
  1577.     }
  1578.     break;
  1579.   case 3:
  1580.     if (CHAR_MATCHES(enc, ptr, ASCII_a)) {
  1581.       ptr += MINBPC(enc);
  1582.       if (CHAR_MATCHES(enc, ptr, ASCII_m)) {
  1583.         ptr += MINBPC(enc);
  1584.         if (CHAR_MATCHES(enc, ptr, ASCII_p))
  1585.           return ASCII_AMP;
  1586.       }
  1587.     }
  1588.     break;
  1589.   case 4:
  1590.     switch (BYTE_TO_ASCII(enc, ptr)) {
  1591.     case ASCII_q:
  1592.       ptr += MINBPC(enc);
  1593.       if (CHAR_MATCHES(enc, ptr, ASCII_u)) {
  1594.         ptr += MINBPC(enc);
  1595.         if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
  1596.           ptr += MINBPC(enc);
  1597.           if (CHAR_MATCHES(enc, ptr, ASCII_t))
  1598.             return ASCII_QUOT;
  1599.         }
  1600.       }
  1601.       break;
  1602.     case ASCII_a:
  1603.       ptr += MINBPC(enc);
  1604.       if (CHAR_MATCHES(enc, ptr, ASCII_p)) {
  1605.         ptr += MINBPC(enc);
  1606.         if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
  1607.           ptr += MINBPC(enc);
  1608.           if (CHAR_MATCHES(enc, ptr, ASCII_s))
  1609.             return ASCII_APOS;
  1610.         }
  1611.       }
  1612.       break;
  1613.     }
  1614.   }
  1615.   return 0;
  1616. }
  1617.  
  1618. static int FASTCALL
  1619. PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
  1620. {
  1621.   for (;;) {
  1622.     switch (BYTE_TYPE(enc, ptr1)) {
  1623. #define LEAD_CASE(n) \
  1624.     case BT_LEAD ## n: \
  1625.       if (*ptr1++ != *ptr2++) \
  1626.         return 0;
  1627.     LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2)
  1628. #undef LEAD_CASE
  1629.       /* fall through */
  1630.       if (*ptr1++ != *ptr2++)
  1631.         return 0;
  1632.       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.       if (*ptr2++ != *ptr1++)
  1643.         return 0;
  1644.       if (MINBPC(enc) > 1) {
  1645.         if (*ptr2++ != *ptr1++)
  1646.           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.       break;
  1657.     default:
  1658.       if (MINBPC(enc) == 1 && *ptr1 == *ptr2)
  1659.         return 1;
  1660.       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.         return 0;
  1674.       default:
  1675.         return 1;
  1676.       }
  1677.     }
  1678.   }
  1679.   /* not reached */
  1680. }
  1681.  
  1682. static int FASTCALL
  1683. PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
  1684.                          const char *end1, const char *ptr2)
  1685. {
  1686.   for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
  1687.     if (ptr1 == end1)
  1688.       return 0;
  1689.     if (!CHAR_MATCHES(enc, ptr1, *ptr2))
  1690.       return 0;
  1691.   }
  1692.   return ptr1 == end1;
  1693. }
  1694.  
  1695. static int FASTCALL
  1696. PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
  1697. {
  1698.   const char *start = ptr;
  1699.   for (;;) {
  1700.     switch (BYTE_TYPE(enc, ptr)) {
  1701. #define LEAD_CASE(n) \
  1702.     case BT_LEAD ## n: ptr += n; break;
  1703.     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.       ptr += MINBPC(enc);
  1715.       break;
  1716.     default:
  1717.       return ptr - start;
  1718.     }
  1719.   }
  1720. }
  1721.  
  1722. static const char * FASTCALL
  1723. PREFIX(skipS)(const ENCODING *enc, const char *ptr)
  1724. {
  1725.   for (;;) {
  1726.     switch (BYTE_TYPE(enc, ptr)) {
  1727.     case BT_LF:
  1728.     case BT_CR:
  1729.     case BT_S:
  1730.       ptr += MINBPC(enc);
  1731.       break;
  1732.     default:
  1733.       return ptr;
  1734.     }
  1735.   }
  1736. }
  1737.  
  1738. static void FASTCALL
  1739. PREFIX(updatePosition)(const ENCODING *enc,
  1740.                        const char *ptr,
  1741.                        const char *end,
  1742.                        POSITION *pos)
  1743. {
  1744.   while (ptr != end) {
  1745.     switch (BYTE_TYPE(enc, ptr)) {
  1746. #define LEAD_CASE(n) \
  1747.     case BT_LEAD ## n: \
  1748.       ptr += n; \
  1749.       break;
  1750.     LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
  1751. #undef LEAD_CASE
  1752.     case BT_LF:
  1753.       pos->columnNumber = (unsigned)-1;
  1754.       pos->lineNumber++;
  1755.       ptr += MINBPC(enc);
  1756.       break;
  1757.     case BT_CR:
  1758.       pos->lineNumber++;
  1759.       ptr += MINBPC(enc);
  1760.       if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
  1761.         ptr += MINBPC(enc);
  1762.       pos->columnNumber = (unsigned)-1;
  1763.       break;
  1764.     default:
  1765.       ptr += MINBPC(enc);
  1766.       break;
  1767.     }
  1768.     pos->columnNumber++;
  1769.   }
  1770. }
  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.