Coverage Report

Created: 2025-11-09 06:18

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
8.16M
#define yxml_isChar(c) 1
100
/* 0xd should be part of SP, too, but yxml_parse() already normalizes that into 0xa */
101
17.9M
#define yxml_isSP(c) (c == 0x20 || c == 0x09 || c == 0x0a)
102
82.8M
#define yxml_isAlpha(c) ((c|32)-'a' < 26)
103
41.4M
#define yxml_isNum(c) (c-'0' < 10)
104
2.32k
#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
75.7M
#define yxml_isNameStart(c) (yxml_isAlpha(c) || c == ':' || c == '_' || c >= 128)
107
34.2M
#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
2.97M
#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.54k
#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
2.43M
static inline void yxml_setchar(char *dest, unsigned ch) {
119
2.43M
  *(unsigned char *)dest = (unsigned char)ch;
120
2.43M
}
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.16k
static void yxml_setutf8(char *dest, unsigned ch) {
125
3.16k
  if(ch <= 0x007F)
126
2.25k
    yxml_setchar(dest++, ch);
127
907
  else if(ch <= 0x07FF) {
128
223
    yxml_setchar(dest++, 0xC0 | (ch>>6));
129
223
    yxml_setchar(dest++, 0x80 | (ch & 0x3F));
130
684
  } else if(ch <= 0xFFFF) {
131
290
    yxml_setchar(dest++, 0xE0 | (ch>>12));
132
290
    yxml_setchar(dest++, 0x80 | ((ch>>6) & 0x3F));
133
290
    yxml_setchar(dest++, 0x80 | (ch & 0x3F));
134
394
  } else {
135
394
    yxml_setchar(dest++, 0xF0 | (ch>>18));
136
394
    yxml_setchar(dest++, 0x80 | ((ch>>12) & 0x3F));
137
394
    yxml_setchar(dest++, 0x80 | ((ch>>6) & 0x3F));
138
394
    yxml_setchar(dest++, 0x80 | (ch & 0x3F));
139
394
  }
140
3.16k
  *dest = 0;
141
3.16k
}
142
143
2.22M
static inline yxml_ret_t yxml_datacontent(yxml_t *x, unsigned ch) {
144
2.22M
  yxml_setchar(x->data, ch);
145
2.22M
  x->data[1] = 0;
146
2.22M
  return YXML_CONTENT;
147
2.22M
}
148
149
354
static inline yxml_ret_t yxml_datapi1(yxml_t *x, unsigned ch) {
150
354
  yxml_setchar(x->data, ch);
151
354
  x->data[1] = 0;
152
354
  return YXML_PICONTENT;
153
354
}
154
155
400
static inline yxml_ret_t yxml_datapi2(yxml_t *x, unsigned ch) {
156
400
  x->data[0] = '?';
157
400
  yxml_setchar(x->data+1, ch);
158
400
  x->data[2] = 0;
159
400
  return YXML_PICONTENT;
160
400
}
161
162
274
static inline yxml_ret_t yxml_datacd1(yxml_t *x, unsigned ch) {
163
274
  x->data[0] = ']';
164
274
  yxml_setchar(x->data+1, ch);
165
274
  x->data[2] = 0;
166
274
  return YXML_CONTENT;
167
274
}
168
169
439
static inline yxml_ret_t yxml_datacd2(yxml_t *x, unsigned ch) {
170
439
  x->data[0] = ']';
171
439
  x->data[1] = ']';
172
439
  yxml_setchar(x->data+2, ch);
173
439
  x->data[3] = 0;
174
439
  return YXML_CONTENT;
175
439
}
176
177
189k
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
189k
  yxml_setchar(x->data, ch == 0x9 || ch == 0xa ? 0x20 : ch);
180
189k
  x->data[1] = 0;
181
189k
  return YXML_ATTRVAL;
182
189k
}
183
184
7.10M
static yxml_ret_t yxml_pushstack(yxml_t *x, char **res, unsigned ch) {
185
7.10M
  if(x->stacklen+2 >= x->stacksize)
186
5
    return YXML_ESTACK;
187
7.10M
  x->stacklen++;
188
7.10M
  *res = (char *)x->stack+x->stacklen;
189
7.10M
  x->stack[x->stacklen] = (unsigned char)ch;
190
7.10M
  x->stacklen++;
191
7.10M
  x->stack[x->stacklen] = 0;
192
7.10M
  return YXML_OK;
193
7.10M
}
194
195
27.1M
static yxml_ret_t yxml_pushstackc(yxml_t *x, unsigned ch) {
196
27.1M
  if(x->stacklen+1 >= x->stacksize)
197
3
    return YXML_ESTACK;
198
27.1M
  x->stack[x->stacklen] = (unsigned char)ch;
199
27.1M
  x->stacklen++;
200
27.1M
  x->stack[x->stacklen] = 0;
201
27.1M
  return YXML_OK;
202
27.1M
}
203
204
7.10M
static void yxml_popstack(yxml_t *x) {
205
7.10M
  do
206
41.3M
    x->stacklen--;
207
41.3M
  while(x->stack[x->stacklen]);
208
7.10M
}
209
210
4.32M
static inline yxml_ret_t yxml_elemstart  (yxml_t *x, unsigned ch) { return yxml_pushstack(x, &x->elem, ch); }
211
279k
static inline yxml_ret_t yxml_elemname   (yxml_t *x, unsigned ch) { return yxml_pushstackc(x, ch); }
212
4.32M
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
4.31M
static yxml_ret_t yxml_selfclose(yxml_t *x, unsigned ch) {
217
4.31M
  yxml_popstack(x);
218
4.31M
  if(x->stacklen) {
219
4.31M
    x->elem = (char *)x->stack+x->stacklen-1;
220
5.12M
    while(*(x->elem-1))
221
806k
      x->elem--;
222
4.31M
    return YXML_ELEMEND;
223
4.31M
  }
224
1.38k
  x->elem = (char *)x->stack;
225
1.38k
  x->state = YXMLS_misc3;
226
1.38k
  return YXML_ELEMEND;
227
4.31M
}
228
229
32.9k
static inline yxml_ret_t yxml_elemclose(yxml_t *x, unsigned ch) {
230
32.9k
  if(*((unsigned char *)x->elem) != ch)
231
92
    return YXML_ECLOSE;
232
32.8k
  x->elem++;
233
32.8k
  return YXML_OK;
234
32.9k
}
235
236
25.6k
static inline yxml_ret_t yxml_elemcloseend(yxml_t *x, unsigned ch) {
237
25.6k
  if(*x->elem)
238
7
    return YXML_ECLOSE;
239
25.6k
  return yxml_selfclose(x, ch);
240
25.6k
}
241
242
2.78M
static inline yxml_ret_t yxml_attrstart  (yxml_t *x, unsigned ch) { return yxml_pushstack(x, &x->attr, ch); }
243
26.8M
static inline yxml_ret_t yxml_attrname   (yxml_t *x, unsigned ch) { return yxml_pushstackc(x, ch); }
244
2.78M
static inline yxml_ret_t yxml_attrnameend(yxml_t *x, unsigned ch) { return YXML_ATTRSTART; }
245
2.78M
static inline yxml_ret_t yxml_attrvalend (yxml_t *x, unsigned ch) { yxml_popstack(x); return YXML_ATTREND; }
246
247
4.48k
static inline yxml_ret_t yxml_pistart  (yxml_t *x, unsigned ch) { return yxml_pushstack(x, &x->pi, ch); }
248
6.49k
static inline yxml_ret_t yxml_piname   (yxml_t *x, unsigned ch) { return yxml_pushstackc(x, ch); }
249
624
static inline yxml_ret_t yxml_piabort  (yxml_t *x, unsigned ch) { yxml_popstack(x); return YXML_OK; }
250
3.58k
static inline yxml_ret_t yxml_pinameend(yxml_t *x, unsigned ch) {
251
3.58k
  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.58k
}
253
3.41k
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.46k
static inline yxml_ret_t yxml_refstart(yxml_t *x, unsigned ch) {
256
3.46k
  memset(x->data, 0, sizeof(x->data));
257
3.46k
  x->reflen = 0;
258
3.46k
  return YXML_OK;
259
3.46k
}
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
20
    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.35k
static yxml_ret_t yxml_refend(yxml_t *x, yxml_ret_t ret) {
270
3.35k
  unsigned char *r = (unsigned char *)x->data;
271
3.35k
  unsigned ch = 0;
272
3.35k
  if(*r == '#') {
273
1.86k
    if(r[1] == 'x')
274
2.32k
      for(r += 2; yxml_isHex((unsigned)*r); r++)
275
1.65k
        ch = (ch<<4) + (*r <= '9' ? *r-'0' : (*r|32)-'a' + 10);
276
1.19k
    else
277
4.17k
      for(r++; yxml_isNum((unsigned)*r); r++)
278
2.98k
        ch = (ch*10) + (*r-'0');
279
1.86k
    if(*r)
280
9
      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.05k
      i == INTFROM5CHARS('a','p','o','s',0) ? '\'':
288
861
      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.35k
  if(!ch || ch > 0x10FFFF || ch == 0xFFFE || ch == 0xFFFF || (ch-0xDFFF) < 0x7FF)
293
188
    return YXML_EREF;
294
3.16k
  yxml_setutf8(x->data, ch);
295
3.16k
  return ret;
296
3.35k
}
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
4.65k
void yxml_init(yxml_t *x, void *stack, size_t stacksize) {
302
4.65k
  memset(x, 0, sizeof(*x));
303
4.65k
  x->line = 1;
304
4.65k
  x->stack = (unsigned char*)stack;
305
4.65k
  x->stacksize = stacksize;
306
4.65k
  *x->stack = 0;
307
4.65k
  x->elem = x->pi = x->attr = (char *)x->stack;
308
4.65k
  x->state = YXMLS_init;
309
4.65k
}
310
311
63.3M
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
63.3M
  unsigned ch = (unsigned)(_ch+256) & 0xff;
315
63.3M
  if(!ch)
316
4
    return YXML_ESYN;
317
63.3M
  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
63.3M
  if(x->ignore == ch) {
324
890
    x->ignore = 0;
325
890
    return YXML_OK;
326
890
  }
327
63.3M
  x->ignore = (ch == 0xd) * 0xa;
328
63.3M
  if(ch == 0xa || ch == 0xd) {
329
2.51M
    ch = 0xa;
330
2.51M
    x->line++;
331
2.51M
    x->byte = 0;
332
2.51M
  }
333
63.3M
  x->byte++;
334
335
63.3M
  switch((yxml_state_t)x->state) {
336
12.7k
  case YXMLS_string:
337
12.7k
    if(ch == *x->string) {
338
12.7k
      x->string++;
339
12.7k
      if(!*x->string)
340
2.37k
        x->state = x->nextstate;
341
12.7k
      return YXML_OK;
342
12.7k
    }
343
11
    break;
344
29.6M
  case YXMLS_attr0:
345
29.6M
    if(yxml_isName(ch))
346
26.8M
      return yxml_attrname(x, ch);
347
2.78M
    if(yxml_isSP(ch)) {
348
2.41M
      x->state = YXMLS_attr1;
349
2.41M
      return yxml_attrnameend(x, ch);
350
2.41M
    }
351
364k
    if(ch == (unsigned char)'=') {
352
364k
      x->state = YXMLS_attr2;
353
364k
      return yxml_attrnameend(x, ch);
354
364k
    }
355
25
    break;
356
2.41M
  case YXMLS_attr1:
357
2.41M
    if(yxml_isSP(ch))
358
601
      return YXML_OK;
359
2.41M
    if(ch == (unsigned char)'=') {
360
2.41M
      x->state = YXMLS_attr2;
361
2.41M
      return YXML_OK;
362
2.41M
    }
363
14
    break;
364
2.78M
  case YXMLS_attr2:
365
2.78M
    if(yxml_isSP(ch))
366
720
      return YXML_OK;
367
2.78M
    if(ch == (unsigned char)'\'' || ch == (unsigned char)'"') {
368
2.78M
      x->state = YXMLS_attr3;
369
2.78M
      x->quote = ch;
370
2.78M
      return YXML_OK;
371
2.78M
    }
372
17
    break;
373
2.97M
  case YXMLS_attr3:
374
2.97M
    if(yxml_isAttValue(ch))
375
189k
      return yxml_dataattr(x, ch);
376
2.78M
    if(ch == (unsigned char)'&') {
377
940
      x->state = YXMLS_attr4;
378
940
      return yxml_refstart(x, ch);
379
940
    }
380
2.78M
    if(x->quote == ch) {
381
2.78M
      x->state = YXMLS_elem2;
382
2.78M
      return yxml_attrvalend(x, ch);
383
2.78M
    }
384
1
    break;
385
4.15k
  case YXMLS_attr4:
386
4.15k
    if(yxml_isRef(ch))
387
3.25k
      return yxml_ref(x, ch);
388
900
    if(ch == (unsigned char)'\x3b') {
389
886
      x->state = YXMLS_attr3;
390
886
      return yxml_refattrval(x, ch);
391
886
    }
392
14
    break;
393
9.31k
  case YXMLS_cd0:
394
9.31k
    if(ch == (unsigned char)']') {
395
1.09k
      x->state = YXMLS_cd1;
396
1.09k
      return YXML_OK;
397
1.09k
    }
398
8.22k
    if(yxml_isChar(ch))
399
8.22k
      return yxml_datacontent(x, ch);
400
0
    break;
401
1.08k
  case YXMLS_cd1:
402
1.08k
    if(ch == (unsigned char)']') {
403
809
      x->state = YXMLS_cd2;
404
809
      return YXML_OK;
405
809
    }
406
274
    if(yxml_isChar(ch)) {
407
274
      x->state = YXMLS_cd0;
408
274
      return yxml_datacd1(x, ch);
409
274
    }
410
0
    break;
411
1.24k
  case YXMLS_cd2:
412
1.24k
    if(ch == (unsigned char)']')
413
448
      return yxml_datacontent(x, ch);
414
795
    if(ch == (unsigned char)'>') {
415
356
      x->state = YXMLS_misc2;
416
356
      return YXML_OK;
417
356
    }
418
439
    if(yxml_isChar(ch)) {
419
439
      x->state = YXMLS_cd0;
420
439
      return yxml_datacd2(x, ch);
421
439
    }
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.09k
  case YXMLS_comment1:
430
1.09k
    if(ch == (unsigned char)'-') {
431
1.08k
      x->state = YXMLS_comment2;
432
1.08k
      return YXML_OK;
433
1.08k
    }
434
10
    break;
435
1.63k
  case YXMLS_comment2:
436
1.63k
    if(ch == (unsigned char)'-') {
437
1.43k
      x->state = YXMLS_comment3;
438
1.43k
      return YXML_OK;
439
1.43k
    }
440
203
    if(yxml_isChar(ch))
441
203
      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
387
    if(yxml_isChar(ch)) {
449
387
      x->state = YXMLS_comment2;
450
387
      return YXML_OK;
451
387
    }
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
11
    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.57k
    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
982
    if(ch == (unsigned char)'<') {
471
762
      x->state = YXMLS_dt2;
472
762
      return YXML_OK;
473
762
    }
474
220
    if(yxml_isChar(ch))
475
220
      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
756
  case YXMLS_dt2:
486
756
    if(ch == (unsigned char)'?') {
487
194
      x->state = YXMLS_pi0;
488
194
      x->nextstate = YXMLS_dt0;
489
194
      return YXML_OK;
490
194
    }
491
562
    if(ch == (unsigned char)'!') {
492
559
      x->state = YXMLS_dt3;
493
559
      return YXML_OK;
494
559
    }
495
3
    break;
496
553
  case YXMLS_dt3:
497
553
    if(ch == (unsigned char)'-') {
498
194
      x->state = YXMLS_comment1;
499
194
      x->nextstate = YXMLS_dt0;
500
194
      return YXML_OK;
501
194
    }
502
359
    if(yxml_isChar(ch)) {
503
359
      x->state = YXMLS_dt4;
504
359
      return YXML_OK;
505
359
    }
506
0
    break;
507
906
  case YXMLS_dt4:
508
906
    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
518
    if(ch == (unsigned char)'>') {
515
311
      x->state = YXMLS_dt0;
516
311
      return YXML_OK;
517
311
    }
518
207
    if(yxml_isChar(ch))
519
207
      return YXML_OK;
520
0
    break;
521
4.60M
  case YXMLS_elem0:
522
4.60M
    if(yxml_isName(ch))
523
279k
      return yxml_elemname(x, ch);
524
4.32M
    if(yxml_isSP(ch)) {
525
6.34k
      x->state = YXMLS_elem1;
526
6.34k
      return yxml_elemnameend(x, ch);
527
6.34k
    }
528
4.31M
    if(ch == (unsigned char)'/') {
529
4.28M
      x->state = YXMLS_elem3;
530
4.28M
      return yxml_elemnameend(x, ch);
531
4.28M
    }
532
27.7k
    if(ch == (unsigned char)'>') {
533
27.7k
      x->state = YXMLS_misc2;
534
27.7k
      return yxml_elemnameend(x, ch);
535
27.7k
    }
536
25
    break;
537
2.78M
  case YXMLS_elem1:
538
2.78M
    if(yxml_isSP(ch))
539
1.38k
      return YXML_OK;
540
2.78M
    if(ch == (unsigned char)'/') {
541
4.10k
      x->state = YXMLS_elem3;
542
4.10k
      return YXML_OK;
543
4.10k
    }
544
2.78M
    if(ch == (unsigned char)'>') {
545
435
      x->state = YXMLS_misc2;
546
435
      return YXML_OK;
547
435
    }
548
2.78M
    if(yxml_isNameStart(ch)) {
549
2.78M
      x->state = YXMLS_attr0;
550
2.78M
      return yxml_attrstart(x, ch);
551
2.78M
    }
552
26
    break;
553
2.78M
  case YXMLS_elem2:
554
2.78M
    if(yxml_isSP(ch)) {
555
2.77M
      x->state = YXMLS_elem1;
556
2.77M
      return YXML_OK;
557
2.77M
    }
558
1.24k
    if(ch == (unsigned char)'/') {
559
1.02k
      x->state = YXMLS_elem3;
560
1.02k
      return YXML_OK;
561
1.02k
    }
562
221
    if(ch == (unsigned char)'>') {
563
207
      x->state = YXMLS_misc2;
564
207
      return YXML_OK;
565
207
    }
566
14
    break;
567
4.29M
  case YXMLS_elem3:
568
4.29M
    if(ch == (unsigned char)'>') {
569
4.29M
      x->state = YXMLS_misc2;
570
4.29M
      return yxml_selfclose(x, ch);
571
4.29M
    }
572
6
    break;
573
790
  case YXMLS_enc0:
574
790
    if(yxml_isSP(ch))
575
584
      return YXML_OK;
576
206
    if(ch == (unsigned char)'=') {
577
190
      x->state = YXMLS_enc1;
578
190
      return YXML_OK;
579
190
    }
580
16
    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.06k
  case YXMLS_enc3:
597
1.06k
    if(yxml_isEncName(ch))
598
977
      return YXML_OK;
599
92
    if(x->quote == ch) {
600
75
      x->state = YXMLS_xmldecl6;
601
75
      return YXML_OK;
602
75
    }
603
17
    break;
604
25.8k
  case YXMLS_etag0:
605
25.8k
    if(yxml_isNameStart(ch)) {
606
25.8k
      x->state = YXMLS_etag1;
607
25.8k
      return yxml_elemclose(x, ch);
608
25.8k
    }
609
13
    break;
610
32.7k
  case YXMLS_etag1:
611
32.7k
    if(yxml_isName(ch))
612
7.09k
      return yxml_elemclose(x, ch);
613
25.6k
    if(yxml_isSP(ch)) {
614
832
      x->state = YXMLS_etag2;
615
832
      return yxml_elemcloseend(x, ch);
616
832
    }
617
24.8k
    if(ch == (unsigned char)'>') {
618
24.8k
      x->state = YXMLS_misc2;
619
24.8k
      return yxml_elemcloseend(x, ch);
620
24.8k
    }
621
20
    break;
622
1.40k
  case YXMLS_etag2:
623
1.40k
    if(yxml_isSP(ch))
624
631
      return YXML_OK;
625
774
    if(ch == (unsigned char)'>') {
626
761
      x->state = YXMLS_misc2;
627
761
      return YXML_OK;
628
761
    }
629
13
    break;
630
4.65k
  case YXMLS_init:
631
4.65k
    if(ch == (unsigned char)'\xef') {
632
17
      x->state = YXMLS_string;
633
17
      x->nextstate = YXMLS_misc0;
634
17
      x->string = (unsigned char *)"\xbb\xbf";
635
17
      return YXML_OK;
636
17
    }
637
4.63k
    if(yxml_isSP(ch)) {
638
103
      x->state = YXMLS_misc0;
639
103
      return YXML_OK;
640
103
    }
641
4.53k
    if(ch == (unsigned char)'<') {
642
4.50k
      x->state = YXMLS_le0;
643
4.50k
      return YXML_OK;
644
4.50k
    }
645
31
    break;
646
4.53k
  case YXMLS_le0:
647
4.53k
    if(ch == (unsigned char)'!') {
648
290
      x->state = YXMLS_lee1;
649
290
      return YXML_OK;
650
290
    }
651
4.24k
    if(ch == (unsigned char)'?') {
652
1.33k
      x->state = YXMLS_leq0;
653
1.33k
      return YXML_OK;
654
1.33k
    }
655
2.90k
    if(yxml_isNameStart(ch)) {
656
2.88k
      x->state = YXMLS_elem0;
657
2.88k
      return yxml_elemstart(x, ch);
658
2.88k
    }
659
20
    break;
660
2.30k
  case YXMLS_le1:
661
2.30k
    if(ch == (unsigned char)'!') {
662
731
      x->state = YXMLS_lee1;
663
731
      return YXML_OK;
664
731
    }
665
1.57k
    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
246
    if(yxml_isNameStart(ch)) {
671
232
      x->state = YXMLS_elem0;
672
232
      return yxml_elemstart(x, ch);
673
232
    }
674
14
    break;
675
4.34M
  case YXMLS_le2:
676
4.34M
    if(ch == (unsigned char)'!') {
677
648
      x->state = YXMLS_lee2;
678
648
      return YXML_OK;
679
648
    }
680
4.34M
    if(ch == (unsigned char)'?') {
681
1.26k
      x->state = YXMLS_pi0;
682
1.26k
      x->nextstate = YXMLS_misc2;
683
1.26k
      return YXML_OK;
684
1.26k
    }
685
4.34M
    if(ch == (unsigned char)'/') {
686
25.8k
      x->state = YXMLS_etag0;
687
25.8k
      return YXML_OK;
688
25.8k
    }
689
4.31M
    if(yxml_isNameStart(ch)) {
690
4.31M
      x->state = YXMLS_elem0;
691
4.31M
      return yxml_elemstart(x, ch);
692
4.31M
    }
693
24
    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.01k
  case YXMLS_lee1:
707
1.01k
    if(ch == (unsigned char)'-') {
708
515
      x->state = YXMLS_comment1;
709
515
      x->nextstate = YXMLS_misc1;
710
515
      return YXML_OK;
711
515
    }
712
498
    if(ch == (unsigned char)'D') {
713
483
      x->state = YXMLS_string;
714
483
      x->nextstate = YXMLS_dt0;
715
483
      x->string = (unsigned char *)"OCTYPE";
716
483
      return YXML_OK;
717
483
    }
718
15
    break;
719
643
  case YXMLS_lee2:
720
643
    if(ch == (unsigned char)'-') {
721
207
      x->state = YXMLS_comment1;
722
207
      x->nextstate = YXMLS_misc2;
723
207
      return YXML_OK;
724
207
    }
725
436
    if(ch == (unsigned char)'[') {
726
426
      x->state = YXMLS_string;
727
426
      x->nextstate = YXMLS_cd0;
728
426
      x->string = (unsigned char *)"CDATA[";
729
426
      return YXML_OK;
730
426
    }
731
10
    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
351
    if(yxml_isNameStart(ch)) {
739
332
      x->state = YXMLS_pi1;
740
332
      x->nextstate = YXMLS_misc1;
741
332
      return yxml_pistart(x, ch);
742
332
    }
743
19
    break;
744
1.20k
  case YXMLS_misc0:
745
1.20k
    if(yxml_isSP(ch))
746
1.14k
      return YXML_OK;
747
60
    if(ch == (unsigned char)'<') {
748
36
      x->state = YXMLS_le0;
749
36
      return YXML_OK;
750
36
    }
751
24
    break;
752
2.96k
  case YXMLS_misc1:
753
2.96k
    if(yxml_isSP(ch))
754
631
      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
17
    break;
760
6.56M
  case YXMLS_misc2:
761
6.56M
    if(ch == (unsigned char)'<') {
762
4.34M
      x->state = YXMLS_le2;
763
4.34M
      return YXML_OK;
764
4.34M
    }
765
2.21M
    if(ch == (unsigned char)'&') {
766
2.52k
      x->state = YXMLS_misc2a;
767
2.52k
      return yxml_refstart(x, ch);
768
2.52k
    }
769
2.21M
    if(yxml_isChar(ch))
770
2.21M
      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.48k
    if(ch == (unsigned char)'\x3b') {
776
2.46k
      x->state = YXMLS_misc2;
777
2.46k
      return yxml_refcontent(x, ch);
778
2.46k
    }
779
18
    break;
780
1.27k
  case YXMLS_misc3:
781
1.27k
    if(yxml_isSP(ch))
782
582
      return YXML_OK;
783
690
    if(ch == (unsigned char)'<') {
784
673
      x->state = YXMLS_le3;
785
673
      return YXML_OK;
786
673
    }
787
17
    break;
788
3.18k
  case YXMLS_pi0:
789
3.18k
    if(yxml_isNameStart(ch)) {
790
3.16k
      x->state = YXMLS_pi1;
791
3.16k
      return yxml_pistart(x, ch);
792
3.16k
    }
793
17
    break;
794
8.16k
  case YXMLS_pi1:
795
8.16k
    if(yxml_isName(ch))
796
4.61k
      return yxml_piname(x, ch);
797
3.55k
    if(ch == (unsigned char)'?') {
798
2.34k
      x->state = YXMLS_pi4;
799
2.34k
      return yxml_pinameend(x, ch);
800
2.34k
    }
801
1.20k
    if(yxml_isSP(ch)) {
802
1.19k
      x->state = YXMLS_pi2;
803
1.19k
      return yxml_pinameend(x, ch);
804
1.19k
    }
805
19
    break;
806
1.87k
  case YXMLS_pi2:
807
1.87k
    if(ch == (unsigned char)'?') {
808
1.52k
      x->state = YXMLS_pi3;
809
1.52k
      return YXML_OK;
810
1.52k
    }
811
354
    if(yxml_isChar(ch))
812
354
      return yxml_datapi1(x, ch);
813
0
    break;
814
1.51k
  case YXMLS_pi3:
815
1.51k
    if(ch == (unsigned char)'>') {
816
1.11k
      x->state = x->nextstate;
817
1.11k
      return yxml_pivalend(x, ch);
818
1.11k
    }
819
400
    if(yxml_isChar(ch)) {
820
400
      x->state = YXMLS_pi2;
821
400
      return yxml_datapi2(x, ch);
822
400
    }
823
0
    break;
824
2.30k
  case YXMLS_pi4:
825
2.30k
    if(ch == (unsigned char)'>') {
826
2.29k
      x->state = x->nextstate;
827
2.29k
      return yxml_pivalend(x, ch);
828
2.29k
    }
829
11
    break;
830
699
  case YXMLS_std0:
831
699
    if(yxml_isSP(ch))
832
582
      return YXML_OK;
833
117
    if(ch == (unsigned char)'=') {
834
101
      x->state = YXMLS_std1;
835
101
      return YXML_OK;
836
101
    }
837
16
    break;
838
658
  case YXMLS_std1:
839
658
    if(yxml_isSP(ch))
840
582
      return YXML_OK;
841
76
    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
13
    break;
847
61
  case YXMLS_std2:
848
61
    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
60
    if(ch == (unsigned char)'n') {
855
48
      x->state = YXMLS_string;
856
48
      x->nextstate = YXMLS_std3;
857
48
      x->string = (unsigned char *)"o";
858
48
      return YXML_OK;
859
48
    }
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
550
    if(ch == (unsigned char)'=') {
871
540
      x->state = YXMLS_ver1;
872
540
      return YXML_OK;
873
540
    }
874
10
    break;
875
1.09k
  case YXMLS_ver1:
876
1.09k
    if(yxml_isSP(ch))
877
582
      return YXML_OK;
878
515
    if(ch == (unsigned char)'\'' || ch == (unsigned char)'"') {
879
496
      x->state = YXMLS_string;
880
496
      x->quote = ch;
881
496
      x->nextstate = YXMLS_ver2;
882
496
      x->string = (unsigned char *)"1.";
883
496
      return YXML_OK;
884
496
    }
885
19
    break;
886
493
  case YXMLS_ver2:
887
493
    if(yxml_isNum(ch)) {
888
482
      x->state = YXMLS_ver3;
889
482
      return YXML_OK;
890
482
    }
891
11
    break;
892
665
  case YXMLS_ver3:
893
665
    if(yxml_isNum(ch))
894
198
      return YXML_OK;
895
467
    if(x->quote == ch) {
896
454
      x->state = YXMLS_xmldecl4;
897
454
      return YXML_OK;
898
454
    }
899
13
    break;
900
984
  case YXMLS_xmldecl0:
901
984
    if(ch == (unsigned char)'m') {
902
870
      x->state = YXMLS_xmldecl1;
903
870
      return yxml_piname(x, ch);
904
870
    }
905
114
    if(yxml_isName(ch)) {
906
56
      x->state = YXMLS_pi1;
907
56
      return yxml_piname(x, ch);
908
56
    }
909
58
    if(ch == (unsigned char)'?') {
910
16
      x->state = YXMLS_pi4;
911
16
      return yxml_pinameend(x, ch);
912
16
    }
913
42
    if(yxml_isSP(ch)) {
914
23
      x->state = YXMLS_pi2;
915
23
      return yxml_pinameend(x, ch);
916
23
    }
917
19
    break;
918
869
  case YXMLS_xmldecl1:
919
869
    if(ch == (unsigned char)'l') {
920
773
      x->state = YXMLS_xmldecl2;
921
773
      return yxml_piname(x, ch);
922
773
    }
923
96
    if(yxml_isName(ch)) {
924
57
      x->state = YXMLS_pi1;
925
57
      return yxml_piname(x, ch);
926
57
    }
927
39
    if(ch == (unsigned char)'?') {
928
3
      x->state = YXMLS_pi4;
929
3
      return yxml_pinameend(x, ch);
930
3
    }
931
36
    if(yxml_isSP(ch)) {
932
11
      x->state = YXMLS_pi2;
933
11
      return yxml_pinameend(x, ch);
934
11
    }
935
25
    break;
936
772
  case YXMLS_xmldecl2:
937
772
    if(yxml_isSP(ch)) {
938
624
      x->state = YXMLS_xmldecl3;
939
624
      return yxml_piabort(x, ch);
940
624
    }
941
148
    if(yxml_isName(ch)) {
942
128
      x->state = YXMLS_pi1;
943
128
      return yxml_piname(x, ch);
944
128
    }
945
20
    break;
946
1.17k
  case YXMLS_xmldecl3:
947
1.17k
    if(yxml_isSP(ch))
948
582
      return YXML_OK;
949
597
    if(ch == (unsigned char)'v') {
950
577
      x->state = YXMLS_string;
951
577
      x->nextstate = YXMLS_ver0;
952
577
      x->string = (unsigned char *)"ersion";
953
577
      return YXML_OK;
954
577
    }
955
20
    break;
956
453
  case YXMLS_xmldecl4:
957
453
    if(yxml_isSP(ch)) {
958
428
      x->state = YXMLS_xmldecl5;
959
428
      return YXML_OK;
960
428
    }
961
25
    if(ch == (unsigned char)'?') {
962
11
      x->state = YXMLS_xmldecl9;
963
11
      return YXML_OK;
964
11
    }
965
14
    break;
966
984
  case YXMLS_xmldecl5:
967
984
    if(yxml_isSP(ch))
968
583
      return YXML_OK;
969
401
    if(ch == (unsigned char)'?') {
970
7
      x->state = YXMLS_xmldecl9;
971
7
      return YXML_OK;
972
7
    }
973
394
    if(ch == (unsigned char)'e') {
974
231
      x->state = YXMLS_string;
975
231
      x->nextstate = YXMLS_enc0;
976
231
      x->string = (unsigned char *)"ncoding";
977
231
      return YXML_OK;
978
231
    }
979
163
    if(ch == (unsigned char)'s') {
980
140
      x->state = YXMLS_string;
981
140
      x->nextstate = YXMLS_std0;
982
140
      x->string = (unsigned char *)"tandalone";
983
140
      return YXML_OK;
984
140
    }
985
23
    break;
986
74
  case YXMLS_xmldecl6:
987
74
    if(yxml_isSP(ch)) {
988
61
      x->state = YXMLS_xmldecl7;
989
61
      return YXML_OK;
990
61
    }
991
13
    if(ch == (unsigned char)'?') {
992
5
      x->state = YXMLS_xmldecl9;
993
5
      return YXML_OK;
994
5
    }
995
8
    break;
996
616
  case YXMLS_xmldecl7:
997
616
    if(yxml_isSP(ch))
998
582
      return YXML_OK;
999
34
    if(ch == (unsigned char)'?') {
1000
7
      x->state = YXMLS_xmldecl9;
1001
7
      return YXML_OK;
1002
7
    }
1003
27
    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
24
    break;
1010
602
  case YXMLS_xmldecl8:
1011
602
    if(yxml_isSP(ch))
1012
582
      return YXML_OK;
1013
20
    if(ch == (unsigned char)'?') {
1014
7
      x->state = YXMLS_xmldecl9;
1015
7
      return YXML_OK;
1016
7
    }
1017
13
    break;
1018
32
  case YXMLS_xmldecl9:
1019
32
    if(ch == (unsigned char)'>') {
1020
31
      x->state = YXMLS_misc1;
1021
31
      return YXML_OK;
1022
31
    }
1023
1
    break;
1024
63.3M
  }
1025
823
  return YXML_ESYN;
1026
63.3M
}
1027
1028
3.43k
yxml_ret_t yxml_eof(yxml_t *x) {
1029
3.43k
  if(x->state != YXMLS_misc3)
1030
2.15k
    return YXML_EEOF;
1031
1.28k
  return YXML_OK;
1032
3.43k
}
1033