diff options
author | Yorhel <git@yorhel.nl> | 2013-09-23 10:39:44 +0200 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2013-09-23 10:40:23 +0200 |
commit | 5e351ff2ccca675c0010c3938f02a06398c0a1f5 (patch) | |
tree | 4a9ec2496b6340f714509bf1a5397ae340470b33 | |
parent | 1b6f4aa7c5503810a3222592ca0f1a0996e6fec6 (diff) |
Pass PIs to the application + verify that PI name isn't /xml/i
-rw-r--r-- | test/pi01.out | 8 | ||||
-rw-r--r-- | test/pi01.xml | 1 | ||||
-rw-r--r-- | test/pi02.out | 7 | ||||
-rw-r--r-- | test/pi02.xml | 1 | ||||
-rw-r--r-- | test/pi03.out | 8 | ||||
-rw-r--r-- | test/pi03.xml | 1 | ||||
-rw-r--r-- | test/pi04.out | 7 | ||||
-rw-r--r-- | test/pi04.xml | 1 | ||||
-rw-r--r-- | test/pi_err01.out | 2 | ||||
-rw-r--r-- | test/pi_err01.xml | 1 | ||||
-rw-r--r-- | test/pi_err02.out | 2 | ||||
-rw-r--r-- | test/pi_err02.xml | 1 | ||||
-rw-r--r-- | test/test.c | 7 | ||||
-rw-r--r-- | test/xmldecl_err11.out | 2 | ||||
-rw-r--r-- | test/xmldecl_err11.xml | 1 | ||||
-rw-r--r-- | yxml-states | 13 | ||||
-rw-r--r-- | yxml.c | 76 | ||||
-rw-r--r-- | yxml.c.in | 49 | ||||
-rw-r--r-- | yxml.h | 23 |
19 files changed, 120 insertions, 91 deletions
diff --git a/test/pi01.out b/test/pi01.out new file mode 100644 index 0000000..16f0f79 --- /dev/null +++ b/test/pi01.out @@ -0,0 +1,8 @@ + +pistart SomePI +data abc? +piend +elemstart a +content +elemend +ok diff --git a/test/pi01.xml b/test/pi01.xml new file mode 100644 index 0000000..7351b3a --- /dev/null +++ b/test/pi01.xml @@ -0,0 +1 @@ +<?SomePI abc?><a/> diff --git a/test/pi02.out b/test/pi02.out new file mode 100644 index 0000000..180f140 --- /dev/null +++ b/test/pi02.out @@ -0,0 +1,7 @@ + +pistart P +piend +elemstart a +content +elemend +ok diff --git a/test/pi02.xml b/test/pi02.xml new file mode 100644 index 0000000..488f4cd --- /dev/null +++ b/test/pi02.xml @@ -0,0 +1 @@ +<?P?><a/> diff --git a/test/pi03.out b/test/pi03.out new file mode 100644 index 0000000..04ebd35 --- /dev/null +++ b/test/pi03.out @@ -0,0 +1,8 @@ + +pistart XMLData +data <? > <!--abc--> ? +piend +elemstart a +content +elemend +ok diff --git a/test/pi03.xml b/test/pi03.xml new file mode 100644 index 0000000..3c2b5a9 --- /dev/null +++ b/test/pi03.xml @@ -0,0 +1 @@ +<?XMLData <? > <!--abc--> ?><a/> diff --git a/test/pi04.out b/test/pi04.out new file mode 100644 index 0000000..71c7761 --- /dev/null +++ b/test/pi04.out @@ -0,0 +1,7 @@ + +pistart XM +piend +elemstart a +content +elemend +ok diff --git a/test/pi04.xml b/test/pi04.xml new file mode 100644 index 0000000..886e70a --- /dev/null +++ b/test/pi04.xml @@ -0,0 +1 @@ +<?xml version="1.1"?><?XM?><a/> diff --git a/test/pi_err01.out b/test/pi_err01.out new file mode 100644 index 0000000..9456d41 --- /dev/null +++ b/test/pi_err01.out @@ -0,0 +1,2 @@ + +error diff --git a/test/pi_err01.xml b/test/pi_err01.xml new file mode 100644 index 0000000..f1edf92 --- /dev/null +++ b/test/pi_err01.xml @@ -0,0 +1 @@ +<?XML?><a/> diff --git a/test/pi_err02.out b/test/pi_err02.out new file mode 100644 index 0000000..9456d41 --- /dev/null +++ b/test/pi_err02.out @@ -0,0 +1,2 @@ + +error diff --git a/test/pi_err02.xml b/test/pi_err02.xml new file mode 100644 index 0000000..c3f0bf8 --- /dev/null +++ b/test/pi_err02.xml @@ -0,0 +1 @@ +<?A9/data?> diff --git a/test/test.c b/test/test.c index 1e5aee3..ca272c9 100644 --- a/test/test.c +++ b/test/test.c @@ -89,6 +89,13 @@ static void y_printres(yxml_t *x, yxml_ret_t r) { } y_printchar(x->data); break; + case YXML_PISTART: + y_printtoken(x, "pistart "); + y_printstring(x->pi); + break; + case YXML_PIEND: + y_printtoken(x, "piend"); + break; default: y_printtoken(x, "error\n"); exit(0); diff --git a/test/xmldecl_err11.out b/test/xmldecl_err11.out new file mode 100644 index 0000000..9456d41 --- /dev/null +++ b/test/xmldecl_err11.out @@ -0,0 +1,2 @@ + +error diff --git a/test/xmldecl_err11.xml b/test/xmldecl_err11.xml new file mode 100644 index 0000000..a7d605f --- /dev/null +++ b/test/xmldecl_err11.xml @@ -0,0 +1 @@ +<?xml version="1.0"?><?xml version="1.0"><a/> diff --git a/yxml-states b/yxml-states index 3fa5f76..efdc17b 100644 --- a/yxml-states +++ b/yxml-states @@ -75,7 +75,7 @@ le3 '!' @misc3 comment0; '?' @misc3 pi0 lee1 '-' @misc1 comment1; 'D' "OCTYPE" dt0 lee2 '-' @misc2 comment1; '[' "CDATA[" cd0 -leq0 'x' "ml" xmldecl0; NameStart @misc1 pi1 +leq0 'x' "ml" xmldecl0; NameStart @misc1 pistart pi1 # XMLDecl, starting from '<?xml', returns to misc1 @@ -119,12 +119,11 @@ comment5 '>' @ # PI, starting from '<?', returns to @ -# TODO: Verify that the PI name isn't /xml/i -# TODO: Pass the name and contents to the application -pi0 NameStart pi1 -pi1 Name pi1; SP pi2 -pi2 '?' pi3; Char pi2 -pi3 '>' @; Char pi2 +pi0 NameStart pistart pi1 +pi1 Name piname pi1; '?' pinameend pi4; SP pinameend pi2 +pi2 '?' setdata pi3; Char setdata pi2 +pi3 '>' pivalend @; Char setdata pi2 +pi4 '>' pivalend @ # CDSect, starting from '<![DATA[', returns to misc2 @@ -74,6 +74,7 @@ typedef enum { YXMLS_pi1, YXMLS_pi2, YXMLS_pi3, + YXMLS_pi4, YXMLS_std0, YXMLS_std1, YXMLS_std2, @@ -158,19 +159,10 @@ static void yxml_popstack(yxml_t *x) { } -static inline int yxml_elemstart(yxml_t *x, unsigned ch) { - return yxml_pushstack(x, &x->elem, ch); -} - - -static inline int yxml_elemname(yxml_t *x, unsigned ch) { - return yxml_pushstackc(x, ch); -} - - -static inline int yxml_elemnameend(yxml_t *x, unsigned ch) { - return YXML_ELEMSTART; -} +static inline int yxml_elemstart (yxml_t *x, unsigned ch) { return yxml_pushstack(x, &x->elem, ch); } +static inline int yxml_elemname (yxml_t *x, unsigned ch) { return yxml_pushstackc(x, ch); } +static inline int yxml_elemnameend(yxml_t *x, unsigned ch) { return YXML_ELEMSTART; } +static inline int yxml_content (yxml_t *x, unsigned ch) { return YXML_CONTENT; } /* Also used in yxml_elemcloseend(), since this function just removes the last @@ -204,30 +196,18 @@ static inline int yxml_elemcloseend(yxml_t *x, unsigned ch) { } -static inline int yxml_attrstart(yxml_t *x, unsigned ch) { - return yxml_pushstack(x, &x->attr, ch); -} - - -static inline int yxml_attrname(yxml_t *x, unsigned ch) { - return yxml_pushstackc(x, ch); -} - - -static inline int yxml_attrnameend(yxml_t *x, unsigned ch) { - return YXML_ATTRSTART; -} - - -static inline int yxml_attrvalend(yxml_t *x, unsigned ch) { - yxml_popstack(x); - return YXML_ATTREND; -} +static inline int yxml_attrstart (yxml_t *x, unsigned ch) { return yxml_pushstack(x, &x->attr, ch); } +static inline int yxml_attrname (yxml_t *x, unsigned ch) { return yxml_pushstackc(x, ch); } +static inline int yxml_attrnameend(yxml_t *x, unsigned ch) { return YXML_ATTRSTART; } +static inline int yxml_attrvalend (yxml_t *x, unsigned ch) { yxml_popstack(x); return YXML_ATTREND; } -static inline int yxml_content(yxml_t *x, unsigned ch) { - return YXML_CONTENT; +static inline int yxml_pistart (yxml_t *x, unsigned ch) { return yxml_pushstack(x, &x->pi, ch); } +static inline int yxml_piname (yxml_t *x, unsigned ch) { return yxml_pushstackc(x, ch); } +static inline int yxml_pinameend(yxml_t *x, unsigned ch) { + return (x->pi[0]|32) == 'x' && (x->pi[1]|32) == 'm' && (x->pi[2]|32) == 'l' && !x->pi[3] ? YXML_ESYN : YXML_PISTART; } +static inline int yxml_pivalend (yxml_t *x, unsigned ch) { yxml_popstack(x); x->pi = (char *)x->stack; return YXML_PIEND; } static inline int yxml_refstart(yxml_t *x, unsigned ch) { @@ -287,7 +267,7 @@ void yxml_init(yxml_t *x, char *stack, size_t stacksize) { x->stack = (unsigned char *)stack; x->stacksize = stacksize; *x->stack = 0; - x->elem = (char *)x->stack; + x->elem = x->pi = (char *)x->stack; x->state = YXMLS_init; } @@ -723,7 +703,7 @@ yxml_ret_t yxml_parse(yxml_t *x, int _ch) { if(yxml_isNameStart(ch)) { x->state = YXMLS_pi1; x->nextstate = YXMLS_misc1; - return YXML_OK; + return yxml_pistart(x, ch); } break; case YXMLS_misc0: @@ -773,33 +753,43 @@ yxml_ret_t yxml_parse(yxml_t *x, int _ch) { case YXMLS_pi0: if(yxml_isNameStart(ch)) { x->state = YXMLS_pi1; - return YXML_OK; + return yxml_pistart(x, ch); } break; case YXMLS_pi1: if(yxml_isName(ch)) - return YXML_OK; + return yxml_piname(x, ch); + if(ch == (unsigned char)'?') { + x->state = YXMLS_pi4; + return yxml_pinameend(x, ch); + } if(yxml_isSP(ch)) { x->state = YXMLS_pi2; - return YXML_OK; + return yxml_pinameend(x, ch); } break; case YXMLS_pi2: if(ch == (unsigned char)'?') { x->state = YXMLS_pi3; - return YXML_OK; + return yxml_setdata(x, ch); } if(yxml_isChar(ch)) - return YXML_OK; + return yxml_setdata(x, ch); break; case YXMLS_pi3: if(ch == (unsigned char)'>') { x->state = x->nextstate; - return YXML_OK; + return yxml_pivalend(x, ch); } if(yxml_isChar(ch)) { x->state = YXMLS_pi2; - return YXML_OK; + return yxml_setdata(x, ch); + } + break; + case YXMLS_pi4: + if(ch == (unsigned char)'>') { + x->state = x->nextstate; + return yxml_pivalend(x, ch); } break; case YXMLS_std0: @@ -94,19 +94,10 @@ static void yxml_popstack(yxml_t *x) { } -static inline int yxml_elemstart(yxml_t *x, unsigned ch) { - return yxml_pushstack(x, &x->elem, ch); -} - - -static inline int yxml_elemname(yxml_t *x, unsigned ch) { - return yxml_pushstackc(x, ch); -} - - -static inline int yxml_elemnameend(yxml_t *x, unsigned ch) { - return YXML_ELEMSTART; -} +static inline int yxml_elemstart (yxml_t *x, unsigned ch) { return yxml_pushstack(x, &x->elem, ch); } +static inline int yxml_elemname (yxml_t *x, unsigned ch) { return yxml_pushstackc(x, ch); } +static inline int yxml_elemnameend(yxml_t *x, unsigned ch) { return YXML_ELEMSTART; } +static inline int yxml_content (yxml_t *x, unsigned ch) { return YXML_CONTENT; } /* Also used in yxml_elemcloseend(), since this function just removes the last @@ -140,30 +131,18 @@ static inline int yxml_elemcloseend(yxml_t *x, unsigned ch) { } -static inline int yxml_attrstart(yxml_t *x, unsigned ch) { - return yxml_pushstack(x, &x->attr, ch); -} +static inline int yxml_attrstart (yxml_t *x, unsigned ch) { return yxml_pushstack(x, &x->attr, ch); } +static inline int yxml_attrname (yxml_t *x, unsigned ch) { return yxml_pushstackc(x, ch); } +static inline int yxml_attrnameend(yxml_t *x, unsigned ch) { return YXML_ATTRSTART; } +static inline int yxml_attrvalend (yxml_t *x, unsigned ch) { yxml_popstack(x); return YXML_ATTREND; } -static inline int yxml_attrname(yxml_t *x, unsigned ch) { - return yxml_pushstackc(x, ch); -} - - -static inline int yxml_attrnameend(yxml_t *x, unsigned ch) { - return YXML_ATTRSTART; -} - - -static inline int yxml_attrvalend(yxml_t *x, unsigned ch) { - yxml_popstack(x); - return YXML_ATTREND; -} - - -static inline int yxml_content(yxml_t *x, unsigned ch) { - return YXML_CONTENT; +static inline int yxml_pistart (yxml_t *x, unsigned ch) { return yxml_pushstack(x, &x->pi, ch); } +static inline int yxml_piname (yxml_t *x, unsigned ch) { return yxml_pushstackc(x, ch); } +static inline int yxml_pinameend(yxml_t *x, unsigned ch) { + return (x->pi[0]|32) == 'x' && (x->pi[1]|32) == 'm' && (x->pi[2]|32) == 'l' && !x->pi[3] ? YXML_ESYN : YXML_PISTART; } +static inline int yxml_pivalend (yxml_t *x, unsigned ch) { yxml_popstack(x); x->pi = (char *)x->stack; return YXML_PIEND; } static inline int yxml_refstart(yxml_t *x, unsigned ch) { @@ -223,7 +202,7 @@ void yxml_init(yxml_t *x, char *stack, size_t stacksize) { x->stack = (unsigned char *)stack; x->stacksize = stacksize; *x->stack = 0; - x->elem = (char *)x->stack; + x->elem = x->pi = (char *)x->stack; x->state = YXMLS_init; } @@ -36,9 +36,11 @@ typedef enum { YXML_CONTENT = 2, /* Start of element content '.. />' or '.. >' */ YXML_ELEMSTCONT = 3, /* Same as YXML_ELEMSTART|YXML_CONTENT */ YXML_ELEMEND = 4, /* End of an element: '.. />' or '</Tag>' */ - YXML_ATTRSTART = 5, /* Attribute: 'Name=..' */ - YXML_ATTREND = 6, /* End of attribute '.."' */ - YXML_DATA = 7 /* Attribute value or element contents */ + YXML_DATA = 5, /* Attribute value or element/PI contents */ + YXML_ATTRSTART = 6, /* Attribute: 'Name=..' */ + YXML_ATTREND = 7, /* End of attribute '.."' */ + YXML_PISTART = 8, /* Start of a processing instruction */ + YXML_PIEND = 9 /* End of a processing instruction */ } yxml_ret_t; /* When, exactly, are tokens returned? @@ -72,14 +74,23 @@ typedef struct { * including the YXML_ELEMCLOSE for the corresponding element. */ char *elem; - /* The last read character of an attribute value or element data. Changed - * after YXML_DATA and only valid until the next yxml_parse() call. */ + /* The last read character of an attribute value, element data, or + * processing instruction. Changed after YXML_DATA and only valid until the + * next yxml_parse() call. + * Note: For processing instructions, the last '?' is considered part of + * the data, unless the PI was empty (e.g. "<?SomePI?>"), in which case + * no DATA token is emitted at all. */ char data; /* Name of the current attribute. Changed after YXML_ATTRSTART, valid up to * and including the next YXML_ATTREND. */ char *attr; + /* Name/target of the current processing instruction, zero-length if not in + * a PI. Changed after YXML_PISTART, valid up to (but excluding) + * the next YXML_PIEND. */ + char *pi; + /* Line number, byte offset within that line, and total bytes read. These * values refer to the position _after_ the last byte given to * yxml_parse(). These are useful for debugging and error reporting. */ @@ -90,7 +101,7 @@ typedef struct { /* PRIVATE */ int state; - unsigned char *stack; /* Stack of element names + attribute name, separated by \0. Also starts with a \0. */ + unsigned char *stack; /* Stack of element names + attribute/PI name, separated by \0. Also starts with a \0. */ size_t stacksize, stacklen; unsigned char ref[8]; unsigned reflen; |