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