iseveral improvements and more efficient xml parser - xml2tsv - a simple xml-to-tsv converter, based on xmlparser Err bitreich.org 70 1Log /scm/xml2tsv/log.gph bitreich.org 70 1Files /scm/xml2tsv/files.gph bitreich.org 70 1Refs /scm/xml2tsv/refs.gph bitreich.org 70 1Tags /scm/xml2tsv/tag bitreich.org 70 1README /scm/xml2tsv/file/README.md.gph bitreich.org 70 1LICENSE /scm/xml2tsv/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 1commit 60c249ec24ab865c4a55759c7ffde2da99530b1d /scm/xml2tsv/commit/60c249ec24ab865c4a55759c7ffde2da99530b1d.gph bitreich.org 70 1parent b416c171bb34297d7f8bc4c027de7136a113d144 /scm/xml2tsv/commit/b416c171bb34297d7f8bc4c027de7136a113d144.gph bitreich.org 70 hAuthor: Hiltjo Posthuma URL:mailto:hiltjo@codemadness.org bitreich.org 70 iDate: Wed, 30 Sep 2020 11:42:07 +0100 Err bitreich.org 70 i Err bitreich.org 70 iseveral improvements and more efficient xml parser Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M xml.c | 36 +++---------------------------- Err bitreich.org 70 i M xml.h | 12 +++++------- Err bitreich.org 70 i M xml2tsv.c | 93 ++++++++++--------------------- Err bitreich.org 70 i Err bitreich.org 70 i3 files changed, 38 insertions(+), 103 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/xml.c b/xml.c /scm/xml2tsv/file/xml.c.gph bitreich.org 70 i@@ -116,49 +116,19 @@ startvalue: Err bitreich.org 70 i static void Err bitreich.org 70 i xml_parsecomment(XMLParser *x) Err bitreich.org 70 i { Err bitreich.org 70 i- size_t datalen = 0, i = 0; Err bitreich.org 70 i+ size_t i = 0; Err bitreich.org 70 i int c; Err bitreich.org 70 i Err bitreich.org 70 i- if (x->xmlcommentstart) Err bitreich.org 70 i- x->xmlcommentstart(x); Err bitreich.org 70 i while ((c = GETNEXT()) != EOF) { Err bitreich.org 70 i- if (c == '-' || c == '>') { Err bitreich.org 70 i- if (x->xmlcomment && datalen) { Err bitreich.org 70 i- x->data[datalen] = '\0'; Err bitreich.org 70 i- x->xmlcomment(x, x->data, datalen); Err bitreich.org 70 i- datalen = 0; Err bitreich.org 70 i- } Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i if (c == '-') { Err bitreich.org 70 i- if (++i > 2) { Err bitreich.org 70 i- if (x->xmlcomment) Err bitreich.org 70 i- for (; i > 2; i--) Err bitreich.org 70 i- x->xmlcomment(x, "-", 1); Err bitreich.org 70 i+ if (++i > 2) Err bitreich.org 70 i i = 2; Err bitreich.org 70 i- } Err bitreich.org 70 i continue; Err bitreich.org 70 i } else if (c == '>' && i == 2) { Err bitreich.org 70 i- if (x->xmlcommentend) Err bitreich.org 70 i- x->xmlcommentend(x); Err bitreich.org 70 i return; Err bitreich.org 70 i } else if (i) { Err bitreich.org 70 i- if (x->xmlcomment) { Err bitreich.org 70 i- for (; i > 0; i--) Err bitreich.org 70 i- x->xmlcomment(x, "-", 1); Err bitreich.org 70 i- } Err bitreich.org 70 i i = 0; Err bitreich.org 70 i } Err bitreich.org 70 i- Err bitreich.org 70 i- if (datalen < sizeof(x->data) - 1) { Err bitreich.org 70 i- x->data[datalen++] = c; Err bitreich.org 70 i- } else { Err bitreich.org 70 i- x->data[datalen] = '\0'; Err bitreich.org 70 i- if (x->xmlcomment) Err bitreich.org 70 i- x->xmlcomment(x, x->data, datalen); Err bitreich.org 70 i- x->data[0] = c; Err bitreich.org 70 i- datalen = 1; Err bitreich.org 70 i- } Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i@@ -286,7 +256,7 @@ numericentitytostr(const char *e, char *buf, size_t bufsiz) Err bitreich.org 70 i l = strtol(++e, &end, 16); Err bitreich.org 70 i else Err bitreich.org 70 i l = strtol(e, &end, 10); Err bitreich.org 70 i- /* invalid value or not a well-formed entity or invalid codepoint */ Err bitreich.org 70 i+ /* invalid value or not a well-formed entity or invalid code point */ Err bitreich.org 70 i if (errno || e == end || *end != ';' || l < 0 || l > 0x10ffff) Err bitreich.org 70 i return -1; Err bitreich.org 70 i len = codepointtoutf8(l, buf); Err bitreich.org 70 1diff --git a/xml.h b/xml.h /scm/xml2tsv/file/xml.h.gph bitreich.org 70 i@@ -1,5 +1,5 @@ Err bitreich.org 70 i-#ifndef _XML_H Err bitreich.org 70 i-#define _XML_H Err bitreich.org 70 i+#ifndef _XML_H_ Err bitreich.org 70 i+#define _XML_H_ Err bitreich.org 70 i Err bitreich.org 70 i #include Err bitreich.org 70 i Err bitreich.org 70 i@@ -16,9 +16,6 @@ typedef struct xmlparser { Err bitreich.org 70 i void (*xmlcdatastart)(struct xmlparser *); Err bitreich.org 70 i void (*xmlcdata)(struct xmlparser *, const char *, size_t); Err bitreich.org 70 i void (*xmlcdataend)(struct xmlparser *); Err bitreich.org 70 i- void (*xmlcommentstart)(struct xmlparser *); Err bitreich.org 70 i- void (*xmlcomment)(struct xmlparser *, const char *, size_t); Err bitreich.org 70 i- void (*xmlcommentend)(struct xmlparser *); Err bitreich.org 70 i void (*xmldata)(struct xmlparser *, const char *, size_t); Err bitreich.org 70 i void (*xmldataend)(struct xmlparser *); Err bitreich.org 70 i void (*xmldataentity)(struct xmlparser *, const char *, size_t); Err bitreich.org 70 i@@ -29,8 +26,9 @@ typedef struct xmlparser { Err bitreich.org 70 i size_t, int); Err bitreich.org 70 i Err bitreich.org 70 i #ifndef GETNEXT Err bitreich.org 70 i- #define GETNEXT (x)->getnext Err bitreich.org 70 i- int (*getnext)(void); Err bitreich.org 70 i+ /* GETNEXT overridden to reduce function call overhead and Err bitreich.org 70 i+ further context optimizations. */ Err bitreich.org 70 i+ #define GETNEXT getchar Err bitreich.org 70 i #endif Err bitreich.org 70 i Err bitreich.org 70 i /* current tag */ Err bitreich.org 70 1diff --git a/xml2tsv.c b/xml2tsv.c /scm/xml2tsv/file/xml2tsv.c.gph bitreich.org 70 i@@ -64,7 +64,7 @@ void stack_init(tstack_t *t){ Err bitreich.org 70 i /* utility functions */ Err bitreich.org 70 i Err bitreich.org 70 i /* quote_print: quote \\, \n, \t, and strip other ctrl chars */ Err bitreich.org 70 i-void quote_print(FILE *f, const char *s){ Err bitreich.org 70 i+void quote_print(const char *s){ Err bitreich.org 70 i const char *tmp = s; Err bitreich.org 70 i size_t len; Err bitreich.org 70 i int i; Err bitreich.org 70 i@@ -72,36 +72,45 @@ void quote_print(FILE *f, const char *s){ Err bitreich.org 70 i len = strcspn(tmp, "\\\n\t"); Err bitreich.org 70 i for(i=0; i 0){ Err bitreich.org 70 i- fprintf(f, "\\n"); Err bitreich.org 70 i+ fputs("\\n", stdout); Err bitreich.org 70 i } Err bitreich.org 70 i tmp ++; Err bitreich.org 70 i break; Err bitreich.org 70 i case '\t': Err bitreich.org 70 i- fprintf(f, "\\t"); Err bitreich.org 70 i+ fputs("\\t", stdout); Err bitreich.org 70 i tmp ++; Err bitreich.org 70 i break; Err bitreich.org 70 i case '\r': Err bitreich.org 70 i- fprintf(f, "\\r"); Err bitreich.org 70 i+ fputs("\\r", stdout); Err bitreich.org 70 i tmp ++; Err bitreich.org 70 i break; Err bitreich.org 70 i case '\\': Err bitreich.org 70 i- fprintf(f, "\\\\"); Err bitreich.org 70 i+ fputs("\\\\", stdout); Err bitreich.org 70 i tmp ++; Err bitreich.org 70 i break; Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i-void print_cur_str(FILE *f, tstack_t *t){ Err bitreich.org 70 i+void print_cur_str(tstack_t *t){ Err bitreich.org 70 i int i; Err bitreich.org 70 i for (i=0; i<=t->top; i++){ Err bitreich.org 70 i- fprintf(f, "/%s", t->st[i]); Err bitreich.org 70 i+ putchar('/'); Err bitreich.org 70 i+ fputs(t->st[i], stdout); Err bitreich.org 70 i+ } Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+void print_cur_str_fp(FILE *f, tstack_t *t){ Err bitreich.org 70 i+ int i; Err bitreich.org 70 i+ for (i=0; i<=t->top; i++){ Err bitreich.org 70 i+ fputc('/', f); Err bitreich.org 70 i+ fputs(t->st[i], f); Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i@@ -110,13 +119,13 @@ void print_cur_str(FILE *f, tstack_t *t){ Err bitreich.org 70 i tstack_t st; Err bitreich.org 70 i char emitsep; Err bitreich.org 70 i Err bitreich.org 70 i-/* xml callbacks */ Err bitreich.org 70 i+/* XML callbacks */ Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i xmlattr(XMLParser *x, const char *t, size_t tl, const char *a, size_t al, Err bitreich.org 70 i const char *v, size_t vl) Err bitreich.org 70 i { Err bitreich.org 70 i- printf("%s", v); Err bitreich.org 70 i+ fputs(v, stdout); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i@@ -133,56 +142,33 @@ xmlattrentity(XMLParser *x, const char *t, size_t tl, const char *a, size_t al, Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i-xmlattrend(XMLParser *x, const char *t, size_t tl, const char *a, size_t al) Err bitreich.org 70 i-{ Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i xmlattrstart(XMLParser *x, const char *t, size_t tl, const char *a, size_t al) Err bitreich.org 70 i { Err bitreich.org 70 i- printf("%c%s%c", SEP, a, SATTR); Err bitreich.org 70 i+ putchar(SEP); Err bitreich.org 70 i+ fputs(a, stdout); Err bitreich.org 70 i+ putchar(SATTR); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i xmlcdatastart(XMLParser *x) Err bitreich.org 70 i { Err bitreich.org 70 i- printf("%c", SEP); Err bitreich.org 70 i+ putchar(SEP); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i xmlcdata(XMLParser *x, const char *d, size_t dl) Err bitreich.org 70 i { Err bitreich.org 70 i- quote_print(stdout, d); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-xmlcdataend(XMLParser *x) Err bitreich.org 70 i-{ Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-xmlcommentstart(XMLParser *x) Err bitreich.org 70 i-{ Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-xmlcomment(XMLParser *x, const char *c, size_t cl) Err bitreich.org 70 i-{ Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-xmlcommentend(XMLParser *x) Err bitreich.org 70 i-{ Err bitreich.org 70 i+ quote_print(d); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i xmldata(XMLParser *x, const char *d, size_t dl) Err bitreich.org 70 i { Err bitreich.org 70 i if (strcspn(d, " \t\n") && emitsep){ Err bitreich.org 70 i- printf("%c", SEP); Err bitreich.org 70 i+ putchar(SEP); Err bitreich.org 70 i emitsep = FALSE; Err bitreich.org 70 i } Err bitreich.org 70 i- quote_print(stdout, d); Err bitreich.org 70 i+ quote_print(d); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i@@ -220,12 +206,6 @@ xmltagend(XMLParser *x, const char *t, size_t tl, int isshort) Err bitreich.org 70 i if (strcmp(t, tag)){ Err bitreich.org 70 i fprintf(stderr, "Error: tag-end '%s' closes tag '%s'\n", t, tag); Err bitreich.org 70 i } Err bitreich.org 70 i- Err bitreich.org 70 i-/* if (isshort) { Err bitreich.org 70 i- printf("\n"); Err bitreich.org 70 i- print_cur_str(stdout, &st); Err bitreich.org 70 i- } Err bitreich.org 70 i-*/ Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i@@ -235,13 +215,8 @@ xmltagstart(XMLParser *x, const char *t, size_t tl) Err bitreich.org 70 i fprintf(stderr, "Error: stack full. Ignoring tag '%s' (parent tag: '%s')\n", t, stack_peek(&st)); Err bitreich.org 70 i return; Err bitreich.org 70 i } Err bitreich.org 70 i- printf("\n"); Err bitreich.org 70 i- print_cur_str(stdout, &st); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-xmltagstartparsed(XMLParser *x, const char *t, size_t tl, int isshort) Err bitreich.org 70 i-{ Err bitreich.org 70 i+ putchar('\n'); Err bitreich.org 70 i+ print_cur_str(&st); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i int Err bitreich.org 70 i@@ -252,30 +227,22 @@ main(void) Err bitreich.org 70 i XMLParser x = { 0 }; Err bitreich.org 70 i Err bitreich.org 70 i x.xmlattr = xmlattr; Err bitreich.org 70 i- x.xmlattrend = xmlattrend; Err bitreich.org 70 i x.xmlattrstart = xmlattrstart; Err bitreich.org 70 i x.xmlattrentity = xmlattrentity; Err bitreich.org 70 i x.xmlcdatastart = xmlcdatastart; Err bitreich.org 70 i x.xmlcdata = xmlcdata; Err bitreich.org 70 i- x.xmlcdataend = xmlcdataend; Err bitreich.org 70 i- x.xmlcommentstart = xmlcommentstart; Err bitreich.org 70 i- x.xmlcomment = xmlcomment; Err bitreich.org 70 i- x.xmlcommentend = xmlcommentend; Err bitreich.org 70 i x.xmldata = xmldata; Err bitreich.org 70 i x.xmldataend = xmldataend; Err bitreich.org 70 i x.xmldataentity = xmldataentity; Err bitreich.org 70 i x.xmldatastart = xmldatastart; Err bitreich.org 70 i x.xmltagend = xmltagend; Err bitreich.org 70 i x.xmltagstart = xmltagstart; Err bitreich.org 70 i- x.xmltagstartparsed = xmltagstartparsed; Err bitreich.org 70 i- Err bitreich.org 70 i- x.getnext = getchar; Err bitreich.org 70 i Err bitreich.org 70 i xml_parse(&x); Err bitreich.org 70 i- printf("\n"); Err bitreich.org 70 i+ putchar('\n'); Err bitreich.org 70 i if (! stack_empty(&st)) { Err bitreich.org 70 i fprintf(stderr, "Error: tags still open at EOF: "); Err bitreich.org 70 i- print_cur_str(stderr, &st); Err bitreich.org 70 i+ print_cur_str_fp(stderr, &st); Err bitreich.org 70 i fprintf(stderr, "\n"); Err bitreich.org 70 i } Err bitreich.org 70 i return 0; Err bitreich.org 70 .