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