ZeroTierOne/ext/miniupnpc/minixmlvalid.c
2017-01-19 15:52:39 -08:00

164 lines
3.5 KiB
C

/* $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;
}