iinitial commit - 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 d10d115bb1de07e38a31f2e5946150f1f86e2d3e /scm/xml2tsv/commit/d10d115bb1de07e38a31f2e5946150f1f86e2d3e.gph bitreich.org 70
hAuthor: KatolaZ <katolaz@freaknet.org> URL:mailto:katolaz@freaknet.org bitreich.org 70
iDate: Fri, 3 Jan 2020 12:25:34 +0000 Err bitreich.org 70
i Err bitreich.org 70
iinitial commit Err bitreich.org 70
i Err bitreich.org 70
iDiffstat: Err bitreich.org 70
i A LICENSE | 15 +++++++++++++++ Err bitreich.org 70
i A xml.c | 454 +++++++++++++++++++++++++++++++ Err bitreich.org 70
i A xml.h | 47 +++++++++++++++++++++++++++++++ Err bitreich.org 70
i A xml2tsv.c | 228 +++++++++++++++++++++++++++++++ Err bitreich.org 70
i Err bitreich.org 70
i4 files changed, 744 insertions(+), 0 deletions(-) Err bitreich.org 70
i--- Err bitreich.org 70
1diff --git a/LICENSE b/LICENSE /scm/xml2tsv/file/LICENSE.gph bitreich.org 70
i@@ -0,0 +1,15 @@ Err bitreich.org 70
i+ISC License Err bitreich.org 70
i+ Err bitreich.org 70
i+Copyright (c) 2020 Vincenzo "KatolaZ" Nicosia <katolaz@freaknet.org> Err bitreich.org 70
i+ Err bitreich.org 70
i+Permission to use, copy, modify, and/or distribute this software for any Err bitreich.org 70
i+purpose with or without fee is hereby granted, provided that the above Err bitreich.org 70
i+copyright notice and this permission notice appear in all copies. Err bitreich.org 70
i+ Err bitreich.org 70
i+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES Err bitreich.org 70
i+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF Err bitreich.org 70
i+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR Err bitreich.org 70
i+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES Err bitreich.org 70
i+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN Err bitreich.org 70
i+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF Err bitreich.org 70
i+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Err bitreich.org 70
1diff --git a/xml.c b/xml.c /scm/xml2tsv/file/xml.c.gph bitreich.org 70
i@@ -0,0 +1,454 @@ Err bitreich.org 70
i+#include <sys/types.h> Err bitreich.org 70
i+ Err bitreich.org 70
i+#include <ctype.h> Err bitreich.org 70
i+#include <errno.h> Err bitreich.org 70
i+#include <limits.h> Err bitreich.org 70
i+#include <stdio.h> Err bitreich.org 70
i+#include <stdlib.h> Err bitreich.org 70
i+#include <string.h> Err bitreich.org 70
i+ Err bitreich.org 70
i+#include "xml.h" Err bitreich.org 70
i+ Err bitreich.org 70
i+static void Err bitreich.org 70
i+xml_parseattrs(XMLParser *x) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ size_t namelen = 0, valuelen; Err bitreich.org 70
i+ int c, endsep, endname = 0, valuestart = 0; Err bitreich.org 70
i+ Err bitreich.org 70
i+ while ((c = GETNEXT()) != EOF) { Err bitreich.org 70
i+ if (isspace(c)) { Err bitreich.org 70
i+ if (namelen) Err bitreich.org 70
i+ endname = 1; Err bitreich.org 70
i+ continue; Err bitreich.org 70
i+ } else if (c == '?') Err bitreich.org 70
i+ ; /* ignore */ Err bitreich.org 70
i+ else if (c == '=') { Err bitreich.org 70
i+ x->name[namelen] = '\0'; Err bitreich.org 70
i+ valuestart = 1; Err bitreich.org 70
i+ endname = 1; Err bitreich.org 70
i+ } else if (namelen && ((endname && !valuestart && isalpha(c)) || (c == '>' || c == '/'))) { Err bitreich.org 70
i+ /* attribute without value */ Err bitreich.org 70
i+ x->name[namelen] = '\0'; Err bitreich.org 70
i+ if (x->xmlattrstart) Err bitreich.org 70
i+ x->xmlattrstart(x, x->tag, x->taglen, x->name, namelen); Err bitreich.org 70
i+ if (x->xmlattr) Err bitreich.org 70
i+ x->xmlattr(x, x->tag, x->taglen, x->name, namelen, "", 0); Err bitreich.org 70
i+ if (x->xmlattrend) Err bitreich.org 70
i+ x->xmlattrend(x, x->tag, x->taglen, x->name, namelen); Err bitreich.org 70
i+ endname = 0; Err bitreich.org 70
i+ x->name[0] = c; Err bitreich.org 70
i+ namelen = 1; Err bitreich.org 70
i+ } else if (namelen && valuestart) { Err bitreich.org 70
i+ /* attribute with value */ Err bitreich.org 70
i+ if (x->xmlattrstart) Err bitreich.org 70
i+ x->xmlattrstart(x, x->tag, x->taglen, x->name, namelen); Err bitreich.org 70
i+ Err bitreich.org 70
i+ valuelen = 0; Err bitreich.org 70
i+ if (c == '\'' || c == '"') { Err bitreich.org 70
i+ endsep = c; Err bitreich.org 70
i+ } else { Err bitreich.org 70
i+ endsep = ' '; /* isspace() */ Err bitreich.org 70
i+ goto startvalue; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ Err bitreich.org 70
i+ while ((c = GETNEXT()) != EOF) { Err bitreich.org 70
i+startvalue: Err bitreich.org 70
i+ if (c == '&') { /* entities */ Err bitreich.org 70
i+ x->data[valuelen] = '\0'; Err bitreich.org 70
i+ /* call data function with data before entity if there is data */ Err bitreich.org 70
i+ if (valuelen && x->xmlattr) Err bitreich.org 70
i+ x->xmlattr(x, x->tag, x->taglen, x->name, namelen, x->data, valuelen); Err bitreich.org 70
i+ x->data[0] = c; Err bitreich.org 70
i+ valuelen = 1; Err bitreich.org 70
i+ while ((c = GETNEXT()) != EOF) { Err bitreich.org 70
i+ if (c == endsep || (endsep == ' ' && (c == '>' || isspace(c)))) Err bitreich.org 70
i+ break; Err bitreich.org 70
i+ if (valuelen < sizeof(x->data) - 1) Err bitreich.org 70
i+ x->data[valuelen++] = c; Err bitreich.org 70
i+ else { Err bitreich.org 70
i+ /* entity too long for buffer, handle as normal data */ Err bitreich.org 70
i+ x->data[valuelen] = '\0'; Err bitreich.org 70
i+ if (x->xmlattr) Err bitreich.org 70
i+ x->xmlattr(x, x->tag, x->taglen, x->name, namelen, x->data, valuelen); Err bitreich.org 70
i+ x->data[0] = c; Err bitreich.org 70
i+ valuelen = 1; Err bitreich.org 70
i+ break; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ if (c == ';') { Err bitreich.org 70
i+ x->data[valuelen] = '\0'; Err bitreich.org 70
i+ if (x->xmlattrentity) Err bitreich.org 70
i+ x->xmlattrentity(x, x->tag, x->taglen, x->name, namelen, x->data, valuelen); Err bitreich.org 70
i+ valuelen = 0; Err bitreich.org 70
i+ break; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ } Err bitreich.org 70
i+ } else if (c != endsep && !(endsep == ' ' && (c == '>' || isspace(c)))) { Err bitreich.org 70
i+ if (valuelen < sizeof(x->data) - 1) { Err bitreich.org 70
i+ x->data[valuelen++] = c; Err bitreich.org 70
i+ } else { Err bitreich.org 70
i+ x->data[valuelen] = '\0'; Err bitreich.org 70
i+ if (x->xmlattr) Err bitreich.org 70
i+ x->xmlattr(x, x->tag, x->taglen, x->name, namelen, x->data, valuelen); Err bitreich.org 70
i+ x->data[0] = c; Err bitreich.org 70
i+ valuelen = 1; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ } Err bitreich.org 70
i+ if (c == endsep || (endsep == ' ' && (c == '>' || isspace(c)))) { Err bitreich.org 70
i+ x->data[valuelen] = '\0'; Err bitreich.org 70
i+ if (x->xmlattr) Err bitreich.org 70
i+ x->xmlattr(x, x->tag, x->taglen, x->name, namelen, x->data, valuelen); Err bitreich.org 70
i+ if (x->xmlattrend) Err bitreich.org 70
i+ x->xmlattrend(x, x->tag, x->taglen, x->name, namelen); Err bitreich.org 70
i+ break; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ } Err bitreich.org 70
i+ namelen = endname = valuestart = 0; Err bitreich.org 70
i+ } else if (namelen < sizeof(x->name) - 1) { Err bitreich.org 70
i+ x->name[namelen++] = c; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ if (c == '>') { Err bitreich.org 70
i+ break; Err bitreich.org 70
i+ } else if (c == '/') { Err bitreich.org 70
i+ x->isshorttag = 1; Err bitreich.org 70
i+ x->name[0] = '\0'; Err bitreich.org 70
i+ namelen = 0; 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+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+ 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+ 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+static void Err bitreich.org 70
i+xml_parsecdata(XMLParser *x) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ size_t datalen = 0, i = 0; Err bitreich.org 70
i+ int c; Err bitreich.org 70
i+ Err bitreich.org 70
i+ if (x->xmlcdatastart) Err bitreich.org 70
i+ x->xmlcdatastart(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->xmlcdata && datalen) { Err bitreich.org 70
i+ x->data[datalen] = '\0'; Err bitreich.org 70
i+ x->xmlcdata(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->xmlcdata) Err bitreich.org 70
i+ for (; i > 2; i--) Err bitreich.org 70
i+ x->xmlcdata(x, "]", 1); 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->xmlcdataend) Err bitreich.org 70
i+ x->xmlcdataend(x); Err bitreich.org 70
i+ return; Err bitreich.org 70
i+ } else if (i) { Err bitreich.org 70
i+ if (x->xmlcdata) Err bitreich.org 70
i+ for (; i > 0; i--) Err bitreich.org 70
i+ x->xmlcdata(x, "]", 1); 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->xmlcdata) Err bitreich.org 70
i+ x->xmlcdata(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+static int Err bitreich.org 70
i+codepointtoutf8(long r, char *s) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ if (r == 0) { Err bitreich.org 70
i+ return 0; /* NUL byte */ Err bitreich.org 70
i+ } else if (r <= 0x7F) { Err bitreich.org 70
i+ /* 1 byte: 0aaaaaaa */ Err bitreich.org 70
i+ s[0] = r; Err bitreich.org 70
i+ return 1; Err bitreich.org 70
i+ } else if (r <= 0x07FF) { Err bitreich.org 70
i+ /* 2 bytes: 00000aaa aabbbbbb */ Err bitreich.org 70
i+ s[0] = 0xC0 | ((r & 0x0007C0) >> 6); /* 110aaaaa */ Err bitreich.org 70
i+ s[1] = 0x80 | (r & 0x00003F); /* 10bbbbbb */ Err bitreich.org 70
i+ return 2; Err bitreich.org 70
i+ } else if (r <= 0xFFFF) { Err bitreich.org 70
i+ /* 3 bytes: aaaabbbb bbcccccc */ Err bitreich.org 70
i+ s[0] = 0xE0 | ((r & 0x00F000) >> 12); /* 1110aaaa */ Err bitreich.org 70
i+ s[1] = 0x80 | ((r & 0x000FC0) >> 6); /* 10bbbbbb */ Err bitreich.org 70
i+ s[2] = 0x80 | (r & 0x00003F); /* 10cccccc */ Err bitreich.org 70
i+ return 3; Err bitreich.org 70
i+ } else { Err bitreich.org 70
i+ /* 4 bytes: 000aaabb bbbbcccc ccdddddd */ Err bitreich.org 70
i+ s[0] = 0xF0 | ((r & 0x1C0000) >> 18); /* 11110aaa */ Err bitreich.org 70
i+ s[1] = 0x80 | ((r & 0x03F000) >> 12); /* 10bbbbbb */ Err bitreich.org 70
i+ s[2] = 0x80 | ((r & 0x000FC0) >> 6); /* 10cccccc */ Err bitreich.org 70
i+ s[3] = 0x80 | (r & 0x00003F); /* 10dddddd */ Err bitreich.org 70
i+ return 4; Err bitreich.org 70
i+ } Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+static int Err bitreich.org 70
i+namedentitytostr(const char *e, char *buf, size_t bufsiz) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ static const struct { Err bitreich.org 70
i+ const char *entity; Err bitreich.org 70
i+ int c; Err bitreich.org 70
i+ } entities[] = { Err bitreich.org 70
i+ { "amp;", '&' }, Err bitreich.org 70
i+ { "lt;", '<' }, Err bitreich.org 70
i+ { "gt;", '>' }, Err bitreich.org 70
i+ { "apos;", '\'' }, Err bitreich.org 70
i+ { "quot;", '"' }, Err bitreich.org 70
i+ }; Err bitreich.org 70
i+ size_t i; Err bitreich.org 70
i+ Err bitreich.org 70
i+ /* buffer is too small */ Err bitreich.org 70
i+ if (bufsiz < 2) Err bitreich.org 70
i+ return -1; Err bitreich.org 70
i+ Err bitreich.org 70
i+ for (i = 0; i < sizeof(entities) / sizeof(*entities); i++) { Err bitreich.org 70
i+ if (!strcmp(e, entities[i].entity)) { Err bitreich.org 70
i+ buf[0] = entities[i].c; Err bitreich.org 70
i+ buf[1] = '\0'; Err bitreich.org 70
i+ return 1; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ } Err bitreich.org 70
i+ return 0; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+static int Err bitreich.org 70
i+numericentitytostr(const char *e, char *buf, size_t bufsiz) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ long l; Err bitreich.org 70
i+ int len; Err bitreich.org 70
i+ char *end; Err bitreich.org 70
i+ Err bitreich.org 70
i+ /* buffer is too small */ Err bitreich.org 70
i+ if (bufsiz < 5) Err bitreich.org 70
i+ return -1; Err bitreich.org 70
i+ Err bitreich.org 70
i+ errno = 0; Err bitreich.org 70
i+ /* hex (16) or decimal (10) */ Err bitreich.org 70
i+ if (*e == 'x') Err bitreich.org 70
i+ l = strtoul(e + 1, &end, 16); Err bitreich.org 70
i+ else Err bitreich.org 70
i+ l = strtoul(e, &end, 10); Err bitreich.org 70
i+ /* invalid value or not a well-formed entity or too high codepoint */ Err bitreich.org 70
i+ if (errno || *end != ';' || l > 0x10FFFF) Err bitreich.org 70
i+ return 0; Err bitreich.org 70
i+ len = codepointtoutf8(l, buf); Err bitreich.org 70
i+ buf[len] = '\0'; Err bitreich.org 70
i+ Err bitreich.org 70
i+ return len; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+/* convert named- or numeric entity string to buffer string Err bitreich.org 70
i+ * returns byte-length of string. */ Err bitreich.org 70
i+int Err bitreich.org 70
i+xml_entitytostr(const char *e, char *buf, size_t bufsiz) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ /* doesn't start with & */ Err bitreich.org 70
i+ if (e[0] != '&') Err bitreich.org 70
i+ return 0; Err bitreich.org 70
i+ /* numeric entity */ Err bitreich.org 70
i+ if (e[1] == '#') Err bitreich.org 70
i+ return numericentitytostr(e + 2, buf, bufsiz); Err bitreich.org 70
i+ else /* named entity */ Err bitreich.org 70
i+ return namedentitytostr(e + 1, buf, bufsiz); Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+void Err bitreich.org 70
i+xml_parse(XMLParser *x) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ size_t datalen, tagdatalen; Err bitreich.org 70
i+ int c, isend; Err bitreich.org 70
i+ Err bitreich.org 70
i+ while ((c = GETNEXT()) != EOF && c != '<') Err bitreich.org 70
i+ ; /* skip until < */ Err bitreich.org 70
i+ Err bitreich.org 70
i+ while (c != EOF) { Err bitreich.org 70
i+ if (c == '<') { /* parse tag */ Err bitreich.org 70
i+ if ((c = GETNEXT()) == EOF) Err bitreich.org 70
i+ return; Err bitreich.org 70
i+ Err bitreich.org 70
i+ if (c == '!') { /* cdata and comments */ Err bitreich.org 70
i+ for (tagdatalen = 0; (c = GETNEXT()) != EOF;) { Err bitreich.org 70
i+ /* NOTE: sizeof(x->data) must be atleast sizeof("[CDATA[") */ Err bitreich.org 70
i+ if (tagdatalen <= sizeof("[CDATA[") - 1) Err bitreich.org 70
i+ x->data[tagdatalen++] = c; Err bitreich.org 70
i+ if (c == '>') Err bitreich.org 70
i+ break; Err bitreich.org 70
i+ else if (c == '-' && tagdatalen == sizeof("--") - 1 && Err bitreich.org 70
i+ (x->data[0] == '-')) { Err bitreich.org 70
i+ xml_parsecomment(x); Err bitreich.org 70
i+ break; Err bitreich.org 70
i+ } else if (c == '[') { Err bitreich.org 70
i+ if (tagdatalen == sizeof("[CDATA[") - 1 && Err bitreich.org 70
i+ !strncmp(x->data, "[CDATA[", tagdatalen)) { Err bitreich.org 70
i+ xml_parsecdata(x); 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+ } else { Err bitreich.org 70
i+ /* normal tag (open, short open, close), processing instruction. */ Err bitreich.org 70
i+ x->tag[0] = c; Err bitreich.org 70
i+ x->taglen = 1; Err bitreich.org 70
i+ x->isshorttag = isend = 0; Err bitreich.org 70
i+ Err bitreich.org 70
i+ /* treat processing instruction as shorttag, don't strip "?" prefix. */ Err bitreich.org 70
i+ if (c == '?') { Err bitreich.org 70
i+ x->isshorttag = 1; Err bitreich.org 70
i+ } else if (c == '/') { Err bitreich.org 70
i+ if ((c = GETNEXT()) == EOF) Err bitreich.org 70
i+ return; Err bitreich.org 70
i+ x->tag[0] = c; Err bitreich.org 70
i+ isend = 1; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ Err bitreich.org 70
i+ while ((c = GETNEXT()) != EOF) { Err bitreich.org 70
i+ if (c == '/') Err bitreich.org 70
i+ x->isshorttag = 1; /* short tag */ Err bitreich.org 70
i+ else if (c == '>' || isspace(c)) { Err bitreich.org 70
i+ x->tag[x->taglen] = '\0'; Err bitreich.org 70
i+ if (isend) { /* end tag, starts with </ */ Err bitreich.org 70
i+ if (x->xmltagend) Err bitreich.org 70
i+ x->xmltagend(x, x->tag, x->taglen, x->isshorttag); Err bitreich.org 70
i+ x->tag[0] = '\0'; Err bitreich.org 70
i+ x->taglen = 0; Err bitreich.org 70
i+ } else { Err bitreich.org 70
i+ /* start tag */ Err bitreich.org 70
i+ if (x->xmltagstart) Err bitreich.org 70
i+ x->xmltagstart(x, x->tag, x->taglen); Err bitreich.org 70
i+ if (isspace(c)) Err bitreich.org 70
i+ xml_parseattrs(x); Err bitreich.org 70
i+ if (x->xmltagstartparsed) Err bitreich.org 70
i+ x->xmltagstartparsed(x, x->tag, x->taglen, x->isshorttag); Err bitreich.org 70
i+ } Err bitreich.org 70
i+ /* call tagend for shortform or processing instruction */ Err bitreich.org 70
i+ if (x->isshorttag) { Err bitreich.org 70
i+ if (x->xmltagend) Err bitreich.org 70
i+ x->xmltagend(x, x->tag, x->taglen, x->isshorttag); Err bitreich.org 70
i+ x->tag[0] = '\0'; Err bitreich.org 70
i+ x->taglen = 0; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ break; Err bitreich.org 70
i+ } else if (x->taglen < sizeof(x->tag) - 1) Err bitreich.org 70
i+ x->tag[x->taglen++] = c; /* NOTE: tag name truncation */ Err bitreich.org 70
i+ } Err bitreich.org 70
i+ } Err bitreich.org 70
i+ } else { Err bitreich.org 70
i+ /* parse tag data */ Err bitreich.org 70
i+ datalen = 0; Err bitreich.org 70
i+ if (x->xmldatastart) Err bitreich.org 70
i+ x->xmldatastart(x); Err bitreich.org 70
i+ while ((c = GETNEXT()) != EOF) { Err bitreich.org 70
i+ if (c == '&') { Err bitreich.org 70
i+ if (datalen) { Err bitreich.org 70
i+ x->data[datalen] = '\0'; Err bitreich.org 70
i+ if (x->xmldata) Err bitreich.org 70
i+ x->xmldata(x, x->data, datalen); Err bitreich.org 70
i+ } Err bitreich.org 70
i+ x->data[0] = c; Err bitreich.org 70
i+ datalen = 1; Err bitreich.org 70
i+ while ((c = GETNEXT()) != EOF) { Err bitreich.org 70
i+ if (c == '<') Err bitreich.org 70
i+ break; 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+ /* entity too long for buffer, handle as normal data */ Err bitreich.org 70
i+ x->data[datalen] = '\0'; Err bitreich.org 70
i+ if (x->xmldata) Err bitreich.org 70
i+ x->xmldata(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+ break; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ if (c == ';') { Err bitreich.org 70
i+ x->data[datalen] = '\0'; Err bitreich.org 70
i+ if (x->xmldataentity) Err bitreich.org 70
i+ x->xmldataentity(x, x->data, datalen); Err bitreich.org 70
i+ datalen = 0; Err bitreich.org 70
i+ break; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ } Err bitreich.org 70
i+ } else if (c != '<') { 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->xmldata) Err bitreich.org 70
i+ x->xmldata(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+ if (c == '<') { Err bitreich.org 70
i+ x->data[datalen] = '\0'; Err bitreich.org 70
i+ if (x->xmldata && datalen) Err bitreich.org 70
i+ x->xmldata(x, x->data, datalen); Err bitreich.org 70
i+ if (x->xmldataend) Err bitreich.org 70
i+ x->xmldataend(x); 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+} Err bitreich.org 70
1diff --git a/xml.h b/xml.h /scm/xml2tsv/file/xml.h.gph bitreich.org 70
i@@ -0,0 +1,47 @@ 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+typedef struct xmlparser { Err bitreich.org 70
i+ /* handlers */ Err bitreich.org 70
i+ void (*xmlattr)(struct xmlparser *, const char *, size_t, Err bitreich.org 70
i+ const char *, size_t, const char *, size_t); Err bitreich.org 70
i+ void (*xmlattrend)(struct xmlparser *, const char *, size_t, Err bitreich.org 70
i+ const char *, size_t); Err bitreich.org 70
i+ void (*xmlattrstart)(struct xmlparser *, const char *, size_t, Err bitreich.org 70
i+ const char *, size_t); Err bitreich.org 70
i+ void (*xmlattrentity)(struct xmlparser *, const char *, size_t, Err bitreich.org 70
i+ const char *, size_t, const char *, size_t); 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+ void (*xmldatastart)(struct xmlparser *); Err bitreich.org 70
i+ void (*xmltagend)(struct xmlparser *, const char *, size_t, int); Err bitreich.org 70
i+ void (*xmltagstart)(struct xmlparser *, const char *, size_t); Err bitreich.org 70
i+ void (*xmltagstartparsed)(struct xmlparser *, const char *, 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+#endif Err bitreich.org 70
i+ Err bitreich.org 70
i+ /* current tag */ Err bitreich.org 70
i+ char tag[1024]; Err bitreich.org 70
i+ size_t taglen; Err bitreich.org 70
i+ /* current tag is in short form ? <tag /> */ Err bitreich.org 70
i+ int isshorttag; Err bitreich.org 70
i+ /* current attribute name */ Err bitreich.org 70
i+ char name[1024]; Err bitreich.org 70
i+ /* data buffer used for tag data, cdata and attribute data */ Err bitreich.org 70
i+ char data[BUFSIZ]; Err bitreich.org 70
i+} XMLParser; Err bitreich.org 70
i+ Err bitreich.org 70
i+int xml_entitytostr(const char *, char *, size_t); Err bitreich.org 70
i+void xml_parse(XMLParser *); Err bitreich.org 70
i+#endif Err bitreich.org 70
1diff --git a/xml2tsv.c b/xml2tsv.c /scm/xml2tsv/file/xml2tsv.c.gph bitreich.org 70
i@@ -0,0 +1,228 @@ Err bitreich.org 70
i+/* Err bitreich.org 70
i+* (c) 2020 Vincenzo "KatolaZ" Nicosia <katolaz@freaknet.org> Err bitreich.org 70
i+* Err bitreich.org 70
i+* A simple xml-to-rsv converter, based on xmlparser by Hiltjo Posthuma Err bitreich.org 70
i+* http://codemadness.org/git/xmlparser/ Err bitreich.org 70
i+* Err bitreich.org 70
i+* You can use, distribute, modify, and/or redistribute this program under Err bitreich.org 70
i+* the terms of the ISC LICENSE. See LICENSE for details. 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+#include <sys/types.h> Err bitreich.org 70
i+ Err bitreich.org 70
i+#include <stdio.h> Err bitreich.org 70
i+#include <string.h> Err bitreich.org 70
i+ Err bitreich.org 70
i+#include "xml.h" Err bitreich.org 70
i+ Err bitreich.org 70
i+#define STR_MAX 128 Err bitreich.org 70
i+#define DEPTH_MAX 50 Err bitreich.org 70
i+ Err bitreich.org 70
i+ Err bitreich.org 70
i+/* tag stack */ Err bitreich.org 70
i+ Err bitreich.org 70
i+typedef struct { Err bitreich.org 70
i+ int top; Err bitreich.org 70
i+ char st[DEPTH_MAX][STR_MAX]; Err bitreich.org 70
i+} tstack_t; Err bitreich.org 70
i+ Err bitreich.org 70
i+int stack_push(tstack_t *t, const char *c){ Err bitreich.org 70
i+ if (t->top < DEPTH_MAX){ Err bitreich.org 70
i+ t->top ++; Err bitreich.org 70
i+ strncpy(t->st[t->top], c, STR_MAX); Err bitreich.org 70
i+ return 0; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ return -1; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+char* stack_pop(tstack_t *t){ Err bitreich.org 70
i+ if (t->top >= 0) Err bitreich.org 70
i+ return t->st[t->top--]; Err bitreich.org 70
i+ return NULL; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+char* stack_peek(tstack_t *t){ Err bitreich.org 70
i+ if (t->top >= 0) Err bitreich.org 70
i+ return t->st[t->top]; Err bitreich.org 70
i+ return NULL; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+int stack_empty(tstack_t *t){ Err bitreich.org 70
i+ return (t->top < 0); Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+void stack_init(tstack_t *t){ Err bitreich.org 70
i+ t->top = -1; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+ Err bitreich.org 70
i+/* utility functions */ Err bitreich.org 70
i+ Err bitreich.org 70
i+void print_no_cr(FILE *f, const char *c){ Err bitreich.org 70
i+ char *tmp = c; Err bitreich.org 70
i+ while (c != NULL){ Err bitreich.org 70
i+ tmp = strchr(c, '\n'); Err bitreich.org 70
i+ if (tmp != NULL) Err bitreich.org 70
i+ *tmp = '\0'; Err bitreich.org 70
i+ fprintf(f, "%s", c); Err bitreich.org 70
i+ if (tmp != NULL) Err bitreich.org 70
i+ c = tmp + 1; Err bitreich.org 70
i+ else Err bitreich.org 70
i+ c = NULL; 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+ 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+ } Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+/* global variables */ Err bitreich.org 70
i+ Err bitreich.org 70
i+tstack_t st; Err bitreich.org 70
i+ Err bitreich.org 70
i+ 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("\t%s=%s", a, v); Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+void Err bitreich.org 70
i+xmlattrentity(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("attrentity: %s\n", a); 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+} 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+} 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+ printf("\t%s", 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+} 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+ printf("\t"); Err bitreich.org 70
i+ print_no_cr(stdout, d); Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+void Err bitreich.org 70
i+xmldataend(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+xmldataentity(XMLParser *x, const char *d, size_t dl) 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+xmldatastart(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+xmltagend(XMLParser *x, const char *t, size_t tl, int isshort) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ char *tag; Err bitreich.org 70
i+ if (stack_empty(&st)){ Err bitreich.org 70
i+ fprintf(stderr, "Error: tag-end '%s' before any open tag", t); Err bitreich.org 70
i+ } Err bitreich.org 70
i+ tag = stack_pop(&st); Err bitreich.org 70
i+ if (strcmp(t, tag)){ Err bitreich.org 70
i+ fprintf(stderr, "Error: tag-end '%s' closes tag '%s'", t, tag); Err bitreich.org 70
i+ } Err bitreich.org 70
i+ /* printf("\n"); */ Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+void Err bitreich.org 70
i+xmltagstart(XMLParser *x, const char *t, size_t tl) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ if (stack_push(&st, t)){ 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+ /* printf("inside tagstartparsed\n"); */ Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+int Err bitreich.org 70
i+main(void) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ stack_init(&st); 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+ return 0; Err bitreich.org 70
i+} Err bitreich.org 70
.
Response:
text/plain