~ubuntu-branches/ubuntu/hardy/ghostscript/hardy

« back to all changes in this revision

Viewing changes to expat/lib/xmltok_impl.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2007-11-22 12:17:43 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20071122121743-cd70s3ypq0r243mp
Tags: 8.61.dfsg.1-0ubtuntu1
* New upstream release
  o Final 8.61 release
* debian/patches/09_ijs_krgb_support.dpatch: Adapted to upstream changes.
* debian/rules: Updated CUPS-related variables for "make install" calls.
* debian/rules: Remove /usr/include/ghostscript from the ghostscript
  package, they go into lings-dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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_PERCENT;
 
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 */