diff options
author | Yorhel <git@yorhel.nl> | 2013-09-04 17:35:20 +0200 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2013-09-04 17:38:33 +0200 |
commit | c8b799d83bb8b2d5f51d0cd6fdc40589701e1fb0 (patch) | |
tree | 5c8127ede9072b4b68cceec3d40f3daa0b68723b | |
parent | 49f4741c72498c28806d0064d09850536cb83969 (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-states | 2 | ||||
-rw-r--r-- | yxml.c | 48 | ||||
-rw-r--r-- | yxml.c.in | 46 | ||||
-rw-r--r-- | yxml.h | 7 |
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 @@ -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: @@ -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; } @@ -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; |