summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2013-09-23 10:39:44 +0200
committerYorhel <git@yorhel.nl>2013-09-23 10:40:23 +0200
commit5e351ff2ccca675c0010c3938f02a06398c0a1f5 (patch)
tree4a9ec2496b6340f714509bf1a5397ae340470b33
parent1b6f4aa7c5503810a3222592ca0f1a0996e6fec6 (diff)
Pass PIs to the application + verify that PI name isn't /xml/i
-rw-r--r--test/pi01.out8
-rw-r--r--test/pi01.xml1
-rw-r--r--test/pi02.out7
-rw-r--r--test/pi02.xml1
-rw-r--r--test/pi03.out8
-rw-r--r--test/pi03.xml1
-rw-r--r--test/pi04.out7
-rw-r--r--test/pi04.xml1
-rw-r--r--test/pi_err01.out2
-rw-r--r--test/pi_err01.xml1
-rw-r--r--test/pi_err02.out2
-rw-r--r--test/pi_err02.xml1
-rw-r--r--test/test.c7
-rw-r--r--test/xmldecl_err11.out2
-rw-r--r--test/xmldecl_err11.xml1
-rw-r--r--yxml-states13
-rw-r--r--yxml.c76
-rw-r--r--yxml.c.in49
-rw-r--r--yxml.h23
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
diff --git a/yxml.c b/yxml.c
index 581cad6..05bd6de 100644
--- a/yxml.c
+++ b/yxml.c
@@ -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:
diff --git a/yxml.c.in b/yxml.c.in
index 5ee9cbf..619240c 100644
--- a/yxml.c.in
+++ b/yxml.c.in
@@ -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;
}
diff --git a/yxml.h b/yxml.h
index 611659a..b8c7190 100644
--- a/yxml.h
+++ b/yxml.h
@@ -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;