164 lines
3.5 KiB
C
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;
|
|
}
|
|
|