summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2013-09-24 10:39:42 +0200
committerYorhel <git@yorhel.nl>2013-09-24 10:42:28 +0200
commitd297de22845fd2fd090d7dba88412941c7b5dbb8 (patch)
treeb9c8e6d2484eb60bcf3119319dfa632617fd701d
parente11e36a4229035cc75a1be837382e58d61583563 (diff)
API: Change 'data' field from a single char to a string
Allowing multiple bytes to be returned in a single YXML_DATA token. This is (unfortunately) necessary for a few special cases: - &#N; for N > 127, - <? ? ?> - <![CDATA[ ] ]]> I'll fix those separately in the next commits. This data string is now also re-used as a temporary buffer for entity/char references, removing the private 'ref' field.
-rw-r--r--test/test.c2
-rw-r--r--yxml.c22
-rw-r--r--yxml.c.in22
-rw-r--r--yxml.h7
4 files changed, 32 insertions, 21 deletions
diff --git a/test/test.c b/test/test.c
index ca272c9..c0a3c6c 100644
--- a/test/test.c
+++ b/test/test.c
@@ -87,7 +87,7 @@ static void y_printres(yxml_t *x, yxml_ret_t r) {
y_printtoken(x, "data ");
indata = 1;
}
- y_printchar(x->data);
+ y_printstring(x->data);
break;
case YXML_PISTART:
y_printtoken(x, "pistart ");
diff --git a/yxml.c b/yxml.c
index c300fbd..213b7d1 100644
--- a/yxml.c
+++ b/yxml.c
@@ -110,14 +110,20 @@ typedef enum {
#define yxml_isRef(c) (yxml_isNum(c) || yxml_isAlpha(c) || c == '#')
-/* Set the x->data value to ch and tell the application we have some data.
- * This can't be done with simple assignment because char may be unsigned, and
+/* Set the given char value to ch (0<=ch<=255).
+ * This can't be done with simple assignment because char may be signed, and
* unsigned-to-signed overflow is implementation defined in C. This function
* /looks/ inefficient, but gcc compiles it down to a single movb instruction
* on x86, even with -O0. */
-static inline int yxml_setdata(yxml_t *x, unsigned ch) {
+static inline void yxml_setchar(char *dest, unsigned ch) {
unsigned char _ch = ch;
- memcpy(&x->data, &_ch, 1);
+ memcpy(dest, &_ch, 1);
+}
+
+
+static inline int yxml_setdata(yxml_t *x, unsigned ch) {
+ yxml_setchar(x->data, ch);
+ x->data[1] = 0;
return YXML_DATA;
}
@@ -209,23 +215,23 @@ static inline int yxml_pivalend (yxml_t *x, unsigned ch) { yxml_popstack(x); x->
static inline int yxml_refstart(yxml_t *x, unsigned ch) {
- memset(x->ref, 0, sizeof(x->ref));
+ memset(x->data, 0, sizeof(x->data));
x->reflen = 0;
return YXML_OK;
}
static int yxml_ref(yxml_t *x, unsigned ch) {
- if(x->reflen >= sizeof(x->ref)-1)
+ if(x->reflen >= sizeof(x->data)-1)
return YXML_EREF;
- x->ref[x->reflen] = ch;
+ yxml_setchar(x->data+x->reflen, ch);
x->reflen++;
return YXML_OK;
}
static int yxml_refend(yxml_t *x, unsigned ch) {
- unsigned char *r = x->ref;
+ unsigned char *r = (unsigned char *)x->data;
ch = 0;
if(*r == '#') {
if(r[1] == 'x')
diff --git a/yxml.c.in b/yxml.c.in
index 6a32a08..c6c1a4a 100644
--- a/yxml.c.in
+++ b/yxml.c.in
@@ -46,14 +46,20 @@ typedef enum {
#define yxml_isRef(c) (yxml_isNum(c) || yxml_isAlpha(c) || c == '#')
-/* Set the x->data value to ch and tell the application we have some data.
- * This can't be done with simple assignment because char may be unsigned, and
+/* Set the given char value to ch (0<=ch<=255).
+ * This can't be done with simple assignment because char may be signed, and
* unsigned-to-signed overflow is implementation defined in C. This function
* /looks/ inefficient, but gcc compiles it down to a single movb instruction
* on x86, even with -O0. */
-static inline int yxml_setdata(yxml_t *x, unsigned ch) {
+static inline void yxml_setchar(char *dest, unsigned ch) {
unsigned char _ch = ch;
- memcpy(&x->data, &_ch, 1);
+ memcpy(dest, &_ch, 1);
+}
+
+
+static inline int yxml_setdata(yxml_t *x, unsigned ch) {
+ yxml_setchar(x->data, ch);
+ x->data[1] = 0;
return YXML_DATA;
}
@@ -145,23 +151,23 @@ static inline int yxml_pivalend (yxml_t *x, unsigned ch) { yxml_popstack(x); x->
static inline int yxml_refstart(yxml_t *x, unsigned ch) {
- memset(x->ref, 0, sizeof(x->ref));
+ memset(x->data, 0, sizeof(x->data));
x->reflen = 0;
return YXML_OK;
}
static int yxml_ref(yxml_t *x, unsigned ch) {
- if(x->reflen >= sizeof(x->ref)-1)
+ if(x->reflen >= sizeof(x->data)-1)
return YXML_EREF;
- x->ref[x->reflen] = ch;
+ yxml_setchar(x->data+x->reflen, ch);
x->reflen++;
return YXML_OK;
}
static int yxml_refend(yxml_t *x, unsigned ch) {
- unsigned char *r = x->ref;
+ unsigned char *r = (unsigned char *)x->data;
ch = 0;
if(*r == '#') {
if(r[1] == 'x')
diff --git a/yxml.h b/yxml.h
index b8c7190..f3a014e 100644
--- a/yxml.h
+++ b/yxml.h
@@ -74,13 +74,13 @@ typedef struct {
* including the YXML_ELEMCLOSE for the corresponding element. */
char *elem;
- /* The last read character of an attribute value, element data, or
+ /* The last read character(s) of an attribute value, element data, or
* processing instruction. Changed after YXML_DATA and only valid until the
- * next yxml_parse() call.
+ * next yxml_parse() call. Currently, only the first byte is ever set.
* 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;
+ char data[8];
/* Name of the current attribute. Changed after YXML_ATTRSTART, valid up to
* and including the next YXML_ATTREND. */
@@ -103,7 +103,6 @@ typedef struct {
int state;
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;
unsigned quote;
int nextstate; /* Used for '@' state remembering and for the "string" consuming state */