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