15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * testRelax.c : a small tester program for RelaxNG validation
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See Copyright for the status of this software.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Daniel.Veillard@w3.org
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libxml.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_SCHEMAS_ENABLED
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlversion.h>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/parser.h>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h>
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_TYPES_H
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h>
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_STAT_H
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/stat.h>
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_FCNTL_H
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h>
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_UNISTD_H
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h>
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_STDLIB_H
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_MMAN_H
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/mman.h>
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* seems needed for Solaris */
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef MAP_FAILED
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAP_FAILED ((void *) -1)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlmemory.h>
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/debugXML.h>
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/relaxng.h>
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_DEBUG_ENABLED
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int debug = 0;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int noout = 0;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tree = 0;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_MMAN_H
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int memory = 0;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, char **argv) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int files = 0;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRelaxNGPtr schema = NULL;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 1; i < argc ; i++) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_DEBUG_ENABLED
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    debug++;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_MMAN_H
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((!strcmp(argv[i], "-memory")) || (!strcmp(argv[i], "--memory"))) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    memory++;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((!strcmp(argv[i], "-noout")) || (!strcmp(argv[i], "--noout"))) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    noout++;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((!strcmp(argv[i], "-tree")) || (!strcmp(argv[i], "--tree"))) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tree++;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlLineNumbersDefault(1);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlSubstituteEntitiesDefault(1);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 1; i < argc ; i++) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (argv[i][0] != '-') {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (schema == NULL) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlRelaxNGParserCtxtPtr ctxt;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_MMAN_H
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (memory) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int fd;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    struct stat info;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    const char *base;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (stat(argv[i], &info) < 0)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if ((fd = open(argv[i], O_RDONLY)) < 0)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    base = mmap(NULL, info.st_size, PROT_READ,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			        MAP_SHARED, fd, 0) ;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (base == (void *) MAP_FAILED)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ctxt = xmlRelaxNGNewMemParserCtxt((char *)base,info.st_size);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRelaxNGSetParserErrors(ctxt,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    (xmlRelaxNGValidityErrorFunc) fprintf,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    (xmlRelaxNGValidityWarningFunc) fprintf,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    stderr);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    schema = xmlRelaxNGParse(ctxt);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRelaxNGFreeParserCtxt(ctxt);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    munmap((char *) base, info.st_size);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ctxt = xmlRelaxNGNewParserCtxt(argv[i]);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRelaxNGSetParserErrors(ctxt,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    (xmlRelaxNGValidityErrorFunc) fprintf,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    (xmlRelaxNGValidityWarningFunc) fprintf,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    stderr);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    schema = xmlRelaxNGParse(ctxt);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRelaxNGFreeParserCtxt(ctxt);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (schema == NULL) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    printf("Relax-NG schema %s failed to compile\n", argv[i]);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    files = -1;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_OUTPUT_ENABLED
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_DEBUG_ENABLED
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (debug)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRelaxNGDump(stdout, schema);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (tree)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRelaxNGDumpTree(stdout, schema);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* LIBXML_OUTPUT_ENABLED */
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlDocPtr doc;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		doc = xmlReadFile(argv[i],NULL,0);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (doc == NULL) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    fprintf(stderr, "Could not parse %s\n", argv[i]);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRelaxNGValidCtxtPtr ctxt;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int ret;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ctxt = xmlRelaxNGNewValidCtxt(schema);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRelaxNGSetValidErrors(ctxt,
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    (xmlRelaxNGValidityErrorFunc) fprintf,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    (xmlRelaxNGValidityWarningFunc) fprintf,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    stderr);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ret = xmlRelaxNGValidateDoc(ctxt, doc);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (ret == 0) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf("%s validates\n", argv[i]);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else if (ret > 0) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf("%s fails to validate\n", argv[i]);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf("%s validation generated an internal error\n",
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       argv[i]);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlRelaxNGFreeValidCtxt(ctxt);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlFreeDoc(doc);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    files ++;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (schema != NULL)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlRelaxNGFree(schema);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (files == 0) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("Usage : %s [--debug] [--noout] schemas XMLfiles ...\n",
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       argv[0]);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("\tParse the HTML files and output the result of the parsing\n");
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_DEBUG_ENABLED
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("\t--debug : dump a debug tree of the in-memory document\n");
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("\t--noout : do not print the result\n");
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("\t--tree : print the intermediate Relax-NG document tree\n");
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_MMAN_H
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf("\t--memory : test the schemas in memory parsing\n");
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlRelaxNGCleanupTypes();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlCleanupParser();
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlMemoryDump();
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("%s : RelaxNG support not compiled in\n", argv[0]);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* LIBXML_SCHEMAS_ENABLED */
195