summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2013-09-04 17:35:20 +0200
committerYorhel <git@yorhel.nl>2013-09-04 17:38:33 +0200
commitc8b799d83bb8b2d5f51d0cd6fdc40589701e1fb0 (patch)
tree5c8127ede9072b4b68cceec3d40f3daa0b68723b
parent49f4741c72498c28806d0064d09850536cb83969 (diff)
Use the stack buffer for attribute names
This makes the yxml_t struct a bit smaller and removes the hardcoded limit on the length of an attribute name. Reduces the compiled size by 200 bytes for some reason I don't understand (better code re-use?). Doesn't seem to affect the performance.
-rw-r--r--yxml-states2
-rw-r--r--yxml.c48
-rw-r--r--yxml.c.in46
-rw-r--r--yxml.h7
4 files changed, 63 insertions, 40 deletions
diff --git a/yxml-states b/yxml-states
index 0c3bc27..b284546 100644
--- a/yxml-states
+++ b/yxml-states
@@ -149,6 +149,6 @@ elem3 '>' selfclose misc2
attr0 Name attrname attr0; SP attrnameend attr1; '=' attrnameend attr2
attr1 SP attr1; '=' attr2
attr2 SP attr2; '\''|'"' $quote attr3
-attr3 AttValue setattrval attr3; '&' refstart attr4; $quote elem2
+attr3 AttValue setattrval attr3; '&' refstart attr4; $quote attrvalend elem2
attr4 Ref ref attr4; '\x3b' refend attr3
diff --git a/yxml.c b/yxml.c
index cf3726c..fc5283c 100644
--- a/yxml.c
+++ b/yxml.c
@@ -131,11 +131,11 @@ static inline int yxml_retmisc(yxml_t *x, unsigned ch) {
}
-static int yxml_elemstart(yxml_t *x, unsigned ch) {
+static int yxml_pushstack(yxml_t *x, char **res, unsigned ch) {
if(x->stacklen+2 >= x->stacksize)
return YXML_ESTACK;
x->stacklen++;
- x->elem = (char *)x->stack+x->stacklen;
+ *res = (char *)x->stack+x->stacklen;
x->stack[x->stacklen] = ch;
x->stacklen++;
x->stack[x->stacklen] = 0;
@@ -143,7 +143,7 @@ static int yxml_elemstart(yxml_t *x, unsigned ch) {
}
-static inline int yxml_elemname(yxml_t *x, unsigned ch) {
+static int yxml_pushstackc(yxml_t *x, unsigned ch) {
if(x->stacklen+1 >= x->stacksize)
return YXML_ESTACK;
x->stack[x->stacklen] = ch;
@@ -153,6 +153,23 @@ static inline int yxml_elemname(yxml_t *x, unsigned ch) {
}
+static void yxml_popstack(yxml_t *x) {
+ do
+ x->stacklen--;
+ while(x->stack[x->stacklen]);
+}
+
+
+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_OPEN;
}
@@ -161,10 +178,7 @@ static inline int yxml_elemnameend(yxml_t *x, unsigned ch) {
/* Also used in yxml_elemcloseend(), since this function just removes the last
* element from the stack and returns CLOSE and EOD when appropriate. */
static int yxml_selfclose(yxml_t *x, unsigned ch) {
- do
- x->stacklen--;
- while(x->stack[x->stacklen]);
-
+ yxml_popstack(x);
if(x->stacklen) {
x->elem = (char *)x->stack+x->stacklen-1;
while(*(x->elem-1))
@@ -192,20 +206,12 @@ static inline int yxml_elemcloseend(yxml_t *x, unsigned ch) {
static inline int yxml_attrstart(yxml_t *x, unsigned ch) {
- x->attrlen = 1;
- x->attr[0] = ch;
- x->attr[1] = 0;
- return YXML_OK;
+ return yxml_pushstack(x, &x->attr, ch);
}
static inline int yxml_attrname(yxml_t *x, unsigned ch) {
- if(x->attrlen >= YXML_MAX_ATTRNAME)
- return YXML_EATTR;
- x->attr[x->attrlen] = ch;
- x->attrlen++;
- x->attr[x->attrlen] = 0;
- return YXML_OK;
+ return yxml_pushstackc(x, ch);
}
@@ -214,6 +220,12 @@ static inline int yxml_attrnameend(yxml_t *x, unsigned ch) {
}
+static inline int yxml_attrvalend(yxml_t *x, unsigned ch) {
+ yxml_popstack(x);
+ return YXML_OK;
+}
+
+
static inline int yxml_attrsend(yxml_t *x, unsigned ch) {
return YXML_EOA;
}
@@ -352,7 +364,7 @@ yxml_ret_t yxml_parse(yxml_t *x, int _ch) {
}
if(x->quote == ch) {
x->state = YXMLS_elem2;
- return YXML_OK;
+ return yxml_attrvalend(x, ch);
}
break;
case YXMLS_attr4:
diff --git a/yxml.c.in b/yxml.c.in
index c6c2bd0..45e0468 100644
--- a/yxml.c.in
+++ b/yxml.c.in
@@ -74,11 +74,11 @@ static inline int yxml_retmisc(yxml_t *x, unsigned ch) {
}
-static int yxml_elemstart(yxml_t *x, unsigned ch) {
+static int yxml_pushstack(yxml_t *x, char **res, unsigned ch) {
if(x->stacklen+2 >= x->stacksize)
return YXML_ESTACK;
x->stacklen++;
- x->elem = (char *)x->stack+x->stacklen;
+ *res = (char *)x->stack+x->stacklen;
x->stack[x->stacklen] = ch;
x->stacklen++;
x->stack[x->stacklen] = 0;
@@ -86,7 +86,7 @@ static int yxml_elemstart(yxml_t *x, unsigned ch) {
}
-static inline int yxml_elemname(yxml_t *x, unsigned ch) {
+static int yxml_pushstackc(yxml_t *x, unsigned ch) {
if(x->stacklen+1 >= x->stacksize)
return YXML_ESTACK;
x->stack[x->stacklen] = ch;
@@ -96,6 +96,23 @@ static inline int yxml_elemname(yxml_t *x, unsigned ch) {
}
+static void yxml_popstack(yxml_t *x) {
+ do
+ x->stacklen--;
+ while(x->stack[x->stacklen]);
+}
+
+
+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_OPEN;
}
@@ -104,10 +121,7 @@ static inline int yxml_elemnameend(yxml_t *x, unsigned ch) {
/* Also used in yxml_elemcloseend(), since this function just removes the last
* element from the stack and returns CLOSE and EOD when appropriate. */
static int yxml_selfclose(yxml_t *x, unsigned ch) {
- do
- x->stacklen--;
- while(x->stack[x->stacklen]);
-
+ yxml_popstack(x);
if(x->stacklen) {
x->elem = (char *)x->stack+x->stacklen-1;
while(*(x->elem-1))
@@ -135,20 +149,12 @@ static inline int yxml_elemcloseend(yxml_t *x, unsigned ch) {
static inline int yxml_attrstart(yxml_t *x, unsigned ch) {
- x->attrlen = 1;
- x->attr[0] = ch;
- x->attr[1] = 0;
- return YXML_OK;
+ return yxml_pushstack(x, &x->attr, ch);
}
static inline int yxml_attrname(yxml_t *x, unsigned ch) {
- if(x->attrlen >= YXML_MAX_ATTRNAME)
- return YXML_EATTR;
- x->attr[x->attrlen] = ch;
- x->attrlen++;
- x->attr[x->attrlen] = 0;
- return YXML_OK;
+ return yxml_pushstackc(x, ch);
}
@@ -157,6 +163,12 @@ static inline int yxml_attrnameend(yxml_t *x, unsigned ch) {
}
+static inline int yxml_attrvalend(yxml_t *x, unsigned ch) {
+ yxml_popstack(x);
+ return YXML_OK;
+}
+
+
static inline int yxml_attrsend(yxml_t *x, unsigned ch) {
return YXML_EOA;
}
diff --git a/yxml.h b/yxml.h
index f8a4648..6e70298 100644
--- a/yxml.h
+++ b/yxml.h
@@ -23,14 +23,13 @@
#include <stdint.h>
#include <stddef.h>
-#define YXML_MAX_ATTRNAME 126
#define YXML_MAX_REF 7 /* Must be >=7 in order for the hack in yxml_refend() to work */
typedef enum {
YXML_EREF = -5, /* Invalid character or entity reference (&whatever;) */
YXML_ECLOSE = -4, /* Close tag does not match open tag (<Tag> .. </OtherTag>) */
- YXML_ESTACK = -3, /* Stack overflow (too deeply nested tags or too long element name) */
+ YXML_ESTACK = -3, /* Stack overflow (too deeply nested tags or too long element/attribute name) */
YXML_EATTR = -2, /* Too long attribute name */
YXML_ESYN = -1, /* Syntax error (unexpected byte) */
YXML_OK = 0, /* Character consumed, no new token present */
@@ -76,7 +75,7 @@ typedef struct {
/* Currently opened attribute name, zero-length if not in an attribute.
* Changed after YXML_ATTR. */
- char attr[YXML_MAX_ATTRNAME+1];
+ char *attr;
/* Line number, byte offset within that line, and total bytes read. These
* values refer to the position _after_ the last byte given to
@@ -88,7 +87,7 @@ typedef struct {
/* PRIVATE */
int state;
- unsigned char *stack; /* Stack of element names, separated by \0. Also starts with a \0. */
+ unsigned char *stack; /* Stack of element names + attribute name, separated by \0. Also starts with a \0. */
size_t stacksize, stacklen;
size_t attrlen;
unsigned quote;