ixml2tsv.c - 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 ixml2tsv.c (4522B) Err bitreich.org 70 i--- Err bitreich.org 70 i 1 /* Err bitreich.org 70 i 2 * (c) 2020 Vincenzo "KatolaZ" Nicosia Err bitreich.org 70 i 3 * Err bitreich.org 70 i 4 * A simple xml-to-tsv converter, based on xmlparser by Hiltjo Posthuma Err bitreich.org 70 i 5 * http://codemadness.org/git/xmlparser/ Err bitreich.org 70 i 6 * Err bitreich.org 70 i 7 * You can use, distribute, modify, and/or redistribute this program under Err bitreich.org 70 i 8 * the terms of the ISC LICENSE. See LICENSE for details. Err bitreich.org 70 i 9 * Err bitreich.org 70 i 10 */ Err bitreich.org 70 i 11 Err bitreich.org 70 i 12 Err bitreich.org 70 i 13 #include Err bitreich.org 70 i 14 Err bitreich.org 70 i 15 #include Err bitreich.org 70 i 16 #include Err bitreich.org 70 i 17 #include Err bitreich.org 70 i 18 Err bitreich.org 70 i 19 #include "xml.h" Err bitreich.org 70 i 20 #include "config.h" Err bitreich.org 70 i 21 Err bitreich.org 70 i 22 Err bitreich.org 70 i 23 #define FALSE 0 Err bitreich.org 70 i 24 #define TRUE 1 Err bitreich.org 70 i 25 Err bitreich.org 70 i 26 /* tag stack */ Err bitreich.org 70 i 27 Err bitreich.org 70 i 28 typedef struct { Err bitreich.org 70 i 29 char s[STR_MAX]; Err bitreich.org 70 i 30 int ref; Err bitreich.org 70 i 31 } taginfo_t; Err bitreich.org 70 i 32 Err bitreich.org 70 i 33 Err bitreich.org 70 i 34 Err bitreich.org 70 i 35 typedef struct { Err bitreich.org 70 i 36 int top; Err bitreich.org 70 i 37 taginfo_t st[DEPTH_MAX]; Err bitreich.org 70 i 38 } tstack_t; Err bitreich.org 70 i 39 Err bitreich.org 70 i 40 int stack_empty(tstack_t *t){ Err bitreich.org 70 i 41 return (t->top < 0); Err bitreich.org 70 i 42 } Err bitreich.org 70 i 43 Err bitreich.org 70 i 44 int stack_push(tstack_t *t, const char *c){ Err bitreich.org 70 i 45 if (t->top < DEPTH_MAX){ Err bitreich.org 70 i 46 t->top ++; Err bitreich.org 70 i 47 strncpy(t->st[t->top].s, c, STR_MAX - 1); Err bitreich.org 70 i 48 t->st[t->top].s[STR_MAX - 1] = '\0'; Err bitreich.org 70 i 49 t->st[t->top].ref = 0; Err bitreich.org 70 i 50 if (t->top){ Err bitreich.org 70 i 51 /* Increment the ref counter of the parent tag*/ Err bitreich.org 70 i 52 t->st[t->top-1].ref += 1; Err bitreich.org 70 i 53 } Err bitreich.org 70 i 54 return 0; Err bitreich.org 70 i 55 } Err bitreich.org 70 i 56 return -1; Err bitreich.org 70 i 57 } Err bitreich.org 70 i 58 Err bitreich.org 70 i 59 taginfo_t* stack_pop(tstack_t *t){ Err bitreich.org 70 i 60 if (!stack_empty(t)) Err bitreich.org 70 i 61 return t->st + t->top--; Err bitreich.org 70 i 62 return NULL; Err bitreich.org 70 i 63 } Err bitreich.org 70 i 64 Err bitreich.org 70 i 65 taginfo_t* stack_peek(tstack_t *t){ Err bitreich.org 70 i 66 if (!stack_empty(t)) Err bitreich.org 70 i 67 return t->st + t->top; Err bitreich.org 70 i 68 return NULL; Err bitreich.org 70 i 69 } Err bitreich.org 70 i 70 Err bitreich.org 70 i 71 void stack_init(tstack_t *t){ Err bitreich.org 70 i 72 t->top = -1; Err bitreich.org 70 i 73 } Err bitreich.org 70 i 74 Err bitreich.org 70 i 75 Err bitreich.org 70 i 76 /* utility functions */ Err bitreich.org 70 i 77 Err bitreich.org 70 i 78 /* quote_print: quote \\, \n, \t, and strip other ctrl chars */ Err bitreich.org 70 i 79 void quote_print(const char *s){ Err bitreich.org 70 i 80 const char *tmp = s; Err bitreich.org 70 i 81 size_t len; Err bitreich.org 70 i 82 int i; Err bitreich.org 70 i 83 while (*tmp != '\0'){ Err bitreich.org 70 i 84 len = strcspn(tmp, "\\\n\t"); Err bitreich.org 70 i 85 for(i=0; i 0){ Err bitreich.org 70 i 93 fputs("\\n", stdout); Err bitreich.org 70 i 94 } Err bitreich.org 70 i 95 tmp ++; Err bitreich.org 70 i 96 break; Err bitreich.org 70 i 97 case '\t': Err bitreich.org 70 i 98 fputs("\\t", stdout); Err bitreich.org 70 i 99 tmp ++; Err bitreich.org 70 i 100 break; Err bitreich.org 70 i 101 case '\r': Err bitreich.org 70 i 102 fputs("\\r", stdout); Err bitreich.org 70 i 103 tmp ++; Err bitreich.org 70 i 104 break; Err bitreich.org 70 i 105 case '\\': Err bitreich.org 70 i 106 fputs("\\\\", stdout); Err bitreich.org 70 i 107 tmp ++; Err bitreich.org 70 i 108 break; Err bitreich.org 70 i 109 } Err bitreich.org 70 i 110 } Err bitreich.org 70 i 111 } Err bitreich.org 70 i 112 Err bitreich.org 70 i 113 void print_cur_str(tstack_t *t){ Err bitreich.org 70 i 114 int i; Err bitreich.org 70 i 115 for (i=0; i<=t->top; i++){ Err bitreich.org 70 i 116 putchar('/'); Err bitreich.org 70 i 117 fputs(t->st[i].s, stdout); Err bitreich.org 70 i 118 } Err bitreich.org 70 i 119 } Err bitreich.org 70 i 120 Err bitreich.org 70 i 121 void print_cur_str_fp(FILE *f, tstack_t *t){ Err bitreich.org 70 i 122 int i; Err bitreich.org 70 i 123 for (i=0; i<=t->top; i++){ Err bitreich.org 70 i 124 fputc('/', f); Err bitreich.org 70 i 125 fputs(t->st[i].s, f); Err bitreich.org 70 i 126 } Err bitreich.org 70 i 127 } Err bitreich.org 70 i 128 Err bitreich.org 70 i 129 /* global variables */ Err bitreich.org 70 i 130 Err bitreich.org 70 i 131 tstack_t st; Err bitreich.org 70 i 132 char emitsep; Err bitreich.org 70 i 133 Err bitreich.org 70 i 134 /* XML callbacks */ Err bitreich.org 70 i 135 Err bitreich.org 70 i 136 void Err bitreich.org 70 i 137 xmlattr(XMLParser *x, const char *t, size_t tl, const char *a, size_t al, Err bitreich.org 70 i 138 const char *v, size_t vl) Err bitreich.org 70 i 139 { Err bitreich.org 70 i 140 fputs(v, stdout); Err bitreich.org 70 i 141 } Err bitreich.org 70 i 142 Err bitreich.org 70 i 143 void Err bitreich.org 70 i 144 xmlattrentity(XMLParser *x, const char *t, size_t tl, const char *a, size_t al, Err bitreich.org 70 i 145 const char *v, size_t vl) Err bitreich.org 70 i 146 { Err bitreich.org 70 i 147 char buf[16]; Err bitreich.org 70 i 148 int n; Err bitreich.org 70 i 149 Err bitreich.org 70 i 150 if ((n = xml_entitytostr(v, buf, sizeof(buf))) > 0) Err bitreich.org 70 i 151 xmlattr(x, t, tl, a, al, buf, (size_t)n); Err bitreich.org 70 i 152 else Err bitreich.org 70 i 153 xmlattr(x, t, tl, a, al, v, vl); Err bitreich.org 70 i 154 } Err bitreich.org 70 i 155 Err bitreich.org 70 i 156 void Err bitreich.org 70 i 157 xmlattrstart(XMLParser *x, const char *t, size_t tl, const char *a, size_t al) Err bitreich.org 70 i 158 { Err bitreich.org 70 i 159 putchar(SEP); Err bitreich.org 70 i 160 fputs(a, stdout); Err bitreich.org 70 i 161 putchar(SATTR); Err bitreich.org 70 i 162 } Err bitreich.org 70 i 163 Err bitreich.org 70 i 164 void Err bitreich.org 70 i 165 xmlcdatastart(XMLParser *x) Err bitreich.org 70 i 166 { Err bitreich.org 70 i 167 putchar(SEP); Err bitreich.org 70 i 168 } Err bitreich.org 70 i 169 Err bitreich.org 70 i 170 void Err bitreich.org 70 i 171 xmlcdata(XMLParser *x, const char *d, size_t dl) Err bitreich.org 70 i 172 { Err bitreich.org 70 i 173 quote_print(d); Err bitreich.org 70 i 174 } Err bitreich.org 70 i 175 Err bitreich.org 70 i 176 void Err bitreich.org 70 i 177 xmldata(XMLParser *x, const char *d, size_t dl) Err bitreich.org 70 i 178 { Err bitreich.org 70 i 179 if ((strcspn(d, " \t\n") || (strspn(d, " \t\n")ref)) && emitsep){ Err bitreich.org 70 i 180 putchar(SEP); Err bitreich.org 70 i 181 emitsep = FALSE; Err bitreich.org 70 i 182 } Err bitreich.org 70 i 183 quote_print(d); Err bitreich.org 70 i 184 } Err bitreich.org 70 i 185 Err bitreich.org 70 i 186 void Err bitreich.org 70 i 187 xmldataend(XMLParser *x) Err bitreich.org 70 i 188 { Err bitreich.org 70 i 189 emitsep = FALSE; Err bitreich.org 70 i 190 } Err bitreich.org 70 i 191 Err bitreich.org 70 i 192 void Err bitreich.org 70 i 193 xmldataentity(XMLParser *x, const char *d, size_t dl) Err bitreich.org 70 i 194 { Err bitreich.org 70 i 195 char buf[16]; Err bitreich.org 70 i 196 int n; Err bitreich.org 70 i 197 Err bitreich.org 70 i 198 if ((n = xml_entitytostr(d, buf, sizeof(buf))) > 0) Err bitreich.org 70 i 199 xmldata(x, buf, (size_t)n); Err bitreich.org 70 i 200 else Err bitreich.org 70 i 201 xmldata(x, d, dl); Err bitreich.org 70 i 202 } Err bitreich.org 70 i 203 Err bitreich.org 70 i 204 void Err bitreich.org 70 i 205 xmldatastart(XMLParser *x) Err bitreich.org 70 i 206 { Err bitreich.org 70 i 207 emitsep = TRUE; Err bitreich.org 70 i 208 } Err bitreich.org 70 i 209 Err bitreich.org 70 i 210 void Err bitreich.org 70 i 211 xmltagend(XMLParser *x, const char *t, size_t tl, int isshort) Err bitreich.org 70 i 212 { Err bitreich.org 70 i 213 char *tag; Err bitreich.org 70 i 214 if (stack_empty(&st)){ Err bitreich.org 70 i 215 fprintf(stderr, "Error: tag-end '%s' before any open tag\n", t); Err bitreich.org 70 i 216 } Err bitreich.org 70 i 217 tag = stack_pop(&st)->s; Err bitreich.org 70 i 218 if (strcmp(t, tag)){ Err bitreich.org 70 i 219 fprintf(stderr, "Error: tag-end '%s' closes tag '%s'\n", t, tag); Err bitreich.org 70 i 220 } Err bitreich.org 70 i 221 } Err bitreich.org 70 i 222 Err bitreich.org 70 i 223 void Err bitreich.org 70 i 224 xmltagstart(XMLParser *x, const char *t, size_t tl) Err bitreich.org 70 i 225 { Err bitreich.org 70 i 226 if (stack_push(&st, t)){ Err bitreich.org 70 i 227 fprintf(stderr, "Error: stack full. Ignoring tag '%s' (parent tag: '%s')\n", t, stack_peek(&st)->s); Err bitreich.org 70 i 228 return; Err bitreich.org 70 i 229 } Err bitreich.org 70 i 230 putchar('\n'); Err bitreich.org 70 i 231 print_cur_str(&st); Err bitreich.org 70 i 232 } Err bitreich.org 70 i 233 Err bitreich.org 70 i 234 int Err bitreich.org 70 i 235 main(void) Err bitreich.org 70 i 236 { Err bitreich.org 70 i 237 stack_init(&st); Err bitreich.org 70 i 238 emitsep = FALSE; Err bitreich.org 70 i 239 XMLParser x = { 0 }; Err bitreich.org 70 i 240 Err bitreich.org 70 i 241 x.xmlattr = xmlattr; Err bitreich.org 70 i 242 x.xmlattrstart = xmlattrstart; Err bitreich.org 70 i 243 x.xmlattrentity = xmlattrentity; Err bitreich.org 70 i 244 x.xmlcdatastart = xmlcdatastart; Err bitreich.org 70 i 245 x.xmlcdata = xmlcdata; Err bitreich.org 70 i 246 x.xmldata = xmldata; Err bitreich.org 70 i 247 x.xmldataend = xmldataend; Err bitreich.org 70 i 248 x.xmldataentity = xmldataentity; Err bitreich.org 70 i 249 x.xmldatastart = xmldatastart; Err bitreich.org 70 i 250 x.xmltagend = xmltagend; Err bitreich.org 70 i 251 x.xmltagstart = xmltagstart; Err bitreich.org 70 i 252 Err bitreich.org 70 i 253 xml_parse(&x); Err bitreich.org 70 i 254 putchar('\n'); Err bitreich.org 70 i 255 if (! stack_empty(&st)) { Err bitreich.org 70 i 256 fprintf(stderr, "Error: tags still open at EOF: "); Err bitreich.org 70 i 257 print_cur_str_fp(stderr, &st); Err bitreich.org 70 i 258 fprintf(stderr, "\n"); Err bitreich.org 70 i 259 } Err bitreich.org 70 i 260 return 0; Err bitreich.org 70 i 261 } Err bitreich.org 70 .