/* $Id: minixmlvalid.c,v 1.7 2015/07/15 12:41:15 nanard Exp $ */ /* MiniUPnP Project * http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/ * minixmlvalid.c : * validation program for the minixml parser * * (c) 2006-2011 Thomas Bernard */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "minixml.h" /* xml event structure */ struct event { enum { ELTSTART, ELTEND, ATT, CHARDATA } type; const char * data; int len; }; struct eventlist { int n; struct event * events; }; /* compare 2 xml event lists * return 0 if the two lists are equals */ int evtlistcmp(struct eventlist * a, struct eventlist * b) { int i; struct event * ae, * be; if(a->n != b->n) { printf("event number not matching : %d != %d\n", a->n, b->n); /*return 1;*/ } for(i=0; i<a->n; i++) { ae = a->events + i; be = b->events + i; if( (ae->type != be->type) ||(ae->len != be->len) ||memcmp(ae->data, be->data, ae->len)) { printf("Found a difference : %d '%.*s' != %d '%.*s'\n", ae->type, ae->len, ae->data, be->type, be->len, be->data); return 1; } } return 0; } /* Test data */ static const char xmldata[] = "<xmlroot>\n" " <elt1 att1=\"attvalue1\" att2=\"attvalue2\">" "character data" "</elt1> \n \t" "<elt1b/>" "<elt1>\n<![CDATA[ <html>stuff !\n ]]> \n</elt1>\n" "<elt2a> \t<elt2b>chardata1</elt2b><elt2b> chardata2 </elt2b></elt2a>" "</xmlroot>"; static const struct event evtref[] = { {ELTSTART, "xmlroot", 7}, {ELTSTART, "elt1", 4}, /* attributes */ {CHARDATA, "character data", 14}, {ELTEND, "elt1", 4}, {ELTSTART, "elt1b", 5}, {ELTSTART, "elt1", 4}, {CHARDATA, " <html>stuff !\n ", 16}, {ELTEND, "elt1", 4}, {ELTSTART, "elt2a", 5}, {ELTSTART, "elt2b", 5}, {CHARDATA, "chardata1", 9}, {ELTEND, "elt2b", 5}, {ELTSTART, "elt2b", 5}, {CHARDATA, " chardata2 ", 11}, {ELTEND, "elt2b", 5}, {ELTEND, "elt2a", 5}, {ELTEND, "xmlroot", 7} }; void startelt(void * data, const char * p, int l) { struct eventlist * evtlist = data; struct event * evt; evt = evtlist->events + evtlist->n; /*printf("startelt : %.*s\n", l, p);*/ evt->type = ELTSTART; evt->data = p; evt->len = l; evtlist->n++; } void endelt(void * data, const char * p, int l) { struct eventlist * evtlist = data; struct event * evt; evt = evtlist->events + evtlist->n; /*printf("endelt : %.*s\n", l, p);*/ evt->type = ELTEND; evt->data = p; evt->len = l; evtlist->n++; } void chardata(void * data, const char * p, int l) { struct eventlist * evtlist = data; struct event * evt; evt = evtlist->events + evtlist->n; /*printf("chardata : '%.*s'\n", l, p);*/ evt->type = CHARDATA; evt->data = p; evt->len = l; evtlist->n++; } int testxmlparser(const char * xml, int size) { int r; struct eventlist evtlist; struct eventlist evtlistref; struct xmlparser parser; evtlist.n = 0; evtlist.events = malloc(sizeof(struct event)*100); if(evtlist.events == NULL) { fprintf(stderr, "Memory allocation error.\n"); return -1; } memset(&parser, 0, sizeof(parser)); parser.xmlstart = xml; parser.xmlsize = size; parser.data = &evtlist; parser.starteltfunc = startelt; parser.endeltfunc = endelt; parser.datafunc = chardata; parsexml(&parser); printf("%d events\n", evtlist.n); /* compare */ evtlistref.n = sizeof(evtref)/sizeof(struct event); evtlistref.events = (struct event *)evtref; r = evtlistcmp(&evtlistref, &evtlist); free(evtlist.events); return r; } int main(int argc, char * * argv) { int r; (void)argc; (void)argv; r = testxmlparser(xmldata, sizeof(xmldata)-1); if(r) printf("minixml validation test failed\n"); return r; }