Coverage Report

Created: 2026-03-31 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/open62541/deps/yxml.c
Line
Count
Source
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
164M
#define yxml_isChar(c) 1
100
/* 0xd should be part of SP, too, but yxml_parse() already normalizes that into 0xa */
101
34.8M
#define yxml_isSP(c) (c == 0x20 || c == 0x09 || c == 0x0a)
102
182M
#define yxml_isAlpha(c) ((c|32)-'a' < 26)
103
91.4M
#define yxml_isNum(c) (c-'0' < 10)
104
2.31k
#define yxml_isHex(c) (yxml_isNum(c) || (c|32)-'a' < 6)
105
1.07k
#define yxml_isEncName(c) (yxml_isAlpha(c) || yxml_isNum(c) || c == '.' || c == '_' || c == '-')
106
169M
#define yxml_isNameStart(c) (yxml_isAlpha(c) || c == ':' || c == '_' || c >= 128)
107
78.4M
#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
9.99M
#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
14.8k
#define yxml_isRef(c) (yxml_isNum(c) || yxml_isAlpha(c) || c == '#')
114
115
5.30k
#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
148M
static inline void yxml_setchar(char *dest, unsigned ch) {
119
148M
  *(unsigned char *)dest = (unsigned char)ch;
120
148M
}
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.05k
static void yxml_setutf8(char *dest, unsigned ch) {
125
3.05k
  if(ch <= 0x007F)
126
2.14k
    yxml_setchar(dest++, ch);
127
917
  else if(ch <= 0x07FF) {
128
222
    yxml_setchar(dest++, 0xC0 | (ch>>6));
129
222
    yxml_setchar(dest++, 0x80 | (ch & 0x3F));
130
695
  } else if(ch <= 0xFFFF) {
131
292
    yxml_setchar(dest++, 0xE0 | (ch>>12));
132
292
    yxml_setchar(dest++, 0x80 | ((ch>>6) & 0x3F));
133
292
    yxml_setchar(dest++, 0x80 | (ch & 0x3F));
134
403
  } else {
135
403
    yxml_setchar(dest++, 0xF0 | (ch>>18));
136
403
    yxml_setchar(dest++, 0x80 | ((ch>>12) & 0x3F));
137
403
    yxml_setchar(dest++, 0x80 | ((ch>>6) & 0x3F));
138
403
    yxml_setchar(dest++, 0x80 | (ch & 0x3F));
139
403
  }
140
3.05k
  *dest = 0;
141
3.05k
}
142
143
144M
static inline yxml_ret_t yxml_datacontent(yxml_t *x, unsigned ch) {
144
144M
  yxml_setchar(x->data, ch);
145
144M
  x->data[1] = 0;
146
144M
  return YXML_CONTENT;
147
144M
}
148
149
103k
static inline yxml_ret_t yxml_datapi1(yxml_t *x, unsigned ch) {
150
103k
  yxml_setchar(x->data, ch);
151
103k
  x->data[1] = 0;
152
103k
  return YXML_PICONTENT;
153
103k
}
154
155
457
static inline yxml_ret_t yxml_datapi2(yxml_t *x, unsigned ch) {
156
457
  x->data[0] = '?';
157
457
  yxml_setchar(x->data+1, ch);
158
457
  x->data[2] = 0;
159
457
  return YXML_PICONTENT;
160
457
}
161
162
250
static inline yxml_ret_t yxml_datacd1(yxml_t *x, unsigned ch) {
163
250
  x->data[0] = ']';
164
250
  yxml_setchar(x->data+1, ch);
165
250
  x->data[2] = 0;
166
250
  return YXML_CONTENT;
167
250
}
168
169
300
static inline yxml_ret_t yxml_datacd2(yxml_t *x, unsigned ch) {
170
300
  x->data[0] = ']';
171
300
  x->data[1] = ']';
172
300
  yxml_setchar(x->data+2, ch);
173
300
  x->data[3] = 0;
174
300
  return YXML_CONTENT;
175
300
}
176
177
4.19M
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
4.19M
  yxml_setchar(x->data, ch == 0x9 || ch == 0xa ? 0x20 : ch);
180
4.19M
  x->data[1] = 0;
181
4.19M
  return YXML_ATTRVAL;
182
4.19M
}
183
184
12.0M
static yxml_ret_t yxml_pushstack(yxml_t *x, char **res, unsigned ch) {
185
12.0M
  if(x->stacklen+2 >= x->stacksize)
186
4
    return YXML_ESTACK;
187
12.0M
  x->stacklen++;
188
12.0M
  *res = (char *)x->stack+x->stacklen;
189
12.0M
  x->stack[x->stacklen] = (unsigned char)ch;
190
12.0M
  x->stacklen++;
191
12.0M
  x->stack[x->stacklen] = 0;
192
12.0M
  return YXML_OK;
193
12.0M
}
194
195
59.9M
static yxml_ret_t yxml_pushstackc(yxml_t *x, unsigned ch) {
196
59.9M
  if(x->stacklen+1 >= x->stacksize)
197
3
    return YXML_ESTACK;
198
59.9M
  x->stack[x->stacklen] = (unsigned char)ch;
199
59.9M
  x->stacklen++;
200
59.9M
  x->stack[x->stacklen] = 0;
201
59.9M
  return YXML_OK;
202
59.9M
}
203
204
12.0M
static void yxml_popstack(yxml_t *x) {
205
12.0M
  do
206
83.9M
    x->stacklen--;
207
83.9M
  while(x->stack[x->stacklen]);
208
12.0M
}
209
210
6.23M
static inline yxml_ret_t yxml_elemstart  (yxml_t *x, unsigned ch) { return yxml_pushstack(x, &x->elem, ch); }
211
7.40M
static inline yxml_ret_t yxml_elemname   (yxml_t *x, unsigned ch) { return yxml_pushstackc(x, ch); }
212
6.23M
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
6.23M
static yxml_ret_t yxml_selfclose(yxml_t *x, unsigned ch) {
217
6.23M
  yxml_popstack(x);
218
6.23M
  if(x->stacklen) {
219
6.14M
    x->elem = (char *)x->stack+x->stacklen-1;
220
17.4M
    while(*(x->elem-1))
221
11.3M
      x->elem--;
222
6.14M
    return YXML_ELEMEND;
223
6.14M
  }
224
85.3k
  x->elem = (char *)x->stack;
225
85.3k
  x->state = YXMLS_misc3;
226
85.3k
  return YXML_ELEMEND;
227
6.23M
}
228
229
6.46M
static inline yxml_ret_t yxml_elemclose(yxml_t *x, unsigned ch) {
230
6.46M
  if(*((unsigned char *)x->elem) != ch)
231
94
    return YXML_ECLOSE;
232
6.46M
  x->elem++;
233
6.46M
  return YXML_OK;
234
6.46M
}
235
236
791k
static inline yxml_ret_t yxml_elemcloseend(yxml_t *x, unsigned ch) {
237
791k
  if(*x->elem)
238
8
    return YXML_ECLOSE;
239
791k
  return yxml_selfclose(x, ch);
240
791k
}
241
242
5.79M
static inline yxml_ret_t yxml_attrstart  (yxml_t *x, unsigned ch) { return yxml_pushstack(x, &x->attr, ch); }
243
52.5M
static inline yxml_ret_t yxml_attrname   (yxml_t *x, unsigned ch) { return yxml_pushstackc(x, ch); }
244
5.79M
static inline yxml_ret_t yxml_attrnameend(yxml_t *x, unsigned ch) { return YXML_ATTRSTART; }
245
5.79M
static inline yxml_ret_t yxml_attrvalend (yxml_t *x, unsigned ch) { yxml_popstack(x); return YXML_ATTREND; }
246
247
4.56k
static inline yxml_ret_t yxml_pistart  (yxml_t *x, unsigned ch) { return yxml_pushstack(x, &x->pi, ch); }
248
5.91k
static inline yxml_ret_t yxml_piname   (yxml_t *x, unsigned ch) { return yxml_pushstackc(x, ch); }
249
625
static inline yxml_ret_t yxml_piabort  (yxml_t *x, unsigned ch) { yxml_popstack(x); return YXML_OK; }
250
3.66k
static inline yxml_ret_t yxml_pinameend(yxml_t *x, unsigned ch) {
251
3.66k
  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.66k
}
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.37k
static inline yxml_ret_t yxml_refstart(yxml_t *x, unsigned ch) {
256
3.37k
  memset(x->data, 0, sizeof(x->data));
257
3.37k
  x->reflen = 0;
258
3.37k
  return YXML_OK;
259
3.37k
}
260
261
11.5k
static yxml_ret_t yxml_ref(yxml_t *x, unsigned ch) {
262
11.5k
  if(x->reflen >= sizeof(x->data)-1)
263
20
    return YXML_EREF;
264
11.4k
  yxml_setchar(x->data+x->reflen, ch);
265
11.4k
  x->reflen++;
266
11.4k
  return YXML_OK;
267
11.5k
}
268
269
3.25k
static yxml_ret_t yxml_refend(yxml_t *x, yxml_ret_t ret) {
270
3.25k
  unsigned char *r = (unsigned char *)x->data;
271
3.25k
  unsigned ch = 0;
272
3.25k
  if(*r == '#') {
273
2.02k
    if(r[1] == 'x')
274
2.31k
      for(r += 2; yxml_isHex((unsigned)*r); r++)
275
1.64k
        ch = (ch<<4) + (*r <= '9' ? *r-'0' : (*r|32)-'a' + 10);
276
1.35k
    else
277
4.56k
      for(r++; yxml_isNum((unsigned)*r); r++)
278
3.20k
        ch = (ch*10) + (*r-'0');
279
2.02k
    if(*r)
280
10
      ch = 0;
281
2.02k
  } else {
282
1.23k
    uint64_t i = INTFROM5CHARS(r[0], r[1], r[2], r[3], r[4]);
283
1.23k
    ch =
284
1.23k
      i == INTFROM5CHARS('l','t', 0,  0, 0) ? '<' :
285
1.23k
      i == INTFROM5CHARS('g','t', 0,  0, 0) ? '>' :
286
1.00k
      i == INTFROM5CHARS('a','m','p', 0, 0) ? '&' :
287
807
      i == INTFROM5CHARS('a','p','o','s',0) ? '\'':
288
613
      i == INTFROM5CHARS('q','u','o','t',0) ? '"' : 0;
289
1.23k
  }
290
291
  /* Codepoints not allowed in the XML 1.1 definition of a Char */
292
3.25k
  if(!ch || ch > 0x10FFFF || ch == 0xFFFE || ch == 0xFFFF || (ch-0xDFFF) < 0x7FF)
293
198
    return YXML_EREF;
294
3.05k
  yxml_setutf8(x->data, ch);
295
3.05k
  return ret;
296
3.25k
}
297
298
2.50k
static inline yxml_ret_t yxml_refcontent(yxml_t *x, unsigned ch) { return yxml_refend(x, YXML_CONTENT); }
299
750
static inline yxml_ret_t yxml_refattrval(yxml_t *x, unsigned ch) { return yxml_refend(x, YXML_ATTRVAL); }
300
301
88.6k
void yxml_init(yxml_t *x, void *stack, size_t stacksize) {
302
88.6k
  memset(x, 0, sizeof(*x));
303
88.6k
  x->line = 1;
304
88.6k
  x->stack = (unsigned char*)stack;
305
88.6k
  x->stacksize = stacksize;
306
88.6k
  *x->stack = 0;
307
88.6k
  x->elem = x->pi = x->attr = (char *)x->stack;
308
88.6k
  x->state = YXMLS_init;
309
88.6k
}
310
311
274M
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
274M
  unsigned ch = (unsigned)(_ch+256) & 0xff;
315
274M
  if(!ch)
316
5
    return YXML_ESYN;
317
274M
  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
274M
  if(x->ignore == ch) {
324
1.08k
    x->ignore = 0;
325
1.08k
    return YXML_OK;
326
1.08k
  }
327
274M
  x->ignore = (ch == 0xd) * 0xa;
328
274M
  if(ch == 0xa || ch == 0xd) {
329
5.07M
    ch = 0xa;
330
5.07M
    x->line++;
331
5.07M
    x->byte = 0;
332
5.07M
  }
333
274M
  x->byte++;
334
335
274M
  switch((yxml_state_t)x->state) {
336
12.1k
  case YXMLS_string:
337
12.1k
    if(ch == *x->string) {
338
12.1k
      x->string++;
339
12.1k
      if(!*x->string)
340
2.28k
        x->state = x->nextstate;
341
12.1k
      return YXML_OK;
342
12.1k
    }
343
12
    break;
344
58.3M
  case YXMLS_attr0:
345
58.3M
    if(yxml_isName(ch))
346
52.5M
      return yxml_attrname(x, ch);
347
5.79M
    if(yxml_isSP(ch)) {
348
4.48M
      x->state = YXMLS_attr1;
349
4.48M
      return yxml_attrnameend(x, ch);
350
4.48M
    }
351
1.30M
    if(ch == (unsigned char)'=') {
352
1.30M
      x->state = YXMLS_attr2;
353
1.30M
      return yxml_attrnameend(x, ch);
354
1.30M
    }
355
25
    break;
356
4.48M
  case YXMLS_attr1:
357
4.48M
    if(yxml_isSP(ch))
358
701
      return YXML_OK;
359
4.48M
    if(ch == (unsigned char)'=') {
360
4.48M
      x->state = YXMLS_attr2;
361
4.48M
      return YXML_OK;
362
4.48M
    }
363
13
    break;
364
5.79M
  case YXMLS_attr2:
365
5.79M
    if(yxml_isSP(ch))
366
696
      return YXML_OK;
367
5.79M
    if(ch == (unsigned char)'\'' || ch == (unsigned char)'"') {
368
5.79M
      x->state = YXMLS_attr3;
369
5.79M
      x->quote = ch;
370
5.79M
      return YXML_OK;
371
5.79M
    }
372
18
    break;
373
9.99M
  case YXMLS_attr3:
374
9.99M
    if(yxml_isAttValue(ch))
375
4.19M
      return yxml_dataattr(x, ch);
376
5.79M
    if(ch == (unsigned char)'&') {
377
807
      x->state = YXMLS_attr4;
378
807
      return yxml_refstart(x, ch);
379
807
    }
380
5.79M
    if(x->quote == ch) {
381
5.79M
      x->state = YXMLS_elem2;
382
5.79M
      return yxml_attrvalend(x, ch);
383
5.79M
    }
384
1
    break;
385
3.23k
  case YXMLS_attr4:
386
3.23k
    if(yxml_isRef(ch))
387
2.47k
      return yxml_ref(x, ch);
388
765
    if(ch == (unsigned char)'\x3b') {
389
750
      x->state = YXMLS_attr3;
390
750
      return yxml_refattrval(x, ch);
391
750
    }
392
15
    break;
393
3.73k
  case YXMLS_cd0:
394
3.73k
    if(ch == (unsigned char)']') {
395
837
      x->state = YXMLS_cd1;
396
837
      return YXML_OK;
397
837
    }
398
2.90k
    if(yxml_isChar(ch))
399
2.90k
      return yxml_datacontent(x, ch);
400
0
    break;
401
831
  case YXMLS_cd1:
402
831
    if(ch == (unsigned char)']') {
403
581
      x->state = YXMLS_cd2;
404
581
      return YXML_OK;
405
581
    }
406
250
    if(yxml_isChar(ch)) {
407
250
      x->state = YXMLS_cd0;
408
250
      return yxml_datacd1(x, ch);
409
250
    }
410
0
    break;
411
857
  case YXMLS_cd2:
412
857
    if(ch == (unsigned char)']')
413
290
      return yxml_datacontent(x, ch);
414
567
    if(ch == (unsigned char)'>') {
415
267
      x->state = YXMLS_misc2;
416
267
      return YXML_OK;
417
267
    }
418
300
    if(yxml_isChar(ch)) {
419
300
      x->state = YXMLS_cd0;
420
300
      return yxml_datacd2(x, ch);
421
300
    }
422
0
    break;
423
218
  case YXMLS_comment0:
424
218
    if(ch == (unsigned char)'-') {
425
207
      x->state = YXMLS_comment1;
426
207
      return YXML_OK;
427
207
    }
428
11
    break;
429
1.10k
  case YXMLS_comment1:
430
1.10k
    if(ch == (unsigned char)'-') {
431
1.08k
      x->state = YXMLS_comment2;
432
1.08k
      return YXML_OK;
433
1.08k
    }
434
12
    break;
435
1.87k
  case YXMLS_comment2:
436
1.87k
    if(ch == (unsigned char)'-') {
437
1.43k
      x->state = YXMLS_comment3;
438
1.43k
      return YXML_OK;
439
1.43k
    }
440
438
    if(yxml_isChar(ch))
441
438
      return YXML_OK;
442
0
    break;
443
1.42k
  case YXMLS_comment3:
444
1.42k
    if(ch == (unsigned char)'-') {
445
1.03k
      x->state = YXMLS_comment4;
446
1.03k
      return YXML_OK;
447
1.03k
    }
448
388
    if(yxml_isChar(ch)) {
449
388
      x->state = YXMLS_comment2;
450
388
      return YXML_OK;
451
388
    }
452
0
    break;
453
1.03k
  case YXMLS_comment4:
454
1.03k
    if(ch == (unsigned char)'>') {
455
1.02k
      x->state = x->nextstate;
456
1.02k
      return YXML_OK;
457
1.02k
    }
458
10
    break;
459
1.89k
  case YXMLS_dt0:
460
1.89k
    if(ch == (unsigned char)'>') {
461
314
      x->state = YXMLS_misc1;
462
314
      return YXML_OK;
463
314
    }
464
1.58k
    if(ch == (unsigned char)'\'' || ch == (unsigned char)'"') {
465
598
      x->state = YXMLS_dt1;
466
598
      x->quote = ch;
467
598
      x->nextstate = YXMLS_dt0;
468
598
      return YXML_OK;
469
598
    }
470
982
    if(ch == (unsigned char)'<') {
471
763
      x->state = YXMLS_dt2;
472
763
      return YXML_OK;
473
763
    }
474
219
    if(yxml_isChar(ch))
475
219
      return YXML_OK;
476
0
    break;
477
1.14k
  case YXMLS_dt1:
478
1.14k
    if(x->quote == ch) {
479
938
      x->state = x->nextstate;
480
938
      return YXML_OK;
481
938
    }
482
202
    if(yxml_isChar(ch))
483
202
      return YXML_OK;
484
0
    break;
485
757
  case YXMLS_dt2:
486
757
    if(ch == (unsigned char)'?') {
487
194
      x->state = YXMLS_pi0;
488
194
      x->nextstate = YXMLS_dt0;
489
194
      return YXML_OK;
490
194
    }
491
563
    if(ch == (unsigned char)'!') {
492
560
      x->state = YXMLS_dt3;
493
560
      return YXML_OK;
494
560
    }
495
3
    break;
496
554
  case YXMLS_dt3:
497
554
    if(ch == (unsigned char)'-') {
498
194
      x->state = YXMLS_comment1;
499
194
      x->nextstate = YXMLS_dt0;
500
194
      return YXML_OK;
501
194
    }
502
360
    if(yxml_isChar(ch)) {
503
360
      x->state = YXMLS_dt4;
504
360
      return YXML_OK;
505
360
    }
506
0
    break;
507
903
  case YXMLS_dt4:
508
903
    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
515
    if(ch == (unsigned char)'>') {
515
311
      x->state = YXMLS_dt0;
516
311
      return YXML_OK;
517
311
    }
518
204
    if(yxml_isChar(ch))
519
204
      return YXML_OK;
520
0
    break;
521
13.6M
  case YXMLS_elem0:
522
13.6M
    if(yxml_isName(ch))
523
7.40M
      return yxml_elemname(x, ch);
524
6.23M
    if(yxml_isSP(ch)) {
525
88.1k
      x->state = YXMLS_elem1;
526
88.1k
      return yxml_elemnameend(x, ch);
527
88.1k
    }
528
6.14M
    if(ch == (unsigned char)'/') {
529
5.39M
      x->state = YXMLS_elem3;
530
5.39M
      return yxml_elemnameend(x, ch);
531
5.39M
    }
532
754k
    if(ch == (unsigned char)'>') {
533
754k
      x->state = YXMLS_misc2;
534
754k
      return yxml_elemnameend(x, ch);
535
754k
    }
536
26
    break;
537
5.79M
  case YXMLS_elem1:
538
5.79M
    if(yxml_isSP(ch))
539
1.82k
      return YXML_OK;
540
5.79M
    if(ch == (unsigned char)'/') {
541
1.85k
      x->state = YXMLS_elem3;
542
1.85k
      return YXML_OK;
543
1.85k
    }
544
5.79M
    if(ch == (unsigned char)'>') {
545
485
      x->state = YXMLS_misc2;
546
485
      return YXML_OK;
547
485
    }
548
5.79M
    if(yxml_isNameStart(ch)) {
549
5.79M
      x->state = YXMLS_attr0;
550
5.79M
      return yxml_attrstart(x, ch);
551
5.79M
    }
552
29
    break;
553
5.79M
  case YXMLS_elem2:
554
5.79M
    if(yxml_isSP(ch)) {
555
5.70M
      x->state = YXMLS_elem1;
556
5.70M
      return YXML_OK;
557
5.70M
    }
558
85.2k
    if(ch == (unsigned char)'/') {
559
46.2k
      x->state = YXMLS_elem3;
560
46.2k
      return YXML_OK;
561
46.2k
    }
562
38.9k
    if(ch == (unsigned char)'>') {
563
38.9k
      x->state = YXMLS_misc2;
564
38.9k
      return YXML_OK;
565
38.9k
    }
566
13
    break;
567
5.44M
  case YXMLS_elem3:
568
5.44M
    if(ch == (unsigned char)'>') {
569
5.44M
      x->state = YXMLS_misc2;
570
5.44M
      return yxml_selfclose(x, ch);
571
5.44M
    }
572
7
    break;
573
788
  case YXMLS_enc0:
574
788
    if(yxml_isSP(ch))
575
583
      return YXML_OK;
576
205
    if(ch == (unsigned char)'=') {
577
190
      x->state = YXMLS_enc1;
578
190
      return YXML_OK;
579
190
    }
580
15
    break;
581
748
  case YXMLS_enc1:
582
748
    if(yxml_isSP(ch))
583
583
      return YXML_OK;
584
165
    if(ch == (unsigned char)'\'' || ch == (unsigned char)'"') {
585
150
      x->state = YXMLS_enc2;
586
150
      x->quote = ch;
587
150
      return YXML_OK;
588
150
    }
589
15
    break;
590
148
  case YXMLS_enc2:
591
148
    if(yxml_isAlpha(ch)) {
592
139
      x->state = YXMLS_enc3;
593
139
      return YXML_OK;
594
139
    }
595
9
    break;
596
1.07k
  case YXMLS_enc3:
597
1.07k
    if(yxml_isEncName(ch))
598
981
      return YXML_OK;
599
92
    if(x->quote == ch) {
600
77
      x->state = YXMLS_xmldecl6;
601
77
      return YXML_OK;
602
77
    }
603
15
    break;
604
791k
  case YXMLS_etag0:
605
791k
    if(yxml_isNameStart(ch)) {
606
791k
      x->state = YXMLS_etag1;
607
791k
      return yxml_elemclose(x, ch);
608
791k
    }
609
14
    break;
610
6.46M
  case YXMLS_etag1:
611
6.46M
    if(yxml_isName(ch))
612
5.67M
      return yxml_elemclose(x, ch);
613
791k
    if(yxml_isSP(ch)) {
614
846
      x->state = YXMLS_etag2;
615
846
      return yxml_elemcloseend(x, ch);
616
846
    }
617
790k
    if(ch == (unsigned char)'>') {
618
790k
      x->state = YXMLS_misc2;
619
790k
      return yxml_elemcloseend(x, ch);
620
790k
    }
621
21
    break;
622
1.42k
  case YXMLS_etag2:
623
1.42k
    if(yxml_isSP(ch))
624
632
      return YXML_OK;
625
796
    if(ch == (unsigned char)'>') {
626
782
      x->state = YXMLS_misc2;
627
782
      return YXML_OK;
628
782
    }
629
14
    break;
630
88.6k
  case YXMLS_init:
631
88.6k
    if(ch == (unsigned char)'\xef') {
632
20
      x->state = YXMLS_string;
633
20
      x->nextstate = YXMLS_misc0;
634
20
      x->string = (unsigned char *)"\xbb\xbf";
635
20
      return YXML_OK;
636
20
    }
637
88.6k
    if(yxml_isSP(ch)) {
638
117
      x->state = YXMLS_misc0;
639
117
      return YXML_OK;
640
117
    }
641
88.5k
    if(ch == (unsigned char)'<') {
642
88.5k
      x->state = YXMLS_le0;
643
88.5k
      return YXML_OK;
644
88.5k
    }
645
34
    break;
646
88.5k
  case YXMLS_le0:
647
88.5k
    if(ch == (unsigned char)'!') {
648
295
      x->state = YXMLS_lee1;
649
295
      return YXML_OK;
650
295
    }
651
88.2k
    if(ch == (unsigned char)'?') {
652
1.34k
      x->state = YXMLS_leq0;
653
1.34k
      return YXML_OK;
654
1.34k
    }
655
86.9k
    if(yxml_isNameStart(ch)) {
656
86.9k
      x->state = YXMLS_elem0;
657
86.9k
      return yxml_elemstart(x, ch);
658
86.9k
    }
659
20
    break;
660
2.31k
  case YXMLS_le1:
661
2.31k
    if(ch == (unsigned char)'!') {
662
733
      x->state = YXMLS_lee1;
663
733
      return YXML_OK;
664
733
    }
665
1.57k
    if(ch == (unsigned char)'?') {
666
1.33k
      x->state = YXMLS_pi0;
667
1.33k
      x->nextstate = YXMLS_misc1;
668
1.33k
      return YXML_OK;
669
1.33k
    }
670
248
    if(yxml_isNameStart(ch)) {
671
234
      x->state = YXMLS_elem0;
672
234
      return yxml_elemstart(x, ch);
673
234
    }
674
14
    break;
675
6.94M
  case YXMLS_le2:
676
6.94M
    if(ch == (unsigned char)'!') {
677
558
      x->state = YXMLS_lee2;
678
558
      return YXML_OK;
679
558
    }
680
6.94M
    if(ch == (unsigned char)'?') {
681
1.32k
      x->state = YXMLS_pi0;
682
1.32k
      x->nextstate = YXMLS_misc2;
683
1.32k
      return YXML_OK;
684
1.32k
    }
685
6.94M
    if(ch == (unsigned char)'/') {
686
791k
      x->state = YXMLS_etag0;
687
791k
      return YXML_OK;
688
791k
    }
689
6.14M
    if(yxml_isNameStart(ch)) {
690
6.14M
      x->state = YXMLS_elem0;
691
6.14M
      return yxml_elemstart(x, ch);
692
6.14M
    }
693
25
    break;
694
667
  case YXMLS_le3:
695
667
    if(ch == (unsigned char)'!') {
696
223
      x->state = YXMLS_comment0;
697
223
      x->nextstate = YXMLS_misc3;
698
223
      return YXML_OK;
699
223
    }
700
444
    if(ch == (unsigned char)'?') {
701
430
      x->state = YXMLS_pi0;
702
430
      x->nextstate = YXMLS_misc3;
703
430
      return YXML_OK;
704
430
    }
705
14
    break;
706
1.02k
  case YXMLS_lee1:
707
1.02k
    if(ch == (unsigned char)'-') {
708
520
      x->state = YXMLS_comment1;
709
520
      x->nextstate = YXMLS_misc1;
710
520
      return YXML_OK;
711
520
    }
712
500
    if(ch == (unsigned char)'D') {
713
485
      x->state = YXMLS_string;
714
485
      x->nextstate = YXMLS_dt0;
715
485
      x->string = (unsigned char *)"OCTYPE";
716
485
      return YXML_OK;
717
485
    }
718
15
    break;
719
553
  case YXMLS_lee2:
720
553
    if(ch == (unsigned char)'-') {
721
207
      x->state = YXMLS_comment1;
722
207
      x->nextstate = YXMLS_misc2;
723
207
      return YXML_OK;
724
207
    }
725
346
    if(ch == (unsigned char)'[') {
726
335
      x->state = YXMLS_string;
727
335
      x->nextstate = YXMLS_cd0;
728
335
      x->string = (unsigned char *)"CDATA[";
729
335
      return YXML_OK;
730
335
    }
731
11
    break;
732
1.34k
  case YXMLS_leq0:
733
1.34k
    if(ch == (unsigned char)'x') {
734
992
      x->state = YXMLS_xmldecl0;
735
992
      x->nextstate = YXMLS_misc1;
736
992
      return yxml_pistart(x, ch);
737
992
    }
738
356
    if(yxml_isNameStart(ch)) {
739
338
      x->state = YXMLS_pi1;
740
338
      x->nextstate = YXMLS_misc1;
741
338
      return yxml_pistart(x, ch);
742
338
    }
743
18
    break;
744
1.22k
  case YXMLS_misc0:
745
1.22k
    if(yxml_isSP(ch))
746
1.14k
      return YXML_OK;
747
75
    if(ch == (unsigned char)'<') {
748
51
      x->state = YXMLS_le0;
749
51
      return YXML_OK;
750
51
    }
751
24
    break;
752
2.95k
  case YXMLS_misc1:
753
2.95k
    if(yxml_isSP(ch))
754
615
      return YXML_OK;
755
2.33k
    if(ch == (unsigned char)'<') {
756
2.31k
      x->state = YXMLS_le1;
757
2.31k
      return YXML_OK;
758
2.31k
    }
759
16
    break;
760
151M
  case YXMLS_misc2:
761
151M
    if(ch == (unsigned char)'<') {
762
6.94M
      x->state = YXMLS_le2;
763
6.94M
      return YXML_OK;
764
6.94M
    }
765
144M
    if(ch == (unsigned char)'&') {
766
2.57k
      x->state = YXMLS_misc2a;
767
2.57k
      return yxml_refstart(x, ch);
768
2.57k
    }
769
144M
    if(yxml_isChar(ch))
770
144M
      return yxml_datacontent(x, ch);
771
0
    break;
772
11.5k
  case YXMLS_misc2a:
773
11.5k
    if(yxml_isRef(ch))
774
9.04k
      return yxml_ref(x, ch);
775
2.53k
    if(ch == (unsigned char)'\x3b') {
776
2.50k
      x->state = YXMLS_misc2;
777
2.50k
      return yxml_refcontent(x, ch);
778
2.50k
    }
779
23
    break;
780
1.27k
  case YXMLS_misc3:
781
1.27k
    if(yxml_isSP(ch))
782
585
      return YXML_OK;
783
692
    if(ch == (unsigned char)'<') {
784
673
      x->state = YXMLS_le3;
785
673
      return YXML_OK;
786
673
    }
787
19
    break;
788
3.25k
  case YXMLS_pi0:
789
3.25k
    if(yxml_isNameStart(ch)) {
790
3.23k
      x->state = YXMLS_pi1;
791
3.23k
      return yxml_pistart(x, ch);
792
3.23k
    }
793
20
    break;
794
7.64k
  case YXMLS_pi1:
795
7.64k
    if(yxml_isName(ch))
796
4.01k
      return yxml_piname(x, ch);
797
3.63k
    if(ch == (unsigned char)'?') {
798
2.34k
      x->state = YXMLS_pi4;
799
2.34k
      return yxml_pinameend(x, ch);
800
2.34k
    }
801
1.28k
    if(yxml_isSP(ch)) {
802
1.26k
      x->state = YXMLS_pi2;
803
1.26k
      return yxml_pinameend(x, ch);
804
1.26k
    }
805
20
    break;
806
104k
  case YXMLS_pi2:
807
104k
    if(ch == (unsigned char)'?') {
808
1.65k
      x->state = YXMLS_pi3;
809
1.65k
      return YXML_OK;
810
1.65k
    }
811
103k
    if(yxml_isChar(ch))
812
103k
      return yxml_datapi1(x, ch);
813
0
    break;
814
1.64k
  case YXMLS_pi3:
815
1.64k
    if(ch == (unsigned char)'>') {
816
1.18k
      x->state = x->nextstate;
817
1.18k
      return yxml_pivalend(x, ch);
818
1.18k
    }
819
457
    if(yxml_isChar(ch)) {
820
457
      x->state = YXMLS_pi2;
821
457
      return yxml_datapi2(x, ch);
822
457
    }
823
0
    break;
824
2.31k
  case YXMLS_pi4:
825
2.31k
    if(ch == (unsigned char)'>') {
826
2.29k
      x->state = x->nextstate;
827
2.29k
      return yxml_pivalend(x, ch);
828
2.29k
    }
829
13
    break;
830
698
  case YXMLS_std0:
831
698
    if(yxml_isSP(ch))
832
582
      return YXML_OK;
833
116
    if(ch == (unsigned char)'=') {
834
100
      x->state = YXMLS_std1;
835
100
      return YXML_OK;
836
100
    }
837
16
    break;
838
657
  case YXMLS_std1:
839
657
    if(yxml_isSP(ch))
840
582
      return YXML_OK;
841
75
    if(ch == (unsigned char)'\'' || ch == (unsigned char)'"') {
842
63
      x->state = YXMLS_std2;
843
63
      x->quote = ch;
844
63
      return YXML_OK;
845
63
    }
846
12
    break;
847
61
  case YXMLS_std2:
848
61
    if(ch == (unsigned char)'y') {
849
3
      x->state = YXMLS_string;
850
3
      x->nextstate = YXMLS_std3;
851
3
      x->string = (unsigned char *)"es";
852
3
      return YXML_OK;
853
3
    }
854
58
    if(ch == (unsigned char)'n') {
855
46
      x->state = YXMLS_string;
856
46
      x->nextstate = YXMLS_std3;
857
46
      x->string = (unsigned char *)"o";
858
46
      return YXML_OK;
859
46
    }
860
12
    break;
861
46
  case YXMLS_std3:
862
46
    if(x->quote == ch) {
863
45
      x->state = YXMLS_xmldecl8;
864
45
      return YXML_OK;
865
45
    }
866
1
    break;
867
1.13k
  case YXMLS_ver0:
868
1.13k
    if(yxml_isSP(ch))
869
582
      return YXML_OK;
870
548
    if(ch == (unsigned char)'=') {
871
537
      x->state = YXMLS_ver1;
872
537
      return YXML_OK;
873
537
    }
874
11
    break;
875
1.09k
  case YXMLS_ver1:
876
1.09k
    if(yxml_isSP(ch))
877
584
      return YXML_OK;
878
512
    if(ch == (unsigned char)'\'' || ch == (unsigned char)'"') {
879
492
      x->state = YXMLS_string;
880
492
      x->quote = ch;
881
492
      x->nextstate = YXMLS_ver2;
882
492
      x->string = (unsigned char *)"1.";
883
492
      return YXML_OK;
884
492
    }
885
20
    break;
886
489
  case YXMLS_ver2:
887
489
    if(yxml_isNum(ch)) {
888
477
      x->state = YXMLS_ver3;
889
477
      return YXML_OK;
890
477
    }
891
12
    break;
892
660
  case YXMLS_ver3:
893
660
    if(yxml_isNum(ch))
894
196
      return YXML_OK;
895
464
    if(x->quote == ch) {
896
449
      x->state = YXMLS_xmldecl4;
897
449
      return YXML_OK;
898
449
    }
899
15
    break;
900
991
  case YXMLS_xmldecl0:
901
991
    if(ch == (unsigned char)'m') {
902
872
      x->state = YXMLS_xmldecl1;
903
872
      return yxml_piname(x, ch);
904
872
    }
905
119
    if(yxml_isName(ch)) {
906
61
      x->state = YXMLS_pi1;
907
61
      return yxml_piname(x, ch);
908
61
    }
909
58
    if(ch == (unsigned char)'?') {
910
17
      x->state = YXMLS_pi4;
911
17
      return yxml_pinameend(x, ch);
912
17
    }
913
41
    if(yxml_isSP(ch)) {
914
20
      x->state = YXMLS_pi2;
915
20
      return yxml_pinameend(x, ch);
916
20
    }
917
21
    break;
918
871
  case YXMLS_xmldecl1:
919
871
    if(ch == (unsigned char)'l') {
920
778
      x->state = YXMLS_xmldecl2;
921
778
      return yxml_piname(x, ch);
922
778
    }
923
93
    if(yxml_isName(ch)) {
924
53
      x->state = YXMLS_pi1;
925
53
      return yxml_piname(x, ch);
926
53
    }
927
40
    if(ch == (unsigned char)'?') {
928
3
      x->state = YXMLS_pi4;
929
3
      return yxml_pinameend(x, ch);
930
3
    }
931
37
    if(yxml_isSP(ch)) {
932
11
      x->state = YXMLS_pi2;
933
11
      return yxml_pinameend(x, ch);
934
11
    }
935
26
    break;
936
777
  case YXMLS_xmldecl2:
937
777
    if(yxml_isSP(ch)) {
938
625
      x->state = YXMLS_xmldecl3;
939
625
      return yxml_piabort(x, ch);
940
625
    }
941
152
    if(yxml_isName(ch)) {
942
134
      x->state = YXMLS_pi1;
943
134
      return yxml_piname(x, ch);
944
134
    }
945
18
    break;
946
1.18k
  case YXMLS_xmldecl3:
947
1.18k
    if(yxml_isSP(ch))
948
582
      return YXML_OK;
949
598
    if(ch == (unsigned char)'v') {
950
575
      x->state = YXMLS_string;
951
575
      x->nextstate = YXMLS_ver0;
952
575
      x->string = (unsigned char *)"ersion";
953
575
      return YXML_OK;
954
575
    }
955
23
    break;
956
448
  case YXMLS_xmldecl4:
957
448
    if(yxml_isSP(ch)) {
958
424
      x->state = YXMLS_xmldecl5;
959
424
      return YXML_OK;
960
424
    }
961
24
    if(ch == (unsigned char)'?') {
962
10
      x->state = YXMLS_xmldecl9;
963
10
      return YXML_OK;
964
10
    }
965
14
    break;
966
979
  case YXMLS_xmldecl5:
967
979
    if(yxml_isSP(ch))
968
582
      return YXML_OK;
969
397
    if(ch == (unsigned char)'?') {
970
7
      x->state = YXMLS_xmldecl9;
971
7
      return YXML_OK;
972
7
    }
973
390
    if(ch == (unsigned char)'e') {
974
230
      x->state = YXMLS_string;
975
230
      x->nextstate = YXMLS_enc0;
976
230
      x->string = (unsigned char *)"ncoding";
977
230
      return YXML_OK;
978
230
    }
979
160
    if(ch == (unsigned char)'s') {
980
137
      x->state = YXMLS_string;
981
137
      x->nextstate = YXMLS_std0;
982
137
      x->string = (unsigned char *)"tandalone";
983
137
      return YXML_OK;
984
137
    }
985
23
    break;
986
76
  case YXMLS_xmldecl6:
987
76
    if(yxml_isSP(ch)) {
988
63
      x->state = YXMLS_xmldecl7;
989
63
      return YXML_OK;
990
63
    }
991
13
    if(ch == (unsigned char)'?') {
992
5
      x->state = YXMLS_xmldecl9;
993
5
      return YXML_OK;
994
5
    }
995
8
    break;
996
619
  case YXMLS_xmldecl7:
997
619
    if(yxml_isSP(ch))
998
583
      return YXML_OK;
999
36
    if(ch == (unsigned char)'?') {
1000
7
      x->state = YXMLS_xmldecl9;
1001
7
      return YXML_OK;
1002
7
    }
1003
29
    if(ch == (unsigned char)'s') {
1004
5
      x->state = YXMLS_string;
1005
5
      x->nextstate = YXMLS_std0;
1006
5
      x->string = (unsigned char *)"tandalone";
1007
5
      return YXML_OK;
1008
5
    }
1009
24
    break;
1010
603
  case YXMLS_xmldecl8:
1011
603
    if(yxml_isSP(ch))
1012
583
      return YXML_OK;
1013
20
    if(ch == (unsigned char)'?') {
1014
9
      x->state = YXMLS_xmldecl9;
1015
9
      return YXML_OK;
1016
9
    }
1017
11
    break;
1018
33
  case YXMLS_xmldecl9:
1019
33
    if(ch == (unsigned char)'>') {
1020
32
      x->state = YXMLS_misc1;
1021
32
      return YXML_OK;
1022
32
    }
1023
1
    break;
1024
274M
  }
1025
852
  return YXML_ESYN;
1026
274M
}
1027
1028
87.4k
yxml_ret_t yxml_eof(yxml_t *x) {
1029
87.4k
  if(x->state != YXMLS_misc3)
1030
2.16k
    return YXML_EEOF;
1031
85.2k
  return YXML_OK;
1032
87.4k
}
1033