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