commit 2d5b42efae35300a9eb7cc3a834dc8c522bf5a71
parent 1ad44956f0f7b044440f04ee72a7affef48b804c
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sat, 22 Aug 2015 20:11:05 +0200
xml: simplify XML reader
Diffstat:
8 files changed, 27 insertions(+), 104 deletions(-)
diff --git a/README.xml b/README.xml
@@ -55,6 +55,8 @@ Should be trivial, see xml.c and xml.h and the examples below.
The most minimal implementation to read and parse from fd 0 (stdin) is:
+ #include <stdio.h>
+
#include "xml.h"
static XMLParser x;
@@ -62,7 +64,8 @@ The most minimal implementation to read and parse from fd 0 (stdin) is:
int
main(void)
{
- xml_parse_fd(&x, 0); /* xml_parse_buf(&x, "<sup />", 7); */
+ x.getnext = getchar;
+ xml_parse(&x);
return 0;
}
diff --git a/sfeed.c b/sfeed.c
@@ -743,7 +743,8 @@ main(int argc, char *argv[])
parser.xmltagstart = xml_handler_start_el;
parser.xmltagstartparsed = xml_handler_start_el_parsed;
- xml_parse_fd(&parser, 0);
+ parser.getnext = getchar;
+ xml_parse(&parser);
return 0;
}
diff --git a/sfeed_opml_import.c b/sfeed_opml_import.c
@@ -95,7 +95,8 @@ main(void)
"# list of feeds to fetch:\n"
"feeds() {\n"
" # feed <name> <feedurl> [basesiteurl] [encoding]\n", stdout);
- xml_parse_fd(&parser, 0);
+ parser.getnext = getchar;
+ xml_parse(&parser);
fputs("}\n", stdout);
return 0;
diff --git a/sfeed_web.c b/sfeed_web.c
@@ -98,7 +98,8 @@ main(int argc, char *argv[])
parser.xmltagstart = xmltagstart;
parser.xmltagstartparsed = xmltagstartparsed;
- xml_parse_fd(&parser, 0);
+ parser.getnext = getchar;
+ xml_parse(&parser);
return found > 0 ? 0: 1;
}
diff --git a/sfeed_xmlenc.c b/sfeed_xmlenc.c
@@ -61,7 +61,8 @@ main(void)
parser.xmltagend = xmltagend;
parser.xmltagstart = xmltagstart;
- xml_parse_fd(&parser, 0);
+ parser.getnext = getchar;
+ xml_parse(&parser);
return 1;
}
diff --git a/util.h b/util.h
@@ -31,5 +31,3 @@ int parseuri(const char *, struct uri *, int);
int strtotime(const char *, time_t *);
char * xbasename(const char *);
void xmlencode(const char *, FILE *);
-
-
diff --git a/xml.c b/xml.c
@@ -8,71 +8,13 @@
#include "xml.h"
-struct xml_context_fd {
- char buf[BUFSIZ];
- int readerrno;
- int fd;
- size_t nread;
- size_t offset;
-};
-
-struct xml_context_buf {
- const char *buf;
- size_t len;
- size_t offset;
-};
-
-static int
-xml_getnext_buf(XMLParser *x)
-{
- struct xml_context_buf *d = (struct xml_context_buf *)x->getnext_data;
-
- if (d->offset >= d->len)
- return EOF;
- return (int)d->buf[d->offset++];
-}
-
-static int /* read from fd with some buffering */
-xml_getnext_fd(XMLParser *x)
-{
- struct xml_context_fd *d = (struct xml_context_fd *)x->getnext_data;
- ssize_t r;
-
- /* previous read error was set */
- if (d->readerrno)
- return EOF;
-
- if (d->offset >= d->nread) {
- d->offset = 0;
-again:
- r = read(d->fd, d->buf, sizeof(d->buf));
- if (r == -1) {
- if (errno == EINTR)
- goto again;
- d->readerrno = errno;
- d->nread = 0;
- return EOF;
- } else if (!r) {
- return EOF;
- }
- d->nread = r;
- }
- return (int)d->buf[d->offset++];
-}
-
-static int
-xml_getnext(XMLParser *x)
-{
- return x->getnext(x);
-}
-
static void
xml_parseattrs(XMLParser *x)
{
size_t namelen = 0, valuelen;
int c, endsep, endname = 0;
- while ((c = xml_getnext(x)) != EOF) {
+ while ((c = x->getnext()) != EOF) {
if (isspace(c)) { /* TODO: simplify endname ? */
if (namelen)
endname = 1;
@@ -99,7 +41,7 @@ xml_parseattrs(XMLParser *x)
endsep = c; /* c is end separator */
if (x->xmlattrstart)
x->xmlattrstart(x, x->tag, x->taglen, x->name, namelen);
- for (valuelen = 0; (c = xml_getnext(x)) != EOF;) {
+ for (valuelen = 0; (c = x->getnext()) != EOF;) {
if (c == '&') { /* entities */
x->data[valuelen] = '\0';
/* call data function with data before entity if there is data */
@@ -107,7 +49,7 @@ xml_parseattrs(XMLParser *x)
x->xmlattr(x, x->tag, x->taglen, x->name, namelen, x->data, valuelen);
x->data[0] = c;
valuelen = 1;
- while ((c = xml_getnext(x)) != EOF) {
+ while ((c = x->getnext()) != EOF) {
if (c == endsep)
break;
if (valuelen < sizeof(x->data) - 1)
@@ -173,7 +115,7 @@ xml_parsecomment(XMLParser *x)
if (x->xmlcommentstart)
x->xmlcommentstart(x);
- while ((c = xml_getnext(x)) != EOF) {
+ while ((c = x->getnext()) != EOF) {
if (c == end[i]) {
if (end[++i] == '\0') { /* end */
x->data[datalen] = '\0';
@@ -217,7 +159,7 @@ xml_parsecdata(XMLParser *x)
if (x->xmlcdatastart)
x->xmlcdatastart(x);
- while ((c = xml_getnext(x)) != EOF) {
+ while ((c = x->getnext()) != EOF) {
if (c == end[i]) {
if (end[++i] == '\0') { /* end */
x->data[datalen] = '\0';
@@ -374,17 +316,19 @@ xml_parse(XMLParser *x)
int c, ispi;
size_t datalen, tagdatalen, taglen;
- while ((c = xml_getnext(x)) != EOF && c != '<')
+ if (!x->getnext)
+ return;
+ while ((c = x->getnext()) != EOF && c != '<')
; /* skip until < */
while (c != EOF) {
if (c == '<') { /* parse tag */
- if ((c = xml_getnext(x)) == EOF)
+ if ((c = x->getnext()) == EOF)
return;
x->tag[0] = '\0';
x->taglen = 0;
if (c == '!') { /* cdata and comments */
- for (tagdatalen = 0; (c = xml_getnext(x)) != EOF;) {
+ for (tagdatalen = 0; (c = x->getnext()) != EOF;) {
if (tagdatalen <= sizeof("[CDATA[") - 1) /* if (d < sizeof(x->data)) */
x->data[tagdatalen++] = c; /* TODO: prevent overflow */
if (c == '>')
@@ -404,7 +348,7 @@ xml_parse(XMLParser *x)
} else {
/* normal tag (open, short open, close), processing instruction. */
if (isspace(c))
- while ((c = xml_getnext(x)) != EOF && isspace(c))
+ while ((c = x->getnext()) != EOF && isspace(c))
;
if (c == EOF)
return;
@@ -412,7 +356,7 @@ xml_parse(XMLParser *x)
ispi = (c == '?') ? 1 : 0;
x->isshorttag = ispi;
taglen = 1;
- while ((c = xml_getnext(x)) != EOF) {
+ while ((c = x->getnext()) != EOF) {
if (c == '/') /* TODO: simplify short tag? */
x->isshorttag = 1; /* short tag */
else if (c == '>' || isspace(c)) {
@@ -444,7 +388,7 @@ xml_parse(XMLParser *x)
datalen = 0;
if (x->xmldatastart)
x->xmldatastart(x);
- while ((c = xml_getnext(x)) != EOF) {
+ while ((c = x->getnext()) != EOF) {
if (c == '&') {
if (datalen) {
x->data[datalen] = '\0';
@@ -453,7 +397,7 @@ xml_parse(XMLParser *x)
}
x->data[0] = c;
datalen = 1;
- while ((c = xml_getnext(x)) != EOF) {
+ while ((c = x->getnext()) != EOF) {
if (c == '<')
break;
if (datalen < sizeof(x->data) - 1)
@@ -491,26 +435,3 @@ xml_parse(XMLParser *x)
}
}
}
-
-void
-xml_parse_buf(XMLParser *x, const char *buf, size_t len)
-{
- struct xml_context_buf ctx = { .buf = buf, .len = len };
-
- x->getnext = xml_getnext_buf;
- x->getnext_data = (void *)&ctx;
- xml_parse(x);
-}
-
-void
-xml_parse_fd(XMLParser *x, int fd)
-{
- struct xml_context_fd ctx;
-
- memset(&ctx, 0, sizeof(ctx));
- ctx.fd = fd;
-
- x->getnext = xml_getnext_fd;
- x->getnext_data = (void *)&ctx;
- xml_parse(x);
-}
diff --git a/xml.h b/xml.h
@@ -23,8 +23,7 @@ typedef struct xmlparser {
void (*xmltagstartparsed)(struct xmlparser *, const char *,
size_t, int);
- int (*getnext)(struct xmlparser *);
- void *getnext_data; /* custom data for getnext */
+ int (*getnext)(void);
/* current tag */
char tag[1024];
@@ -43,5 +42,3 @@ ssize_t xml_namedentitytostr(const char *, char *, size_t);
ssize_t xml_numericetitytostr(const char *, char *, size_t);
void xml_parse(XMLParser *);
-void xml_parse_buf(XMLParser *, const char *, size_t);
-void xml_parse_fd(XMLParser *, int);