xmltok_impl.c
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:43k
源码类别:

Symbian

开发平台:

C/C++

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