1 /* $Id: minixmlvalid.c,v 1.7 2015/07/15 12:41:15 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 */
15 struct event {
16 	enum { ELTSTART, ELTEND, ATT, CHARDATA } type;
17 	const char * data;
18 	int len;
19 };
20 
21 struct 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 */
evtlistcmp(struct eventlist * a,struct eventlist * b)28 int 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 */
55 static 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 
65 static 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 
startelt(void * data,const char * p,int l)87 void 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 
endelt(void * data,const char * p,int l)99 void 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 
chardata(void * data,const char * p,int l)111 void 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 
testxmlparser(const char * xml,int size)123 int 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 	if(evtlist.events == NULL)
132 	{
133 		fprintf(stderr, "Memory allocation error.\n");
134 		return -1;
135 	}
136 	memset(&parser, 0, sizeof(parser));
137 	parser.xmlstart = xml;
138 	parser.xmlsize = size;
139 	parser.data = &evtlist;
140 	parser.starteltfunc = startelt;
141 	parser.endeltfunc = endelt;
142 	parser.datafunc = chardata;
143 	parsexml(&parser);
144 	printf("%d events\n", evtlist.n);
145 	/* compare */
146 	evtlistref.n = sizeof(evtref)/sizeof(struct event);
147 	evtlistref.events = (struct event *)evtref;
148 	r = evtlistcmp(&evtlistref, &evtlist);
149 	free(evtlist.events);
150 	return r;
151 }
152 
main(int argc,char ** argv)153 int main(int argc, char * * argv)
154 {
155 	int r;
156 	(void)argc; (void)argv;
157 
158 	r = testxmlparser(xmldata, sizeof(xmldata)-1);
159 	if(r)
160 		printf("minixml validation test failed\n");
161 	return r;
162 }
163 
164