1/* $Id: minixmlvalid.c,v 1.6 2012/05/01 16:24:07 nanard Exp $ */ 2/* MiniUPnP Project 3 * http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/ 4 * minixmlvalid.c : 5 * validation program for the minixml parser 6 * 7 * (c) 2006-2011 Thomas Bernard */ 8 9#include <stdlib.h> 10#include <stdio.h> 11#include <string.h> 12#include "minixml.h" 13 14/* xml event structure */ 15struct event { 16 enum { ELTSTART, ELTEND, ATT, CHARDATA } type; 17 const char * data; 18 int len; 19}; 20 21struct eventlist { 22 int n; 23 struct event * events; 24}; 25 26/* compare 2 xml event lists 27 * return 0 if the two lists are equals */ 28int evtlistcmp(struct eventlist * a, struct eventlist * b) 29{ 30 int i; 31 struct event * ae, * be; 32 if(a->n != b->n) 33 { 34 printf("event number not matching : %d != %d\n", a->n, b->n); 35 /*return 1;*/ 36 } 37 for(i=0; i<a->n; i++) 38 { 39 ae = a->events + i; 40 be = b->events + i; 41 if( (ae->type != be->type) 42 ||(ae->len != be->len) 43 ||memcmp(ae->data, be->data, ae->len)) 44 { 45 printf("Found a difference : %d '%.*s' != %d '%.*s'\n", 46 ae->type, ae->len, ae->data, 47 be->type, be->len, be->data); 48 return 1; 49 } 50 } 51 return 0; 52} 53 54/* Test data */ 55static const char xmldata[] = 56"<xmlroot>\n" 57" <elt1 att1=\"attvalue1\" att2=\"attvalue2\">" 58"character data" 59"</elt1> \n \t" 60"<elt1b/>" 61"<elt1>\n<![CDATA[ <html>stuff !\n ]]> \n</elt1>\n" 62"<elt2a> \t<elt2b>chardata1</elt2b><elt2b> chardata2 </elt2b></elt2a>" 63"</xmlroot>"; 64 65static const struct event evtref[] = 66{ 67 {ELTSTART, "xmlroot", 7}, 68 {ELTSTART, "elt1", 4}, 69 /* attributes */ 70 {CHARDATA, "character data", 14}, 71 {ELTEND, "elt1", 4}, 72 {ELTSTART, "elt1b", 5}, 73 {ELTSTART, "elt1", 4}, 74 {CHARDATA, " <html>stuff !\n ", 16}, 75 {ELTEND, "elt1", 4}, 76 {ELTSTART, "elt2a", 5}, 77 {ELTSTART, "elt2b", 5}, 78 {CHARDATA, "chardata1", 9}, 79 {ELTEND, "elt2b", 5}, 80 {ELTSTART, "elt2b", 5}, 81 {CHARDATA, " chardata2 ", 11}, 82 {ELTEND, "elt2b", 5}, 83 {ELTEND, "elt2a", 5}, 84 {ELTEND, "xmlroot", 7} 85}; 86 87void startelt(void * data, const char * p, int l) 88{ 89 struct eventlist * evtlist = data; 90 struct event * evt; 91 evt = evtlist->events + evtlist->n; 92 /*printf("startelt : %.*s\n", l, p);*/ 93 evt->type = ELTSTART; 94 evt->data = p; 95 evt->len = l; 96 evtlist->n++; 97} 98 99void endelt(void * data, const char * p, int l) 100{ 101 struct eventlist * evtlist = data; 102 struct event * evt; 103 evt = evtlist->events + evtlist->n; 104 /*printf("endelt : %.*s\n", l, p);*/ 105 evt->type = ELTEND; 106 evt->data = p; 107 evt->len = l; 108 evtlist->n++; 109} 110 111void chardata(void * data, const char * p, int l) 112{ 113 struct eventlist * evtlist = data; 114 struct event * evt; 115 evt = evtlist->events + evtlist->n; 116 /*printf("chardata : '%.*s'\n", l, p);*/ 117 evt->type = CHARDATA; 118 evt->data = p; 119 evt->len = l; 120 evtlist->n++; 121} 122 123int testxmlparser(const char * xml, int size) 124{ 125 int r; 126 struct eventlist evtlist; 127 struct eventlist evtlistref; 128 struct xmlparser parser; 129 evtlist.n = 0; 130 evtlist.events = malloc(sizeof(struct event)*100); 131 memset(&parser, 0, sizeof(parser)); 132 parser.xmlstart = xml; 133 parser.xmlsize = size; 134 parser.data = &evtlist; 135 parser.starteltfunc = startelt; 136 parser.endeltfunc = endelt; 137 parser.datafunc = chardata; 138 parsexml(&parser); 139 printf("%d events\n", evtlist.n); 140 /* compare */ 141 evtlistref.n = sizeof(evtref)/sizeof(struct event); 142 evtlistref.events = (struct event *)evtref; 143 r = evtlistcmp(&evtlistref, &evtlist); 144 free(evtlist.events); 145 return r; 146} 147 148int main(int argc, char * * argv) 149{ 150 int r; 151 (void)argc; (void)argv; 152 153 r = testxmlparser(xmldata, sizeof(xmldata)-1); 154 if(r) 155 printf("minixml validation test failed\n"); 156 return r; 157} 158 159