summaryrefslogtreecommitdiff
path: root/xml2tsv.c
diff options
context:
space:
mode:
Diffstat (limited to 'xml2tsv.c')
-rw-r--r--xml2tsv.c228
1 files changed, 228 insertions, 0 deletions
diff --git a/xml2tsv.c b/xml2tsv.c
new file mode 100644
index 0000000..9418d66
--- /dev/null
+++ b/xml2tsv.c
@@ -0,0 +1,228 @@
+/*
+* (c) 2020 Vincenzo "KatolaZ" Nicosia <katolaz@freaknet.org>
+*
+* A simple xml-to-rsv converter, based on xmlparser by Hiltjo Posthuma
+* http://codemadness.org/git/xmlparser/
+*
+* You can use, distribute, modify, and/or redistribute this program under
+* the terms of the ISC LICENSE. See LICENSE for details.
+*
+*/
+
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "xml.h"
+
+#define STR_MAX 128
+#define DEPTH_MAX 50
+
+
+/* tag stack */
+
+typedef struct {
+ int top;
+ char st[DEPTH_MAX][STR_MAX];
+} tstack_t;
+
+int stack_push(tstack_t *t, const char *c){
+ if (t->top < DEPTH_MAX){
+ t->top ++;
+ strncpy(t->st[t->top], c, STR_MAX);
+ return 0;
+ }
+ return -1;
+}
+
+char* stack_pop(tstack_t *t){
+ if (t->top >= 0)
+ return t->st[t->top--];
+ return NULL;
+}
+
+char* stack_peek(tstack_t *t){
+ if (t->top >= 0)
+ return t->st[t->top];
+ return NULL;
+}
+
+int stack_empty(tstack_t *t){
+ return (t->top < 0);
+}
+
+void stack_init(tstack_t *t){
+ t->top = -1;
+}
+
+
+/* utility functions */
+
+void print_no_cr(FILE *f, const char *c){
+ char *tmp = c;
+ while (c != NULL){
+ tmp = strchr(c, '\n');
+ if (tmp != NULL)
+ *tmp = '\0';
+ fprintf(f, "%s", c);
+ if (tmp != NULL)
+ c = tmp + 1;
+ else
+ c = NULL;
+ }
+}
+
+void print_cur_str(FILE *f, tstack_t *t){
+ int i;
+ for (i=0; i<=t->top; i++){
+ fprintf(f, "/%s", t->st[i]);
+ }
+}
+
+/* global variables */
+
+tstack_t st;
+
+
+/* xml callbacks */
+
+void
+xmlattr(XMLParser *x, const char *t, size_t tl, const char *a, size_t al,
+ const char *v, size_t vl)
+{
+ printf("\t%s=%s", a, v);
+}
+
+void
+xmlattrentity(XMLParser *x, const char *t, size_t tl, const char *a, size_t al,
+ const char *v, size_t vl)
+{
+ printf("attrentity: %s\n", a);
+}
+
+void
+xmlattrend(XMLParser *x, const char *t, size_t tl, const char *a, size_t al)
+{
+}
+
+void
+xmlattrstart(XMLParser *x, const char *t, size_t tl, const char *a, size_t al)
+{
+}
+
+void
+xmlcdatastart(XMLParser *x)
+{
+}
+
+void
+xmlcdata(XMLParser *x, const char *d, size_t dl)
+{
+ printf("\t%s", d);
+}
+
+void
+xmlcdataend(XMLParser *x)
+{
+}
+
+void
+xmlcommentstart(XMLParser *x)
+{
+}
+
+void
+xmlcomment(XMLParser *x, const char *c, size_t cl)
+{
+}
+
+void
+xmlcommentend(XMLParser *x)
+{
+}
+
+void
+xmldata(XMLParser *x, const char *d, size_t dl)
+{
+ printf("\t");
+ print_no_cr(stdout, d);
+}
+
+void
+xmldataend(XMLParser *x)
+{
+}
+
+void
+xmldataentity(XMLParser *x, const char *d, size_t dl)
+{
+}
+
+void
+xmldatastart(XMLParser *x)
+{
+}
+
+void
+xmltagend(XMLParser *x, const char *t, size_t tl, int isshort)
+{
+ char *tag;
+ if (stack_empty(&st)){
+ fprintf(stderr, "Error: tag-end '%s' before any open tag", t);
+ }
+ tag = stack_pop(&st);
+ if (strcmp(t, tag)){
+ fprintf(stderr, "Error: tag-end '%s' closes tag '%s'", t, tag);
+ }
+ /* printf("\n"); */
+}
+
+void
+xmltagstart(XMLParser *x, const char *t, size_t tl)
+{
+ if (stack_push(&st, t)){
+ fprintf(stderr, "Error: stack full. Ignoring tag '%s' (parent tag: '%s')\n", t, stack_peek(&st));
+ return;
+ }
+ printf("\n");
+ print_cur_str(stdout, &st);
+}
+
+void
+xmltagstartparsed(XMLParser *x, const char *t, size_t tl, int isshort)
+{
+ /* printf("inside tagstartparsed\n"); */
+}
+
+int
+main(void)
+{
+ stack_init(&st);
+ XMLParser x = { 0 };
+
+ x.xmlattr = xmlattr;
+ x.xmlattrend = xmlattrend;
+ x.xmlattrstart = xmlattrstart;
+ x.xmlattrentity = xmlattrentity;
+ x.xmlcdatastart = xmlcdatastart;
+ x.xmlcdata = xmlcdata;
+ x.xmlcdataend = xmlcdataend;
+ x.xmlcommentstart = xmlcommentstart;
+ x.xmlcomment = xmlcomment;
+ x.xmlcommentend = xmlcommentend;
+ x.xmldata = xmldata;
+ x.xmldataend = xmldataend;
+ x.xmldataentity = xmldataentity;
+ x.xmldatastart = xmldatastart;
+ x.xmltagend = xmltagend;
+ x.xmltagstart = xmltagstart;
+ x.xmltagstartparsed = xmltagstartparsed;
+
+ x.getnext = getchar;
+
+ xml_parse(&x);
+ printf("\n");
+ return 0;
+}