Coverage Report

Created: 2025-07-11 07:06

/src/open62541/deps/yxml.c
Line
Count
Source (jump to first uncovered line)
1
/* This file is generated by yxml-gen.pl using yxml-states and yxml.c.in as input files.
2
 * It is preferable to edit those files instead of this one if you want to make a change.
3
 * The source files can be found through the homepage: https://dev.yorhel.nl/yxml */
4
5
/* Copyright (c) 2013-2014 Yoran Heling
6
7
  Permission is hereby granted, free of charge, to any person obtaining
8
  a copy of this software and associated documentation files (the
9
  "Software"), to deal in the Software without restriction, including
10
  without limitation the rights to use, copy, modify, merge, publish,
11
  distribute, sublicense, and/or sell copies of the Software, and to
12
  permit persons to whom the Software is furnished to do so, subject to
13
  the following conditions:
14
15
  The above copyright notice and this permission notice shall be included
16
  in all copies or substantial portions of the Software.
17
18
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21
  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22
  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
*/
26
27
#include "yxml.h"
28
#include <string.h>
29
30
typedef enum {
31
  YXMLS_string,
32
  YXMLS_attr0,
33
  YXMLS_attr1,
34
  YXMLS_attr2,
35
  YXMLS_attr3,
36
  YXMLS_attr4,
37
  YXMLS_cd0,
38
  YXMLS_cd1,
39
  YXMLS_cd2,
40
  YXMLS_comment0,
41
  YXMLS_comment1,
42
  YXMLS_comment2,
43
  YXMLS_comment3,
44
  YXMLS_comment4,
45
  YXMLS_dt0,
46
  YXMLS_dt1,
47
  YXMLS_dt2,
48
  YXMLS_dt3,
49
  YXMLS_dt4,
50
  YXMLS_elem0,
51
  YXMLS_elem1,
52
  YXMLS_elem2,
53
  YXMLS_elem3,
54
  YXMLS_enc0,
55
  YXMLS_enc1,
56
  YXMLS_enc2,
57
  YXMLS_enc3,
58
  YXMLS_etag0,
59
  YXMLS_etag1,
60
  YXMLS_etag2,
61
  YXMLS_init,
62
  YXMLS_le0,
63
  YXMLS_le1,
64
  YXMLS_le2,
65
  YXMLS_le3,
66
  YXMLS_lee1,
67
  YXMLS_lee2,
68
  YXMLS_leq0,
69
  YXMLS_misc0,
70
  YXMLS_misc1,
71
  YXMLS_misc2,
72
  YXMLS_misc2a,
73
  YXMLS_misc3,
74
  YXMLS_pi0,
75
  YXMLS_pi1,
76
  YXMLS_pi2,
77
  YXMLS_pi3,
78
  YXMLS_pi4,
79
  YXMLS_std0,
80
  YXMLS_std1,
81
  YXMLS_std2,
82
  YXMLS_std3,
83
  YXMLS_ver0,
84
  YXMLS_ver1,
85
  YXMLS_ver2,
86
  YXMLS_ver3,
87
  YXMLS_xmldecl0,
88
  YXMLS_xmldecl1,
89
  YXMLS_xmldecl2,
90
  YXMLS_xmldecl3,
91
  YXMLS_xmldecl4,
92
  YXMLS_xmldecl5,
93
  YXMLS_xmldecl6,
94
  YXMLS_xmldecl7,
95
  YXMLS_xmldecl8,
96
  YXMLS_xmldecl9
97
} yxml_state_t;
98
99
102M
#define yxml_isChar(c) 1
100
/* 0xd should be part of SP, too, but yxml_parse() already normalizes that into 0xa */
101
13.8M
#define yxml_isSP(c) (c == 0x20 || c == 0x09 || c == 0x0a)
102
79.8M
#define yxml_isAlpha(c) ((c|32)-'a' < 26)
103
40.0M
#define yxml_isNum(c) (c-'0' < 10)
104
2.28k
#define yxml_isHex(c) (yxml_isNum(c) || (c|32)-'a' < 6)
105
1.06k
#define yxml_isEncName(c) (yxml_isAlpha(c) || yxml_isNum(c) || c == '.' || c == '_' || c == '-')
106
72.2M
#define yxml_isNameStart(c) (yxml_isAlpha(c) || c == ':' || c == '_' || c >= 128)
107
32.3M
#define yxml_isName(c) (yxml_isNameStart(c) || yxml_isNum(c) || c == '-' || c == '.')
108
/* XXX: The valid characters are dependent on the quote char, hence the access to x->quote */
109
4.31M
#define yxml_isAttValue(c) (yxml_isChar(c) && c != x->quote && c != '<' && c != '&')
110
/* Anything between '&' and ';', the yxml_ref* functions will do further
111
 * validation. Strictly speaking, this is "yxml_isName(c) || c == '#'", but
112
 * this parser doesn't understand entities with '.', ':', etc, anwyay.  */
113
15.5k
#define yxml_isRef(c) (yxml_isNum(c) || yxml_isAlpha(c) || c == '#')
114
115
6.57k
#define INTFROM5CHARS(a, b, c, d, e) ((((uint64_t)(a))<<32) | (((uint64_t)(b))<<24) | (((uint64_t)(c))<<16) | (((uint64_t)(d))<<8) | (uint64_t)(e))
116
117
/* Set the given char value to ch (0<=ch<=255). */
118
96.4M
static inline void yxml_setchar(char *dest, unsigned ch) {
119
96.4M
  *(unsigned char *)dest = ch;
120
96.4M
}
121
122
/* Similar to yxml_setchar(), but will convert ch (any valid unicode point) to
123
 * UTF-8 and appends a '\0'. dest must have room for at least 5 bytes. */
124
3.14k
static void yxml_setutf8(char *dest, unsigned ch) {
125
3.14k
  if(ch <= 0x007F)
126
2.25k
    yxml_setchar(dest++, ch);
127
897
  else if(ch <= 0x07FF) {
128
222
    yxml_setchar(dest++, 0xC0 | (ch>>6));
129
222
    yxml_setchar(dest++, 0x80 | (ch & 0x3F));
130
675
  } else if(ch <= 0xFFFF) {
131
288
    yxml_setchar(dest++, 0xE0 | (ch>>12));
132
288
    yxml_setchar(dest++, 0x80 | ((ch>>6) & 0x3F));
133
288
    yxml_setchar(dest++, 0x80 | (ch & 0x3F));
134
387
  } else {
135
387
    yxml_setchar(dest++, 0xF0 | (ch>>18));
136
387
    yxml_setchar(dest++, 0x80 | ((ch>>12) & 0x3F));
137
387
    yxml_setchar(dest++, 0x80 | ((ch>>6) & 0x3F));
138
387
    yxml_setchar(dest++, 0x80 | (ch & 0x3F));
139
387
  }
140
3.14k
  *dest = 0;
141
3.14k
}
142
143
93.6M
static inline yxml_ret_t yxml_datacontent(yxml_t *x, unsigned ch) {
144
93.6M
  yxml_setchar(x->data, ch);
145
93.6M
  x->data[1] = 0;
146
93.6M
  return YXML_CONTENT;
147
93.6M
}
148
149
386
static inline yxml_ret_t yxml_datapi1(yxml_t *x, unsigned ch) {
150
386
  yxml_setchar(x->data, ch);
151
386
  x->data[1] = 0;
152
386
  return YXML_PICONTENT;
153
386
}
154
155
409
static inline yxml_ret_t yxml_datapi2(yxml_t *x, unsigned ch) {
156
409
  x->data[0] = '?';
157
409
  yxml_setchar(x->data+1, ch);
158
409
  x->data[2] = 0;
159
409
  return YXML_PICONTENT;
160
409
}
161
162
231
static inline yxml_ret_t yxml_datacd1(yxml_t *x, unsigned ch) {
163
231
  x->data[0] = ']';
164
231
  yxml_setchar(x->data+1, ch);
165
231
  x->data[2] = 0;
166
231
  return YXML_CONTENT;
167
231
}
168
169
230
static inline yxml_ret_t yxml_datacd2(yxml_t *x, unsigned ch) {
170
230
  x->data[0] = ']';
171
230
  x->data[1] = ']';
172
230
  yxml_setchar(x->data+2, ch);
173
230
  x->data[3] = 0;
174
230
  return YXML_CONTENT;
175
230
}
176
177
2.71M
static inline yxml_ret_t yxml_dataattr(yxml_t *x, unsigned ch) {
178
  /* Normalize attribute values according to the XML spec section 3.3.3. */
179
2.71M
  yxml_setchar(x->data, ch == 0x9 || ch == 0xa ? 0x20 : ch);
180
2.71M
  x->data[1] = 0;
181
2.71M
  return YXML_ATTRVAL;
182
2.71M
}
183
184
7.01M
static yxml_ret_t yxml_pushstack(yxml_t *x, char **res, unsigned ch) {
185
7.01M
  if(x->stacklen+2 >= x->stacksize)
186
5
    return YXML_ESTACK;
187
7.01M
  x->stacklen++;
188
7.01M
  *res = (char *)x->stack+x->stacklen;
189
7.01M
  x->stack[x->stacklen] = ch;
190
7.01M
  x->stacklen++;
191
7.01M
  x->stack[x->stacklen] = 0;
192
7.01M
  return YXML_OK;
193
7.01M
}
194
195
20.8M
static yxml_ret_t yxml_pushstackc(yxml_t *x, unsigned ch) {
196
20.8M
  if(x->stacklen+1 >= x->stacksize)
197
3
    return YXML_ESTACK;
198
20.8M
  x->stack[x->stacklen] = ch;
199
20.8M
  x->stacklen++;
200
20.8M
  x->stack[x->stacklen] = 0;
201
20.8M
  return YXML_OK;
202
20.8M
}
203
204
7.00M
static void yxml_popstack(yxml_t *x) {
205
7.00M
  do
206
34.8M
    x->stacklen--;
207
34.8M
  while(x->stack[x->stacklen]);
208
7.00M
}
209
210
5.40M
static inline yxml_ret_t yxml_elemstart  (yxml_t *x, unsigned ch) { return yxml_pushstack(x, &x->elem, ch); }
211
5.24M
static inline yxml_ret_t yxml_elemname   (yxml_t *x, unsigned ch) { return yxml_pushstackc(x, ch); }
212
5.40M
static inline yxml_ret_t yxml_elemnameend(yxml_t *x, unsigned ch) { return YXML_ELEMSTART; }
213
214
/* Also used in yxml_elemcloseend(), since this function just removes the last
215
 * element from the stack and returns ELEMEND. */
216
5.40M
static yxml_ret_t yxml_selfclose(yxml_t *x, unsigned ch) {
217
5.40M
  yxml_popstack(x);
218
5.40M
  if(x->stacklen) {
219
5.34M
    x->elem = (char *)x->stack+x->stacklen-1;
220
10.4M
    while(*(x->elem-1))
221
5.11M
      x->elem--;
222
5.34M
    return YXML_ELEMEND;
223
5.34M
  }
224
57.3k
  x->elem = (char *)x->stack;
225
57.3k
  x->state = YXMLS_misc3;
226
57.3k
  return YXML_ELEMEND;
227
5.40M
}
228
229
4.43M
static inline yxml_ret_t yxml_elemclose(yxml_t *x, unsigned ch) {
230
4.43M
  if(*((unsigned char *)x->elem) != ch)
231
99
    return YXML_ECLOSE;
232
4.43M
  x->elem++;
233
4.43M
  return YXML_OK;
234
4.43M
}
235
236
568k
static inline yxml_ret_t yxml_elemcloseend(yxml_t *x, unsigned ch) {
237
568k
  if(*x->elem)
238
8
    return YXML_ECLOSE;
239
568k
  return yxml_selfclose(x, ch);
240
568k
}
241
242
1.59M
static inline yxml_ret_t yxml_attrstart  (yxml_t *x, unsigned ch) { return yxml_pushstack(x, &x->attr, ch); }
243
15.6M
static inline yxml_ret_t yxml_attrname   (yxml_t *x, unsigned ch) { return yxml_pushstackc(x, ch); }
244
1.59M
static inline yxml_ret_t yxml_attrnameend(yxml_t *x, unsigned ch) { return YXML_ATTRSTART; }
245
1.59M
static inline yxml_ret_t yxml_attrvalend (yxml_t *x, unsigned ch) { yxml_popstack(x); return YXML_ATTREND; }
246
247
4.53k
static inline yxml_ret_t yxml_pistart  (yxml_t *x, unsigned ch) { return yxml_pushstack(x, &x->pi, ch); }
248
6.75k
static inline yxml_ret_t yxml_piname   (yxml_t *x, unsigned ch) { return yxml_pushstackc(x, ch); }
249
610
static inline yxml_ret_t yxml_piabort  (yxml_t *x, unsigned ch) { yxml_popstack(x); return YXML_OK; }
250
3.64k
static inline yxml_ret_t yxml_pinameend(yxml_t *x, unsigned ch) {
251
3.64k
  return (x->pi[0]|32) == 'x' && (x->pi[1]|32) == 'm' && (x->pi[2]|32) == 'l' && !x->pi[3] ? YXML_ESYN : YXML_PISTART;
252
3.64k
}
253
3.48k
static inline yxml_ret_t yxml_pivalend (yxml_t *x, unsigned ch) { yxml_popstack(x); x->pi = (char *)x->stack; return YXML_PIEND; }
254
255
3.45k
static inline yxml_ret_t yxml_refstart(yxml_t *x, unsigned ch) {
256
3.45k
  memset(x->data, 0, sizeof(x->data));
257
3.45k
  x->reflen = 0;
258
3.45k
  return YXML_OK;
259
3.45k
}
260
261
12.1k
static yxml_ret_t yxml_ref(yxml_t *x, unsigned ch) {
262
12.1k
  if(x->reflen >= sizeof(x->data)-1)
263
19
    return YXML_EREF;
264
12.1k
  yxml_setchar(x->data+x->reflen, ch);
265
12.1k
  x->reflen++;
266
12.1k
  return YXML_OK;
267
12.1k
}
268
269
3.34k
static yxml_ret_t yxml_refend(yxml_t *x, yxml_ret_t ret) {
270
3.34k
  unsigned char *r = (unsigned char *)x->data;
271
3.34k
  unsigned ch = 0;
272
3.34k
  if(*r == '#') {
273
1.86k
    if(r[1] == 'x')
274
2.28k
      for(r += 2; yxml_isHex((unsigned)*r); r++)
275
1.62k
        ch = (ch<<4) + (*r <= '9' ? *r-'0' : (*r|32)-'a' + 10);
276
1.20k
    else
277
4.20k
      for(r++; yxml_isNum((unsigned)*r); r++)
278
2.99k
        ch = (ch*10) + (*r-'0');
279
1.86k
    if(*r)
280
8
      ch = 0;
281
1.86k
  } else {
282
1.48k
    uint64_t i = INTFROM5CHARS(r[0], r[1], r[2], r[3], r[4]);
283
1.48k
    ch =
284
1.48k
      i == INTFROM5CHARS('l','t', 0,  0, 0) ? '<' :
285
1.48k
      i == INTFROM5CHARS('g','t', 0,  0, 0) ? '>' :
286
1.25k
      i == INTFROM5CHARS('a','m','p', 0, 0) ? '&' :
287
1.06k
      i == INTFROM5CHARS('a','p','o','s',0) ? '\'':
288
868
      i == INTFROM5CHARS('q','u','o','t',0) ? '"' : 0;
289
1.48k
  }
290
291
  /* Codepoints not allowed in the XML 1.1 definition of a Char */
292
3.34k
  if(!ch || ch > 0x10FFFF || ch == 0xFFFE || ch == 0xFFFF || (ch-0xDFFF) < 0x7FF)
293
199
    return YXML_EREF;
294
3.14k
  yxml_setutf8(x->data, ch);
295
3.14k
  return ret;
296
3.34k
}
297
298
2.46k
static inline yxml_ret_t yxml_refcontent(yxml_t *x, unsigned ch) { return yxml_refend(x, YXML_CONTENT); }
299
886
static inline yxml_ret_t yxml_refattrval(yxml_t *x, unsigned ch) { return yxml_refend(x, YXML_ATTRVAL); }
300
301
60.5k
void yxml_init(yxml_t *x, void *stack, size_t stacksize) {
302
60.5k
  memset(x, 0, sizeof(*x));
303
60.5k
  x->line = 1;
304
60.5k
  x->stack = (unsigned char*)stack;
305
60.5k
  x->stacksize = stacksize;
306
60.5k
  *x->stack = 0;
307
60.5k
  x->elem = x->pi = x->attr = (char *)x->stack;
308
60.5k
  x->state = YXMLS_init;
309
60.5k
}
310
311
153M
yxml_ret_t yxml_parse(yxml_t *x, int _ch) {
312
  /* Ensure that characters are in the range of 0..255 rather than -126..125.
313
   * All character comparisons are done with positive integers. */
314
153M
  unsigned ch = (unsigned)(_ch+256) & 0xff;
315
153M
  if(!ch)
316
4
    return YXML_ESYN;
317
153M
  x->total++;
318
319
  /* End-of-Line normalization, "\rX", "\r\n" and "\n" are recognized and
320
   * normalized to a single '\n' as per XML 1.0 section 2.11. XML 1.1 adds
321
   * some non-ASCII character sequences to this list, but we can only handle
322
   * ASCII here without making assumptions about the input encoding. */
323
153M
  if(x->ignore == ch) {
324
743
    x->ignore = 0;
325
743
    return YXML_OK;
326
743
  }
327
153M
  x->ignore = (ch == 0xd) * 0xa;
328
153M
  if(ch == 0xa || ch == 0xd) {
329
1.45M
    ch = 0xa;
330
1.45M
    x->line++;
331
1.45M
    x->byte = 0;
332
1.45M
  }
333
153M
  x->byte++;
334
335
153M
  switch((yxml_state_t)x->state) {
336
11.6k
  case YXMLS_string:
337
11.6k
    if(ch == *x->string) {
338
11.6k
      x->string++;
339
11.6k
      if(!*x->string)
340
2.19k
        x->state = x->nextstate;
341
11.6k
      return YXML_OK;
342
11.6k
    }
343
12
    break;
344
17.2M
  case YXMLS_attr0:
345
17.2M
    if(yxml_isName(ch))
346
15.6M
      return yxml_attrname(x, ch);
347
1.59M
    if(yxml_isSP(ch)) {
348
1.39M
      x->state = YXMLS_attr1;
349
1.39M
      return yxml_attrnameend(x, ch);
350
1.39M
    }
351
205k
    if(ch == (unsigned char)'=') {
352
205k
      x->state = YXMLS_attr2;
353
205k
      return yxml_attrnameend(x, ch);
354
205k
    }
355
21
    break;
356
1.39M
  case YXMLS_attr1:
357
1.39M
    if(yxml_isSP(ch))
358
748
      return YXML_OK;
359
1.39M
    if(ch == (unsigned char)'=') {
360
1.39M
      x->state = YXMLS_attr2;
361
1.39M
      return YXML_OK;
362
1.39M
    }
363
15
    break;
364
1.59M
  case YXMLS_attr2:
365
1.59M
    if(yxml_isSP(ch))
366
686
      return YXML_OK;
367
1.59M
    if(ch == (unsigned char)'\'' || ch == (unsigned char)'"') {
368
1.59M
      x->state = YXMLS_attr3;
369
1.59M
      x->quote = ch;
370
1.59M
      return YXML_OK;
371
1.59M
    }
372
17
    break;
373
4.31M
  case YXMLS_attr3:
374
4.31M
    if(yxml_isAttValue(ch))
375
2.71M
      return yxml_dataattr(x, ch);
376
1.59M
    if(ch == (unsigned char)'&') {
377
932
      x->state = YXMLS_attr4;
378
932
      return yxml_refstart(x, ch);
379
932
    }
380
1.59M
    if(x->quote == ch) {
381
1.59M
      x->state = YXMLS_elem2;
382
1.59M
      return yxml_attrvalend(x, ch);
383
1.59M
    }
384
1
    break;
385
4.13k
  case YXMLS_attr4:
386
4.13k
    if(yxml_isRef(ch))
387
3.24k
      return yxml_ref(x, ch);
388
894
    if(ch == (unsigned char)'\x3b') {
389
886
      x->state = YXMLS_attr3;
390
886
      return yxml_refattrval(x, ch);
391
886
    }
392
8
    break;
393
944
  case YXMLS_cd0:
394
944
    if(ch == (unsigned char)']') {
395
703
      x->state = YXMLS_cd1;
396
703
      return YXML_OK;
397
703
    }
398
241
    if(yxml_isChar(ch))
399
241
      return yxml_datacontent(x, ch);
400
0
    break;
401
697
  case YXMLS_cd1:
402
697
    if(ch == (unsigned char)']') {
403
466
      x->state = YXMLS_cd2;
404
466
      return YXML_OK;
405
466
    }
406
231
    if(yxml_isChar(ch)) {
407
231
      x->state = YXMLS_cd0;
408
231
      return yxml_datacd1(x, ch);
409
231
    }
410
0
    break;
411
658
  case YXMLS_cd2:
412
658
    if(ch == (unsigned char)']')
413
206
      return yxml_datacontent(x, ch);
414
452
    if(ch == (unsigned char)'>') {
415
222
      x->state = YXMLS_misc2;
416
222
      return YXML_OK;
417
222
    }
418
230
    if(yxml_isChar(ch)) {
419
230
      x->state = YXMLS_cd0;
420
230
      return yxml_datacd2(x, ch);
421
230
    }
422
0
    break;
423
208
  case YXMLS_comment0:
424
208
    if(ch == (unsigned char)'-') {
425
207
      x->state = YXMLS_comment1;
426
207
      return YXML_OK;
427
207
    }
428
1
    break;
429
1.07k
  case YXMLS_comment1:
430
1.07k
    if(ch == (unsigned char)'-') {
431
1.06k
      x->state = YXMLS_comment2;
432
1.06k
      return YXML_OK;
433
1.06k
    }
434
10
    break;
435
1.61k
  case YXMLS_comment2:
436
1.61k
    if(ch == (unsigned char)'-') {
437
1.41k
      x->state = YXMLS_comment3;
438
1.41k
      return YXML_OK;
439
1.41k
    }
440
202
    if(yxml_isChar(ch))
441
202
      return YXML_OK;
442
0
    break;
443
1.40k
  case YXMLS_comment3:
444
1.40k
    if(ch == (unsigned char)'-') {
445
1.02k
      x->state = YXMLS_comment4;
446
1.02k
      return YXML_OK;
447
1.02k
    }
448
381
    if(yxml_isChar(ch)) {
449
381
      x->state = YXMLS_comment2;
450
381
      return YXML_OK;
451
381
    }
452
0
    break;
453
1.02k
  case YXMLS_comment4:
454
1.02k
    if(ch == (unsigned char)'>') {
455
1.02k
      x->state = x->nextstate;
456
1.02k
      return YXML_OK;
457
1.02k
    }
458
1
    break;
459
1.87k
  case YXMLS_dt0:
460
1.87k
    if(ch == (unsigned char)'>') {
461
314
      x->state = YXMLS_misc1;
462
314
      return YXML_OK;
463
314
    }
464
1.55k
    if(ch == (unsigned char)'\'' || ch == (unsigned char)'"') {
465
597
      x->state = YXMLS_dt1;
466
597
      x->quote = ch;
467
597
      x->nextstate = YXMLS_dt0;
468
597
      return YXML_OK;
469
597
    }
470
962
    if(ch == (unsigned char)'<') {
471
746
      x->state = YXMLS_dt2;
472
746
      return YXML_OK;
473
746
    }
474
216
    if(yxml_isChar(ch))
475
216
      return YXML_OK;
476
0
    break;
477
1.13k
  case YXMLS_dt1:
478
1.13k
    if(x->quote == ch) {
479
938
      x->state = x->nextstate;
480
938
      return YXML_OK;
481
938
    }
482
201
    if(yxml_isChar(ch))
483
201
      return YXML_OK;
484
0
    break;
485
740
  case YXMLS_dt2:
486
740
    if(ch == (unsigned char)'?') {
487
194
      x->state = YXMLS_pi0;
488
194
      x->nextstate = YXMLS_dt0;
489
194
      return YXML_OK;
490
194
    }
491
546
    if(ch == (unsigned char)'!') {
492
544
      x->state = YXMLS_dt3;
493
544
      return YXML_OK;
494
544
    }
495
2
    break;
496
538
  case YXMLS_dt3:
497
538
    if(ch == (unsigned char)'-') {
498
194
      x->state = YXMLS_comment1;
499
194
      x->nextstate = YXMLS_dt0;
500
194
      return YXML_OK;
501
194
    }
502
344
    if(yxml_isChar(ch)) {
503
344
      x->state = YXMLS_dt4;
504
344
      return YXML_OK;
505
344
    }
506
0
    break;
507
895
  case YXMLS_dt4:
508
895
    if(ch == (unsigned char)'\'' || ch == (unsigned char)'"') {
509
388
      x->state = YXMLS_dt1;
510
388
      x->quote = ch;
511
388
      x->nextstate = YXMLS_dt4;
512
388
      return YXML_OK;
513
388
    }
514
507
    if(ch == (unsigned char)'>') {
515
311
      x->state = YXMLS_dt0;
516
311
      return YXML_OK;
517
311
    }
518
196
    if(yxml_isChar(ch))
519
196
      return YXML_OK;
520
0
    break;
521
10.6M
  case YXMLS_elem0:
522
10.6M
    if(yxml_isName(ch))
523
5.24M
      return yxml_elemname(x, ch);
524
5.40M
    if(yxml_isSP(ch)) {
525
65.7k
      x->state = YXMLS_elem1;
526
65.7k
      return yxml_elemnameend(x, ch);
527
65.7k
    }
528
5.34M
    if(ch == (unsigned char)'/') {
529
4.79M
      x->state = YXMLS_elem3;
530
4.79M
      return yxml_elemnameend(x, ch);
531
4.79M
    }
532
543k
    if(ch == (unsigned char)'>') {
533
543k
      x->state = YXMLS_misc2;
534
543k
      return yxml_elemnameend(x, ch);
535
543k
    }
536
23
    break;
537
1.60M
  case YXMLS_elem1:
538
1.60M
    if(yxml_isSP(ch))
539
873
      return YXML_OK;
540
1.60M
    if(ch == (unsigned char)'/') {
541
6.35k
      x->state = YXMLS_elem3;
542
6.35k
      return YXML_OK;
543
6.35k
    }
544
1.59M
    if(ch == (unsigned char)'>') {
545
440
      x->state = YXMLS_misc2;
546
440
      return YXML_OK;
547
440
    }
548
1.59M
    if(yxml_isNameStart(ch)) {
549
1.59M
      x->state = YXMLS_attr0;
550
1.59M
      return yxml_attrstart(x, ch);
551
1.59M
    }
552
25
    break;
553
1.59M
  case YXMLS_elem2:
554
1.59M
    if(yxml_isSP(ch)) {
555
1.54M
      x->state = YXMLS_elem1;
556
1.54M
      return YXML_OK;
557
1.54M
    }
558
58.4k
    if(ch == (unsigned char)'/') {
559
31.7k
      x->state = YXMLS_elem3;
560
31.7k
      return YXML_OK;
561
31.7k
    }
562
26.6k
    if(ch == (unsigned char)'>') {
563
26.6k
      x->state = YXMLS_misc2;
564
26.6k
      return YXML_OK;
565
26.6k
    }
566
14
    break;
567
4.83M
  case YXMLS_elem3:
568
4.83M
    if(ch == (unsigned char)'>') {
569
4.83M
      x->state = YXMLS_misc2;
570
4.83M
      return yxml_selfclose(x, ch);
571
4.83M
    }
572
7
    break;
573
775
  case YXMLS_enc0:
574
775
    if(yxml_isSP(ch))
575
582
      return YXML_OK;
576
193
    if(ch == (unsigned char)'=') {
577
185
      x->state = YXMLS_enc1;
578
185
      return YXML_OK;
579
185
    }
580
8
    break;
581
742
  case YXMLS_enc1:
582
742
    if(yxml_isSP(ch))
583
582
      return YXML_OK;
584
160
    if(ch == (unsigned char)'\'' || ch == (unsigned char)'"') {
585
149
      x->state = YXMLS_enc2;
586
149
      x->quote = ch;
587
149
      return YXML_OK;
588
149
    }
589
11
    break;
590
147
  case YXMLS_enc2:
591
147
    if(yxml_isAlpha(ch)) {
592
138
      x->state = YXMLS_enc3;
593
138
      return YXML_OK;
594
138
    }
595
9
    break;
596
1.06k
  case YXMLS_enc3:
597
1.06k
    if(yxml_isEncName(ch))
598
973
      return YXML_OK;
599
93
    if(x->quote == ch) {
600
73
      x->state = YXMLS_xmldecl6;
601
73
      return YXML_OK;
602
73
    }
603
20
    break;
604
568k
  case YXMLS_etag0:
605
568k
    if(yxml_isNameStart(ch)) {
606
568k
      x->state = YXMLS_etag1;
607
568k
      return yxml_elemclose(x, ch);
608
568k
    }
609
13
    break;
610
4.43M
  case YXMLS_etag1:
611
4.43M
    if(yxml_isName(ch))
612
3.86M
      return yxml_elemclose(x, ch);
613
568k
    if(yxml_isSP(ch)) {
614
961
      x->state = YXMLS_etag2;
615
961
      return yxml_elemcloseend(x, ch);
616
961
    }
617
567k
    if(ch == (unsigned char)'>') {
618
567k
      x->state = YXMLS_misc2;
619
567k
      return yxml_elemcloseend(x, ch);
620
567k
    }
621
21
    break;
622
1.53k
  case YXMLS_etag2:
623
1.53k
    if(yxml_isSP(ch))
624
638
      return YXML_OK;
625
896
    if(ch == (unsigned char)'>') {
626
879
      x->state = YXMLS_misc2;
627
879
      return YXML_OK;
628
879
    }
629
17
    break;
630
60.5k
  case YXMLS_init:
631
60.5k
    if(ch == (unsigned char)'\xef') {
632
18
      x->state = YXMLS_string;
633
18
      x->nextstate = YXMLS_misc0;
634
18
      x->string = (unsigned char *)"\xbb\xbf";
635
18
      return YXML_OK;
636
18
    }
637
60.5k
    if(yxml_isSP(ch)) {
638
124
      x->state = YXMLS_misc0;
639
124
      return YXML_OK;
640
124
    }
641
60.3k
    if(ch == (unsigned char)'<') {
642
60.3k
      x->state = YXMLS_le0;
643
60.3k
      return YXML_OK;
644
60.3k
    }
645
30
    break;
646
60.4k
  case YXMLS_le0:
647
60.4k
    if(ch == (unsigned char)'!') {
648
254
      x->state = YXMLS_lee1;
649
254
      return YXML_OK;
650
254
    }
651
60.1k
    if(ch == (unsigned char)'?') {
652
1.33k
      x->state = YXMLS_leq0;
653
1.33k
      return YXML_OK;
654
1.33k
    }
655
58.8k
    if(yxml_isNameStart(ch)) {
656
58.8k
      x->state = YXMLS_elem0;
657
58.8k
      return yxml_elemstart(x, ch);
658
58.8k
    }
659
21
    break;
660
2.31k
  case YXMLS_le1:
661
2.31k
    if(ch == (unsigned char)'!') {
662
731
      x->state = YXMLS_lee1;
663
731
      return YXML_OK;
664
731
    }
665
1.58k
    if(ch == (unsigned char)'?') {
666
1.32k
      x->state = YXMLS_pi0;
667
1.32k
      x->nextstate = YXMLS_misc1;
668
1.32k
      return YXML_OK;
669
1.32k
    }
670
256
    if(yxml_isNameStart(ch)) {
671
248
      x->state = YXMLS_elem0;
672
248
      return yxml_elemstart(x, ch);
673
248
    }
674
8
    break;
675
5.91M
  case YXMLS_le2:
676
5.91M
    if(ch == (unsigned char)'!') {
677
508
      x->state = YXMLS_lee2;
678
508
      return YXML_OK;
679
508
    }
680
5.91M
    if(ch == (unsigned char)'?') {
681
1.30k
      x->state = YXMLS_pi0;
682
1.30k
      x->nextstate = YXMLS_misc2;
683
1.30k
      return YXML_OK;
684
1.30k
    }
685
5.91M
    if(ch == (unsigned char)'/') {
686
568k
      x->state = YXMLS_etag0;
687
568k
      return YXML_OK;
688
568k
    }
689
5.34M
    if(yxml_isNameStart(ch)) {
690
5.34M
      x->state = YXMLS_elem0;
691
5.34M
      return yxml_elemstart(x, ch);
692
5.34M
    }
693
20
    break;
694
654
  case YXMLS_le3:
695
654
    if(ch == (unsigned char)'!') {
696
213
      x->state = YXMLS_comment0;
697
213
      x->nextstate = YXMLS_misc3;
698
213
      return YXML_OK;
699
213
    }
700
441
    if(ch == (unsigned char)'?') {
701
430
      x->state = YXMLS_pi0;
702
430
      x->nextstate = YXMLS_misc3;
703
430
      return YXML_OK;
704
430
    }
705
11
    break;
706
977
  case YXMLS_lee1:
707
977
    if(ch == (unsigned char)'-') {
708
498
      x->state = YXMLS_comment1;
709
498
      x->nextstate = YXMLS_misc1;
710
498
      return YXML_OK;
711
498
    }
712
479
    if(ch == (unsigned char)'D') {
713
464
      x->state = YXMLS_string;
714
464
      x->nextstate = YXMLS_dt0;
715
464
      x->string = (unsigned char *)"OCTYPE";
716
464
      return YXML_OK;
717
464
    }
718
15
    break;
719
503
  case YXMLS_lee2:
720
503
    if(ch == (unsigned char)'-') {
721
207
      x->state = YXMLS_comment1;
722
207
      x->nextstate = YXMLS_misc2;
723
207
      return YXML_OK;
724
207
    }
725
296
    if(ch == (unsigned char)'[') {
726
285
      x->state = YXMLS_string;
727
285
      x->nextstate = YXMLS_cd0;
728
285
      x->string = (unsigned char *)"CDATA[";
729
285
      return YXML_OK;
730
285
    }
731
11
    break;
732
1.33k
  case YXMLS_leq0:
733
1.33k
    if(ch == (unsigned char)'x') {
734
985
      x->state = YXMLS_xmldecl0;
735
985
      x->nextstate = YXMLS_misc1;
736
985
      return yxml_pistart(x, ch);
737
985
    }
738
353
    if(yxml_isNameStart(ch)) {
739
335
      x->state = YXMLS_pi1;
740
335
      x->nextstate = YXMLS_misc1;
741
335
      return yxml_pistart(x, ch);
742
335
    }
743
18
    break;
744
1.21k
  case YXMLS_misc0:
745
1.21k
    if(yxml_isSP(ch))
746
1.13k
      return YXML_OK;
747
81
    if(ch == (unsigned char)'<') {
748
61
      x->state = YXMLS_le0;
749
61
      return YXML_OK;
750
61
    }
751
20
    break;
752
3.07k
  case YXMLS_misc1:
753
3.07k
    if(yxml_isSP(ch))
754
731
      return YXML_OK;
755
2.34k
    if(ch == (unsigned char)'<') {
756
2.32k
      x->state = YXMLS_le1;
757
2.32k
      return YXML_OK;
758
2.32k
    }
759
19
    break;
760
99.6M
  case YXMLS_misc2:
761
99.6M
    if(ch == (unsigned char)'<') {
762
5.91M
      x->state = YXMLS_le2;
763
5.91M
      return YXML_OK;
764
5.91M
    }
765
93.6M
    if(ch == (unsigned char)'&') {
766
2.52k
      x->state = YXMLS_misc2a;
767
2.52k
      return yxml_refstart(x, ch);
768
2.52k
    }
769
93.6M
    if(yxml_isChar(ch))
770
93.6M
      return yxml_datacontent(x, ch);
771
0
    break;
772
11.3k
  case YXMLS_misc2a:
773
11.3k
    if(yxml_isRef(ch))
774
8.89k
      return yxml_ref(x, ch);
775
2.47k
    if(ch == (unsigned char)'\x3b') {
776
2.46k
      x->state = YXMLS_misc2;
777
2.46k
      return yxml_refcontent(x, ch);
778
2.46k
    }
779
16
    break;
780
1.26k
  case YXMLS_misc3:
781
1.26k
    if(yxml_isSP(ch))
782
582
      return YXML_OK;
783
681
    if(ch == (unsigned char)'<') {
784
660
      x->state = YXMLS_le3;
785
660
      return YXML_OK;
786
660
    }
787
21
    break;
788
3.23k
  case YXMLS_pi0:
789
3.23k
    if(yxml_isNameStart(ch)) {
790
3.21k
      x->state = YXMLS_pi1;
791
3.21k
      return yxml_pistart(x, ch);
792
3.21k
    }
793
16
    break;
794
8.49k
  case YXMLS_pi1:
795
8.49k
    if(yxml_isName(ch))
796
4.88k
      return yxml_piname(x, ch);
797
3.61k
    if(ch == (unsigned char)'?') {
798
2.38k
      x->state = YXMLS_pi4;
799
2.38k
      return yxml_pinameend(x, ch);
800
2.38k
    }
801
1.22k
    if(yxml_isSP(ch)) {
802
1.20k
      x->state = YXMLS_pi2;
803
1.20k
      return yxml_pinameend(x, ch);
804
1.20k
    }
805
21
    break;
806
1.93k
  case YXMLS_pi2:
807
1.93k
    if(ch == (unsigned char)'?') {
808
1.54k
      x->state = YXMLS_pi3;
809
1.54k
      return YXML_OK;
810
1.54k
    }
811
386
    if(yxml_isChar(ch))
812
386
      return yxml_datapi1(x, ch);
813
0
    break;
814
1.53k
  case YXMLS_pi3:
815
1.53k
    if(ch == (unsigned char)'>') {
816
1.12k
      x->state = x->nextstate;
817
1.12k
      return yxml_pivalend(x, ch);
818
1.12k
    }
819
409
    if(yxml_isChar(ch)) {
820
409
      x->state = YXMLS_pi2;
821
409
      return yxml_datapi2(x, ch);
822
409
    }
823
0
    break;
824
2.36k
  case YXMLS_pi4:
825
2.36k
    if(ch == (unsigned char)'>') {
826
2.35k
      x->state = x->nextstate;
827
2.35k
      return yxml_pivalend(x, ch);
828
2.35k
    }
829
10
    break;
830
706
  case YXMLS_std0:
831
706
    if(yxml_isSP(ch))
832
582
      return YXML_OK;
833
124
    if(ch == (unsigned char)'=') {
834
106
      x->state = YXMLS_std1;
835
106
      return YXML_OK;
836
106
    }
837
18
    break;
838
663
  case YXMLS_std1:
839
663
    if(yxml_isSP(ch))
840
582
      return YXML_OK;
841
81
    if(ch == (unsigned char)'\'' || ch == (unsigned char)'"') {
842
64
      x->state = YXMLS_std2;
843
64
      x->quote = ch;
844
64
      return YXML_OK;
845
64
    }
846
17
    break;
847
62
  case YXMLS_std2:
848
62
    if(ch == (unsigned char)'y') {
849
1
      x->state = YXMLS_string;
850
1
      x->nextstate = YXMLS_std3;
851
1
      x->string = (unsigned char *)"es";
852
1
      return YXML_OK;
853
1
    }
854
61
    if(ch == (unsigned char)'n') {
855
49
      x->state = YXMLS_string;
856
49
      x->nextstate = YXMLS_std3;
857
49
      x->string = (unsigned char *)"o";
858
49
      return YXML_OK;
859
49
    }
860
12
    break;
861
48
  case YXMLS_std3:
862
48
    if(x->quote == ch) {
863
47
      x->state = YXMLS_xmldecl8;
864
47
      return YXML_OK;
865
47
    }
866
1
    break;
867
1.12k
  case YXMLS_ver0:
868
1.12k
    if(yxml_isSP(ch))
869
582
      return YXML_OK;
870
542
    if(ch == (unsigned char)'=') {
871
523
      x->state = YXMLS_ver1;
872
523
      return YXML_OK;
873
523
    }
874
19
    break;
875
1.08k
  case YXMLS_ver1:
876
1.08k
    if(yxml_isSP(ch))
877
582
      return YXML_OK;
878
498
    if(ch == (unsigned char)'\'' || ch == (unsigned char)'"') {
879
483
      x->state = YXMLS_string;
880
483
      x->quote = ch;
881
483
      x->nextstate = YXMLS_ver2;
882
483
      x->string = (unsigned char *)"1.";
883
483
      return YXML_OK;
884
483
    }
885
15
    break;
886
480
  case YXMLS_ver2:
887
480
    if(yxml_isNum(ch)) {
888
470
      x->state = YXMLS_ver3;
889
470
      return YXML_OK;
890
470
    }
891
10
    break;
892
652
  case YXMLS_ver3:
893
652
    if(yxml_isNum(ch))
894
197
      return YXML_OK;
895
455
    if(x->quote == ch) {
896
442
      x->state = YXMLS_xmldecl4;
897
442
      return YXML_OK;
898
442
    }
899
13
    break;
900
984
  case YXMLS_xmldecl0:
901
984
    if(ch == (unsigned char)'m') {
902
862
      x->state = YXMLS_xmldecl1;
903
862
      return yxml_piname(x, ch);
904
862
    }
905
122
    if(yxml_isName(ch)) {
906
59
      x->state = YXMLS_pi1;
907
59
      return yxml_piname(x, ch);
908
59
    }
909
63
    if(ch == (unsigned char)'?') {
910
17
      x->state = YXMLS_pi4;
911
17
      return yxml_pinameend(x, ch);
912
17
    }
913
46
    if(yxml_isSP(ch)) {
914
21
      x->state = YXMLS_pi2;
915
21
      return yxml_pinameend(x, ch);
916
21
    }
917
25
    break;
918
861
  case YXMLS_xmldecl1:
919
861
    if(ch == (unsigned char)'l') {
920
761
      x->state = YXMLS_xmldecl2;
921
761
      return yxml_piname(x, ch);
922
761
    }
923
100
    if(yxml_isName(ch)) {
924
63
      x->state = YXMLS_pi1;
925
63
      return yxml_piname(x, ch);
926
63
    }
927
37
    if(ch == (unsigned char)'?') {
928
3
      x->state = YXMLS_pi4;
929
3
      return yxml_pinameend(x, ch);
930
3
    }
931
34
    if(yxml_isSP(ch)) {
932
9
      x->state = YXMLS_pi2;
933
9
      return yxml_pinameend(x, ch);
934
9
    }
935
25
    break;
936
760
  case YXMLS_xmldecl2:
937
760
    if(yxml_isSP(ch)) {
938
610
      x->state = YXMLS_xmldecl3;
939
610
      return yxml_piabort(x, ch);
940
610
    }
941
150
    if(yxml_isName(ch)) {
942
128
      x->state = YXMLS_pi1;
943
128
      return yxml_piname(x, ch);
944
128
    }
945
22
    break;
946
1.16k
  case YXMLS_xmldecl3:
947
1.16k
    if(yxml_isSP(ch))
948
582
      return YXML_OK;
949
583
    if(ch == (unsigned char)'v') {
950
569
      x->state = YXMLS_string;
951
569
      x->nextstate = YXMLS_ver0;
952
569
      x->string = (unsigned char *)"ersion";
953
569
      return YXML_OK;
954
569
    }
955
14
    break;
956
441
  case YXMLS_xmldecl4:
957
441
    if(yxml_isSP(ch)) {
958
414
      x->state = YXMLS_xmldecl5;
959
414
      return YXML_OK;
960
414
    }
961
27
    if(ch == (unsigned char)'?') {
962
10
      x->state = YXMLS_xmldecl9;
963
10
      return YXML_OK;
964
10
    }
965
17
    break;
966
969
  case YXMLS_xmldecl5:
967
969
    if(yxml_isSP(ch))
968
582
      return YXML_OK;
969
387
    if(ch == (unsigned char)'?') {
970
7
      x->state = YXMLS_xmldecl9;
971
7
      return YXML_OK;
972
7
    }
973
380
    if(ch == (unsigned char)'e') {
974
218
      x->state = YXMLS_string;
975
218
      x->nextstate = YXMLS_enc0;
976
218
      x->string = (unsigned char *)"ncoding";
977
218
      return YXML_OK;
978
218
    }
979
162
    if(ch == (unsigned char)'s') {
980
147
      x->state = YXMLS_string;
981
147
      x->nextstate = YXMLS_std0;
982
147
      x->string = (unsigned char *)"tandalone";
983
147
      return YXML_OK;
984
147
    }
985
15
    break;
986
72
  case YXMLS_xmldecl6:
987
72
    if(yxml_isSP(ch)) {
988
53
      x->state = YXMLS_xmldecl7;
989
53
      return YXML_OK;
990
53
    }
991
19
    if(ch == (unsigned char)'?') {
992
5
      x->state = YXMLS_xmldecl9;
993
5
      return YXML_OK;
994
5
    }
995
14
    break;
996
608
  case YXMLS_xmldecl7:
997
608
    if(yxml_isSP(ch))
998
582
      return YXML_OK;
999
26
    if(ch == (unsigned char)'?') {
1000
7
      x->state = YXMLS_xmldecl9;
1001
7
      return YXML_OK;
1002
7
    }
1003
19
    if(ch == (unsigned char)'s') {
1004
3
      x->state = YXMLS_string;
1005
3
      x->nextstate = YXMLS_std0;
1006
3
      x->string = (unsigned char *)"tandalone";
1007
3
      return YXML_OK;
1008
3
    }
1009
16
    break;
1010
606
  case YXMLS_xmldecl8:
1011
606
    if(yxml_isSP(ch))
1012
584
      return YXML_OK;
1013
22
    if(ch == (unsigned char)'?') {
1014
7
      x->state = YXMLS_xmldecl9;
1015
7
      return YXML_OK;
1016
7
    }
1017
15
    break;
1018
31
  case YXMLS_xmldecl9:
1019
31
    if(ch == (unsigned char)'>') {
1020
30
      x->state = YXMLS_misc1;
1021
30
      return YXML_OK;
1022
30
    }
1023
1
    break;
1024
153M
  }
1025
782
  return YXML_ESYN;
1026
153M
}
1027
1028
59.3k
yxml_ret_t yxml_eof(yxml_t *x) {
1029
59.3k
  if(x->state != YXMLS_misc3)
1030
2.10k
    return YXML_EEOF;
1031
57.2k
  return YXML_OK;
1032
59.3k
}
1033