16eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/*
26eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * relaxng.c : implementation of the Relax-NG handling and validity checking
36eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
46eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * See Copyright for the status of this software.
56eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
66eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Daniel Veillard <veillard@redhat.com>
76eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
86eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
9d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard/**
10d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * TODO:
11f4b4f9883928901706e31db825f8a7345c045d57Daniel Veillard * - add support for DTD compatibility spec
12f4b4f9883928901706e31db825f8a7345c045d57Daniel Veillard *   http://www.oasis-open.org/committees/relax-ng/compatibility-20011203.html
13ac297930c24964cfa1bde996d837081a74f57eeaDaniel Veillard * - report better mem allocations pbms at runtime and abort immediately.
14d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard */
15d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
166eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#define IN_LIBXML
176eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#include "libxml.h"
186eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
196eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#ifdef LIBXML_SCHEMAS_ENABLED
206eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
216eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#include <string.h>
226eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#include <stdio.h>
236eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#include <libxml/xmlmemory.h>
246eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#include <libxml/parser.h>
256eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#include <libxml/parserInternals.h>
266eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#include <libxml/hash.h>
276eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#include <libxml/uri.h>
286eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
296eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#include <libxml/relaxng.h>
306eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
316eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#include <libxml/xmlschemastypes.h>
326eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#include <libxml/xmlautomata.h>
336eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#include <libxml/xmlregexp.h>
34c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard#include <libxml/xmlschemastypes.h>
356eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
366eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/*
376eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * The Relax-NG namespace
386eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
396eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic const xmlChar *xmlRelaxNGNs = (const xmlChar *)
406eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    "http://relaxng.org/ns/structure/1.0";
416eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
42264cee695ad2ff20776ec880f1bb8185367bbf58Daniel Veillard#define IS_RELAXNG(node, typ)						\
436eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard   ((node != NULL) && (node->ns != NULL) &&				\
44264cee695ad2ff20776ec880f1bb8185367bbf58Daniel Veillard    (node->type == XML_ELEMENT_NODE) &&					\
45264cee695ad2ff20776ec880f1bb8185367bbf58Daniel Veillard    (xmlStrEqual(node->name, (const xmlChar *) typ)) &&		\
466eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    (xmlStrEqual(node->ns->href, xmlRelaxNGNs)))
476eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
486eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
4923a47d604877300624c0f5d701e2c0dec7cf80f6Daniel Veillard#if 0
5087254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard#define DEBUG 1
514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
5287254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard#define DEBUG_GRAMMAR 1
534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
5487254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard#define DEBUG_CONTENT 1
554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
5687254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard#define DEBUG_TYPE 1
574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
5887254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard#define DEBUG_VALID 1
594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
6087254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard#define DEBUG_INTERLEAVE 1
614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
6287254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard#define DEBUG_LIST 1
634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
64f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#define DEBUG_INCLUDE 1
654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
6687254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard#define DEBUG_ERROR 1
674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
6887254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard#define DEBUG_COMPILE 1
694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
7087254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard#define DEBUG_PROGRESSIVE 1
7187254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard#endif
726eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
735f1946ad7cf7015f3f9af8f619b845a9221cc7f9Daniel Veillard#define MAX_ERROR 5
745f1946ad7cf7015f3f9af8f619b845a9221cc7f9Daniel Veillard
75f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#define TODO								\
766eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlGenericError(xmlGenericErrorContext,				\
776eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard	    "Unimplemented block at %s:%d\n",				\
786eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard            __FILE__, __LINE__);
796eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
806eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardtypedef struct _xmlRelaxNGSchema xmlRelaxNGSchema;
816eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardtypedef xmlRelaxNGSchema *xmlRelaxNGSchemaPtr;
826eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
836eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardtypedef struct _xmlRelaxNGDefine xmlRelaxNGDefine;
846eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardtypedef xmlRelaxNGDefine *xmlRelaxNGDefinePtr;
856eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
86d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillardtypedef struct _xmlRelaxNGDocument xmlRelaxNGDocument;
87d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillardtypedef xmlRelaxNGDocument *xmlRelaxNGDocumentPtr;
88d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
89a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillardtypedef struct _xmlRelaxNGInclude xmlRelaxNGInclude;
90a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillardtypedef xmlRelaxNGInclude *xmlRelaxNGIncludePtr;
91a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard
926eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardtypedef enum {
934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_COMBINE_UNDEFINED = 0,  /* undefined */
944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_COMBINE_CHOICE, /* choice */
954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_COMBINE_INTERLEAVE      /* interleave */
966eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard} xmlRelaxNGCombine;
976eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
984c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillardtypedef enum {
994c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard    XML_RELAXNG_CONTENT_ERROR = -1,
1004c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard    XML_RELAXNG_CONTENT_EMPTY = 0,
1014c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard    XML_RELAXNG_CONTENT_SIMPLE,
1024c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard    XML_RELAXNG_CONTENT_COMPLEX
1034c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard} xmlRelaxNGContentType;
1044c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard
1056eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardtypedef struct _xmlRelaxNGGrammar xmlRelaxNGGrammar;
1066eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardtypedef xmlRelaxNGGrammar *xmlRelaxNGGrammarPtr;
1076eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
1086eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstruct _xmlRelaxNGGrammar {
1094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGGrammarPtr parent;        /* the parent grammar if any */
1104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGGrammarPtr children;      /* the children grammar if any */
1114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGGrammarPtr next;  /* the next grammar if any */
1124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDefinePtr start;  /* <start> content */
1134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGCombine combine;  /* the default combine value */
1144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDefinePtr startList;      /* list of <start> definitions */
1154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlHashTablePtr defs;       /* define* */
1164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlHashTablePtr refs;       /* references */
1176eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard};
1186eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
1196eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
1206eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardtypedef enum {
1214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_NOOP = -1,      /* a no operation from simplification  */
1224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_EMPTY = 0,      /* an empty pattern */
1236eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    XML_RELAXNG_NOT_ALLOWED,    /* not allowed top */
1244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_EXCEPT,         /* except present in nameclass defs */
1254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_TEXT,           /* textual content */
1264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_ELEMENT,        /* an element */
1274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_DATATYPE,       /* extenal data type definition */
1284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_PARAM,          /* extenal data type parameter */
1294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_VALUE,          /* value from an extenal data type definition */
1304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_LIST,           /* a list of patterns */
1314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_ATTRIBUTE,      /* an attrbute following a pattern */
1324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_DEF,            /* a definition */
1334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_REF,            /* reference to a definition */
1344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_EXTERNALREF,    /* reference to an external def */
1354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_PARENTREF,      /* reference to a def in the parent grammar */
1364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_OPTIONAL,       /* optional patterns */
1374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_ZEROORMORE,     /* zero or more non empty patterns */
1384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_ONEORMORE,      /* one or more non empty patterns */
1394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_CHOICE,         /* a choice between non empty patterns */
1404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_GROUP,          /* a pair/group of non empty patterns */
1414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_INTERLEAVE,     /* interleaving choice of non-empty patterns */
1424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    XML_RELAXNG_START           /* Used to keep track of starts on grammars */
1436eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard} xmlRelaxNGType;
1446eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
14552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard#define IS_NULLABLE		(1 << 0)
14652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard#define IS_NOT_NULLABLE		(1 << 1)
14752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard#define IS_INDETERMINIST	(1 << 2)
14852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard#define IS_MIXED		(1 << 3)
14952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard#define IS_TRIABLE		(1 << 4)
15052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard#define IS_PROCESSED		(1 << 5)
15152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard#define IS_COMPILABLE		(1 << 6)
15252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard#define IS_NOT_COMPILABLE	(1 << 7)
153aa422d9254f373141428bf0879f08af7ad15f3bfDaniel Veillard#define IS_EXTERNAL_REF	        (1 << 8)
1541564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
1556eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstruct _xmlRelaxNGDefine {
1564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGType type;        /* the type of definition */
1574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlNodePtr node;            /* the node in the source */
1584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlChar *name;              /* the element local name if present */
1594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlChar *ns;                /* the namespace local name if present */
1604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlChar *value;             /* value when available */
1614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    void *data;                 /* data lib or specific pointer */
1624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDefinePtr content;        /* the expected content */
1634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDefinePtr parent; /* the parent definition, if any */
1644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDefinePtr next;   /* list within grouping sequences */
1654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDefinePtr attrs;  /* list of attributes for elements */
1664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDefinePtr nameClass;      /* the nameClass definition if any */
1674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDefinePtr nextHash;       /* next define in defs/refs hash tables */
1684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    short depth;                /* used for the cycle detection */
1694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    short dflags;               /* define related flags */
1704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRegexpPtr contModel;     /* a compiled content model if available */
1716eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard};
1726eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
1736eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
1746eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * _xmlRelaxNG:
1756eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
1766eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * A RelaxNGs definition
1776eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
1786eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstruct _xmlRelaxNG {
1794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    void *_private;             /* unused by the library for users or bindings */
1806eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGGrammarPtr topgrammar;
1816eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlDocPtr doc;
1826eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
1834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int idref;                  /* requires idref checking */
184c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard
1854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlHashTablePtr defs;       /* define */
1864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlHashTablePtr refs;       /* references */
1874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDocumentPtr documents;    /* all the documents loaded */
1884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGIncludePtr includes;      /* all the includes loaded */
1894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int defNr;                  /* number of defines used */
1904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDefinePtr *defTab;        /* pointer to the allocated definitions */
191c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard
1926eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard};
1936eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
19477648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard#define XML_RELAXNG_IN_ATTRIBUTE	(1 << 0)
19577648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard#define XML_RELAXNG_IN_ONEORMORE	(1 << 1)
19677648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard#define XML_RELAXNG_IN_LIST		(1 << 2)
19777648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard#define XML_RELAXNG_IN_DATAEXCEPT	(1 << 3)
19877648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard#define XML_RELAXNG_IN_START		(1 << 4)
19977648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard#define XML_RELAXNG_IN_OOMGROUP		(1 << 5)
20077648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard#define XML_RELAXNG_IN_OOMINTERLEAVE	(1 << 6)
20177648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard#define XML_RELAXNG_IN_EXTERNALREF	(1 << 7)
202c5312d7c7658f12e30e11f8700f1c00d9ca3a99fDaniel Veillard#define XML_RELAXNG_IN_ANYEXCEPT	(1 << 8)
203c5312d7c7658f12e30e11f8700f1c00d9ca3a99fDaniel Veillard#define XML_RELAXNG_IN_NSEXCEPT		(1 << 9)
2046eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
2056eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstruct _xmlRelaxNGParserCtxt {
2064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    void *userData;             /* user specific data block */
2074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGValidityErrorFunc error;  /* the callback in case of errors */
2084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGValidityWarningFunc warning;      /* the callback in case of warning */
209659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard    xmlStructuredErrorFunc serror;
21042f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    xmlRelaxNGValidErr err;
2116eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
2124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGPtr schema;       /* The schema in use */
2134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGGrammarPtr grammar;       /* the current grammar */
2144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGGrammarPtr parentgrammar; /* the parent grammar */
2154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int flags;                  /* parser flags */
2164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int nbErrors;               /* number of errors at parse time */
2174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int nbWarnings;             /* number of warnings at parse time */
2184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    const xmlChar *define;      /* the current define scope */
2194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDefinePtr def;    /* the current define */
22076fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard
2214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int nbInterleaves;
2224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlHashTablePtr interleaves;        /* keep track of all the interleaves */
2236eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
2244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDocumentPtr documents;    /* all the documents loaded */
2254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGIncludePtr includes;      /* all the includes loaded */
2264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlChar *URL;
2274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlDocPtr document;
2286eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
2294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int defNr;                  /* number of defines used */
2304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int defMax;                 /* number of defines aloocated */
2314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDefinePtr *defTab;        /* pointer to the allocated definitions */
232419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard
2334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    const char *buffer;
2344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int size;
2356eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
236d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    /* the document stack */
2374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDocumentPtr doc;  /* Current parsed external ref */
2384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int docNr;                  /* Depth of the parsing stack */
2394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int docMax;                 /* Max depth of the parsing stack */
2404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDocumentPtr *docTab;      /* array of docs */
241a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard
242a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    /* the include stack */
2434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGIncludePtr inc;   /* Current parsed include */
2444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int incNr;                  /* Depth of the include parsing stack */
2454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int incMax;                 /* Max depth of the parsing stack */
2464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGIncludePtr *incTab;       /* array of incs */
247c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard
2484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int idref;                  /* requires idref checking */
24952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard
25052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard    /* used to compile content models */
2514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlAutomataPtr am;          /* the automata */
2524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlAutomataStatePtr state;  /* used to build the automata */
25303c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard
25403c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard    int crng;			/* compact syntax and other flags */
2554259532303e96e089a185c6f55056cb7c4902d71Daniel Veillard    int freedoc;		/* need to free the document */
2566eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard};
2576eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
2586eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#define FLAGS_IGNORABLE		1
2596eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#define FLAGS_NEGATIVE		2
260249d7bbee28570177a8573a99eab4aa9e27384d9Daniel Veillard#define FLAGS_MIXED_CONTENT	4
261b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard#define FLAGS_NOERROR		8
2626eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
2636eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
26476fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * xmlRelaxNGInterleaveGroup:
26576fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard *
26676fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * A RelaxNGs partition set associated to lists of definitions
26776fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard */
26876fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillardtypedef struct _xmlRelaxNGInterleaveGroup xmlRelaxNGInterleaveGroup;
26976fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillardtypedef xmlRelaxNGInterleaveGroup *xmlRelaxNGInterleaveGroupPtr;
27076fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillardstruct _xmlRelaxNGInterleaveGroup {
2714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDefinePtr rule;   /* the rule to satisfy */
2724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDefinePtr *defs;  /* the array of element definitions */
2734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDefinePtr *attrs; /* the array of attributes definitions */
27476fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard};
27576fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard
276bbb78b5d6d18b008bbd14edefecde4156d85f949Daniel Veillard#define IS_DETERMINIST		1
277bbb78b5d6d18b008bbd14edefecde4156d85f949Daniel Veillard#define IS_NEEDCHECK		2
2784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
27976fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard/**
28076fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * xmlRelaxNGPartitions:
28176fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard *
28276fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * A RelaxNGs partition associated to an interleave group
28376fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard */
28476fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillardtypedef struct _xmlRelaxNGPartition xmlRelaxNGPartition;
28576fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillardtypedef xmlRelaxNGPartition *xmlRelaxNGPartitionPtr;
28676fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillardstruct _xmlRelaxNGPartition {
2874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int nbgroups;               /* number of groups in the partitions */
2884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlHashTablePtr triage;     /* hash table used to direct nodes to the
2894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                 * right group when possible */
2904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int flags;                  /* determinist ? */
29176fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    xmlRelaxNGInterleaveGroupPtr *groups;
29276fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard};
29376fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard
29476fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard/**
2956eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGValidState:
2966eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
2976eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * A RelaxNGs validation state
2986eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
2996eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#define MAX_ATTR 20
3006eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardtypedef struct _xmlRelaxNGValidState xmlRelaxNGValidState;
3016eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardtypedef xmlRelaxNGValidState *xmlRelaxNGValidStatePtr;
3026eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstruct _xmlRelaxNGValidState {
3034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlNodePtr node;            /* the current node */
3044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlNodePtr seq;             /* the sequence of children left to validate */
3054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int nbAttrs;                /* the number of attributes */
3064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int maxAttrs;               /* the size of attrs */
3074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int nbAttrLeft;             /* the number of attributes left to validate */
3084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlChar *value;             /* the value when operating on string */
3094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlChar *endvalue;          /* the end value when operating on string */
3104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlAttrPtr *attrs;          /* the array of attributes */
3116eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard};
3126eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
3136eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
314fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGStates:
315fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *
316fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * A RelaxNGs container for validation state
317fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard */
318fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillardtypedef struct _xmlRelaxNGStates xmlRelaxNGStates;
319fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillardtypedef xmlRelaxNGStates *xmlRelaxNGStatesPtr;
320fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillardstruct _xmlRelaxNGStates {
3214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int nbState;                /* the number of states */
3224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int maxState;               /* the size of the array */
323fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGValidStatePtr *tabState;
324fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard};
325fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
326c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard#define ERROR_IS_DUP	1
3274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
328fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard/**
32942f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * xmlRelaxNGValidError:
33042f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard *
33142f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * A RelaxNGs validation error
33242f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard */
33342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillardtypedef struct _xmlRelaxNGValidError xmlRelaxNGValidError;
33442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillardtypedef xmlRelaxNGValidError *xmlRelaxNGValidErrorPtr;
33542f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillardstruct _xmlRelaxNGValidError {
3364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGValidErr err;     /* the error number */
3374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int flags;                  /* flags */
3384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlNodePtr node;            /* the current node */
3394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlNodePtr seq;             /* the current child */
3404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    const xmlChar *arg1;        /* first arg */
3414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    const xmlChar *arg2;        /* second arg */
34242f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard};
34342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard
34442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard/**
3456eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGValidCtxt:
3466eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
3476eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * A RelaxNGs validation context
3486eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
3496eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
3506eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstruct _xmlRelaxNGValidCtxt {
3514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    void *userData;             /* user specific data block */
3524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGValidityErrorFunc error;  /* the callback in case of errors */
3534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGValidityWarningFunc warning;      /* the callback in case of warning */
354659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard    xmlStructuredErrorFunc serror;
3554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int nbErrors;               /* number of errors in validation */
3564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
3574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGPtr schema;       /* The schema in use */
3584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlDocPtr doc;              /* the document being validated */
3594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int flags;                  /* validation flags */
3604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int depth;                  /* validation depth */
3614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int idref;                  /* requires idref checking */
3624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int errNo;                  /* the first error found */
36342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard
36442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    /*
36542f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard     * Errors accumulated in branches may have to be stacked to be
36642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard     * provided back when it's sure they affect validation.
36742f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard     */
36842f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    xmlRelaxNGValidErrorPtr err;        /* Last error */
3694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int errNr;                  /* Depth of the error stack */
3704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int errMax;                 /* Max depth of the error stack */
3714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGValidErrorPtr errTab;     /* stack of errors */
3721564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
3734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGValidStatePtr state;      /* the current validation state */
3744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGStatesPtr states; /* the accumulated state list */
375798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard
3764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGStatesPtr freeState;      /* the pool of free valid states */
3774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int freeStatesNr;
3784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int freeStatesMax;
3794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGStatesPtr *freeStates;    /* the pool of free state groups */
380f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
381f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    /*
382f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard     * This is used for "progressive" validation
383f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard     */
3844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRegExecCtxtPtr elem;     /* the current element regexp */
3854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int elemNr;                 /* the number of element validated */
3864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int elemMax;                /* the max depth of elements */
3874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRegExecCtxtPtr *elemTab; /* the stack of regexp runtime */
3884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int pstate;                 /* progressive state */
3894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlNodePtr pnode;           /* the current node */
3904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDefinePtr pdef;   /* the non-streamable definition */
3914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int perr;                   /* signal error in content model
3924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                 * outside the regexp */
3936eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard};
3946eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
395d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard/**
396a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * xmlRelaxNGInclude:
397a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard *
398a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * Structure associated to a RelaxNGs document element
399a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard */
400a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillardstruct _xmlRelaxNGInclude {
4014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGIncludePtr next;  /* keep a chain of includes */
4024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlChar *href;              /* the normalized href value */
4034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlDocPtr doc;              /* the associated XML document */
4044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDefinePtr content;        /* the definitions */
4054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGPtr schema;       /* the schema */
406a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard};
407a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard
408a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard/**
409d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * xmlRelaxNGDocument:
410d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard *
411d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * Structure associated to a RelaxNGs document element
412d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard */
413d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillardstruct _xmlRelaxNGDocument {
414c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    xmlRelaxNGDocumentPtr next; /* keep a chain of documents */
4154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlChar *href;              /* the normalized href value */
4164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlDocPtr doc;              /* the associated XML document */
4174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGDefinePtr content;        /* the definitions */
4184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGPtr schema;       /* the schema */
41981c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard    int externalRef;            /* 1 if an external ref */
420d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard};
421d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
4223ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard
4236eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/************************************************************************
4244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard *									*
425f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *		Some factorized error routines				*
4264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard *									*
4274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard ************************************************************************/
4284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
4294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard/**
4304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * xmlRngPErrMemory:
4314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @ctxt:  an Relax-NG parser context
4324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @extra:  extra informations
4334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard *
4344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * Handle a redefinition of attribute error
4354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard */
4364c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic void
4374c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRngPErrMemory(xmlRelaxNGParserCtxtPtr ctxt, const char *extra)
4384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
439659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard    xmlStructuredErrorFunc schannel = NULL;
4404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlGenericErrorFunc channel = NULL;
4414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    void *data = NULL;
4424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
4434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (ctxt != NULL) {
444b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard        if (ctxt->serror != NULL)
445b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard	    schannel = ctxt->serror;
446b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard	else
447b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard	    channel = ctxt->error;
4484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        data = ctxt->userData;
4494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->nbErrors++;
4504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
4514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (extra)
452659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard        __xmlRaiseError(schannel, channel, data,
4534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        NULL, NULL, XML_FROM_RELAXNGP,
4544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
4554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        NULL, NULL, 0, 0,
4564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        "Memory allocation failed : %s\n", extra);
4574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    else
458659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard        __xmlRaiseError(schannel, channel, data,
4594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        NULL, NULL, XML_FROM_RELAXNGP,
4604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
4614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        NULL, NULL, 0, 0, "Memory allocation failed\n");
4624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard}
4634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
4644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard/**
4654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * xmlRngVErrMemory:
4664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @ctxt:  a Relax-NG validation context
4674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @extra:  extra informations
4684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard *
4694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * Handle a redefinition of attribute error
4704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard */
4714c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic void
4724c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRngVErrMemory(xmlRelaxNGValidCtxtPtr ctxt, const char *extra)
4734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
474659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard    xmlStructuredErrorFunc schannel = NULL;
4754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlGenericErrorFunc channel = NULL;
4764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    void *data = NULL;
4774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
4784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (ctxt != NULL) {
479b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard        if (ctxt->serror != NULL)
480b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard	    schannel = ctxt->serror;
481b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard	else
482b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard	    channel = ctxt->error;
4834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        data = ctxt->userData;
4844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->nbErrors++;
4854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
4864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (extra)
487659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard        __xmlRaiseError(schannel, channel, data,
4884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        NULL, NULL, XML_FROM_RELAXNGV,
4894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
4904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        NULL, NULL, 0, 0,
4914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        "Memory allocation failed : %s\n", extra);
4924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    else
493659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard        __xmlRaiseError(schannel, channel, data,
4944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        NULL, NULL, XML_FROM_RELAXNGV,
4954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
4964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        NULL, NULL, 0, 0, "Memory allocation failed\n");
4974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard}
4984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
4994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard/**
5004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * xmlRngPErr:
5014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @ctxt:  a Relax-NG parser context
5024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @node:  the node raising the error
5034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @error:  the error code
5044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @msg:  message
5054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @str1:  extra info
5064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @str2:  extra info
5074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard *
5084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * Handle a Relax NG Parsing error
5094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard */
5104c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic void
5114c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRngPErr(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node, int error,
5124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard           const char *msg, const xmlChar * str1, const xmlChar * str2)
5134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
514659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard    xmlStructuredErrorFunc schannel = NULL;
5154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlGenericErrorFunc channel = NULL;
5164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    void *data = NULL;
5174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
5184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (ctxt != NULL) {
519b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard        if (ctxt->serror != NULL)
520b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard	    schannel = ctxt->serror;
521b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard	else
522b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard	    channel = ctxt->error;
5234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        data = ctxt->userData;
5244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->nbErrors++;
5254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
526659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard    __xmlRaiseError(schannel, channel, data,
5274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    NULL, node, XML_FROM_RELAXNGP,
5284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    error, XML_ERR_ERROR, NULL, 0,
5294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (const char *) str1, (const char *) str2, NULL, 0, 0,
5304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    msg, str1, str2);
5314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard}
5324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
5334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard/**
5344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * xmlRngVErr:
5354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @ctxt:  a Relax-NG validation context
5364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @node:  the node raising the error
5374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @error:  the error code
5384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @msg:  message
5394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @str1:  extra info
5404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @str2:  extra info
5414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard *
5424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * Handle a Relax NG Validation error
5434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard */
5444c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic void
5454c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRngVErr(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node, int error,
5464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard           const char *msg, const xmlChar * str1, const xmlChar * str2)
5474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
548659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard    xmlStructuredErrorFunc schannel = NULL;
5494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlGenericErrorFunc channel = NULL;
5504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    void *data = NULL;
5514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
5524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (ctxt != NULL) {
553b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard        if (ctxt->serror != NULL)
554b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard	    schannel = ctxt->serror;
555b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard	else
556b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard	    channel = ctxt->error;
5574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        data = ctxt->userData;
5584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->nbErrors++;
5594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
560659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard    __xmlRaiseError(schannel, channel, data,
5614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    NULL, node, XML_FROM_RELAXNGV,
5624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    error, XML_ERR_ERROR, NULL, 0,
5634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (const char *) str1, (const char *) str2, NULL, 0, 0,
5644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    msg, str1, str2);
5654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard}
5664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
5674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard/************************************************************************
568f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
569f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *		Preliminary type checking interfaces			*
570f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
571dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard ************************************************************************/
5724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
573dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard/**
574dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * xmlRelaxNGTypeHave:
575dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @data:  data needed for the library
576dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @type:  the type name
577dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @value:  the value to check
578dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
579dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Function provided by a type library to check if a type is exported
580dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
581dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Returns 1 if yes, 0 if no and -1 in case of error.
582dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard */
5834c0041471199f283c4e696526c73e2809da54e21Daniel Veillardtypedef int (*xmlRelaxNGTypeHave) (void *data, const xmlChar * type);
584dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
585dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard/**
586dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * xmlRelaxNGTypeCheck:
587dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @data:  data needed for the library
588dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @type:  the type name
589dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @value:  the value to check
5908bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * @result:  place to store the result if needed
591dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
592dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Function provided by a type library to check if a value match a type
593dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
594dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Returns 1 if yes, 0 if no and -1 in case of error.
595dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard */
5964c0041471199f283c4e696526c73e2809da54e21Daniel Veillardtypedef int (*xmlRelaxNGTypeCheck) (void *data, const xmlChar * type,
5974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                    const xmlChar * value, void **result,
5984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                    xmlNodePtr node);
5998bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard
6008bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard/**
6018bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * xmlRelaxNGFacetCheck:
6028bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * @data:  data needed for the library
6038bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * @type:  the type name
6048bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * @facet:  the facet name
6058bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * @val:  the facet value
6068bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * @strval:  the string value
6078bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * @value:  the value to check
6088bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard *
6098bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * Function provided by a type library to check a value facet
6108bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard *
6118bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * Returns 1 if yes, 0 if no and -1 in case of error.
6128bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard */
6134c0041471199f283c4e696526c73e2809da54e21Daniel Veillardtypedef int (*xmlRelaxNGFacetCheck) (void *data, const xmlChar * type,
6144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     const xmlChar * facet,
6154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     const xmlChar * val,
6164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     const xmlChar * strval, void *value);
6178bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard
6188bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard/**
6198bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * xmlRelaxNGTypeFree:
6208bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * @data:  data needed for the library
6218bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * @result:  the value to free
6228bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard *
6238bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * Function provided by a type library to free a returned result
6248bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard */
6258bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillardtypedef void (*xmlRelaxNGTypeFree) (void *data, void *result);
626dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
627dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard/**
628dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * xmlRelaxNGTypeCompare:
629dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @data:  data needed for the library
630dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @type:  the type name
631dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @value1:  the first value
632dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @value2:  the second value
633dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
634dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Function provided by a type library to compare two values accordingly
635dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * to a type.
636dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
637dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Returns 1 if yes, 0 if no and -1 in case of error.
638dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard */
6394c0041471199f283c4e696526c73e2809da54e21Daniel Veillardtypedef int (*xmlRelaxNGTypeCompare) (void *data, const xmlChar * type,
6404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                      const xmlChar * value1,
6414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                      xmlNodePtr ctxt1,
6424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                      void *comp1,
6434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                      const xmlChar * value2,
6444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                      xmlNodePtr ctxt2);
645dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillardtypedef struct _xmlRelaxNGTypeLibrary xmlRelaxNGTypeLibrary;
646dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillardtypedef xmlRelaxNGTypeLibrary *xmlRelaxNGTypeLibraryPtr;
647dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillardstruct _xmlRelaxNGTypeLibrary {
6484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    const xmlChar *namespace;   /* the datatypeLibrary value */
6494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    void *data;                 /* data needed for the library */
6504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGTypeHave have;    /* the export function */
6514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGTypeCheck check;  /* the checking function */
6524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGTypeCompare comp; /* the compare function */
6534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGFacetCheck facet; /* the facet check function */
6544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGTypeFree freef;   /* the freeing function */
655dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard};
656dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
657dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard/************************************************************************
658f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
659f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *			Allocation functions				*
660f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
6616eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard ************************************************************************/
6626eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic void xmlRelaxNGFreeGrammar(xmlRelaxNGGrammarPtr grammar);
6636eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic void xmlRelaxNGFreeDefine(xmlRelaxNGDefinePtr define);
6644c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic void xmlRelaxNGNormExtSpace(xmlChar * value);
665c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillardstatic void xmlRelaxNGFreeInnerSchema(xmlRelaxNGPtr schema);
6664c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic int xmlRelaxNGEqualValidState(xmlRelaxNGValidCtxtPtr ctxt
6674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     ATTRIBUTE_UNUSED,
6684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     xmlRelaxNGValidStatePtr state1,
6694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     xmlRelaxNGValidStatePtr state2);
670798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillardstatic void xmlRelaxNGFreeValidState(xmlRelaxNGValidCtxtPtr ctxt,
6714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     xmlRelaxNGValidStatePtr state);
6726eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
6736eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
674d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * xmlRelaxNGFreeDocument:
675d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * @docu:  a document structure
676d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard *
677d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * Deallocate a RelaxNG document structure.
678d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard */
679d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillardstatic void
680d41f4f488864d962a42239eb4526729a2dadc685Daniel VeillardxmlRelaxNGFreeDocument(xmlRelaxNGDocumentPtr docu)
681d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard{
682d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    if (docu == NULL)
683d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard        return;
684d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
685d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    if (docu->href != NULL)
6864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(docu->href);
687d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    if (docu->doc != NULL)
6884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFreeDoc(docu->doc);
689d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    if (docu->schema != NULL)
6904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeInnerSchema(docu->schema);
691d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    xmlFree(docu);
692d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard}
693d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
694d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard/**
695c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard * xmlRelaxNGFreeDocumentList:
696c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard * @docu:  a list of  document structure
697c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard *
698c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard * Deallocate a RelaxNG document structures.
699c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard */
700c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillardstatic void
701c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel VeillardxmlRelaxNGFreeDocumentList(xmlRelaxNGDocumentPtr docu)
702c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard{
703c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    xmlRelaxNGDocumentPtr next;
7044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
705c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    while (docu != NULL) {
7064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        next = docu->next;
7074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeDocument(docu);
7084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        docu = next;
709c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    }
710c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard}
711c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard
712c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard/**
713a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * xmlRelaxNGFreeInclude:
714a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * @incl:  a include structure
715a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard *
716a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * Deallocate a RelaxNG include structure.
717a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard */
718a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillardstatic void
719a9d912de798de5a88f3492e57e3330826a2f1247Daniel VeillardxmlRelaxNGFreeInclude(xmlRelaxNGIncludePtr incl)
720a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard{
721a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    if (incl == NULL)
722a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard        return;
723a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard
724a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    if (incl->href != NULL)
7254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(incl->href);
726a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    if (incl->doc != NULL)
7274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFreeDoc(incl->doc);
728a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    if (incl->schema != NULL)
7294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFree(incl->schema);
730a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    xmlFree(incl);
731a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard}
732a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard
733a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard/**
734c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard * xmlRelaxNGFreeIncludeList:
735c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard * @incl:  a include structure list
736c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard *
737c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard * Deallocate a RelaxNG include structure.
738c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard */
739c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillardstatic void
740c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel VeillardxmlRelaxNGFreeIncludeList(xmlRelaxNGIncludePtr incl)
741c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard{
742c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    xmlRelaxNGIncludePtr next;
7434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
744c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    while (incl != NULL) {
7454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        next = incl->next;
7464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeInclude(incl);
7474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        incl = next;
748c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    }
749c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard}
750c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard
751c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard/**
7526eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGNewRelaxNG:
7536eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG validation context (optional)
7546eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
7556eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Allocate a new RelaxNG structure.
7566eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
7576eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns the newly allocated structure or NULL in case or error
7586eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
7596eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic xmlRelaxNGPtr
7606eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGNewRelaxNG(xmlRelaxNGParserCtxtPtr ctxt)
7616eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard{
7626eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGPtr ret;
7636eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
7646eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ret = (xmlRelaxNGPtr) xmlMalloc(sizeof(xmlRelaxNG));
7656eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ret == NULL) {
7664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErrMemory(ctxt, NULL);
7676eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        return (NULL);
7686eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
7696eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    memset(ret, 0, sizeof(xmlRelaxNG));
7706eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
7716eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    return (ret);
7726eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
7736eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
7746eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
775c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard * xmlRelaxNGFreeInnerSchema:
776c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard * @schema:  a schema structure
777c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard *
778c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard * Deallocate a RelaxNG schema structure.
779c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard */
780c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillardstatic void
781c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel VeillardxmlRelaxNGFreeInnerSchema(xmlRelaxNGPtr schema)
782c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard{
783c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    if (schema == NULL)
784c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard        return;
785c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard
786c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    if (schema->doc != NULL)
7874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFreeDoc(schema->doc);
788c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    if (schema->defTab != NULL) {
7894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        int i;
790c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard
7914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        for (i = 0; i < schema->defNr; i++)
7924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGFreeDefine(schema->defTab[i]);
7934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(schema->defTab);
794c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    }
795c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard
796c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    xmlFree(schema);
797c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard}
798c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard
799c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard/**
8006eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGFree:
8016eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @schema:  a schema structure
8026eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
8036eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Deallocate a RelaxNG structure.
8046eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
8056eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardvoid
8066eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGFree(xmlRelaxNGPtr schema)
8076eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard{
8086eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (schema == NULL)
8096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        return;
8106eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
8116eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (schema->topgrammar != NULL)
8124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeGrammar(schema->topgrammar);
8136eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (schema->doc != NULL)
8144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFreeDoc(schema->doc);
815d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    if (schema->documents != NULL)
8164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeDocumentList(schema->documents);
817a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    if (schema->includes != NULL)
8184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeIncludeList(schema->includes);
819419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard    if (schema->defTab != NULL) {
8204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        int i;
821419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard
8224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        for (i = 0; i < schema->defNr; i++)
8234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGFreeDefine(schema->defTab[i]);
8244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(schema->defTab);
825419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard    }
8266eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
8276eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlFree(schema);
8286eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
8296eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
8306eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
8316eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGNewGrammar:
8326eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG validation context (optional)
8336eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
8346eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Allocate a new RelaxNG grammar.
8356eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
8366eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns the newly allocated structure or NULL in case or error
8376eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
8386eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic xmlRelaxNGGrammarPtr
8396eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGNewGrammar(xmlRelaxNGParserCtxtPtr ctxt)
8406eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard{
8416eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGGrammarPtr ret;
8426eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
8436eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ret = (xmlRelaxNGGrammarPtr) xmlMalloc(sizeof(xmlRelaxNGGrammar));
8446eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ret == NULL) {
8454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErrMemory(ctxt, NULL);
8466eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        return (NULL);
8476eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
8486eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    memset(ret, 0, sizeof(xmlRelaxNGGrammar));
8496eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
8506eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    return (ret);
8516eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
8526eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
8536eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
8546eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGFreeGrammar:
8556eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @grammar:  a grammar structure
8566eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
8576eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Deallocate a RelaxNG grammar structure.
8586eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
8596eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic void
8606eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGFreeGrammar(xmlRelaxNGGrammarPtr grammar)
8616eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard{
8626eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (grammar == NULL)
8636eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        return;
8646eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
865c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    if (grammar->children != NULL) {
8664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeGrammar(grammar->children);
867c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    }
868419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard    if (grammar->next != NULL) {
8694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeGrammar(grammar->next);
870419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard    }
8716eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (grammar->refs != NULL) {
8724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlHashFree(grammar->refs, NULL);
8736eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
8746eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (grammar->defs != NULL) {
8754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlHashFree(grammar->defs, NULL);
8766eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
8776eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
8786eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlFree(grammar);
8796eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
8806eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
8816eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
8826eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGNewDefine:
8836eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG validation context
8846eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @node:  the node in the input document.
8856eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
8866eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Allocate a new RelaxNG define.
8876eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
8886eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns the newly allocated structure or NULL in case or error
8896eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
8906eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic xmlRelaxNGDefinePtr
891fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel VeillardxmlRelaxNGNewDefine(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
8926eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard{
8936eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGDefinePtr ret;
8946eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
895419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard    if (ctxt->defMax == 0) {
8964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->defMax = 16;
8974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->defNr = 0;
8984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->defTab = (xmlRelaxNGDefinePtr *)
8994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlMalloc(ctxt->defMax * sizeof(xmlRelaxNGDefinePtr));
9004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->defTab == NULL) {
9014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErrMemory(ctxt, "allocating define\n");
9024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
9034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
904419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard    } else if (ctxt->defMax <= ctxt->defNr) {
9054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGDefinePtr *tmp;
9064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
9074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->defMax *= 2;
9084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        tmp = (xmlRelaxNGDefinePtr *) xmlRealloc(ctxt->defTab,
9094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                 ctxt->defMax *
9104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                 sizeof
9114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                 (xmlRelaxNGDefinePtr));
9124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (tmp == NULL) {
9134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErrMemory(ctxt, "allocating define\n");
9144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
9154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
9164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->defTab = tmp;
917419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard    }
9186eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ret = (xmlRelaxNGDefinePtr) xmlMalloc(sizeof(xmlRelaxNGDefine));
9196eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ret == NULL) {
9204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErrMemory(ctxt, "allocating define\n");
9214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
9226eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
9236eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    memset(ret, 0, sizeof(xmlRelaxNGDefine));
924419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard    ctxt->defTab[ctxt->defNr++] = ret;
9256eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ret->node = node;
926d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard    ret->depth = -1;
9276eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    return (ret);
9286eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
9296eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
9306eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
93176fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * xmlRelaxNGFreePartition:
93276fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * @partitions:  a partition set structure
93376fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard *
93476fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * Deallocate RelaxNG partition set structures.
93576fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard */
93676fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillardstatic void
9374c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGFreePartition(xmlRelaxNGPartitionPtr partitions)
9384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
93976fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    xmlRelaxNGInterleaveGroupPtr group;
94076fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    int j;
94176fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard
94276fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    if (partitions != NULL) {
9434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (partitions->groups != NULL) {
9444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            for (j = 0; j < partitions->nbgroups; j++) {
9454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                group = partitions->groups[j];
9464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (group != NULL) {
9474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (group->defs != NULL)
9484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlFree(group->defs);
9494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (group->attrs != NULL)
9504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlFree(group->attrs);
9514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlFree(group);
9524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
9534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
9544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlFree(partitions->groups);
9554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
9564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (partitions->triage != NULL) {
9574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlHashFree(partitions->triage, NULL);
9584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
9594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(partitions);
96076fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    }
96176fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard}
9624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
96376fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard/**
9646eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGFreeDefine:
9656eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @define:  a define structure
9666eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
9676eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Deallocate a RelaxNG define structure.
9686eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
9696eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic void
9706eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGFreeDefine(xmlRelaxNGDefinePtr define)
9716eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard{
9726eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (define == NULL)
9736eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        return;
9746eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
9754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if ((define->type == XML_RELAXNG_VALUE) && (define->attrs != NULL)) {
9764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGTypeLibraryPtr lib;
977e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard
9784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        lib = (xmlRelaxNGTypeLibraryPtr) define->data;
9794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((lib != NULL) && (lib->freef != NULL))
9804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            lib->freef(lib->data, (void *) define->attrs);
981e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    }
9824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if ((define->data != NULL) && (define->type == XML_RELAXNG_INTERLEAVE))
9834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreePartition((xmlRelaxNGPartitionPtr) define->data);
9844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if ((define->data != NULL) && (define->type == XML_RELAXNG_CHOICE))
9854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlHashFree((xmlHashTablePtr) define->data, NULL);
9866eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (define->name != NULL)
9874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(define->name);
9886eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (define->ns != NULL)
9894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(define->ns);
990edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    if (define->value != NULL)
9914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(define->value);
99252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard    if (define->contModel != NULL)
99352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        xmlRegFreeRegexp(define->contModel);
9946eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlFree(define);
9956eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
9966eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
9976eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
998fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGNewStates:
999fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @ctxt:  a Relax-NG validation context
1000fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @size:  the default size for the container
1001fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *
1002fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Allocate a new RelaxNG validation state container
1003fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *
1004fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Returns the newly allocated structure or NULL in case or error
1005fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard */
1006fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillardstatic xmlRelaxNGStatesPtr
1007fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel VeillardxmlRelaxNGNewStates(xmlRelaxNGValidCtxtPtr ctxt, int size)
1008fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard{
1009fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGStatesPtr ret;
1010fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
1011798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    if ((ctxt != NULL) &&
10129fcd462f271fb7bf49b6c7c6993cf42dcf879377Daniel Veillard        (ctxt->freeStates != NULL) && (ctxt->freeStatesNr > 0)) {
10134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->freeStatesNr--;
10144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = ctxt->freeStates[ctxt->freeStatesNr];
10154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret->nbState = 0;
10164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (ret);
1017798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    }
10184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (size < 16)
10194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        size = 16;
1020fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
1021fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    ret = (xmlRelaxNGStatesPtr) xmlMalloc(sizeof(xmlRelaxNGStates) +
10224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                          (size -
10234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                           1) *
10244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                          sizeof(xmlRelaxNGValidStatePtr));
1025fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (ret == NULL) {
10264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngVErrMemory(ctxt, "allocating states\n");
1027fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        return (NULL);
1028fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
1029fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    ret->nbState = 0;
1030fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    ret->maxState = size;
10314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    ret->tabState = (xmlRelaxNGValidStatePtr *) xmlMalloc((size) *
10324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                          sizeof
10334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                          (xmlRelaxNGValidStatePtr));
1034fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (ret->tabState == NULL) {
10354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngVErrMemory(ctxt, "allocating states\n");
10364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(ret);
1037fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        return (NULL);
1038fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
10394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
1040fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard}
1041fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
1042fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard/**
1043798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard * xmlRelaxNGAddStateUniq:
1044798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard * @ctxt:  a Relax-NG validation context
1045798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard * @states:  the states container
1046798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard * @state:  the validation state
1047798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard *
1048798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard * Add a RelaxNG validation state to the container without checking
1049798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard * for unicity.
1050798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard *
1051798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard * Return 1 in case of success and 0 if this is a duplicate and -1 on error
1052798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard */
1053798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillardstatic int
1054798024a1106a00891a12e5a56ee1a0048697ed46Daniel VeillardxmlRelaxNGAddStatesUniq(xmlRelaxNGValidCtxtPtr ctxt,
10554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGStatesPtr states,
10564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGValidStatePtr state)
1057798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard{
1058798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    if (state == NULL) {
10594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
1060798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    }
1061798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    if (states->nbState >= states->maxState) {
10624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGValidStatePtr *tmp;
10634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        int size;
10644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
10654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        size = states->maxState * 2;
10664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        tmp = (xmlRelaxNGValidStatePtr *) xmlRealloc(states->tabState,
10674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                     (size) *
10684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                     sizeof
10694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                     (xmlRelaxNGValidStatePtr));
1070798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard        if (tmp == NULL) {
10714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngVErrMemory(ctxt, "adding states\n");
10724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (-1);
10734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
10744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        states->tabState = tmp;
10754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        states->maxState = size;
1076798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    }
1077798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    states->tabState[states->nbState++] = state;
10784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (1);
1079798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard}
1080798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard
1081798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard/**
1082fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGAddState:
1083fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @ctxt:  a Relax-NG validation context
1084fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @states:  the states container
1085fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @state:  the validation state
1086fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *
1087fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Add a RelaxNG validation state to the container
1088fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *
1089fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Return 1 in case of success and 0 if this is a duplicate and -1 on error
1090fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard */
1091fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillardstatic int
10924c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGAddStates(xmlRelaxNGValidCtxtPtr ctxt,
10934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGStatesPtr states,
10944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGValidStatePtr state)
1095fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard{
1096fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    int i;
1097fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
10987d2e8c950f1f017f5f3a45f999e5a3aad3e699daGaurav Gupta    if (state == NULL || states == NULL) {
10994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
1100fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
1101fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (states->nbState >= states->maxState) {
11024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGValidStatePtr *tmp;
11034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        int size;
11044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
11054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        size = states->maxState * 2;
11064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        tmp = (xmlRelaxNGValidStatePtr *) xmlRealloc(states->tabState,
11074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                     (size) *
11084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                     sizeof
11094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                     (xmlRelaxNGValidStatePtr));
1110fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        if (tmp == NULL) {
11114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngVErrMemory(ctxt, "adding states\n");
11124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (-1);
11134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
11144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        states->tabState = tmp;
11154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        states->maxState = size;
11164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
11174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    for (i = 0; i < states->nbState; i++) {
11184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (xmlRelaxNGEqualValidState(ctxt, state, states->tabState[i])) {
11194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGFreeValidState(ctxt, state);
11204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (0);
11214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
1122fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
1123fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    states->tabState[states->nbState++] = state;
11244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (1);
1125fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard}
1126fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
1127fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard/**
1128fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGFreeStates:
1129fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @ctxt:  a Relax-NG validation context
1130fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @states:  teh container
1131fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *
1132fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Free a RelaxNG validation state container
1133fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard */
1134fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillardstatic void
1135798024a1106a00891a12e5a56ee1a0048697ed46Daniel VeillardxmlRelaxNGFreeStates(xmlRelaxNGValidCtxtPtr ctxt,
11364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     xmlRelaxNGStatesPtr states)
1137fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard{
1138798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    if (states == NULL)
11394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
1140798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    if ((ctxt != NULL) && (ctxt->freeStates == NULL)) {
11414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->freeStatesMax = 40;
11424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->freeStatesNr = 0;
11434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->freeStates = (xmlRelaxNGStatesPtr *)
11444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlMalloc(ctxt->freeStatesMax * sizeof(xmlRelaxNGStatesPtr));
11454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->freeStates == NULL) {
11464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngVErrMemory(ctxt, "storing states\n");
11474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
11484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    } else if ((ctxt != NULL)
11494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard               && (ctxt->freeStatesNr >= ctxt->freeStatesMax)) {
11504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGStatesPtr *tmp;
11514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
11524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        tmp = (xmlRelaxNGStatesPtr *) xmlRealloc(ctxt->freeStates,
11534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                 2 * ctxt->freeStatesMax *
11544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                 sizeof
11554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                 (xmlRelaxNGStatesPtr));
11564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (tmp == NULL) {
11574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngVErrMemory(ctxt, "storing states\n");
11584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlFree(states->tabState);
11594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlFree(states);
11604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return;
11614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
11624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->freeStates = tmp;
11634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->freeStatesMax *= 2;
1164798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    }
116514b5643947845df089376106517c4f7ba061e4b0Daniel Veillard    if ((ctxt == NULL) || (ctxt->freeStates == NULL)) {
11664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(states->tabState);
11674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(states);
1168798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    } else {
11694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->freeStates[ctxt->freeStatesNr++] = states;
1170fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
1171fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard}
1172fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
1173fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard/**
11746eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGNewValidState:
11756eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG validation context
11766eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @node:  the current node or NULL for the document
11776eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
11786eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Allocate a new RelaxNG validation state
11796eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
11806eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns the newly allocated structure or NULL in case or error
11816eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
11826eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic xmlRelaxNGValidStatePtr
11836eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGNewValidState(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node)
11846eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard{
11856eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGValidStatePtr ret;
11866eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlAttrPtr attr;
11876eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlAttrPtr attrs[MAX_ATTR];
11886eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    int nbAttrs = 0;
11896eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlNodePtr root = NULL;
11906eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
11916eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (node == NULL) {
11924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        root = xmlDocGetRootElement(ctxt->doc);
11934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (root == NULL)
11944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
11956eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    } else {
11964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        attr = node->properties;
11974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        while (attr != NULL) {
11984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (nbAttrs < MAX_ATTR)
11994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                attrs[nbAttrs++] = attr;
12004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            else
12014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                nbAttrs++;
12024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            attr = attr->next;
12034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
12044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
12054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if ((ctxt->freeState != NULL) && (ctxt->freeState->nbState > 0)) {
12064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->freeState->nbState--;
12074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = ctxt->freeState->tabState[ctxt->freeState->nbState];
1208798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    } else {
12094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret =
12104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (xmlRelaxNGValidStatePtr)
12114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlMalloc(sizeof(xmlRelaxNGValidState));
12124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ret == NULL) {
12134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngVErrMemory(ctxt, "allocating states\n");
12144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
12154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
12164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        memset(ret, 0, sizeof(xmlRelaxNGValidState));
12176eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
1218e5b110b3844d58ff4bea56bcb699144f6fbe0b83Daniel Veillard    ret->value = NULL;
1219e5b110b3844d58ff4bea56bcb699144f6fbe0b83Daniel Veillard    ret->endvalue = NULL;
12206eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (node == NULL) {
12214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret->node = (xmlNodePtr) ctxt->doc;
12224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret->seq = root;
12236eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    } else {
12244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret->node = node;
12254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret->seq = node->children;
1226798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    }
1227798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    ret->nbAttrs = 0;
1228798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    if (nbAttrs > 0) {
12294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ret->attrs == NULL) {
12304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (nbAttrs < 4)
12314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret->maxAttrs = 4;
12324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            else
12334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret->maxAttrs = nbAttrs;
12344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret->attrs = (xmlAttrPtr *) xmlMalloc(ret->maxAttrs *
12354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                  sizeof(xmlAttrPtr));
12364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret->attrs == NULL) {
12374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngVErrMemory(ctxt, "allocating states\n");
12384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (ret);
12394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
12404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (ret->maxAttrs < nbAttrs) {
12414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlAttrPtr *tmp;
12424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
12434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp = (xmlAttrPtr *) xmlRealloc(ret->attrs, nbAttrs *
12444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                            sizeof(xmlAttrPtr));
12454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (tmp == NULL) {
12464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngVErrMemory(ctxt, "allocating states\n");
12474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (ret);
12484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
12494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret->attrs = tmp;
12504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret->maxAttrs = nbAttrs;
12514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
12524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret->nbAttrs = nbAttrs;
12534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (nbAttrs < MAX_ATTR) {
12544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            memcpy(ret->attrs, attrs, sizeof(xmlAttrPtr) * nbAttrs);
12554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
12564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            attr = node->properties;
12574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            nbAttrs = 0;
12584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            while (attr != NULL) {
12594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret->attrs[nbAttrs++] = attr;
12604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                attr = attr->next;
12614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
12624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
12636eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
12641ed7f364bdb278e583b8d7663d7cc0f90307b6bbDaniel Veillard    ret->nbAttrLeft = ret->nbAttrs;
12656eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    return (ret);
12666eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
12676eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
12686eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
1269fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGCopyValidState:
1270fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @ctxt:  a Relax-NG validation context
1271fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @state:  a validation state
1272fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *
1273fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Copy the validation state
1274fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *
1275fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Returns the newly allocated structure or NULL in case or error
1276fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard */
1277fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillardstatic xmlRelaxNGValidStatePtr
1278fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel VeillardxmlRelaxNGCopyValidState(xmlRelaxNGValidCtxtPtr ctxt,
12794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         xmlRelaxNGValidStatePtr state)
1280fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard{
1281fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGValidStatePtr ret;
1282798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    unsigned int maxAttrs;
1283798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    xmlAttrPtr *attrs;
1284fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
1285fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (state == NULL)
12864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
12874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if ((ctxt->freeState != NULL) && (ctxt->freeState->nbState > 0)) {
12884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->freeState->nbState--;
12894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = ctxt->freeState->tabState[ctxt->freeState->nbState];
1290798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    } else {
12914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret =
12924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (xmlRelaxNGValidStatePtr)
12934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlMalloc(sizeof(xmlRelaxNGValidState));
12944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ret == NULL) {
12954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngVErrMemory(ctxt, "allocating states\n");
12964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
12974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
12984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        memset(ret, 0, sizeof(xmlRelaxNGValidState));
1299798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    }
1300798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    attrs = ret->attrs;
1301798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    maxAttrs = ret->maxAttrs;
1302798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    memcpy(ret, state, sizeof(xmlRelaxNGValidState));
1303798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    ret->attrs = attrs;
1304798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    ret->maxAttrs = maxAttrs;
1305798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    if (state->nbAttrs > 0) {
13064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ret->attrs == NULL) {
13074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret->maxAttrs = state->maxAttrs;
13084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret->attrs = (xmlAttrPtr *) xmlMalloc(ret->maxAttrs *
13094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                  sizeof(xmlAttrPtr));
13104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret->attrs == NULL) {
13114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngVErrMemory(ctxt, "allocating states\n");
13124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret->nbAttrs = 0;
13134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (ret);
13144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
13154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (ret->maxAttrs < state->nbAttrs) {
13164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlAttrPtr *tmp;
13174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
13184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp = (xmlAttrPtr *) xmlRealloc(ret->attrs, state->maxAttrs *
13194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                            sizeof(xmlAttrPtr));
13204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (tmp == NULL) {
13214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngVErrMemory(ctxt, "allocating states\n");
13224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret->nbAttrs = 0;
13234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (ret);
13244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
13254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret->maxAttrs = state->maxAttrs;
13264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret->attrs = tmp;
13274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
13284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        memcpy(ret->attrs, state->attrs,
13294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard               state->nbAttrs * sizeof(xmlAttrPtr));
13304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
13314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
1332fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard}
1333fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
1334fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard/**
1335fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGEqualValidState:
1336fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @ctxt:  a Relax-NG validation context
1337fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @state1:  a validation state
1338fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @state2:  a validation state
1339fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *
1340fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Compare the validation states for equality
1341fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *
1342fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Returns 1 if equald, 0 otherwise
1343fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard */
1344fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillardstatic int
1345fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel VeillardxmlRelaxNGEqualValidState(xmlRelaxNGValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
13464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                          xmlRelaxNGValidStatePtr state1,
13474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                          xmlRelaxNGValidStatePtr state2)
1348fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard{
1349fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    int i;
1350fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
1351fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if ((state1 == NULL) || (state2 == NULL))
13524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (0);
1353fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (state1 == state2)
13544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (1);
1355fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (state1->node != state2->node)
13564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (0);
1357fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (state1->seq != state2->seq)
13584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (0);
1359fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (state1->nbAttrLeft != state2->nbAttrLeft)
13604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (0);
1361fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (state1->nbAttrs != state2->nbAttrs)
13624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (0);
1363fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (state1->endvalue != state2->endvalue)
13644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (0);
1365fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if ((state1->value != state2->value) &&
13664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        (!xmlStrEqual(state1->value, state2->value)))
13674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (0);
13684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    for (i = 0; i < state1->nbAttrs; i++) {
13694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (state1->attrs[i] != state2->attrs[i])
13704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (0);
1371fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
13724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (1);
1373fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard}
1374fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
1375fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard/**
13766eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGFreeValidState:
13776eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @state:  a validation state structure
13786eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
13796eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Deallocate a RelaxNG validation state structure.
13806eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
13816eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic void
1382798024a1106a00891a12e5a56ee1a0048697ed46Daniel VeillardxmlRelaxNGFreeValidState(xmlRelaxNGValidCtxtPtr ctxt,
13834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         xmlRelaxNGValidStatePtr state)
13846eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard{
13856eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (state == NULL)
13866eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        return;
13876eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
1388798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    if ((ctxt != NULL) && (ctxt->freeState == NULL)) {
13894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->freeState = xmlRelaxNGNewStates(ctxt, 40);
1390798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    }
1391798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    if ((ctxt == NULL) || (ctxt->freeState == NULL)) {
13924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (state->attrs != NULL)
13934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlFree(state->attrs);
13944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(state);
1395798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    } else {
13964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGAddStatesUniq(ctxt, ctxt->freeState, state);
1397798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    }
13986eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
13996eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
14006eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/************************************************************************
1401f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
1402f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *			Semi internal functions				*
1403f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
140403c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard ************************************************************************/
140503c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard
140603c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard/**
140703c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard * xmlRelaxParserSetFlag:
140803c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard * @ctxt: a RelaxNG parser context
140903c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard * @flags: a set of flags values
141003c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard *
141103c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard * Semi private function used to pass informations to a parser context
141203c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard * which are a combination of xmlRelaxNGParserFlag .
141303c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard *
141403c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard * Returns 0 if success and -1 in case of error
141503c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard */
141603c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillardint
141703c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel VeillardxmlRelaxParserSetFlag(xmlRelaxNGParserCtxtPtr ctxt, int flags)
141803c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard{
141903c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard    if (ctxt == NULL) return(-1);
142003c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard    if (flags & XML_RELAXNGP_FREE_DOC) {
142103c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard        ctxt->crng |= XML_RELAXNGP_FREE_DOC;
142203c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard	flags -= XML_RELAXNGP_FREE_DOC;
142303c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard    }
142403c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard    if (flags & XML_RELAXNGP_CRNG) {
142503c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard        ctxt->crng |= XML_RELAXNGP_CRNG;
142603c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard	flags -= XML_RELAXNGP_CRNG;
142703c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard    }
142803c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard    if (flags != 0) return(-1);
142903c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard    return(0);
143003c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard}
143103c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard
143203c2f0a41d11ce26510a601f8a0ef9afa6c9a828Daniel Veillard/************************************************************************
1433f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
1434f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *			Document functions				*
1435f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
1436d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard ************************************************************************/
1437d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillardstatic xmlDocPtr xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt,
14384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                      xmlDocPtr doc);
1439d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
1440d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard/**
1441a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * xmlRelaxNGIncludePush:
1442a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * @ctxt:  the parser context
1443a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * @value:  the element doc
1444a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard *
1445a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * Pushes a new include on top of the include stack
1446a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard *
1447a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * Returns 0 in case of error, the index in the stack otherwise
1448a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard */
1449a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillardstatic int
1450a9d912de798de5a88f3492e57e3330826a2f1247Daniel VeillardxmlRelaxNGIncludePush(xmlRelaxNGParserCtxtPtr ctxt,
14514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                      xmlRelaxNGIncludePtr value)
1452a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard{
1453a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    if (ctxt->incTab == NULL) {
14544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->incMax = 4;
14554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->incNr = 0;
14564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->incTab =
14574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (xmlRelaxNGIncludePtr *) xmlMalloc(ctxt->incMax *
14584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               sizeof(ctxt->incTab[0]));
1459a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard        if (ctxt->incTab == NULL) {
14604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErrMemory(ctxt, "allocating include\n");
1461a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard            return (0);
1462a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard        }
1463a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    }
1464a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    if (ctxt->incNr >= ctxt->incMax) {
1465a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard        ctxt->incMax *= 2;
1466a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard        ctxt->incTab =
1467a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard            (xmlRelaxNGIncludePtr *) xmlRealloc(ctxt->incTab,
14684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                ctxt->incMax *
14694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                sizeof(ctxt->incTab[0]));
1470a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard        if (ctxt->incTab == NULL) {
14714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErrMemory(ctxt, "allocating include\n");
1472a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard            return (0);
1473a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard        }
1474a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    }
1475a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    ctxt->incTab[ctxt->incNr] = value;
1476a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    ctxt->inc = value;
1477a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    return (ctxt->incNr++);
1478a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard}
1479a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard
1480a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard/**
1481a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * xmlRelaxNGIncludePop:
1482a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * @ctxt: the parser context
1483a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard *
1484a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * Pops the top include from the include stack
1485a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard *
1486a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * Returns the include just removed
1487a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard */
1488a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillardstatic xmlRelaxNGIncludePtr
1489a9d912de798de5a88f3492e57e3330826a2f1247Daniel VeillardxmlRelaxNGIncludePop(xmlRelaxNGParserCtxtPtr ctxt)
1490a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard{
1491a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    xmlRelaxNGIncludePtr ret;
1492a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard
1493a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    if (ctxt->incNr <= 0)
149424505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard        return (NULL);
1495a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    ctxt->incNr--;
1496a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    if (ctxt->incNr > 0)
1497a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard        ctxt->inc = ctxt->incTab[ctxt->incNr - 1];
1498a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    else
1499a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard        ctxt->inc = NULL;
1500a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    ret = ctxt->incTab[ctxt->incNr];
150124505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard    ctxt->incTab[ctxt->incNr] = NULL;
1502a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    return (ret);
1503a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard}
1504a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard
1505a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard/**
15065add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard * xmlRelaxNGRemoveRedefine:
15075add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard * @ctxt: the parser context
15085add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard * @URL:  the normalized URL
15095add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard * @target:  the included target
15105add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard * @name:  the define name to eliminate
15115add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard *
15125add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard * Applies the elimination algorithm of 4.7
15135add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard *
15145add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard * Returns 0 in case of error, 1 in case of success.
15155add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard */
15165add868b2e79a304c8d99be57bc446f94798af84Daniel Veillardstatic int
15175add868b2e79a304c8d99be57bc446f94798af84Daniel VeillardxmlRelaxNGRemoveRedefine(xmlRelaxNGParserCtxtPtr ctxt,
15184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         const xmlChar * URL ATTRIBUTE_UNUSED,
15194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         xmlNodePtr target, const xmlChar * name)
15204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
15215add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard    int found = 0;
15225add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard    xmlNodePtr tmp, tmp2;
15235add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard    xmlChar *name2;
15245add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard
15255add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard#ifdef DEBUG_INCLUDE
1526952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard    if (name == NULL)
15274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
15284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        "Elimination of <include> start from %s\n", URL);
1529952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard    else
15304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
15314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        "Elimination of <include> define %s from %s\n",
15324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        name, URL);
15335add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard#endif
15345add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard    tmp = target;
15355add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard    while (tmp != NULL) {
15364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        tmp2 = tmp->next;
15374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((name == NULL) && (IS_RELAXNG(tmp, "start"))) {
15384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            found = 1;
15394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlUnlinkNode(tmp);
15404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlFreeNode(tmp);
15414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if ((name != NULL) && (IS_RELAXNG(tmp, "define"))) {
15424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            name2 = xmlGetProp(tmp, BAD_CAST "name");
15434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGNormExtSpace(name2);
15444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (name2 != NULL) {
15454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (xmlStrEqual(name, name2)) {
15464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    found = 1;
15474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlUnlinkNode(tmp);
15484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlFreeNode(tmp);
15494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
15504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlFree(name2);
15514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
15524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (IS_RELAXNG(tmp, "include")) {
15534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlChar *href = NULL;
1554807daf826510d2d0597fdd10314e51b4d56c5e96Daniel Veillard            xmlRelaxNGDocumentPtr inc = tmp->psvi;
15554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
15564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((inc != NULL) && (inc->doc != NULL) &&
15574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                (inc->doc->children != NULL)) {
15584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
15594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (xmlStrEqual
15604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (inc->doc->children->name, BAD_CAST "grammar")) {
15615add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard#ifdef DEBUG_INCLUDE
15624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    href = xmlGetProp(tmp, BAD_CAST "href");
15635add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard#endif
15644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (xmlRelaxNGRemoveRedefine(ctxt, href,
1565d7eb9b5d47e1f5ea1c45db3a0ca5a1c8621cfb05Shaun McCance                                                 xmlDocGetRootElement(inc->doc)->children,
1566d7eb9b5d47e1f5ea1c45db3a0ca5a1c8621cfb05Shaun McCance                                                 name) == 1) {
15674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        found = 1;
15684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
156914b5643947845df089376106517c4f7ba061e4b0Daniel Veillard#ifdef DEBUG_INCLUDE
15704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (href != NULL)
15714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlFree(href);
157214b5643947845df089376106517c4f7ba061e4b0Daniel Veillard#endif
15734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
15744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
15754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
15764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        tmp = tmp2;
15775add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard    }
15784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (found);
15795add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard}
15805add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard
15815add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard/**
1582a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * xmlRelaxNGLoadInclude:
1583a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * @ctxt: the parser context
1584a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * @URL:  the normalized URL
1585a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * @node: the include node.
1586416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard * @ns:  the namespace passed from the context.
1587a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard *
1588a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * First lookup if the document is already loaded into the parser context,
1589a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * check against recursion. If not found the resource is loaded and
1590a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * the content is preprocessed before being returned back to the caller.
1591a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard *
1592a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * Returns the xmlRelaxNGIncludePtr or NULL in case of error
1593a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard */
1594a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillardstatic xmlRelaxNGIncludePtr
15954c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * URL,
15964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                      xmlNodePtr node, const xmlChar * ns)
15974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
1598a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    xmlRelaxNGIncludePtr ret = NULL;
1599a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    xmlDocPtr doc;
1600a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    int i;
16015add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard    xmlNodePtr root, cur;
16025add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard
16035add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard#ifdef DEBUG_INCLUDE
16045add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard    xmlGenericError(xmlGenericErrorContext,
16054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    "xmlRelaxNGLoadInclude(%s)\n", URL);
16065add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard#endif
1607a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard
1608a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    /*
1609a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard     * check against recursion in the stack
1610a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard     */
16114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    for (i = 0; i < ctxt->incNr; i++) {
16124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (xmlStrEqual(ctxt->incTab[i]->href, URL)) {
16134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, NULL, XML_RNGP_INCLUDE_RECURSE,
16144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Detected an Include recursion for %s\n", URL,
16154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       NULL);
16164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
16174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
1618a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    }
1619a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard
1620a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    /*
1621a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard     * load the document
1622a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard     */
162387247e87408561aee625b2e800ea3c13211af897Daniel Veillard    doc = xmlReadFile((const char *) URL,NULL,0);
1624a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    if (doc == NULL) {
16254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_PARSE_ERROR,
16264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "xmlRelaxNG: could not load %s\n", URL, NULL);
16274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
1628a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    }
16295add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard#ifdef DEBUG_INCLUDE
16304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlGenericError(xmlGenericErrorContext, "Parsed %s Okay\n", URL);
16315add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard#endif
16325add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard
1633a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    /*
1634a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard     * Allocate the document structures and register it first.
1635a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard     */
1636a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    ret = (xmlRelaxNGIncludePtr) xmlMalloc(sizeof(xmlRelaxNGInclude));
1637a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    if (ret == NULL) {
16384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErrMemory(ctxt, "allocating include\n");
16394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFreeDoc(doc);
16404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
1641a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    }
1642a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    memset(ret, 0, sizeof(xmlRelaxNGInclude));
1643a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    ret->doc = doc;
1644a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    ret->href = xmlStrdup(URL);
1645c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    ret->next = ctxt->includes;
1646c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    ctxt->includes = ret;
1647a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard
1648a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    /*
1649416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard     * transmit the ns if needed
1650416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard     */
1651416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard    if (ns != NULL) {
16524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        root = xmlDocGetRootElement(doc);
16534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (root != NULL) {
16544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (xmlHasProp(root, BAD_CAST "ns") == NULL) {
16554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlSetProp(root, BAD_CAST "ns", ns);
16564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
16574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
1658416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard    }
1659416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard
1660416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard    /*
1661c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard     * push it on the stack
1662a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard     */
1663a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    xmlRelaxNGIncludePush(ctxt, ret);
1664a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard
1665a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    /*
1666a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard     * Some preprocessing of the document content, this include recursing
1667a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard     * in the include stack.
1668a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard     */
16695add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard#ifdef DEBUG_INCLUDE
16704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlGenericError(xmlGenericErrorContext, "cleanup of %s\n", URL);
16715add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard#endif
16725add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard
1673a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    doc = xmlRelaxNGCleanupDoc(ctxt, doc);
1674a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    if (doc == NULL) {
16754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->inc = NULL;
16764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
1677a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    }
1678a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard
1679a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    /*
1680a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard     * Pop up the include from the stack
1681a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard     */
1682a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    xmlRelaxNGIncludePop(ctxt);
1683a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard
16845add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard#ifdef DEBUG_INCLUDE
16854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlGenericError(xmlGenericErrorContext, "Checking of %s\n", URL);
16865add868b2e79a304c8d99be57bc446f94798af84Daniel Veillard#endif
1687a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    /*
1688a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard     * Check that the top element is a grammar
1689a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard     */
1690a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    root = xmlDocGetRootElement(doc);
1691a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    if (root == NULL) {
16924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_EMPTY,
16934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "xmlRelaxNG: included document is empty %s\n", URL,
16944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   NULL);
16954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
1696a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    }
1697a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    if (!IS_RELAXNG(root, "grammar")) {
16984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_GRAMMAR_MISSING,
16994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "xmlRelaxNG: included document %s root is not a grammar\n",
17004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   URL, NULL);
17014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
1702a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    }
1703a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard
1704a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    /*
1705a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard     * Elimination of redefined rules in the include.
1706a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard     */
1707a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    cur = node->children;
1708a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    while (cur != NULL) {
17094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (IS_RELAXNG(cur, "start")) {
17104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            int found = 0;
17114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
17124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            found =
17134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGRemoveRedefine(ctxt, URL, root->children, NULL);
17144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (!found) {
17154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, node, XML_RNGP_START_MISSING,
17164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "xmlRelaxNG: include %s has a start but not the included grammar\n",
17174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           URL, NULL);
17184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
17194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (IS_RELAXNG(cur, "define")) {
17204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlChar *name;
17214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
17224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            name = xmlGetProp(cur, BAD_CAST "name");
17234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (name == NULL) {
17244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, node, XML_RNGP_NAME_MISSING,
17254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "xmlRelaxNG: include %s has define without name\n",
17264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           URL, NULL);
17274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
17284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                int found;
17294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
17304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGNormExtSpace(name);
17314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                found = xmlRelaxNGRemoveRedefine(ctxt, URL,
17324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                 root->children, name);
17334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (!found) {
17344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_MISSING,
17354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "xmlRelaxNG: include %s has a define %s but not the included grammar\n",
17364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               URL, name);
17374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
17384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlFree(name);
17394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
17404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
17414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = cur->next;
17424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
17434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
17444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
17454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
1746a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard}
1747a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard
1748a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard/**
174942f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * xmlRelaxNGValidErrorPush:
175042f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @ctxt:  the validation context
175142f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @err:  the error code
175242f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @arg1:  the first string argument
175342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @arg2:  the second string argument
1754c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard * @dup:  arg need to be duplicated
175542f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard *
175642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * Pushes a new error on top of the error stack
175742f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard *
175842f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * Returns 0 in case of error, the index in the stack otherwise
175942f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard */
176042f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillardstatic int
17614c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGValidErrorPush(xmlRelaxNGValidCtxtPtr ctxt,
17624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         xmlRelaxNGValidErr err, const xmlChar * arg1,
17634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         const xmlChar * arg2, int dup)
176442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard{
176542f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    xmlRelaxNGValidErrorPtr cur;
17664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
1767a507fbf3c2fce830a71445f4684383b9754ab83cDaniel Veillard#ifdef DEBUG_ERROR
1768a507fbf3c2fce830a71445f4684383b9754ab83cDaniel Veillard    xmlGenericError(xmlGenericErrorContext,
17694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    "Pushing error %d at %d on stack\n", err, ctxt->errNr);
1770a507fbf3c2fce830a71445f4684383b9754ab83cDaniel Veillard#endif
177142f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    if (ctxt->errTab == NULL) {
17724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->errMax = 8;
17734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->errNr = 0;
17744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->errTab =
17754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (xmlRelaxNGValidErrorPtr) xmlMalloc(ctxt->errMax *
17764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                sizeof
17774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                (xmlRelaxNGValidError));
177842f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard        if (ctxt->errTab == NULL) {
17794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngVErrMemory(ctxt, "pushing error\n");
178042f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard            return (0);
178142f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard        }
17824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->err = NULL;
178342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    }
178442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    if (ctxt->errNr >= ctxt->errMax) {
17854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->errMax *= 2;
178642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard        ctxt->errTab =
178742f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard            (xmlRelaxNGValidErrorPtr) xmlRealloc(ctxt->errTab,
17884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                 ctxt->errMax *
17894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                 sizeof
17904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                 (xmlRelaxNGValidError));
179142f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard        if (ctxt->errTab == NULL) {
17924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngVErrMemory(ctxt, "pushing error\n");
179342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard            return (0);
179442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard        }
17954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->err = &ctxt->errTab[ctxt->errNr - 1];
179642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    }
1797249d7bbee28570177a8573a99eab4aa9e27384d9Daniel Veillard    if ((ctxt->err != NULL) && (ctxt->state != NULL) &&
17984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        (ctxt->err->node == ctxt->state->node) && (ctxt->err->err == err))
17994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (ctxt->errNr);
180042f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    cur = &ctxt->errTab[ctxt->errNr];
180142f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    cur->err = err;
1802c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard    if (dup) {
1803c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard        cur->arg1 = xmlStrdup(arg1);
1804c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard        cur->arg2 = xmlStrdup(arg2);
18054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur->flags = ERROR_IS_DUP;
1806c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard    } else {
1807c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard        cur->arg1 = arg1;
1808c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard        cur->arg2 = arg2;
18094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur->flags = 0;
1810c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard    }
181142f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    if (ctxt->state != NULL) {
18124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur->node = ctxt->state->node;
18134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur->seq = ctxt->state->seq;
181442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    } else {
18154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur->node = NULL;
18164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur->seq = NULL;
181742f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    }
181842f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    ctxt->err = cur;
181942f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    return (ctxt->errNr++);
182042f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard}
182142f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard
182242f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard/**
182342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * xmlRelaxNGValidErrorPop:
182442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @ctxt: the validation context
182542f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard *
182642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * Pops the top error from the error stack
182742f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard */
1828c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillardstatic void
182942f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel VeillardxmlRelaxNGValidErrorPop(xmlRelaxNGValidCtxtPtr ctxt)
183042f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard{
1831c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard    xmlRelaxNGValidErrorPtr cur;
183242f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard
1833580ced8ee28ecd99374da9383897678e4ba6c358Daniel Veillard    if (ctxt->errNr <= 0) {
18344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->err = NULL;
1835c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard        return;
1836580ced8ee28ecd99374da9383897678e4ba6c358Daniel Veillard    }
183742f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    ctxt->errNr--;
183842f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    if (ctxt->errNr > 0)
183942f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard        ctxt->err = &ctxt->errTab[ctxt->errNr - 1];
184042f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    else
184142f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard        ctxt->err = NULL;
1842c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard    cur = &ctxt->errTab[ctxt->errNr];
1843c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard    if (cur->flags & ERROR_IS_DUP) {
18444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (cur->arg1 != NULL)
18454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlFree((xmlChar *) cur->arg1);
18464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur->arg1 = NULL;
18474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (cur->arg2 != NULL)
18484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlFree((xmlChar *) cur->arg2);
18494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur->arg2 = NULL;
18504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur->flags = 0;
1851c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard    }
185242f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard}
185342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard
185442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard/**
1855d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * xmlRelaxNGDocumentPush:
1856d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * @ctxt:  the parser context
1857d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * @value:  the element doc
1858d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard *
1859d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * Pushes a new doc on top of the doc stack
1860d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard *
1861d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * Returns 0 in case of error, the index in the stack otherwise
1862d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard */
1863d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillardstatic int
1864d41f4f488864d962a42239eb4526729a2dadc685Daniel VeillardxmlRelaxNGDocumentPush(xmlRelaxNGParserCtxtPtr ctxt,
18654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       xmlRelaxNGDocumentPtr value)
1866d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard{
1867d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    if (ctxt->docTab == NULL) {
18684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->docMax = 4;
18694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->docNr = 0;
18704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->docTab =
18714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (xmlRelaxNGDocumentPtr *) xmlMalloc(ctxt->docMax *
18724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                sizeof(ctxt->docTab[0]));
1873d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard        if (ctxt->docTab == NULL) {
18744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErrMemory(ctxt, "adding document\n");
1875d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard            return (0);
1876d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard        }
1877d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    }
1878d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    if (ctxt->docNr >= ctxt->docMax) {
1879d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard        ctxt->docMax *= 2;
1880d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard        ctxt->docTab =
1881d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard            (xmlRelaxNGDocumentPtr *) xmlRealloc(ctxt->docTab,
18824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                 ctxt->docMax *
18834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                 sizeof(ctxt->docTab[0]));
1884d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard        if (ctxt->docTab == NULL) {
18854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErrMemory(ctxt, "adding document\n");
1886d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard            return (0);
1887d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard        }
1888d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    }
1889d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    ctxt->docTab[ctxt->docNr] = value;
1890d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    ctxt->doc = value;
1891d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    return (ctxt->docNr++);
1892d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard}
1893d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
1894d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard/**
1895d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * xmlRelaxNGDocumentPop:
1896d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * @ctxt: the parser context
1897d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard *
1898d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * Pops the top doc from the doc stack
1899d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard *
1900d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * Returns the doc just removed
1901d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard */
1902d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillardstatic xmlRelaxNGDocumentPtr
1903d41f4f488864d962a42239eb4526729a2dadc685Daniel VeillardxmlRelaxNGDocumentPop(xmlRelaxNGParserCtxtPtr ctxt)
1904d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard{
1905d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    xmlRelaxNGDocumentPtr ret;
1906d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
1907d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    if (ctxt->docNr <= 0)
190824505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard        return (NULL);
1909d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    ctxt->docNr--;
1910d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    if (ctxt->docNr > 0)
1911d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard        ctxt->doc = ctxt->docTab[ctxt->docNr - 1];
1912d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    else
1913d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard        ctxt->doc = NULL;
1914d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    ret = ctxt->docTab[ctxt->docNr];
191524505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard    ctxt->docTab[ctxt->docNr] = NULL;
1916d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    return (ret);
1917d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard}
1918d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
1919d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard/**
1920a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard * xmlRelaxNGLoadExternalRef:
1921d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * @ctxt: the parser context
1922d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * @URL:  the normalized URL
1923d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * @ns:  the inherited ns if any
1924d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard *
1925d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * First lookup if the document is already loaded into the parser context,
1926d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * check against recursion. If not found the resource is loaded and
1927d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * the content is preprocessed before being returned back to the caller.
1928d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard *
1929d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard * Returns the xmlRelaxNGDocumentPtr or NULL in case of error
1930d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard */
1931d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillardstatic xmlRelaxNGDocumentPtr
19324c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGLoadExternalRef(xmlRelaxNGParserCtxtPtr ctxt,
19334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                          const xmlChar * URL, const xmlChar * ns)
19344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
1935d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    xmlRelaxNGDocumentPtr ret = NULL;
1936d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    xmlDocPtr doc;
1937d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    xmlNodePtr root;
1938d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    int i;
1939d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
1940d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    /*
1941d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard     * check against recursion in the stack
1942d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard     */
19434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    for (i = 0; i < ctxt->docNr; i++) {
19444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (xmlStrEqual(ctxt->docTab[i]->href, URL)) {
19454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, NULL, XML_RNGP_EXTERNALREF_RECURSE,
19464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Detected an externalRef recursion for %s\n", URL,
19474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       NULL);
19484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
19494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
1950d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    }
1951d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
1952d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    /*
1953d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard     * load the document
1954d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard     */
195587247e87408561aee625b2e800ea3c13211af897Daniel Veillard    doc = xmlReadFile((const char *) URL,NULL,0);
1956d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    if (doc == NULL) {
19574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
19584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "xmlRelaxNG: could not load %s\n", URL, NULL);
19594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
1960d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    }
1961d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
1962d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    /*
1963d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard     * Allocate the document structures and register it first.
1964d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard     */
1965d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    ret = (xmlRelaxNGDocumentPtr) xmlMalloc(sizeof(xmlRelaxNGDocument));
1966d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    if (ret == NULL) {
19674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, (xmlNodePtr) doc, XML_ERR_NO_MEMORY,
19684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "xmlRelaxNG: allocate memory for doc %s\n", URL, NULL);
19694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFreeDoc(doc);
19704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
1971d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    }
1972d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    memset(ret, 0, sizeof(xmlRelaxNGDocument));
1973d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    ret->doc = doc;
1974d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    ret->href = xmlStrdup(URL);
1975c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    ret->next = ctxt->documents;
197681c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard    ret->externalRef = 1;
1977c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    ctxt->documents = ret;
1978d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
1979d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    /*
1980d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard     * transmit the ns if needed
1981d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard     */
1982d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    if (ns != NULL) {
19834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        root = xmlDocGetRootElement(doc);
19844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (root != NULL) {
19854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (xmlHasProp(root, BAD_CAST "ns") == NULL) {
19864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlSetProp(root, BAD_CAST "ns", ns);
19874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
19884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
1989d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    }
1990d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
1991d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    /*
1992d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard     * push it on the stack and register it in the hash table
1993d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard     */
1994d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    xmlRelaxNGDocumentPush(ctxt, ret);
1995d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
1996d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    /*
1997d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard     * Some preprocessing of the document content
1998d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard     */
1999d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    doc = xmlRelaxNGCleanupDoc(ctxt, doc);
2000d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    if (doc == NULL) {
20014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->doc = NULL;
20024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
2003d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    }
2004d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
2005d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    xmlRelaxNGDocumentPop(ctxt);
2006d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
20074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
2008d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard}
2009d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard
2010d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard/************************************************************************
2011f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
2012f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *			Error functions					*
2013f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
20146eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard ************************************************************************/
20156eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
2016c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard#define VALID_ERR(a) xmlRelaxNGAddValidError(ctxt, a, NULL, NULL, 0);
2017c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard#define VALID_ERR2(a, b) xmlRelaxNGAddValidError(ctxt, a, b, NULL, 0);
2018c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard#define VALID_ERR3(a, b, c) xmlRelaxNGAddValidError(ctxt, a, b, c, 0);
2019c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard#define VALID_ERR2P(a, b) xmlRelaxNGAddValidError(ctxt, a, b, NULL, 1);
2020c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard#define VALID_ERR3P(a, b, c) xmlRelaxNGAddValidError(ctxt, a, b, c, 1);
20216eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
2022231d791fc4d9bec385a726a7d556cb62b777614bDaniel Veillardstatic const char *
20234c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGDefName(xmlRelaxNGDefinePtr def)
20244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
2025231d791fc4d9bec385a726a7d556cb62b777614bDaniel Veillard    if (def == NULL)
20264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return ("none");
20274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    switch (def->type) {
20284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_EMPTY:
20294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("empty");
20304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_NOT_ALLOWED:
20314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("notAllowed");
20324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_EXCEPT:
20334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("except");
20344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_TEXT:
20354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("text");
20364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ELEMENT:
20374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("element");
20384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_DATATYPE:
20394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("datatype");
20404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_VALUE:
20414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("value");
20424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_LIST:
20434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("list");
20444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ATTRIBUTE:
20454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("attribute");
20464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_DEF:
20474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("def");
20484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_REF:
20494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("ref");
20504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_EXTERNALREF:
20514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("externalRef");
20524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_PARENTREF:
20534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("parentRef");
20544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_OPTIONAL:
20554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("optional");
20564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ZEROORMORE:
20574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("zeroOrMore");
20584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ONEORMORE:
20594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("oneOrMore");
20604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_CHOICE:
20614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("choice");
20624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_GROUP:
20634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("group");
20644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_INTERLEAVE:
20654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("interleave");
20664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_START:
20674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("start");
20684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_NOOP:
20694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("noop");
20704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_PARAM:
20714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return ("param");
20724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
20734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return ("unknown");
2074231d791fc4d9bec385a726a7d556cb62b777614bDaniel Veillard}
2075d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard
20766eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
207742f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * xmlRelaxNGGetErrorString:
207842f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @err:  the error code
207942f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @arg1:  the first string argument
208042f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @arg2:  the second string argument
208142f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard *
208242f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * computes a formatted error string for the given error code and args
208342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard *
208442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * Returns the error string, it must be deallocated by the caller
208542f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard */
208642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillardstatic xmlChar *
20874c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGGetErrorString(xmlRelaxNGValidErr err, const xmlChar * arg1,
20884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         const xmlChar * arg2)
20894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
209042f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    char msg[1000];
209142f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard
209242f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    if (arg1 == NULL)
20934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        arg1 = BAD_CAST "";
209442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    if (arg2 == NULL)
20954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        arg2 = BAD_CAST "";
209642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard
209742f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    msg[0] = 0;
209842f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    switch (err) {
20994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_OK:
21004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
21014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_MEMORY:
21024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (xmlCharStrdup("out of memory\n"));
210342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard        case XML_RELAXNG_ERR_TYPE:
21044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "failed to validate type %s\n", arg1);
21054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_TYPEVAL:
21074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Type %s doesn't allow value '%s'\n", arg1,
21084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     arg2);
21094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_DUPID:
21114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "ID %s redefined\n", arg1);
21124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_TYPECMP:
21144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "failed to compare type %s\n", arg1);
21154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_NOSTATE:
21174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (xmlCharStrdup("Internal error: no state\n"));
21184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_NODEFINE:
21194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (xmlCharStrdup("Internal error: no define\n"));
21204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_INTERNAL:
21214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Internal error: %s\n", arg1);
21224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_LISTEXTRA:
21244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Extra data in list: %s\n", arg1);
21254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_INTERNODATA:
21274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (xmlCharStrdup
21284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ("Internal: interleave block has no data\n"));
21294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_INTERSEQ:
21304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (xmlCharStrdup("Invalid sequence in interleave\n"));
21314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_INTEREXTRA:
21324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Extra element %s in interleave\n", arg1);
21334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_ELEMNAME:
21354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Expecting element %s, got %s\n", arg1,
21364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     arg2);
21374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_ELEMNONS:
21394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Expecting a namespace for element %s\n",
21404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     arg1);
21414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_ELEMWRONGNS:
21434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000,
21444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     "Element %s has wrong namespace: expecting %s\n", arg1,
21454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     arg2);
21464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_ELEMWRONG:
21484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Did not expect element %s there\n", arg1);
21494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_TEXTWRONG:
21514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000,
21524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     "Did not expect text in element %s content\n", arg1);
21534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_ELEMEXTRANS:
21554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Expecting no namespace for element %s\n",
21564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     arg1);
21574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_ELEMNOTEMPTY:
21594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Expecting element %s to be empty\n", arg1);
21604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_NOELEM:
21624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Expecting an element %s, got nothing\n",
21634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     arg1);
21644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_NOTELEM:
21664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (xmlCharStrdup("Expecting an element got text\n"));
21674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_ATTRVALID:
21684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Element %s failed to validate attributes\n",
21694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     arg1);
21704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_CONTENTVALID:
21724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Element %s failed to validate content\n",
21734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     arg1);
21744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_EXTRACONTENT:
21764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Element %s has extra content: %s\n",
21774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     arg1, arg2);
21784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_INVALIDATTR:
21804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Invalid attribute %s for element %s\n",
21814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     arg1, arg2);
21824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_LACKDATA:
21844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Datatype element %s contains no data\n",
21854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     arg1);
21864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_DATAELEM:
21884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Datatype element %s has child elements\n",
21894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     arg1);
21904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_VALELEM:
21924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Value element %s has child elements\n",
21934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     arg1);
21944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_LISTELEM:
21964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "List element %s has child elements\n",
21974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     arg1);
21984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
21994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_DATATYPE:
22004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Error validating datatype %s\n", arg1);
22014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
22024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_VALUE:
22034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(msg, 1000, "Error validating value %s\n", arg1);
22044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
22054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_LIST:
22064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (xmlCharStrdup("Error validating list\n"));
22074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_NOGRAMMAR:
22084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (xmlCharStrdup("No top grammar defined\n"));
22094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ERR_EXTRADATA:
22104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (xmlCharStrdup("Extra data in the document\n"));
22114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        default:
22124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (xmlCharStrdup("Unknown error !\n"));
221342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    }
221442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    if (msg[0] == 0) {
22154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        snprintf(msg, 1000, "Unknown error code %d\n", err);
221642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    }
2217adbb0e634fdba141cd19f7cab7600fb4eb5997f1Daniel Veillard    msg[1000 - 1] = 0;
22184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (xmlStrdup((xmlChar *) msg));
221942f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard}
222042f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard
222142f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard/**
222242f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * xmlRelaxNGShowValidError:
222342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @ctxt:  the validation context
222442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @err:  the error number
222542f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @node:  the node
222642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @child:  the node child generating the problem.
222742f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @arg1:  the first argument
222842f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @arg2:  the second argument
222942f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard *
223042f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * Show a validation error.
223142f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard */
223242f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillardstatic void
22334c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGShowValidError(xmlRelaxNGValidCtxtPtr ctxt,
22344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         xmlRelaxNGValidErr err, xmlNodePtr node,
22354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         xmlNodePtr child, const xmlChar * arg1,
22364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         const xmlChar * arg2)
223742f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard{
223842f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    xmlChar *msg;
223942f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard
2240b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard    if (ctxt->flags & FLAGS_NOERROR)
2241f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard        return;
2242f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard
2243a507fbf3c2fce830a71445f4684383b9754ab83cDaniel Veillard#ifdef DEBUG_ERROR
22444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlGenericError(xmlGenericErrorContext, "Show error %d\n", err);
2245a507fbf3c2fce830a71445f4684383b9754ab83cDaniel Veillard#endif
224642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    msg = xmlRelaxNGGetErrorString(err, arg1, arg2);
224742f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    if (msg == NULL)
22484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
224942f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard
2250a507fbf3c2fce830a71445f4684383b9754ab83cDaniel Veillard    if (ctxt->errNo == XML_RELAXNG_OK)
22514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->errNo = err;
22524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRngVErr(ctxt, (child == NULL ? node : child), err,
22534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard               (const char *) msg, arg1, arg2);
225442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    xmlFree(msg);
225542f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard}
225642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard
225742f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard/**
225828c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard * xmlRelaxNGPopErrors:
225928c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard * @ctxt:  the validation context
226028c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard * @level:  the error level in the stack
226128c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard *
226228c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard * pop and discard all errors until the given level is reached
226328c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard */
226428c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillardstatic void
22654c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGPopErrors(xmlRelaxNGValidCtxtPtr ctxt, int level)
22664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
226728c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard    int i;
226828c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard    xmlRelaxNGValidErrorPtr err;
226928c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard
2270a507fbf3c2fce830a71445f4684383b9754ab83cDaniel Veillard#ifdef DEBUG_ERROR
2271a507fbf3c2fce830a71445f4684383b9754ab83cDaniel Veillard    xmlGenericError(xmlGenericErrorContext,
22724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    "Pop errors till level %d\n", level);
2273a507fbf3c2fce830a71445f4684383b9754ab83cDaniel Veillard#endif
22744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    for (i = level; i < ctxt->errNr; i++) {
22754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        err = &ctxt->errTab[i];
22764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (err->flags & ERROR_IS_DUP) {
22774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (err->arg1 != NULL)
22784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlFree((xmlChar *) err->arg1);
22794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            err->arg1 = NULL;
22804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (err->arg2 != NULL)
22814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlFree((xmlChar *) err->arg2);
22824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            err->arg2 = NULL;
22834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            err->flags = 0;
22844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
228528c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard    }
228628c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard    ctxt->errNr = level;
2287580ced8ee28ecd99374da9383897678e4ba6c358Daniel Veillard    if (ctxt->errNr <= 0)
22884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->err = NULL;
228928c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard}
22904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
229128c52ab518d34a36fd8da6870a5850088f129a6aDaniel Veillard/**
229242f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * xmlRelaxNGDumpValidError:
229342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @ctxt:  the validation context
229442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard *
229542f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * Show all validation error over a given index.
229642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard */
229742f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillardstatic void
22984c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGDumpValidError(xmlRelaxNGValidCtxtPtr ctxt)
22994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
23005f1946ad7cf7015f3f9af8f619b845a9221cc7f9Daniel Veillard    int i, j, k;
2301580ced8ee28ecd99374da9383897678e4ba6c358Daniel Veillard    xmlRelaxNGValidErrorPtr err, dup;
230242f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard
2303a507fbf3c2fce830a71445f4684383b9754ab83cDaniel Veillard#ifdef DEBUG_ERROR
2304a507fbf3c2fce830a71445f4684383b9754ab83cDaniel Veillard    xmlGenericError(xmlGenericErrorContext,
23054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    "Dumping error stack %d errors\n", ctxt->errNr);
2306a507fbf3c2fce830a71445f4684383b9754ab83cDaniel Veillard#endif
23074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    for (i = 0, k = 0; i < ctxt->errNr; i++) {
23084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        err = &ctxt->errTab[i];
23094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (k < MAX_ERROR) {
23104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            for (j = 0; j < i; j++) {
23114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                dup = &ctxt->errTab[j];
23124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((err->err == dup->err) && (err->node == dup->node) &&
23134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (xmlStrEqual(err->arg1, dup->arg1)) &&
23144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (xmlStrEqual(err->arg2, dup->arg2))) {
23154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    goto skip;
23164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
23174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
23184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGShowValidError(ctxt, err->err, err->node, err->seq,
23194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     err->arg1, err->arg2);
23204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            k++;
23214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
23224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard      skip:
23234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (err->flags & ERROR_IS_DUP) {
23244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (err->arg1 != NULL)
23254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlFree((xmlChar *) err->arg1);
23264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            err->arg1 = NULL;
23274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (err->arg2 != NULL)
23284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlFree((xmlChar *) err->arg2);
23294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            err->arg2 = NULL;
23304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            err->flags = 0;
23314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
233242f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    }
233342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    ctxt->errNr = 0;
233442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard}
23354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
233642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard/**
233742f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * xmlRelaxNGAddValidError:
233842f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @ctxt:  the validation context
233942f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @err:  the error number
234042f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @arg1:  the first argument
234142f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * @arg2:  the second argument
2342c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard * @dup:  need to dup the args
234342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard *
234442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * Register a validation error, either generating it if it's sure
234542f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard * or stacking it for later handling if unsure.
234642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard */
234742f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillardstatic void
23484c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGAddValidError(xmlRelaxNGValidCtxtPtr ctxt,
23494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGValidErr err, const xmlChar * arg1,
23504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        const xmlChar * arg2, int dup)
235142f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard{
2352b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard    if (ctxt == NULL)
2353b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard        return;
2354b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard    if (ctxt->flags & FLAGS_NOERROR)
23554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
235642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard
2357a507fbf3c2fce830a71445f4684383b9754ab83cDaniel Veillard#ifdef DEBUG_ERROR
23584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlGenericError(xmlGenericErrorContext, "Adding error %d\n", err);
2359a507fbf3c2fce830a71445f4684383b9754ab83cDaniel Veillard#endif
236042f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    /*
236142f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard     * generate the error directly
236242f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard     */
2363609296259555c3ea1c42292b497e04fad30bbcf6William M. Brack    if (((ctxt->flags & FLAGS_IGNORABLE) == 0) ||
2364f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	 (ctxt->flags & FLAGS_NEGATIVE)) {
23654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlNodePtr node, seq;
23664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
23674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        /*
23684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         * Flush first any stacked error which might be the
23694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         * real cause of the problem.
23704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         */
23714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->errNr != 0)
23724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpValidError(ctxt);
23734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->state != NULL) {
23744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            node = ctxt->state->node;
23754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            seq = ctxt->state->seq;
23764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
23774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            node = seq = NULL;
23784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
2379ec18c96008cf8f3b6b0b81ed8bfc2ccfe51d26e7Daniel Veillard        if ((node == NULL) && (seq == NULL)) {
2380ec18c96008cf8f3b6b0b81ed8bfc2ccfe51d26e7Daniel Veillard            node = ctxt->pnode;
2381ec18c96008cf8f3b6b0b81ed8bfc2ccfe51d26e7Daniel Veillard        }
23824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGShowValidError(ctxt, err, node, seq, arg1, arg2);
238342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    }
238442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    /*
238542f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard     * Stack the error for later processing if needed
238642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard     */
238742f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    else {
23884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGValidErrorPush(ctxt, err, arg1, arg2, dup);
238942f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    }
239042f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard}
239142f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard
23926eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
23936eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/************************************************************************
2394f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
2395f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *			Type library hooks				*
2396f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
23976eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard ************************************************************************/
2398ea3f398c3905b0c1e57eb0cc897ccc5bccd95d67Daniel Veillardstatic xmlChar *xmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt,
23994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                    const xmlChar * str);
24006eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
2401dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard/**
2402dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * xmlRelaxNGSchemaTypeHave:
2403dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @data:  data needed for the library
2404dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @type:  the type name
2405dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
2406dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Check if the given type is provided by
2407dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * the W3C XMLSchema Datatype library.
2408dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
2409dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Returns 1 if yes, 0 if no and -1 in case of error.
2410dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard */
2411dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillardstatic int
24124c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGSchemaTypeHave(void *data ATTRIBUTE_UNUSED, const xmlChar * type)
24134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
2414c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    xmlSchemaTypePtr typ;
2415c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard
2416c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    if (type == NULL)
24174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
24184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    typ = xmlSchemaGetPredefinedType(type,
24194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     BAD_CAST
24204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     "http://www.w3.org/2001/XMLSchema");
2421c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    if (typ == NULL)
24224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (0);
24234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (1);
2424dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard}
2425dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
2426dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard/**
2427dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * xmlRelaxNGSchemaTypeCheck:
2428dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @data:  data needed for the library
2429dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @type:  the type name
2430dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @value:  the value to check
2431c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard * @node:  the node
2432dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
2433dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Check if the given type and value are validated by
2434dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * the W3C XMLSchema Datatype library.
2435dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
2436dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Returns 1 if yes, 0 if no and -1 in case of error.
2437dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard */
2438dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillardstatic int
2439dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel VeillardxmlRelaxNGSchemaTypeCheck(void *data ATTRIBUTE_UNUSED,
24404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                          const xmlChar * type,
24414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                          const xmlChar * value,
24424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                          void **result, xmlNodePtr node)
24434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
2444c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    xmlSchemaTypePtr typ;
2445c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    int ret;
2446c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard
2447c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    if ((type == NULL) || (value == NULL))
24484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
24494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    typ = xmlSchemaGetPredefinedType(type,
24504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     BAD_CAST
24514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     "http://www.w3.org/2001/XMLSchema");
2452c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    if (typ == NULL)
24534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
2454c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard    ret = xmlSchemaValPredefTypeNode(typ, value,
24554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     (xmlSchemaValPtr *) result, node);
24564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (ret == 2)               /* special ID error code */
24574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (2);
2458c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    if (ret == 0)
24594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (1);
2460c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    if (ret > 0)
24614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (0);
24624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (-1);
2463dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard}
2464dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
2465dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard/**
24668bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * xmlRelaxNGSchemaFacetCheck:
24678bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * @data:  data needed for the library
24688bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * @type:  the type name
24698bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * @facet:  the facet name
24708bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * @val:  the facet value
24718bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * @strval:  the string value
24728bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * @value:  the value to check
24738bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard *
24748bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * Function provided by a type library to check a value facet
24758bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard *
24768bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard * Returns 1 if yes, 0 if no and -1 in case of error.
24778bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard */
24788bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillardstatic int
24794c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGSchemaFacetCheck(void *data ATTRIBUTE_UNUSED,
24804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           const xmlChar * type, const xmlChar * facetname,
24814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           const xmlChar * val, const xmlChar * strval,
24824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           void *value)
24834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
24848bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    xmlSchemaFacetPtr facet;
24858bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    xmlSchemaTypePtr typ;
24868bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    int ret;
24878bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard
24888bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    if ((type == NULL) || (strval == NULL))
24894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
24904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    typ = xmlSchemaGetPredefinedType(type,
24914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     BAD_CAST
24924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     "http://www.w3.org/2001/XMLSchema");
24938bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    if (typ == NULL)
24944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
24958bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard
24968bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    facet = xmlSchemaNewFacet();
24978bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    if (facet == NULL)
24984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
24998bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard
25004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (xmlStrEqual(facetname, BAD_CAST "minInclusive")) {
25018bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard        facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
25024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    } else if (xmlStrEqual(facetname, BAD_CAST "minExclusive")) {
25038bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard        facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
25044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    } else if (xmlStrEqual(facetname, BAD_CAST "maxInclusive")) {
25058bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard        facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
25064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    } else if (xmlStrEqual(facetname, BAD_CAST "maxExclusive")) {
25078bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard        facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
25084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    } else if (xmlStrEqual(facetname, BAD_CAST "totalDigits")) {
25098bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard        facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
25104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    } else if (xmlStrEqual(facetname, BAD_CAST "fractionDigits")) {
25118bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard        facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
25124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    } else if (xmlStrEqual(facetname, BAD_CAST "pattern")) {
25138bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard        facet->type = XML_SCHEMA_FACET_PATTERN;
25144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    } else if (xmlStrEqual(facetname, BAD_CAST "enumeration")) {
25158bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard        facet->type = XML_SCHEMA_FACET_ENUMERATION;
25164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    } else if (xmlStrEqual(facetname, BAD_CAST "whiteSpace")) {
25178bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard        facet->type = XML_SCHEMA_FACET_WHITESPACE;
25184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    } else if (xmlStrEqual(facetname, BAD_CAST "length")) {
25198bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard        facet->type = XML_SCHEMA_FACET_LENGTH;
25204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    } else if (xmlStrEqual(facetname, BAD_CAST "maxLength")) {
25218bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard        facet->type = XML_SCHEMA_FACET_MAXLENGTH;
25228bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    } else if (xmlStrEqual(facetname, BAD_CAST "minLength")) {
25238bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard        facet->type = XML_SCHEMA_FACET_MINLENGTH;
25248bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    } else {
25254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlSchemaFreeFacet(facet);
25264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
25278bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    }
25286dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard    facet->value = val;
25298bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    ret = xmlSchemaCheckFacet(facet, typ, NULL, type);
25308bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    if (ret != 0) {
25314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlSchemaFreeFacet(facet);
25324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
25338bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    }
25348bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    ret = xmlSchemaValidateFacet(typ, facet, strval, value);
25358bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    xmlSchemaFreeFacet(facet);
25368bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    if (ret != 0)
25374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
25384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (0);
25398bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard}
25408bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard
25418bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard/**
254280b19092f24410a6b869abf519227686e8f207caDaniel Veillard * xmlRelaxNGSchemaFreeValue:
254380b19092f24410a6b869abf519227686e8f207caDaniel Veillard * @data:  data needed for the library
254480b19092f24410a6b869abf519227686e8f207caDaniel Veillard * @value:  the value to free
254580b19092f24410a6b869abf519227686e8f207caDaniel Veillard *
254680b19092f24410a6b869abf519227686e8f207caDaniel Veillard * Function provided by a type library to free a Schemas value
254780b19092f24410a6b869abf519227686e8f207caDaniel Veillard *
254880b19092f24410a6b869abf519227686e8f207caDaniel Veillard * Returns 1 if yes, 0 if no and -1 in case of error.
254980b19092f24410a6b869abf519227686e8f207caDaniel Veillard */
255080b19092f24410a6b869abf519227686e8f207caDaniel Veillardstatic void
25514c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGSchemaFreeValue(void *data ATTRIBUTE_UNUSED, void *value)
25524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
255380b19092f24410a6b869abf519227686e8f207caDaniel Veillard    xmlSchemaFreeValue(value);
255480b19092f24410a6b869abf519227686e8f207caDaniel Veillard}
255580b19092f24410a6b869abf519227686e8f207caDaniel Veillard
255680b19092f24410a6b869abf519227686e8f207caDaniel Veillard/**
2557dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * xmlRelaxNGSchemaTypeCompare:
2558dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @data:  data needed for the library
2559dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @type:  the type name
2560dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @value1:  the first value
2561dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @value2:  the second value
2562dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
256380b19092f24410a6b869abf519227686e8f207caDaniel Veillard * Compare two values for equality accordingly a type from the W3C XMLSchema
2564dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Datatype library.
2565dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
256680b19092f24410a6b869abf519227686e8f207caDaniel Veillard * Returns 1 if equal, 0 if no and -1 in case of error.
2567dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard */
2568dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillardstatic int
2569dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel VeillardxmlRelaxNGSchemaTypeCompare(void *data ATTRIBUTE_UNUSED,
25704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            const xmlChar * type,
25714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            const xmlChar * value1,
25724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlNodePtr ctxt1,
25734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            void *comp1,
25744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            const xmlChar * value2, xmlNodePtr ctxt2)
25754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
257680b19092f24410a6b869abf519227686e8f207caDaniel Veillard    int ret;
257780b19092f24410a6b869abf519227686e8f207caDaniel Veillard    xmlSchemaTypePtr typ;
257880b19092f24410a6b869abf519227686e8f207caDaniel Veillard    xmlSchemaValPtr res1 = NULL, res2 = NULL;
257980b19092f24410a6b869abf519227686e8f207caDaniel Veillard
258080b19092f24410a6b869abf519227686e8f207caDaniel Veillard    if ((type == NULL) || (value1 == NULL) || (value2 == NULL))
25814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
25824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    typ = xmlSchemaGetPredefinedType(type,
25834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     BAD_CAST
25844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     "http://www.w3.org/2001/XMLSchema");
258580b19092f24410a6b869abf519227686e8f207caDaniel Veillard    if (typ == NULL)
25864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
2587e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    if (comp1 == NULL) {
25884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = xmlSchemaValPredefTypeNode(typ, value1, &res1, ctxt1);
25894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ret != 0)
25904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (-1);
25914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (res1 == NULL)
25924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (-1);
2593e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    } else {
25944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        res1 = (xmlSchemaValPtr) comp1;
2595e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    }
2596e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    ret = xmlSchemaValPredefTypeNode(typ, value2, &res2, ctxt2);
259780b19092f24410a6b869abf519227686e8f207caDaniel Veillard    if (ret != 0) {
25987d4e259fbfa24ef2c07a66f4b3d7ad311e68de1bGaurav	if (res1 != (xmlSchemaValPtr) comp1)
2599f46440392e105e1aca573036ee6b3ca04871b496Daniel Veillard	    xmlSchemaFreeValue(res1);
26004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
260180b19092f24410a6b869abf519227686e8f207caDaniel Veillard    }
260280b19092f24410a6b869abf519227686e8f207caDaniel Veillard    ret = xmlSchemaCompareValues(res1, res2);
2603e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    if (res1 != (xmlSchemaValPtr) comp1)
26044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlSchemaFreeValue(res1);
260580b19092f24410a6b869abf519227686e8f207caDaniel Veillard    xmlSchemaFreeValue(res2);
260680b19092f24410a6b869abf519227686e8f207caDaniel Veillard    if (ret == -2)
26074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
260880b19092f24410a6b869abf519227686e8f207caDaniel Veillard    if (ret == 0)
26094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (1);
26104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (0);
2611dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard}
26124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
2613dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard/**
2614dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * xmlRelaxNGDefaultTypeHave:
2615dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @data:  data needed for the library
2616dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @type:  the type name
2617dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
2618dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Check if the given type is provided by
2619dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * the default datatype library.
2620dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
2621dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Returns 1 if yes, 0 if no and -1 in case of error.
2622dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard */
2623dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillardstatic int
26244c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGDefaultTypeHave(void *data ATTRIBUTE_UNUSED,
26254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                          const xmlChar * type)
26264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
2627dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if (type == NULL)
26284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
2629dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if (xmlStrEqual(type, BAD_CAST "string"))
26304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (1);
2631dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if (xmlStrEqual(type, BAD_CAST "token"))
26324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (1);
26334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (0);
2634dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard}
2635dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
2636dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard/**
2637dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * xmlRelaxNGDefaultTypeCheck:
2638dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @data:  data needed for the library
2639dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @type:  the type name
2640dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @value:  the value to check
2641c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard * @node:  the node
2642dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
2643dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Check if the given type and value are validated by
2644dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * the default datatype library.
2645dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
2646dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Returns 1 if yes, 0 if no and -1 in case of error.
2647dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard */
2648dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillardstatic int
2649dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel VeillardxmlRelaxNGDefaultTypeCheck(void *data ATTRIBUTE_UNUSED,
26504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           const xmlChar * type ATTRIBUTE_UNUSED,
26514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           const xmlChar * value ATTRIBUTE_UNUSED,
26524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           void **result ATTRIBUTE_UNUSED,
26534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           xmlNodePtr node ATTRIBUTE_UNUSED)
26544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
2655d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard    if (value == NULL)
26564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
2657d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard    if (xmlStrEqual(type, BAD_CAST "string"))
26584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (1);
2659d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard    if (xmlStrEqual(type, BAD_CAST "token")) {
26604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (1);
2661d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard    }
2662d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard
26634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (0);
2664dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard}
2665dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
2666dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard/**
2667dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * xmlRelaxNGDefaultTypeCompare:
2668dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @data:  data needed for the library
2669dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @type:  the type name
2670dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @value1:  the first value
2671dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @value2:  the second value
2672dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
2673dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Compare two values accordingly a type from the default
2674dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * datatype library.
2675dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
2676dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Returns 1 if yes, 0 if no and -1 in case of error.
2677dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard */
2678dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillardstatic int
2679dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel VeillardxmlRelaxNGDefaultTypeCompare(void *data ATTRIBUTE_UNUSED,
26804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                             const xmlChar * type,
26814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                             const xmlChar * value1,
26824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                             xmlNodePtr ctxt1 ATTRIBUTE_UNUSED,
26834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                             void *comp1 ATTRIBUTE_UNUSED,
26844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                             const xmlChar * value2,
26854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                             xmlNodePtr ctxt2 ATTRIBUTE_UNUSED)
26864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
2687ea3f398c3905b0c1e57eb0cc897ccc5bccd95d67Daniel Veillard    int ret = -1;
2688ea3f398c3905b0c1e57eb0cc897ccc5bccd95d67Daniel Veillard
2689ea3f398c3905b0c1e57eb0cc897ccc5bccd95d67Daniel Veillard    if (xmlStrEqual(type, BAD_CAST "string")) {
26904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = xmlStrEqual(value1, value2);
2691ea3f398c3905b0c1e57eb0cc897ccc5bccd95d67Daniel Veillard    } else if (xmlStrEqual(type, BAD_CAST "token")) {
26924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (!xmlStrEqual(value1, value2)) {
26934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlChar *nval, *nvalue;
26944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
26954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /*
26964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * TODO: trivial optimizations are possible by
26974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * computing at compile-time
26984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             */
26994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            nval = xmlRelaxNGNormalize(NULL, value1);
27004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            nvalue = xmlRelaxNGNormalize(NULL, value2);
27014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
27024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((nval == NULL) || (nvalue == NULL))
27034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = -1;
27044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            else if (xmlStrEqual(nval, nvalue))
27054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = 1;
27064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            else
27074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = 0;
27084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (nval != NULL)
27094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlFree(nval);
27104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (nvalue != NULL)
27114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlFree(nvalue);
27124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else
27134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = 1;
27144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
27154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
27164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard}
27174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
2718dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillardstatic int xmlRelaxNGTypeInitialized = 0;
2719dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillardstatic xmlHashTablePtr xmlRelaxNGRegisteredTypes = NULL;
2720dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
2721dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard/**
2722dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * xmlRelaxNGFreeTypeLibrary:
2723dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @lib:  the type library structure
2724dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @namespace:  the URI bound to the library
2725dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
2726dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Free the structure associated to the type library
2727dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard */
27286eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic void
2729dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel VeillardxmlRelaxNGFreeTypeLibrary(xmlRelaxNGTypeLibraryPtr lib,
27304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                          const xmlChar * namespace ATTRIBUTE_UNUSED)
27314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
2732dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if (lib == NULL)
27334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
2734dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if (lib->namespace != NULL)
27354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree((xmlChar *) lib->namespace);
2736dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    xmlFree(lib);
2737dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard}
2738dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
2739dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard/**
2740dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * xmlRelaxNGRegisterTypeLibrary:
2741dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @namespace:  the URI bound to the library
2742dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @data:  data associated to the library
2743dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @have:  the provide function
2744dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @check:  the checking function
2745dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @comp:  the comparison function
2746dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
2747dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Register a new type library
2748dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
2749dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Returns 0 in case of success and -1 in case of error.
2750dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard */
2751dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillardstatic int
27524c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGRegisterTypeLibrary(const xmlChar * namespace, void *data,
27534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                              xmlRelaxNGTypeHave have,
27544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                              xmlRelaxNGTypeCheck check,
27554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                              xmlRelaxNGTypeCompare comp,
27564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                              xmlRelaxNGFacetCheck facet,
27574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                              xmlRelaxNGTypeFree freef)
27584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
2759dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    xmlRelaxNGTypeLibraryPtr lib;
2760dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    int ret;
2761dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
2762dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if ((xmlRelaxNGRegisteredTypes == NULL) || (namespace == NULL) ||
27634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        (check == NULL) || (comp == NULL))
27644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
2765dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if (xmlHashLookup(xmlRelaxNGRegisteredTypes, namespace) != NULL) {
27664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
27674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        "Relax-NG types library '%s' already registered\n",
27684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        namespace);
27694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
2770dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    }
27714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    lib =
27724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        (xmlRelaxNGTypeLibraryPtr)
27734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlMalloc(sizeof(xmlRelaxNGTypeLibrary));
2774dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if (lib == NULL) {
27754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngVErrMemory(NULL, "adding types library\n");
2776dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard        return (-1);
2777dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    }
2778dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    memset(lib, 0, sizeof(xmlRelaxNGTypeLibrary));
2779dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    lib->namespace = xmlStrdup(namespace);
2780dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    lib->data = data;
2781dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    lib->have = have;
2782dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    lib->comp = comp;
2783dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    lib->check = check;
27848bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    lib->facet = facet;
27858bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    lib->freef = freef;
2786dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    ret = xmlHashAddEntry(xmlRelaxNGRegisteredTypes, namespace, lib);
2787dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if (ret < 0) {
27884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
27894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        "Relax-NG types library failed to register '%s'\n",
27904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        namespace);
27914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeTypeLibrary(lib, namespace);
27924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
2793dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    }
27944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (0);
2795dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard}
2796dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
2797dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard/**
2798dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * xmlRelaxNGInitTypes:
2799dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
2800dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Initilize the default type libraries.
2801dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
2802dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Returns 0 in case of success and -1 in case of error.
2803dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard */
2804dd6d300896cfeacbacf7c5bceb5bec2f36790efeDaniel Veillardint
28054c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGInitTypes(void)
28064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
2807dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if (xmlRelaxNGTypeInitialized != 0)
28084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (0);
2809dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    xmlRelaxNGRegisteredTypes = xmlHashCreate(10);
2810dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if (xmlRelaxNGRegisteredTypes == NULL) {
28114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
28124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        "Failed to allocate sh table for Relax-NG types\n");
28134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
28144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
28154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGRegisterTypeLibrary(BAD_CAST
28164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                  "http://www.w3.org/2001/XMLSchema-datatypes",
28174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                  NULL, xmlRelaxNGSchemaTypeHave,
28184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                  xmlRelaxNGSchemaTypeCheck,
28194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                  xmlRelaxNGSchemaTypeCompare,
28204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                  xmlRelaxNGSchemaFacetCheck,
28214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                  xmlRelaxNGSchemaFreeValue);
28224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRelaxNGRegisterTypeLibrary(xmlRelaxNGNs, NULL,
28234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                  xmlRelaxNGDefaultTypeHave,
28244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                  xmlRelaxNGDefaultTypeCheck,
28254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                  xmlRelaxNGDefaultTypeCompare, NULL,
28264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                  NULL);
2827dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    xmlRelaxNGTypeInitialized = 1;
28284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (0);
28296eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
28306eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
28316eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
28326eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGCleanupTypes:
28336eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
28346eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Cleanup the default Schemas type library associated to RelaxNG
28356eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
28364c0041471199f283c4e696526c73e2809da54e21Daniel Veillardvoid
28374c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGCleanupTypes(void)
28384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
2839a84c0b30c411afe3b55e84ecce99ba0d42c39e3eDaniel Veillard    xmlSchemaCleanupTypes();
2840dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if (xmlRelaxNGTypeInitialized == 0)
28414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
2842dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    xmlHashFree(xmlRelaxNGRegisteredTypes, (xmlHashDeallocator)
28434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGFreeTypeLibrary);
2844dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    xmlRelaxNGTypeInitialized = 0;
28456eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
28466eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
28476eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/************************************************************************
2848f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
2849f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *		Compiling element content into regexp			*
2850f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
2851952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard * Sometime the element content can be compiled into a pure regexp,	*
2852952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard * This allows a faster execution and streamability at that level	*
2853f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
2854952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard ************************************************************************/
2855952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard
28561ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard/* from automata.c but not exported */
28571ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillardvoid xmlAutomataSetFlags(xmlAutomataPtr am, int flags);
28581ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard
28591ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard
286052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillardstatic int xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt,
286152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard                                xmlRelaxNGDefinePtr def);
286252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard
2863952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard/**
2864952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard * xmlRelaxNGIsCompileable:
2865952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard * @define:  the definition to check
2866952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard *
2867952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard * Check if a definition is nullable.
2868952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard *
2869952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard * Returns 1 if yes, 0 if no and -1 in case of error
2870952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard */
2871952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillardstatic int
28724c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGIsCompileable(xmlRelaxNGDefinePtr def)
28734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
287452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard    int ret = -1;
287552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard
2876952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard    if (def == NULL) {
28774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
2878952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard    }
287952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard    if ((def->type != XML_RELAXNG_ELEMENT) &&
288052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        (def->dflags & IS_COMPILABLE))
28814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (1);
288252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard    if ((def->type != XML_RELAXNG_ELEMENT) &&
288352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        (def->dflags & IS_NOT_COMPILABLE))
28844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (0);
28854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    switch (def->type) {
2886952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard        case XML_RELAXNG_NOOP:
28874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGIsCompileable(def->content);
28884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
2889952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard        case XML_RELAXNG_TEXT:
2890952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard        case XML_RELAXNG_EMPTY:
28914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = 1;
28924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
2893952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard        case XML_RELAXNG_ELEMENT:
28944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /*
28954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * Check if the element content is compileable
28964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             */
28974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (((def->dflags & IS_NOT_COMPILABLE) == 0) &&
28984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ((def->dflags & IS_COMPILABLE) == 0)) {
28994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGDefinePtr list;
29004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
29014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                list = def->content;
29024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (list != NULL) {
29034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret = xmlRelaxNGIsCompileable(list);
29044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ret != 1)
29054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        break;
29064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    list = list->next;
29074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
2908609296259555c3ea1c42292b497e04fad30bbcf6William M. Brack		/*
2909609296259555c3ea1c42292b497e04fad30bbcf6William M. Brack		 * Because the routine is recursive, we must guard against
2910609296259555c3ea1c42292b497e04fad30bbcf6William M. Brack		 * discovering both COMPILABLE and NOT_COMPILABLE
2911609296259555c3ea1c42292b497e04fad30bbcf6William M. Brack		 */
2912609296259555c3ea1c42292b497e04fad30bbcf6William M. Brack                if (ret == 0) {
2913609296259555c3ea1c42292b497e04fad30bbcf6William M. Brack		    def->dflags &= ~IS_COMPILABLE;
29144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    def->dflags |= IS_NOT_COMPILABLE;
2915609296259555c3ea1c42292b497e04fad30bbcf6William M. Brack		}
2916609296259555c3ea1c42292b497e04fad30bbcf6William M. Brack                if ((ret == 1) && !(def->dflags &= IS_NOT_COMPILABLE))
29174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    def->dflags |= IS_COMPILABLE;
2918d94849b092539a91ac1060c0df03ea79ae1e8d33Daniel Veillard#ifdef DEBUG_COMPILE
29194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ret == 1) {
29204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlGenericError(xmlGenericErrorContext,
29214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                    "element content for %s is compilable\n",
29224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                    def->name);
29234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else if (ret == 0) {
29244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlGenericError(xmlGenericErrorContext,
29254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                    "element content for %s is not compilable\n",
29264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                    def->name);
29274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else {
29284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlGenericError(xmlGenericErrorContext,
29294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                    "Problem in RelaxNGIsCompileable for element %s\n",
29304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                    def->name);
29314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
2932d94849b092539a91ac1060c0df03ea79ae1e8d33Daniel Veillard#endif
29334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
29344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /*
29354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * All elements return a compileable status unless they
29364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * are generic like anyName
29374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             */
29384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((def->nameClass != NULL) || (def->name == NULL))
29394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = 0;
29404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            else
29414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = 1;
29424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (ret);
29432134ab18c72eea6bf3a684752d0912721dc8185bDaniel Veillard        case XML_RELAXNG_REF:
29442134ab18c72eea6bf3a684752d0912721dc8185bDaniel Veillard        case XML_RELAXNG_EXTERNALREF:
29452134ab18c72eea6bf3a684752d0912721dc8185bDaniel Veillard        case XML_RELAXNG_PARENTREF:
29464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (def->depth == -20) {
29474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (1);
29484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
29494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGDefinePtr list;
29504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
29514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                def->depth = -20;
29524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                list = def->content;
29534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (list != NULL) {
29544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret = xmlRelaxNGIsCompileable(list);
29554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ret != 1)
29564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        break;
29574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    list = list->next;
29584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
29594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
29604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
29612134ab18c72eea6bf3a684752d0912721dc8185bDaniel Veillard        case XML_RELAXNG_START:
2962952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard        case XML_RELAXNG_OPTIONAL:
2963952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard        case XML_RELAXNG_ZEROORMORE:
2964952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard        case XML_RELAXNG_ONEORMORE:
2965952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard        case XML_RELAXNG_CHOICE:
2966952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard        case XML_RELAXNG_GROUP:
29674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_DEF:{
29684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGDefinePtr list;
29694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
29704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                list = def->content;
29714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (list != NULL) {
29724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret = xmlRelaxNGIsCompileable(list);
29734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ret != 1)
29744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        break;
29754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    list = list->next;
29764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
29774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
29784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
2979952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard        case XML_RELAXNG_EXCEPT:
2980952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard        case XML_RELAXNG_ATTRIBUTE:
2981952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard        case XML_RELAXNG_INTERLEAVE:
298252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_DATATYPE:
298352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_LIST:
298452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_PARAM:
298552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_VALUE:
2986952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard        case XML_RELAXNG_NOT_ALLOWED:
29877e29c0a457f90fad66d8d421dfc2647944024f09William M. Brack            ret = 0;
29884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
2989952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard    }
29904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (ret == 0)
29914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->dflags |= IS_NOT_COMPILABLE;
29924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (ret == 1)
29934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->dflags |= IS_COMPILABLE;
2994d94849b092539a91ac1060c0df03ea79ae1e8d33Daniel Veillard#ifdef DEBUG_COMPILE
2995d94849b092539a91ac1060c0df03ea79ae1e8d33Daniel Veillard    if (ret == 1) {
29964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
29974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        "RelaxNGIsCompileable %s : true\n",
29984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGDefName(def));
2999d94849b092539a91ac1060c0df03ea79ae1e8d33Daniel Veillard    } else if (ret == 0) {
30004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
30014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        "RelaxNGIsCompileable %s : false\n",
30024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGDefName(def));
3003d94849b092539a91ac1060c0df03ea79ae1e8d33Daniel Veillard    } else {
30044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
30054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        "Problem in RelaxNGIsCompileable %s\n",
30064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGDefName(def));
3007d94849b092539a91ac1060c0df03ea79ae1e8d33Daniel Veillard    }
3008d94849b092539a91ac1060c0df03ea79ae1e8d33Daniel Veillard#endif
30094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
301052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard}
301152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard
301252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard/**
301352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * xmlRelaxNGCompile:
301452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * ctxt:  the RelaxNG parser context
301552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @define:  the definition tree to compile
301652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard *
301752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * Compile the set of definitions, it works recursively, till the
301852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * element boundaries, where it tries to compile the content if possible
301952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard *
302052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * Returns 0 if success and -1 in case of error
302152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard */
302252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillardstatic int
30234c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
30244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
302552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard    int ret = 0;
302652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard    xmlRelaxNGDefinePtr list;
302752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard
30284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if ((ctxt == NULL) || (def == NULL))
30294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
303052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard
30314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    switch (def->type) {
303252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_START:
303352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard            if ((xmlRelaxNGIsCompileable(def) == 1) && (def->depth != -25)) {
30344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataPtr oldam = ctxt->am;
30354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataStatePtr oldstate = ctxt->state;
303652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard
303752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard                def->depth = -25;
303852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard
30394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                list = def->content;
30404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->am = xmlNewAutomata();
30414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ctxt->am == NULL)
30424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    return (-1);
30431ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard
30441ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard                /*
30451ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard                 * assume identical strings but not same pointer are different
30461ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard                 * atoms, needed for non-determinism detection
30471ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard                 * That way if 2 elements with the same name are in a choice
30481ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard                 * branch the automata is found non-deterministic and
30491ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard                 * we fallback to the normal validation which does the right
30501ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard                 * thing of exploring both choices.
30511ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard                 */
30521ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard                xmlAutomataSetFlags(ctxt->am, 1);
30531ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard
30544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state = xmlAutomataGetInitState(ctxt->am);
30554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (list != NULL) {
30564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGCompile(ctxt, list);
30574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    list = list->next;
30584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
30594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataSetFinalState(ctxt->am, ctxt->state);
30609313ae8517a7d91d7b6671d566c4013b02982ee3Noam                if (xmlAutomataIsDeterminist(ctxt->am))
30619313ae8517a7d91d7b6671d566c4013b02982ee3Noam                    def->contModel = xmlAutomataCompile(ctxt->am);
30624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
30634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlFreeAutomata(ctxt->am);
30644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state = oldstate;
30654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->am = oldam;
30664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
30674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
306852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_ELEMENT:
30694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((ctxt->am != NULL) && (def->name != NULL)) {
30704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state = xmlAutomataNewTransition2(ctxt->am,
30714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                        ctxt->state, NULL,
30724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                        def->name, def->ns,
30734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                        def);
30744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
307552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard            if ((def->dflags & IS_COMPILABLE) && (def->depth != -25)) {
30764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataPtr oldam = ctxt->am;
30774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataStatePtr oldstate = ctxt->state;
307852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard
307952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard                def->depth = -25;
308052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard
30814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                list = def->content;
30824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->am = xmlNewAutomata();
30834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ctxt->am == NULL)
30844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    return (-1);
30851ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard                xmlAutomataSetFlags(ctxt->am, 1);
30864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state = xmlAutomataGetInitState(ctxt->am);
30874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (list != NULL) {
30884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGCompile(ctxt, list);
30894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    list = list->next;
30904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
30914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataSetFinalState(ctxt->am, ctxt->state);
30924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                def->contModel = xmlAutomataCompile(ctxt->am);
30934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (!xmlRegexpIsDeterminist(def->contModel)) {
30941ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard#ifdef DEBUG_COMPILE
30951ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard                    xmlGenericError(xmlGenericErrorContext,
30961ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard                        "Content model not determinist %s\n",
30971ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard                                    def->name);
30981ba2aca3ebc3b47653a86849746b168a4e0bd8c6Daniel Veillard#endif
30994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    /*
31004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     * we can only use the automata if it is determinist
31014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     */
31024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRegFreeRegexp(def->contModel);
31034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    def->contModel = NULL;
31044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
31054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlFreeAutomata(ctxt->am);
31064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state = oldstate;
31074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->am = oldam;
31084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
31094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataPtr oldam = ctxt->am;
31104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
31114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                /*
31124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 * we can't build the content model for this element content
31134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 * but it still might be possible to build it for some of its
31144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 * children, recurse.
31154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 */
31164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = xmlRelaxNGTryCompile(ctxt, def);
31174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->am = oldam;
31184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
31194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
312052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_NOOP:
31214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGCompile(ctxt, def->content);
31224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
31234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_OPTIONAL:{
31244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataStatePtr oldstate = ctxt->state;
31254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
3126fd78077281da3a3f51e1dc4de7113acfcb3c017cDaniel Veillard                list = def->content;
3127fd78077281da3a3f51e1dc4de7113acfcb3c017cDaniel Veillard                while (list != NULL) {
3128fd78077281da3a3f51e1dc4de7113acfcb3c017cDaniel Veillard                    xmlRelaxNGCompile(ctxt, list);
3129fd78077281da3a3f51e1dc4de7113acfcb3c017cDaniel Veillard                    list = list->next;
3130fd78077281da3a3f51e1dc4de7113acfcb3c017cDaniel Veillard                }
31314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
31324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
31334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
31344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ZEROORMORE:{
31354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataStatePtr oldstate;
31364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
31374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state =
31384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
31394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                oldstate = ctxt->state;
31404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                list = def->content;
31414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (list != NULL) {
31424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGCompile(ctxt, list);
31434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    list = list->next;
31444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
31454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldstate);
31464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state =
31474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlAutomataNewEpsilon(ctxt->am, oldstate, NULL);
31484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
31494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
31504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ONEORMORE:{
31514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataStatePtr oldstate;
31524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
31534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                list = def->content;
31544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (list != NULL) {
31554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGCompile(ctxt, list);
31564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    list = list->next;
31574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
31584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                oldstate = ctxt->state;
31594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                list = def->content;
31604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (list != NULL) {
31614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGCompile(ctxt, list);
31624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    list = list->next;
31634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
31644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldstate);
31654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state =
31664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlAutomataNewEpsilon(ctxt->am, oldstate, NULL);
31674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
31684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
31694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_CHOICE:{
31704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataStatePtr target = NULL;
31714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataStatePtr oldstate = ctxt->state;
31724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
31734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                list = def->content;
31744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (list != NULL) {
31754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ctxt->state = oldstate;
31764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret = xmlRelaxNGCompile(ctxt, list);
31774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ret != 0)
31784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        break;
31794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (target == NULL)
31804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        target = ctxt->state;
31814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    else {
31824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlAutomataNewEpsilon(ctxt->am, ctxt->state,
31834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                              target);
31844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
31854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    list = list->next;
31864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
31874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state = target;
31884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
31894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
31904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
31912134ab18c72eea6bf3a684752d0912721dc8185bDaniel Veillard        case XML_RELAXNG_REF:
31922134ab18c72eea6bf3a684752d0912721dc8185bDaniel Veillard        case XML_RELAXNG_EXTERNALREF:
31932134ab18c72eea6bf3a684752d0912721dc8185bDaniel Veillard        case XML_RELAXNG_PARENTREF:
319452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_GROUP:
319552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_DEF:
31964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            list = def->content;
31974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            while (list != NULL) {
31984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = xmlRelaxNGCompile(ctxt, list);
31994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ret != 0)
32004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    break;
32014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                list = list->next;
32024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
32034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
32044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_TEXT:{
32054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataStatePtr oldstate;
32064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
32074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state =
32084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
32094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                oldstate = ctxt->state;
32104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGCompile(ctxt, def->content);
32114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataNewTransition(ctxt->am, ctxt->state,
32124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                         ctxt->state, BAD_CAST "#text",
32134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                         NULL);
32144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state =
32154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlAutomataNewEpsilon(ctxt->am, oldstate, NULL);
32164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
32174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
321852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_EMPTY:
32194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->state =
32204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
32214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
322252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_EXCEPT:
322352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_ATTRIBUTE:
322452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_INTERLEAVE:
322552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_NOT_ALLOWED:
322652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_DATATYPE:
322752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_LIST:
322852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_PARAM:
322952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_VALUE:
32304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /* This should not happen and generate an internal error */
32314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(stderr, "RNG internal error trying to compile %s\n",
32324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGDefName(def));
32334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
323452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard    }
32354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
323652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard}
323752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard
323852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard/**
323952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * xmlRelaxNGTryCompile:
324052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * ctxt:  the RelaxNG parser context
324152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * @define:  the definition tree to compile
324252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard *
324352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * Try to compile the set of definitions, it works recursively,
324452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * possibly ignoring parts which cannot be compiled.
324552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard *
324652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard * Returns 0 if success and -1 in case of error
324752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard */
324852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillardstatic int
32494c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
32504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
325152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard    int ret = 0;
325252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard    xmlRelaxNGDefinePtr list;
325352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard
32544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if ((ctxt == NULL) || (def == NULL))
32554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
325652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard
325752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard    if ((def->type == XML_RELAXNG_START) ||
325852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        (def->type == XML_RELAXNG_ELEMENT)) {
32594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = xmlRelaxNGIsCompileable(def);
32604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((def->dflags & IS_COMPILABLE) && (def->depth != -25)) {
32614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->am = NULL;
32624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGCompile(ctxt, def);
32632134ab18c72eea6bf3a684752d0912721dc8185bDaniel Veillard#ifdef DEBUG_PROGRESSIVE
32644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret == 0) {
32654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (def->type == XML_RELAXNG_START)
32664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlGenericError(xmlGenericErrorContext,
32674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                    "compiled the start\n");
32684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                else
32694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlGenericError(xmlGenericErrorContext,
32704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                    "compiled element %s\n", def->name);
32714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
32724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (def->type == XML_RELAXNG_START)
32734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlGenericError(xmlGenericErrorContext,
32744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                    "failed to compile the start\n");
32754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                else
32764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlGenericError(xmlGenericErrorContext,
32774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                    "failed to compile element %s\n",
32784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                    def->name);
32794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
32802134ab18c72eea6bf3a684752d0912721dc8185bDaniel Veillard#endif
32814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (ret);
32824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
328352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard    }
32844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    switch (def->type) {
328552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_NOOP:
32864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGTryCompile(ctxt, def->content);
32874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
328852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_TEXT:
328952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_DATATYPE:
329052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_LIST:
329152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_PARAM:
329252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_VALUE:
329352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_EMPTY:
329452b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_ELEMENT:
32954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = 0;
32964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
329752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_OPTIONAL:
329852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_ZEROORMORE:
329952b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_ONEORMORE:
330052b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_CHOICE:
330152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_GROUP:
330252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_DEF:
33032134ab18c72eea6bf3a684752d0912721dc8185bDaniel Veillard        case XML_RELAXNG_START:
33042134ab18c72eea6bf3a684752d0912721dc8185bDaniel Veillard        case XML_RELAXNG_REF:
33052134ab18c72eea6bf3a684752d0912721dc8185bDaniel Veillard        case XML_RELAXNG_EXTERNALREF:
33062134ab18c72eea6bf3a684752d0912721dc8185bDaniel Veillard        case XML_RELAXNG_PARENTREF:
33074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            list = def->content;
33084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            while (list != NULL) {
33094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = xmlRelaxNGTryCompile(ctxt, list);
33104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ret != 0)
33114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    break;
33124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                list = list->next;
33134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
33144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
331552b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_EXCEPT:
331652b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_ATTRIBUTE:
331752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_INTERLEAVE:
331852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard        case XML_RELAXNG_NOT_ALLOWED:
33194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = 0;
33204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
332152b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard    }
33224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
3323952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard}
3324952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard
3325952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard/************************************************************************
3326f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
3327f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *			Parsing functions				*
3328f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
33296eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard ************************************************************************/
33306eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
33314c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic xmlRelaxNGDefinePtr xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr
33324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                    ctxt, xmlNodePtr node);
33334c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic xmlRelaxNGDefinePtr xmlRelaxNGParseElement(xmlRelaxNGParserCtxtPtr
33344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                  ctxt, xmlNodePtr node);
33354c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic xmlRelaxNGDefinePtr xmlRelaxNGParsePatterns(xmlRelaxNGParserCtxtPtr
33364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                   ctxt, xmlNodePtr nodes,
33374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                   int group);
33384c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic xmlRelaxNGDefinePtr xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr
33394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                  ctxt, xmlNodePtr node);
33404c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic xmlRelaxNGPtr xmlRelaxNGParseDocument(xmlRelaxNGParserCtxtPtr ctxt,
33414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                             xmlNodePtr node);
33424c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic int xmlRelaxNGParseGrammarContent(xmlRelaxNGParserCtxtPtr ctxt,
33434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                         xmlNodePtr nodes);
33444c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic xmlRelaxNGDefinePtr xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr
33454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                    ctxt, xmlNodePtr node,
33464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                    xmlRelaxNGDefinePtr
33474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                    def);
33484c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic xmlRelaxNGGrammarPtr xmlRelaxNGParseGrammar(xmlRelaxNGParserCtxtPtr
33494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                   ctxt, xmlNodePtr nodes);
33504c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic int xmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,
33514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                  xmlRelaxNGDefinePtr define,
33524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                  xmlNodePtr elem);
33536eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
33546eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
3355249d7bbee28570177a8573a99eab4aa9e27384d9Daniel Veillard#define IS_BLANK_NODE(n) (xmlRelaxNGIsBlank((n)->content))
33566eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
33576eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
3358fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGIsNullable:
3359fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @define:  the definition to verify
3360fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *
3361fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Check if a definition is nullable.
3362fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *
3363fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Returns 1 if yes, 0 if no and -1 in case of error
3364fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard */
3365fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillardstatic int
33664c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGIsNullable(xmlRelaxNGDefinePtr define)
33674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
3368fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    int ret;
33694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
3370fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (define == NULL)
33714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
3372fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
3373e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard    if (define->dflags & IS_NULLABLE)
33744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (1);
3375e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard    if (define->dflags & IS_NOT_NULLABLE)
33764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (0);
3377fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    switch (define->type) {
3378fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_EMPTY:
3379fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_TEXT:
33804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = 1;
33814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
3382fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_NOOP:
3383fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_DEF:
3384fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_REF:
3385fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_EXTERNALREF:
3386fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_PARENTREF:
3387fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_ONEORMORE:
33884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGIsNullable(define->content);
33894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
3390fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_EXCEPT:
3391fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_NOT_ALLOWED:
3392fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_ELEMENT:
3393fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_DATATYPE:
3394fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_PARAM:
3395fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_VALUE:
3396fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_LIST:
3397fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_ATTRIBUTE:
33984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = 0;
33994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
34004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_CHOICE:{
34014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGDefinePtr list = define->content;
34024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
34034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (list != NULL) {
34044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret = xmlRelaxNGIsNullable(list);
34054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ret != 0)
34064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        goto done;
34074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    list = list->next;
34084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
34094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = 0;
34104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
34114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
3412fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_START:
3413fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_INTERLEAVE:
34144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_GROUP:{
34154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGDefinePtr list = define->content;
34164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
34174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (list != NULL) {
34184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret = xmlRelaxNGIsNullable(list);
34194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ret != 1)
34204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        goto done;
34214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    list = list->next;
34224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
34234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (1);
34244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
34254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        default:
34264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (-1);
34274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
34284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard  done:
3429fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (ret == 0)
34304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        define->dflags |= IS_NOT_NULLABLE;
3431fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (ret == 1)
34324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        define->dflags |= IS_NULLABLE;
34334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
3434fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard}
3435fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
3436fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard/**
34376eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGIsBlank:
34386eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @str:  a string
34396eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
34406eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Check if a string is ignorable c.f. 4.2. Whitespace
34416eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
34426eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
34436eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
34446eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic int
34454c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGIsBlank(xmlChar * str)
34464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
34476eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (str == NULL)
34484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (1);
34496eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    while (*str != 0) {
345076e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack        if (!(IS_BLANK_CH(*str)))
34514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (0);
34524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        str++;
34536eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
34544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (1);
34556eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
34566eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
34576eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
34586eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGGetDataTypeLibrary:
34596eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG parser context
34606eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @node:  the current data or value element
34616eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
34626eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Applies algorithm from 4.3. datatypeLibrary attribute
34636eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
34646eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns the datatypeLibary value or NULL if not found
34656eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
34666eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic xmlChar *
34676eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGGetDataTypeLibrary(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
34684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                             xmlNodePtr node)
34694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
34706eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlChar *ret, *escape;
34716eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
3472d44b9364991bd0067d50c29bdff48305dfdad4ceDaniel Veillard    if (node == NULL)
3473d44b9364991bd0067d50c29bdff48305dfdad4ceDaniel Veillard        return(NULL);
3474d44b9364991bd0067d50c29bdff48305dfdad4ceDaniel Veillard
34756eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if ((IS_RELAXNG(node, "data")) || (IS_RELAXNG(node, "value"))) {
34764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = xmlGetProp(node, BAD_CAST "datatypeLibrary");
34774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ret != NULL) {
34784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret[0] == 0) {
34794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlFree(ret);
34804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (NULL);
34814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
34824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            escape = xmlURIEscapeStr(ret, BAD_CAST ":/#?");
34834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (escape == NULL) {
34844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (ret);
34854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
34864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlFree(ret);
34874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (escape);
34884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
34896eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
34906eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    node = node->parent;
34916eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    while ((node != NULL) && (node->type == XML_ELEMENT_NODE)) {
34924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = xmlGetProp(node, BAD_CAST "datatypeLibrary");
34934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ret != NULL) {
34944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret[0] == 0) {
34954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlFree(ret);
34964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (NULL);
34974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
34984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            escape = xmlURIEscapeStr(ret, BAD_CAST ":/#?");
34994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (escape == NULL) {
35004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (ret);
35014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
35024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlFree(ret);
35034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (escape);
35044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
35054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        node = node->parent;
35066eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
35074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (NULL);
35086eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
3509dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
3510dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard/**
3511edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard * xmlRelaxNGParseValue:
3512edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard * @ctxt:  a Relax-NG parser context
3513edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard * @node:  the data node.
3514edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard *
3515edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard * parse the content of a RelaxNG value node.
3516edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard *
3517edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard * Returns the definition pointer or NULL in case of error
3518edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard */
3519edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillardstatic xmlRelaxNGDefinePtr
35204c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGParseValue(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
35214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
3522edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    xmlRelaxNGDefinePtr def = NULL;
35235f1946ad7cf7015f3f9af8f619b845a9221cc7f9Daniel Veillard    xmlRelaxNGTypeLibraryPtr lib = NULL;
3524edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    xmlChar *type;
3525edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    xmlChar *library;
3526e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    int success = 0;
3527edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard
3528fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    def = xmlRelaxNGNewDefine(ctxt, node);
3529edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    if (def == NULL)
35304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
3531fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    def->type = XML_RELAXNG_VALUE;
3532edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard
3533edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    type = xmlGetProp(node, BAD_CAST "type");
3534edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    if (type != NULL) {
35354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGNormExtSpace(type);
35364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (xmlValidateNCName(type, 0)) {
35374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_TYPE_VALUE,
35384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "value type '%s' is not an NCName\n", type, NULL);
35394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
35404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        library = xmlRelaxNGGetDataTypeLibrary(ctxt, node);
35414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (library == NULL)
35424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            library =
35434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlStrdup(BAD_CAST "http://relaxng.org/ns/structure/1.0");
35444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
35454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->name = type;
35464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->ns = library;
35474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
35484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        lib = (xmlRelaxNGTypeLibraryPtr)
35494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlHashLookup(xmlRelaxNGRegisteredTypes, library);
35504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (lib == NULL) {
35514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_TYPE_LIB,
35524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Use of unregistered type library '%s'\n", library,
35534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       NULL);
35544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def->data = NULL;
35554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
35564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def->data = lib;
35574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (lib->have == NULL) {
35584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, node, XML_RNGP_ERROR_TYPE_LIB,
35594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Internal error with type library '%s': no 'have'\n",
35604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           library, NULL);
35614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
35624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                success = lib->have(lib->data, def->name);
35634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (success != 1) {
35644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, node, XML_RNGP_TYPE_NOT_FOUND,
35654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "Error type '%s' is not exported by type library '%s'\n",
35664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               def->name, library);
35674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
35684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
35694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
3570edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    }
3571edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    if (node->children == NULL) {
35724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->value = xmlStrdup(BAD_CAST "");
357339eb88b4ca9c13de82e631faaccd5300514bb8bdDaniel Veillard    } else if (((node->children->type != XML_TEXT_NODE) &&
35744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                (node->children->type != XML_CDATA_SECTION_NODE)) ||
35754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard               (node->children->next != NULL)) {
35764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_TEXT_EXPECTED,
35774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "Expecting a single text value for <value>content\n",
35784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   NULL, NULL);
3579e637c4ad2e5c5422393f76b5be5ddb9ebe3755e2Daniel Veillard    } else if (def != NULL) {
35804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->value = xmlNodeGetContent(node);
35814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def->value == NULL) {
35824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_VALUE_NO_CONTENT,
35834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Element <value> has no content\n", NULL, NULL);
35844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if ((lib != NULL) && (lib->check != NULL) && (success == 1)) {
35854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            void *val = NULL;
35864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
35874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            success =
35884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                lib->check(lib->data, def->name, def->value, &val, node);
35894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (success != 1) {
35904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, node, XML_RNGP_INVALID_VALUE,
35914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Value '%s' is not acceptable for type '%s'\n",
35924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           def->value, def->name);
35934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
35944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (val != NULL)
35954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    def->attrs = val;
35964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
35974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
35984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
35994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (def);
3600edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard}
3601edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard
3602edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard/**
3603dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * xmlRelaxNGParseData:
3604dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @ctxt:  a Relax-NG parser context
3605dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @node:  the data node.
3606dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
3607dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * parse the content of a RelaxNG data node.
3608dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
3609dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Returns the definition pointer or NULL in case of error
3610dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard */
3611dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillardstatic xmlRelaxNGDefinePtr
36124c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGParseData(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
36134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
361414b5643947845df089376106517c4f7ba061e4b0Daniel Veillard    xmlRelaxNGDefinePtr def = NULL, except;
36158fe98710a5b3c75eaca7c78e172dc7bdb1640245Daniel Veillard    xmlRelaxNGDefinePtr param, lastparam = NULL;
3616dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    xmlRelaxNGTypeLibraryPtr lib;
3617dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    xmlChar *type;
3618dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    xmlChar *library;
3619dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    xmlNodePtr content;
3620dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    int tmp;
3621dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
3622dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    type = xmlGetProp(node, BAD_CAST "type");
3623dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if (type == NULL) {
36244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_TYPE_MISSING, "data has no type\n", NULL,
36254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   NULL);
36264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
3627dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    }
3628d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    xmlRelaxNGNormExtSpace(type);
3629d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    if (xmlValidateNCName(type, 0)) {
36304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_TYPE_VALUE,
36314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "data type '%s' is not an NCName\n", type, NULL);
3632d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    }
3633dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    library = xmlRelaxNGGetDataTypeLibrary(ctxt, node);
3634dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if (library == NULL)
36354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        library =
36364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlStrdup(BAD_CAST "http://relaxng.org/ns/structure/1.0");
3637dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
3638fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    def = xmlRelaxNGNewDefine(ctxt, node);
3639dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if (def == NULL) {
36404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(type);
36414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
3642dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    }
3643fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    def->type = XML_RELAXNG_DATATYPE;
3644dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    def->name = type;
3645dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    def->ns = library;
3646dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
3647dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    lib = (xmlRelaxNGTypeLibraryPtr)
36484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlHashLookup(xmlRelaxNGRegisteredTypes, library);
3649dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if (lib == NULL) {
36504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_TYPE_LIB,
36514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "Use of unregistered type library '%s'\n", library,
36524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   NULL);
36534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->data = NULL;
3654dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    } else {
36554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->data = lib;
36564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (lib->have == NULL) {
36574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_ERROR_TYPE_LIB,
36584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Internal error with type library '%s': no 'have'\n",
36594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       library, NULL);
36604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
36614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp = lib->have(lib->data, def->name);
36624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (tmp != 1) {
36634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, node, XML_RNGP_TYPE_NOT_FOUND,
36644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Error type '%s' is not exported by type library '%s'\n",
36654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           def->name, library);
36664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else
36674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((xmlStrEqual
36684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     (library,
36694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                      BAD_CAST
36704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                      "http://www.w3.org/2001/XMLSchema-datatypes"))
36714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    && ((xmlStrEqual(def->name, BAD_CAST "IDREF"))
36724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        || (xmlStrEqual(def->name, BAD_CAST "IDREFS")))) {
36734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->idref = 1;
36744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
36754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
3676dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    }
3677dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    content = node->children;
3678416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard
3679416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard    /*
3680416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard     * Handle optional params
3681416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard     */
3682dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    while (content != NULL) {
36834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (!xmlStrEqual(content->name, BAD_CAST "param"))
36844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
36854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (xmlStrEqual(library,
36864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        BAD_CAST "http://relaxng.org/ns/structure/1.0")) {
36874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_PARAM_FORBIDDEN,
36884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Type library '%s' does not allow type parameters\n",
36894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       library, NULL);
36904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            content = content->next;
36914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            while ((content != NULL) &&
36924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   (xmlStrEqual(content->name, BAD_CAST "param")))
36934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                content = content->next;
36944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
36954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            param = xmlRelaxNGNewDefine(ctxt, node);
36964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (param != NULL) {
36974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                param->type = XML_RELAXNG_PARAM;
36984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                param->name = xmlGetProp(content, BAD_CAST "name");
36994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (param->name == NULL) {
37004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, node, XML_RNGP_PARAM_NAME_MISSING,
37014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "param has no name\n", NULL, NULL);
37024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
37034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                param->value = xmlNodeGetContent(content);
37044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (lastparam == NULL) {
37054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    def->attrs = lastparam = param;
37064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else {
37074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    lastparam->next = param;
37084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    lastparam = param;
37094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
37104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (lib != NULL) {
37114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
37124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
37134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            content = content->next;
37144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
3715dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    }
3716416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard    /*
3717416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard     * Handle optional except
3718416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard     */
37194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if ((content != NULL)
37204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        && (xmlStrEqual(content->name, BAD_CAST "except"))) {
37214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlNodePtr child;
372214b5643947845df089376106517c4f7ba061e4b0Daniel Veillard        xmlRelaxNGDefinePtr tmp2, last = NULL;
37234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
37244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        except = xmlRelaxNGNewDefine(ctxt, node);
37254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (except == NULL) {
37264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (def);
37274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
37284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        except->type = XML_RELAXNG_EXCEPT;
37294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        child = content->children;
373014b5643947845df089376106517c4f7ba061e4b0Daniel Veillard	def->content = except;
37314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (child == NULL) {
37324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, content, XML_RNGP_EXCEPT_NO_CONTENT,
37334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "except has no content\n", NULL, NULL);
37344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
37354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        while (child != NULL) {
37364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp2 = xmlRelaxNGParsePattern(ctxt, child);
37374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (tmp2 != NULL) {
373814b5643947845df089376106517c4f7ba061e4b0Daniel Veillard                if (last == NULL) {
373914b5643947845df089376106517c4f7ba061e4b0Daniel Veillard                    except->content = last = tmp2;
37404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else {
374114b5643947845df089376106517c4f7ba061e4b0Daniel Veillard                    last->next = tmp2;
374214b5643947845df089376106517c4f7ba061e4b0Daniel Veillard                    last = tmp2;
37434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
37444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
37454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            child = child->next;
37464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
37474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        content = content->next;
3748416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard    }
3749416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard    /*
3750416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard     * Check there is no unhandled data
3751416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard     */
3752416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard    if (content != NULL) {
37534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, content, XML_RNGP_DATA_CONTENT,
37544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "Element data has unexpected content %s\n",
37554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   content->name, NULL);
3756416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard    }
3757dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
37584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (def);
3759dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard}
3760dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
37613ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillardstatic const xmlChar *invalidName = BAD_CAST "\1";
37623ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard
376376fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard/**
37643ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard * xmlRelaxNGCompareNameClasses:
37653ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard * @defs1:  the first element/attribute defs
37663ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard * @defs2:  the second element/attribute defs
37673ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard * @name:  the restriction on the name
37683ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard * @ns:  the restriction on the namespace
376976fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard *
377076fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * Compare the 2 lists of element definitions. The comparison is
377176fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * that if both lists do not accept the same QNames, it returns 1
377276fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * If the 2 lists can accept the same QName the comparison returns 0
377376fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard *
377476fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * Returns 1 disttinct, 0 if equal
377576fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard */
377676fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillardstatic int
37773ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel VeillardxmlRelaxNGCompareNameClasses(xmlRelaxNGDefinePtr def1,
37784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                             xmlRelaxNGDefinePtr def2)
37794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
37803ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard    int ret = 1;
37813ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard    xmlNode node;
37823ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard    xmlNs ns;
37833ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard    xmlRelaxNGValidCtxt ctxt;
37844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
378542f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    memset(&ctxt, 0, sizeof(xmlRelaxNGValidCtxt));
378642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard
3787b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard    ctxt.flags = FLAGS_IGNORABLE | FLAGS_NOERROR;
3788b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard
37893ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard    if ((def1->type == XML_RELAXNG_ELEMENT) ||
37904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        (def1->type == XML_RELAXNG_ATTRIBUTE)) {
37914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def2->type == XML_RELAXNG_TEXT)
37924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (1);
37934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def1->name != NULL) {
37944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            node.name = def1->name;
37954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
37964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            node.name = invalidName;
37974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
37984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def1->ns != NULL) {
37994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (def1->ns[0] == 0) {
38004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                node.ns = NULL;
38014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
3802a74a6ff056dbbbc29263a701e25d7c45e2619758William M. Brack	        node.ns = &ns;
38034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ns.href = def1->ns;
38044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
38054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
3806a74a6ff056dbbbc29263a701e25d7c45e2619758William M. Brack            node.ns = NULL;
38074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
3808fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        if (xmlRelaxNGElementMatch(&ctxt, def2, &node)) {
38094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (def1->nameClass != NULL) {
38104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = xmlRelaxNGCompareNameClasses(def1->nameClass, def2);
38114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
38124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = 0;
38134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
38144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
38154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = 1;
38164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
38173ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard    } else if (def1->type == XML_RELAXNG_TEXT) {
38184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def2->type == XML_RELAXNG_TEXT)
38194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (0);
38204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (1);
38213ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard    } else if (def1->type == XML_RELAXNG_EXCEPT) {
38224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        TODO ret = 0;
38233ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard    } else {
38244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        TODO ret = 0;
38253ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard    }
38263ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard    if (ret == 0)
38274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (ret);
38283ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard    if ((def2->type == XML_RELAXNG_ELEMENT) ||
38294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        (def2->type == XML_RELAXNG_ATTRIBUTE)) {
38304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def2->name != NULL) {
38314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            node.name = def2->name;
38324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
38334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            node.name = invalidName;
38344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
38354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        node.ns = &ns;
38364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def2->ns != NULL) {
38374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (def2->ns[0] == 0) {
38384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                node.ns = NULL;
38394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
38404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ns.href = def2->ns;
38414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
38424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
38434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ns.href = invalidName;
38444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
3845fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        if (xmlRelaxNGElementMatch(&ctxt, def1, &node)) {
38464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (def2->nameClass != NULL) {
38474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = xmlRelaxNGCompareNameClasses(def2->nameClass, def1);
38484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
38494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = 0;
38504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
38514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
38524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = 1;
38534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
38543ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard    } else {
38554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        TODO ret = 0;
38563ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard    }
38573ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard
38584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
38593ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard}
38603ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard
38613ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard/**
38623ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard * xmlRelaxNGCompareElemDefLists:
38633ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard * @ctxt:  a Relax-NG parser context
38643ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard * @defs1:  the first list of element/attribute defs
38653ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard * @defs2:  the second list of element/attribute defs
38663ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard *
38673ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard * Compare the 2 lists of element or attribute definitions. The comparison
38683ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard * is that if both lists do not accept the same QNames, it returns 1
38693ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard * If the 2 lists can accept the same QName the comparison returns 0
38703ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard *
38713ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard * Returns 1 disttinct, 0 if equal
38723ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard */
38733ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillardstatic int
38744c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGCompareElemDefLists(xmlRelaxNGParserCtxtPtr ctxt
38754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                              ATTRIBUTE_UNUSED, xmlRelaxNGDefinePtr * def1,
38764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                              xmlRelaxNGDefinePtr * def2)
38774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
387876fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    xmlRelaxNGDefinePtr *basedef2 = def2;
38794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
3880154877e55495468de2e971531fb7f18a644a3412Daniel Veillard    if ((def1 == NULL) || (def2 == NULL))
38814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (1);
388276fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    if ((*def1 == NULL) || (*def2 == NULL))
38834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (1);
388476fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    while (*def1 != NULL) {
38854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        while ((*def2) != NULL) {
38864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (xmlRelaxNGCompareNameClasses(*def1, *def2) == 0)
38874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (0);
38884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def2++;
38894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
38904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def2 = basedef2;
38914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def1++;
389276fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    }
38934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (1);
389476fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard}
389576fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard
389676fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard/**
3897ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard * xmlRelaxNGGenerateAttributes:
3898ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard * @ctxt:  a Relax-NG parser context
3899ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard * @def:  the definition definition
3900ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard *
3901ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard * Check if the definition can only generate attributes
3902ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard *
3903ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard * Returns 1 if yes, 0 if no and -1 in case of error.
3904ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard */
3905ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillardstatic int
3906ce192eb8a698c87a223a87b8c01739580f008a52Daniel VeillardxmlRelaxNGGenerateAttributes(xmlRelaxNGParserCtxtPtr ctxt,
39074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                             xmlRelaxNGDefinePtr def)
39084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
3909ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    xmlRelaxNGDefinePtr parent, cur, tmp;
3910ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard
3911ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    /*
3912ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard     * Don't run that check in case of error. Infinite recursion
3913ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard     * becomes possible.
3914ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard     */
3915ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    if (ctxt->nbErrors != 0)
39164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
3917ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard
3918ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    parent = NULL;
3919ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    cur = def;
3920ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    while (cur != NULL) {
39214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((cur->type == XML_RELAXNG_ELEMENT) ||
39224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_TEXT) ||
39234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_DATATYPE) ||
39244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_PARAM) ||
39254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_LIST) ||
39264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_VALUE) ||
39274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_EMPTY))
39284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (0);
39294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((cur->type == XML_RELAXNG_CHOICE) ||
39304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_INTERLEAVE) ||
39314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_GROUP) ||
39324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_ONEORMORE) ||
39334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_ZEROORMORE) ||
39344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_OPTIONAL) ||
39354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_PARENTREF) ||
39364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_EXTERNALREF) ||
39374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_REF) ||
39384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_DEF)) {
39394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur->content != NULL) {
39404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                parent = cur;
39414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur = cur->content;
39424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp = cur;
39434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (tmp != NULL) {
39444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    tmp->parent = parent;
39454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    tmp = tmp->next;
39464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
39474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                continue;
39484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
39494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
39504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (cur == def)
39514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
39524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (cur->next != NULL) {
39534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur = cur->next;
39544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            continue;
39554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
39564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        do {
39574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur = cur->parent;
39584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur == NULL)
39594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
39604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur == def)
39614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (1);
39624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur->next != NULL) {
39634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur = cur->next;
39644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
39654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
39664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } while (cur != NULL);
39674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
39684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (1);
39694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard}
39704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
3971ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard/**
397276fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * xmlRelaxNGGetElements:
397376fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * @ctxt:  a Relax-NG parser context
397444e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard * @def:  the definition definition
397544e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard * @eora:  gather elements (0) or attributes (1)
397676fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard *
397776fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * Compute the list of top elements a definition can generate
397876fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard *
397976fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * Returns a list of elements or NULL if none was found.
398076fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard */
398176fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillardstatic xmlRelaxNGDefinePtr *
398276fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel VeillardxmlRelaxNGGetElements(xmlRelaxNGParserCtxtPtr ctxt,
39834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                      xmlRelaxNGDefinePtr def, int eora)
39844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
3985fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGDefinePtr *ret = NULL, parent, cur, tmp;
398676fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    int len = 0;
398776fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    int max = 0;
398876fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard
398944e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard    /*
399044e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard     * Don't run that check in case of error. Infinite recursion
399144e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard     * becomes possible.
399244e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard     */
399344e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard    if (ctxt->nbErrors != 0)
39944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
399544e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard
399676fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    parent = NULL;
399776fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    cur = def;
399876fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    while (cur != NULL) {
39994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (((eora == 0) && ((cur->type == XML_RELAXNG_ELEMENT) ||
40004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                             (cur->type == XML_RELAXNG_TEXT))) ||
40014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ((eora == 1) && (cur->type == XML_RELAXNG_ATTRIBUTE))) {
40024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret == NULL) {
40034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                max = 10;
40044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = (xmlRelaxNGDefinePtr *)
40054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlMalloc((max + 1) * sizeof(xmlRelaxNGDefinePtr));
40064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ret == NULL) {
40074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErrMemory(ctxt, "getting element list\n");
40084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    return (NULL);
40094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
40104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else if (max <= len) {
4011079f6a7559533ccf48d2acb5737d0728fcd9c939Daniel Veillard	        xmlRelaxNGDefinePtr *temp;
4012079f6a7559533ccf48d2acb5737d0728fcd9c939Daniel Veillard
40134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                max *= 2;
4014079f6a7559533ccf48d2acb5737d0728fcd9c939Daniel Veillard                temp = xmlRealloc(ret,
40154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               (max + 1) * sizeof(xmlRelaxNGDefinePtr));
4016079f6a7559533ccf48d2acb5737d0728fcd9c939Daniel Veillard                if (temp == NULL) {
40174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErrMemory(ctxt, "getting element list\n");
4018079f6a7559533ccf48d2acb5737d0728fcd9c939Daniel Veillard		    xmlFree(ret);
40194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    return (NULL);
40204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
4021079f6a7559533ccf48d2acb5737d0728fcd9c939Daniel Veillard		ret = temp;
40224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
40234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret[len++] = cur;
40244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret[len] = NULL;
40254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if ((cur->type == XML_RELAXNG_CHOICE) ||
40264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   (cur->type == XML_RELAXNG_INTERLEAVE) ||
40274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   (cur->type == XML_RELAXNG_GROUP) ||
40284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   (cur->type == XML_RELAXNG_ONEORMORE) ||
40294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   (cur->type == XML_RELAXNG_ZEROORMORE) ||
40304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   (cur->type == XML_RELAXNG_OPTIONAL) ||
40314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   (cur->type == XML_RELAXNG_PARENTREF) ||
40324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   (cur->type == XML_RELAXNG_REF) ||
4033236c8c09f0145a338fb383fb9bffffd09f33a981William M. Brack                   (cur->type == XML_RELAXNG_DEF) ||
4034236c8c09f0145a338fb383fb9bffffd09f33a981William M. Brack		   (cur->type == XML_RELAXNG_EXTERNALREF)) {
40354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /*
40364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * Don't go within elements or attributes or string values.
40374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * Just gather the element top list
40384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             */
40394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur->content != NULL) {
40404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                parent = cur;
40414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur = cur->content;
40424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp = cur;
40434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (tmp != NULL) {
40444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    tmp->parent = parent;
40454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    tmp = tmp->next;
40464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
40474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                continue;
40484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
40494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
40504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (cur == def)
40514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
40524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (cur->next != NULL) {
40534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur = cur->next;
40544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            continue;
40554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
40564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        do {
40574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur = cur->parent;
40584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur == NULL)
40594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
40604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur == def)
40614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (ret);
40624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur->next != NULL) {
40634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur = cur->next;
40644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
40654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
40664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } while (cur != NULL);
40674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
40684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
40694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard}
40704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
407176fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard/**
4072fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGCheckChoiceDeterminism:
407344e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard * @ctxt:  a Relax-NG parser context
4074fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @def:  the choice definition
407544e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard *
4076fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Also used to find indeterministic pattern in choice
407744e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard */
407844e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillardstatic void
4079fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel VeillardxmlRelaxNGCheckChoiceDeterminism(xmlRelaxNGParserCtxtPtr ctxt,
40804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                 xmlRelaxNGDefinePtr def)
40814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
4082fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGDefinePtr **list;
4083fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGDefinePtr cur;
4084fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    int nbchild = 0, i, j, ret;
4085fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    int is_nullable = 0;
4086fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    int is_indeterminist = 0;
4087e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard    xmlHashTablePtr triage = NULL;
4088e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard    int is_triable = 1;
408944e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard
40904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if ((def == NULL) || (def->type != XML_RELAXNG_CHOICE))
40914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
409244e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard
4093e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard    if (def->dflags & IS_PROCESSED)
40944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
4095e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard
409644e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard    /*
409744e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard     * Don't run that check in case of error. Infinite recursion
409844e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard     * becomes possible.
409944e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard     */
410044e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard    if (ctxt->nbErrors != 0)
41014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
410244e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard
4103fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    is_nullable = xmlRelaxNGIsNullable(def);
410444e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard
4105fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    cur = def->content;
4106fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    while (cur != NULL) {
41074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        nbchild++;
41084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = cur->next;
4109fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
411044e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard
4111fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    list = (xmlRelaxNGDefinePtr **) xmlMalloc(nbchild *
41124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                              sizeof(xmlRelaxNGDefinePtr
41134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                     *));
4114fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (list == NULL) {
41154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErrMemory(ctxt, "building choice\n");
41164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
4117fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
4118fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    i = 0;
4119e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard    /*
4120e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard     * a bit strong but safe
4121e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard     */
4122e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard    if (is_nullable == 0) {
41234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        triage = xmlHashCreate(10);
4124e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard    } else {
41254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        is_triable = 0;
4126e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard    }
4127fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    cur = def->content;
4128fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    while (cur != NULL) {
41294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        list[i] = xmlRelaxNGGetElements(ctxt, cur, 0);
41304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((list[i] == NULL) || (list[i][0] == NULL)) {
41314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            is_triable = 0;
41324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (is_triable == 1) {
41334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDefinePtr *tmp;
41344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            int res;
41354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
41364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp = list[i];
41374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            while ((*tmp != NULL) && (is_triable == 1)) {
41384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((*tmp)->type == XML_RELAXNG_TEXT) {
41394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    res = xmlHashAddEntry2(triage,
41404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                           BAD_CAST "#text", NULL,
41414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                           (void *) cur);
41424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (res != 0)
41434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        is_triable = -1;
41444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else if (((*tmp)->type == XML_RELAXNG_ELEMENT) &&
41454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           ((*tmp)->name != NULL)) {
41464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
41474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        res = xmlHashAddEntry2(triage,
41484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               (*tmp)->name, NULL,
41494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               (void *) cur);
41504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    else
41514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        res = xmlHashAddEntry2(triage,
41524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               (*tmp)->name, (*tmp)->ns,
41534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               (void *) cur);
41544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (res != 0)
41554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        is_triable = -1;
41564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else if ((*tmp)->type == XML_RELAXNG_ELEMENT) {
41574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
41584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        res = xmlHashAddEntry2(triage,
41594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               BAD_CAST "#any", NULL,
41604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               (void *) cur);
41614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    else
41624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        res = xmlHashAddEntry2(triage,
41634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               BAD_CAST "#any", (*tmp)->ns,
41644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               (void *) cur);
41654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (res != 0)
41664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        is_triable = -1;
41674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else {
41684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    is_triable = -1;
41694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
41704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp++;
41714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
41724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
41734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        i++;
41744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = cur->next;
41754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
41764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
41774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    for (i = 0; i < nbchild; i++) {
41784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (list[i] == NULL)
41794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            continue;
41804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        for (j = 0; j < i; j++) {
41814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (list[j] == NULL)
41824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                continue;
41834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGCompareElemDefLists(ctxt, list[i], list[j]);
41844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret == 0) {
41854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                is_indeterminist = 1;
41864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
41874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
41884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
41894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    for (i = 0; i < nbchild; i++) {
41904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (list[i] != NULL)
41914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlFree(list[i]);
4192fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
4193fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
4194fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlFree(list);
4195fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (is_indeterminist) {
41964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->dflags |= IS_INDETERMINIST;
4197e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard    }
4198e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard    if (is_triable == 1) {
41994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->dflags |= IS_TRIABLE;
42004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->data = triage;
4201e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard    } else if (triage != NULL) {
42024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlHashFree(triage, NULL);
420344e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard    }
4204e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard    def->dflags |= IS_PROCESSED;
420544e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard}
420644e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard
420744e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard/**
4208fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGCheckGroupAttrs:
420976fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * @ctxt:  a Relax-NG parser context
42101564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * @def:  the group definition
421176fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard *
42121564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * Detects violations of rule 7.3
421376fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard */
421476fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillardstatic void
4215fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel VeillardxmlRelaxNGCheckGroupAttrs(xmlRelaxNGParserCtxtPtr ctxt,
42164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                          xmlRelaxNGDefinePtr def)
42174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
4218fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGDefinePtr **list;
4219fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGDefinePtr cur;
4220fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    int nbchild = 0, i, j, ret;
422176fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard
42221564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    if ((def == NULL) ||
42234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ((def->type != XML_RELAXNG_GROUP) &&
42244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         (def->type != XML_RELAXNG_ELEMENT)))
42254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
422676fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard
4227e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard    if (def->dflags & IS_PROCESSED)
42284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
4229e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard
423044e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard    /*
423144e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard     * Don't run that check in case of error. Infinite recursion
423244e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard     * becomes possible.
423344e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard     */
423444e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard    if (ctxt->nbErrors != 0)
42354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
423644e1dd0027983f7112e5b6a9101156b574ecbc26Daniel Veillard
4237fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    cur = def->attrs;
4238fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    while (cur != NULL) {
42394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        nbchild++;
42404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = cur->next;
4241fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
4242fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    cur = def->content;
4243fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    while (cur != NULL) {
42444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        nbchild++;
42454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = cur->next;
4246fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
4247fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
4248fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    list = (xmlRelaxNGDefinePtr **) xmlMalloc(nbchild *
42494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                              sizeof(xmlRelaxNGDefinePtr
42504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                     *));
4251fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (list == NULL) {
42524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErrMemory(ctxt, "building group\n");
42534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
4254fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
4255fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    i = 0;
4256fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    cur = def->attrs;
4257fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    while (cur != NULL) {
42584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        list[i] = xmlRelaxNGGetElements(ctxt, cur, 1);
42594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        i++;
42604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = cur->next;
4261fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
4262fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    cur = def->content;
4263fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    while (cur != NULL) {
42644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        list[i] = xmlRelaxNGGetElements(ctxt, cur, 1);
42654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        i++;
42664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = cur->next;
42674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
42684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
42694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    for (i = 0; i < nbchild; i++) {
42704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (list[i] == NULL)
42714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            continue;
42724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        for (j = 0; j < i; j++) {
42734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (list[j] == NULL)
42744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                continue;
42754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGCompareElemDefLists(ctxt, list[i], list[j]);
42764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret == 0) {
42774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, def->node, XML_RNGP_GROUP_ATTR_CONFLICT,
42784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Attributes conflicts in group\n", NULL, NULL);
42794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
42804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
42814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
42824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    for (i = 0; i < nbchild; i++) {
42834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (list[i] != NULL)
42844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlFree(list[i]);
4285fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
4286fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
4287fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlFree(list);
4288e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard    def->dflags |= IS_PROCESSED;
4289fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard}
4290fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
4291fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard/**
4292fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGComputeInterleaves:
4293fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @def:  the interleave definition
4294fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @ctxt:  a Relax-NG parser context
4295fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @name:  the definition name
4296fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *
4297fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * A lot of work for preprocessing interleave definitions
4298fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * is potentially needed to get a decent execution speed at runtime
4299fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *   - trying to get a total order on the element nodes generated
4300fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *     by the interleaves, order the list of interleave definitions
4301fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *     following that order.
4302fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *   - if <text/> is used to handle mixed content, it is better to
4303fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *     flag this in the define and simplify the runtime checking
4304fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *     algorithm
4305fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard */
4306fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillardstatic void
4307fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel VeillardxmlRelaxNGComputeInterleaves(xmlRelaxNGDefinePtr def,
43084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                             xmlRelaxNGParserCtxtPtr ctxt,
43094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                             xmlChar * name ATTRIBUTE_UNUSED)
43104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
4311bbb78b5d6d18b008bbd14edefecde4156d85f949Daniel Veillard    xmlRelaxNGDefinePtr cur, *tmp;
4312fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
4313fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGPartitionPtr partitions = NULL;
4314fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGInterleaveGroupPtr *groups = NULL;
4315fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGInterleaveGroupPtr group;
43164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    int i, j, ret, res;
4317fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    int nbgroups = 0;
4318fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    int nbchild = 0;
4319249d7bbee28570177a8573a99eab4aa9e27384d9Daniel Veillard    int is_mixed = 0;
4320bbb78b5d6d18b008bbd14edefecde4156d85f949Daniel Veillard    int is_determinist = 1;
4321fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
4322fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    /*
4323fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     * Don't run that check in case of error. Infinite recursion
4324fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     * becomes possible.
4325fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     */
4326fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (ctxt->nbErrors != 0)
43274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
4328fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
4329fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard#ifdef DEBUG_INTERLEAVE
4330fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlGenericError(xmlGenericErrorContext,
43314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    "xmlRelaxNGComputeInterleaves(%s)\n", name);
4332fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard#endif
4333fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    cur = def->content;
4334fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    while (cur != NULL) {
43354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        nbchild++;
43364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = cur->next;
4337fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
43384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
4339fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard#ifdef DEBUG_INTERLEAVE
4340fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlGenericError(xmlGenericErrorContext, "  %d child\n", nbchild);
4341fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard#endif
4342fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    groups = (xmlRelaxNGInterleaveGroupPtr *)
43434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlMalloc(nbchild * sizeof(xmlRelaxNGInterleaveGroupPtr));
4344fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (groups == NULL)
43454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        goto error;
4346fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    cur = def->content;
4347fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    while (cur != NULL) {
43484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        groups[nbgroups] = (xmlRelaxNGInterleaveGroupPtr)
43494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlMalloc(sizeof(xmlRelaxNGInterleaveGroup));
43504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (groups[nbgroups] == NULL)
43514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            goto error;
43524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (cur->type == XML_RELAXNG_TEXT)
43534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            is_mixed++;
43544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        groups[nbgroups]->rule = cur;
43554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        groups[nbgroups]->defs = xmlRelaxNGGetElements(ctxt, cur, 0);
43564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        groups[nbgroups]->attrs = xmlRelaxNGGetElements(ctxt, cur, 1);
43574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        nbgroups++;
43584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = cur->next;
4359fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
4360fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard#ifdef DEBUG_INTERLEAVE
4361fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlGenericError(xmlGenericErrorContext, "  %d groups\n", nbgroups);
4362fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard#endif
4363fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
4364fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    /*
4365fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     * Let's check that all rules makes a partitions according to 7.4
4366fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     */
4367fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    partitions = (xmlRelaxNGPartitionPtr)
43684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlMalloc(sizeof(xmlRelaxNGPartition));
4369fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (partitions == NULL)
4370fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        goto error;
43712086382959c57a720a3c57ba35f6c9c6c5b40af3Daniel Veillard    memset(partitions, 0, sizeof(xmlRelaxNGPartition));
4372fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    partitions->nbgroups = nbgroups;
4373bbb78b5d6d18b008bbd14edefecde4156d85f949Daniel Veillard    partitions->triage = xmlHashCreate(nbgroups);
43744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    for (i = 0; i < nbgroups; i++) {
43754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        group = groups[i];
43764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        for (j = i + 1; j < nbgroups; j++) {
43774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (groups[j] == NULL)
43784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                continue;
43794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
43804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGCompareElemDefLists(ctxt, group->defs,
43814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                groups[j]->defs);
43824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret == 0) {
43834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, def->node, XML_RNGP_ELEM_TEXT_CONFLICT,
43844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Element or text conflicts in interleave\n",
43854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
43864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
43874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGCompareElemDefLists(ctxt, group->attrs,
43884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                groups[j]->attrs);
43894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret == 0) {
43904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, def->node, XML_RNGP_ATTR_CONFLICT,
43914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Attributes conflicts in interleave\n", NULL,
43924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL);
43934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
43944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
43954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        tmp = group->defs;
43964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((tmp != NULL) && (*tmp != NULL)) {
43974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            while (*tmp != NULL) {
43984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((*tmp)->type == XML_RELAXNG_TEXT) {
43994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    res = xmlHashAddEntry2(partitions->triage,
44004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                           BAD_CAST "#text", NULL,
44014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                           (void *) (long) (i + 1));
44024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (res != 0)
44034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        is_determinist = -1;
44044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else if (((*tmp)->type == XML_RELAXNG_ELEMENT) &&
44054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           ((*tmp)->name != NULL)) {
44064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
44074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        res = xmlHashAddEntry2(partitions->triage,
44084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               (*tmp)->name, NULL,
44094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               (void *) (long) (i + 1));
44104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    else
44114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        res = xmlHashAddEntry2(partitions->triage,
44124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               (*tmp)->name, (*tmp)->ns,
44134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               (void *) (long) (i + 1));
44144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (res != 0)
44154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        is_determinist = -1;
44164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else if ((*tmp)->type == XML_RELAXNG_ELEMENT) {
44174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
44184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        res = xmlHashAddEntry2(partitions->triage,
44194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               BAD_CAST "#any", NULL,
44204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               (void *) (long) (i + 1));
44214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    else
44224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        res = xmlHashAddEntry2(partitions->triage,
44234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               BAD_CAST "#any", (*tmp)->ns,
44244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               (void *) (long) (i + 1));
44254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if ((*tmp)->nameClass != NULL)
44264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        is_determinist = 2;
44274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (res != 0)
44284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        is_determinist = -1;
44294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else {
44304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    is_determinist = -1;
44314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
44324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp++;
44334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
44344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
44354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            is_determinist = 0;
44364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
4437fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
4438fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    partitions->groups = groups;
4439fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
4440fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    /*
4441fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     * and save the partition list back in the def
4442fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     */
4443fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    def->data = partitions;
4444249d7bbee28570177a8573a99eab4aa9e27384d9Daniel Veillard    if (is_mixed != 0)
44454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->dflags |= IS_MIXED;
4446bbb78b5d6d18b008bbd14edefecde4156d85f949Daniel Veillard    if (is_determinist == 1)
44474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        partitions->flags = IS_DETERMINIST;
4448bbb78b5d6d18b008bbd14edefecde4156d85f949Daniel Veillard    if (is_determinist == 2)
44494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        partitions->flags = IS_DETERMINIST | IS_NEEDCHECK;
4450fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    return;
4451fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
44524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard  error:
44534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlRngPErrMemory(ctxt, "in interleave computation\n");
4454fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (groups != NULL) {
44554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        for (i = 0; i < nbgroups; i++)
44564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (groups[i] != NULL) {
44574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (groups[i]->defs != NULL)
44584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlFree(groups[i]->defs);
44594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlFree(groups[i]);
44604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
44614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(groups);
446276fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    }
4463fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGFreePartition(partitions);
446476fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard}
446576fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard
446676fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard/**
446776fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * xmlRelaxNGParseInterleave:
446876fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * @ctxt:  a Relax-NG parser context
446976fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * @node:  the data node.
447076fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard *
447176fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * parse the content of a RelaxNG interleave node.
447276fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard *
447376fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard * Returns the definition pointer or NULL in case of error
447476fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard */
447576fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillardstatic xmlRelaxNGDefinePtr
44764c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGParseInterleave(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
44774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
447876fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    xmlRelaxNGDefinePtr def = NULL;
4479fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGDefinePtr last = NULL, cur;
448076fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    xmlNodePtr child;
448176fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard
4482fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    def = xmlRelaxNGNewDefine(ctxt, node);
4483fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (def == NULL) {
44844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
4485fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
4486fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    def->type = XML_RELAXNG_INTERLEAVE;
4487fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
4488fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (ctxt->interleaves == NULL)
44894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->interleaves = xmlHashCreate(10);
4490fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (ctxt->interleaves == NULL) {
44914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErrMemory(ctxt, "create interleaves\n");
449276fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    } else {
44934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        char name[32];
449476fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard
44954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        snprintf(name, 32, "interleave%d", ctxt->nbInterleaves++);
44964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST name, def) < 0) {
44974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_INTERLEAVE_ADD,
44984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Failed to add %s to hash table\n",
44994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard		       (const xmlChar *) name, NULL);
45004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
450176fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    }
4502fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    child = node->children;
4503fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (child == NULL) {
45044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_INTERLEAVE_NO_CONTENT,
45054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "Element interleave is empty\n", NULL, NULL);
4506fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
4507fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    while (child != NULL) {
45084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (IS_RELAXNG(child, "element")) {
45094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur = xmlRelaxNGParseElement(ctxt, child);
45104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
45114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur = xmlRelaxNGParsePattern(ctxt, child);
45124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
45134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (cur != NULL) {
45144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur->parent = def;
45154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (last == NULL) {
45164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                def->content = last = cur;
45174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
45184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                last->next = cur;
45194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                last = cur;
45204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
45214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
45224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        child = child->next;
4523fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
4524fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
45254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (def);
452676fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard}
45276eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
45286eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
4529e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard * xmlRelaxNGParseInclude:
4530e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard * @ctxt:  a Relax-NG parser context
4531e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard * @node:  the include node
4532e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard *
4533e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard * Integrate the content of an include node in the current grammar
4534e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard *
4535e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard * Returns 0 in case of success or -1 in case of error
4536e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard */
4537e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillardstatic int
45384c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGParseInclude(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
45394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
4540e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    xmlRelaxNGIncludePtr incl;
4541e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    xmlNodePtr root;
4542e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    int ret = 0, tmp;
4543e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard
4544807daf826510d2d0597fdd10314e51b4d56c5e96Daniel Veillard    incl = node->psvi;
4545e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    if (incl == NULL) {
45464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_INCLUDE_EMPTY,
45474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "Include node has no data\n", NULL, NULL);
45484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
4549e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    }
4550e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    root = xmlDocGetRootElement(incl->doc);
4551e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    if (root == NULL) {
45524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_EMPTY, "Include document is empty\n",
45534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   NULL, NULL);
45544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
4555e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    }
4556e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    if (!xmlStrEqual(root->name, BAD_CAST "grammar")) {
45574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_GRAMMAR_MISSING,
45584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "Include document root is not a grammar\n", NULL, NULL);
45594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
4560e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    }
4561e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard
4562e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    /*
4563e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard     * Merge the definition from both the include and the internal list
4564e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard     */
4565e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    if (root->children != NULL) {
45664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        tmp = xmlRelaxNGParseGrammarContent(ctxt, root->children);
45674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (tmp != 0)
45684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = -1;
4569e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    }
4570e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    if (node->children != NULL) {
45714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        tmp = xmlRelaxNGParseGrammarContent(ctxt, node->children);
45724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (tmp != 0)
45734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = -1;
4574e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    }
45754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
4576e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard}
4577e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard
4578e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard/**
4579276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard * xmlRelaxNGParseDefine:
4580276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard * @ctxt:  a Relax-NG parser context
4581276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard * @node:  the define node
4582276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard *
4583276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard * parse the content of a RelaxNG define element node.
4584276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard *
4585e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard * Returns 0 in case of success or -1 in case of error
4586276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard */
4587276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillardstatic int
45884c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGParseDefine(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
45894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
4590276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard    xmlChar *name;
4591276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard    int ret = 0, tmp;
4592276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard    xmlRelaxNGDefinePtr def;
4593276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard    const xmlChar *olddefine;
4594276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard
4595276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard    name = xmlGetProp(node, BAD_CAST "name");
4596276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard    if (name == NULL) {
45974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_NAME_MISSING,
45984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "define has no name\n", NULL, NULL);
4599276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard    } else {
46004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGNormExtSpace(name);
46014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (xmlValidateNCName(name, 0)) {
46024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_INVALID_DEFINE_NAME,
46034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "define name '%s' is not an NCName\n", name, NULL);
46044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
46054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGNewDefine(ctxt, node);
46064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def == NULL) {
46074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlFree(name);
46084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (-1);
46094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
46104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->type = XML_RELAXNG_DEF;
46114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->name = name;
46124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (node->children == NULL) {
46134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_EMPTY,
46144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "define has no children\n", NULL, NULL);
46154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
46164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            olddefine = ctxt->define;
46174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->define = name;
46184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def->content =
46194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGParsePatterns(ctxt, node->children, 0);
46204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->define = olddefine;
46214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
46224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->grammar->defs == NULL)
46234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->grammar->defs = xmlHashCreate(10);
46244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->grammar->defs == NULL) {
46254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_CREATE_FAILED,
46264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Could not create definition hash\n", NULL, NULL);
46274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = -1;
46284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
46294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp = xmlHashAddEntry(ctxt->grammar->defs, name, def);
46304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (tmp < 0) {
46314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGDefinePtr prev;
46324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
46334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                prev = xmlHashLookup(ctxt->grammar->defs, name);
46344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (prev == NULL) {
46354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_CREATE_FAILED,
46364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "Internal error on define aggregation of %s\n",
46374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               name, NULL);
46384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret = -1;
46394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else {
46404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    while (prev->nextHash != NULL)
46414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        prev = prev->nextHash;
46424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    prev->nextHash = def;
46434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
46444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
46454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
46464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
46474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
4648276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard}
4649276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard
4650276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard/**
465181c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard * xmlRelaxNGParseImportRef:
465281c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard * @payload: the parser context
465381c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard * @data: the current grammar
465481c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard * @name: the reference name
465581c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard *
465681c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard * Import import one references into the current grammar
465781c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard */
465881c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillardstatic void
465981c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel VeillardxmlRelaxNGParseImportRef(void *payload, void *data, xmlChar *name) {
466081c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard    xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data;
466181c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard    xmlRelaxNGDefinePtr def = (xmlRelaxNGDefinePtr) payload;
466281c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard    int tmp;
466381c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard
4664aa422d9254f373141428bf0879f08af7ad15f3bfDaniel Veillard    def->dflags |= IS_EXTERNAL_REF;
4665aa422d9254f373141428bf0879f08af7ad15f3bfDaniel Veillard
466681c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard    tmp = xmlHashAddEntry(ctxt->grammar->refs, name, def);
466781c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard    if (tmp < 0) {
466881c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard        xmlRelaxNGDefinePtr prev;
466981c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard
467081c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard        prev = (xmlRelaxNGDefinePtr)
467181c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard            xmlHashLookup(ctxt->grammar->refs, def->name);
467281c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard        if (prev == NULL) {
467381c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard            if (def->name != NULL) {
467481c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
467581c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                           "Error refs definitions '%s'\n",
467681c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                           def->name, NULL);
467781c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard            } else {
467881c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
467981c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                           "Error refs definitions\n",
468081c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                           NULL, NULL);
468181c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard            }
468281c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard        } else {
468381c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard            def->nextHash = prev->nextHash;
468481c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard            prev->nextHash = def;
468581c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard        }
468681c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard    }
468781c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard}
468881c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard
468981c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard/**
469081c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard * xmlRelaxNGParseImportRefs:
469181c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard * @ctxt: the parser context
469281c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard * @grammar: the sub grammar
469381c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard *
469481c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard * Import references from the subgrammar into the current grammar
469581c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard *
469681c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard * Returns 0 in case of success, -1 in case of failure
469781c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard */
469881c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillardstatic int
469981c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel VeillardxmlRelaxNGParseImportRefs(xmlRelaxNGParserCtxtPtr ctxt,
470081c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                          xmlRelaxNGGrammarPtr grammar) {
470181c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard    if ((ctxt == NULL) || (grammar == NULL) || (ctxt->grammar == NULL))
470281c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard        return(-1);
470381c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard    if (grammar->refs == NULL)
470481c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard        return(0);
470581c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard    if (ctxt->grammar->refs == NULL)
470681c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard        ctxt->grammar->refs = xmlHashCreate(10);
470781c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard    if (ctxt->grammar->refs == NULL) {
470881c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard        xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
470981c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                   "Could not create references hash\n", NULL, NULL);
471081c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard        return(-1);
471181c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard    }
471281c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard    xmlHashScan(grammar->refs, xmlRelaxNGParseImportRef, ctxt);
4713ec18c96008cf8f3b6b0b81ed8bfc2ccfe51d26e7Daniel Veillard    return(0);
471481c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard}
471581c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard
471681c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard/**
4717febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard * xmlRelaxNGProcessExternalRef:
4718febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard * @ctxt: the parser context
4719febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard * @node:  the externlRef node
4720febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard *
4721febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard * Process and compile an externlRef node
4722febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard *
4723febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard * Returns the xmlRelaxNGDefinePtr or NULL in case of error
4724febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard */
4725febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillardstatic xmlRelaxNGDefinePtr
47264c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGProcessExternalRef(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
47274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
4728febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard    xmlRelaxNGDocumentPtr docu;
4729febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard    xmlNodePtr root, tmp;
4730febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard    xmlChar *ns;
473177648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard    int newNs = 0, oldflags;
4732febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard    xmlRelaxNGDefinePtr def;
4733febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard
4734807daf826510d2d0597fdd10314e51b4d56c5e96Daniel Veillard    docu = node->psvi;
4735febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard    if (docu != NULL) {
47364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGNewDefine(ctxt, node);
47374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def == NULL)
47384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
47394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->type = XML_RELAXNG_EXTERNALREF;
47404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
47414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (docu->content == NULL) {
47424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /*
47434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * Then do the parsing for good
47444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             */
47454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            root = xmlDocGetRootElement(docu->doc);
47464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (root == NULL) {
47474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, node, XML_RNGP_EXTERNALREF_EMTPY,
47484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "xmlRelaxNGParse: %s is empty\n", ctxt->URL,
47494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL);
47504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (NULL);
47514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
47524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /*
47534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * ns transmission rules
47544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             */
47554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ns = xmlGetProp(root, BAD_CAST "ns");
47564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ns == NULL) {
47574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp = node;
47584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while ((tmp != NULL) && (tmp->type == XML_ELEMENT_NODE)) {
47594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ns = xmlGetProp(tmp, BAD_CAST "ns");
47604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ns != NULL) {
47614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        break;
47624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
47634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    tmp = tmp->parent;
47644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
47654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ns != NULL) {
47664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlSetProp(root, BAD_CAST "ns", ns);
47674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    newNs = 1;
47684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlFree(ns);
47694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
47704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
47714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlFree(ns);
47724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
47734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
47744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /*
47754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * Parsing to get a precompiled schemas.
47764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             */
47774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            oldflags = ctxt->flags;
47784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->flags |= XML_RELAXNG_IN_EXTERNALREF;
47794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            docu->schema = xmlRelaxNGParseDocument(ctxt, root);
47804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->flags = oldflags;
47814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((docu->schema != NULL) &&
47824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                (docu->schema->topgrammar != NULL)) {
47834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                docu->content = docu->schema->topgrammar->start;
478481c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                if (docu->schema->topgrammar->refs)
478581c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                    xmlRelaxNGParseImportRefs(ctxt, docu->schema->topgrammar);
47864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
47874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
47884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /*
47894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * the externalRef may be reused in a different ns context
47904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             */
47914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (newNs == 1) {
47924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlUnsetProp(root, BAD_CAST "ns");
47934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
47944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
47954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->content = docu->content;
4796febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard    } else {
47974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = NULL;
4798febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard    }
47994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (def);
4800febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard}
4801febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard
4802febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard/**
48036eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGParsePattern:
48046eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG parser context
48056eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @node:  the pattern node.
48066eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
48076eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * parse the content of a RelaxNG pattern node.
48086eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
4809276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard * Returns the definition pointer or NULL in case of error or if no
4810276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard *     pattern is generated.
48116eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
48126eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic xmlRelaxNGDefinePtr
48134c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
48144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
48156eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGDefinePtr def = NULL;
48166eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
4817d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    if (node == NULL) {
48184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
4819d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    }
48206eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (IS_RELAXNG(node, "element")) {
48214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGParseElement(ctxt, node);
48226eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    } else if (IS_RELAXNG(node, "attribute")) {
48234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGParseAttribute(ctxt, node);
48246eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    } else if (IS_RELAXNG(node, "empty")) {
48254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGNewDefine(ctxt, node);
48264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def == NULL)
48274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
48284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->type = XML_RELAXNG_EMPTY;
48294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (node->children != NULL) {
48304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_NOT_EMPTY,
48314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "empty: had a child node\n", NULL, NULL);
48324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
48336eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    } else if (IS_RELAXNG(node, "text")) {
48344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGNewDefine(ctxt, node);
48354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def == NULL)
48364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
48374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->type = XML_RELAXNG_TEXT;
48384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (node->children != NULL) {
48394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_TEXT_HAS_CHILD,
48404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "text: had a child node\n", NULL, NULL);
48414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
48426eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    } else if (IS_RELAXNG(node, "zeroOrMore")) {
48434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGNewDefine(ctxt, node);
48444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def == NULL)
48454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
48464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->type = XML_RELAXNG_ZEROORMORE;
48474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (node->children == NULL) {
48484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
48494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Element %s is empty\n", node->name, NULL);
48504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
48514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def->content =
48524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGParsePatterns(ctxt, node->children, 1);
48534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
48546eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    } else if (IS_RELAXNG(node, "oneOrMore")) {
48554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGNewDefine(ctxt, node);
48564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def == NULL)
48574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
48584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->type = XML_RELAXNG_ONEORMORE;
48594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (node->children == NULL) {
48604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
48614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Element %s is empty\n", node->name, NULL);
48624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
48634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def->content =
48644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGParsePatterns(ctxt, node->children, 1);
48654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
48666eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    } else if (IS_RELAXNG(node, "optional")) {
48674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGNewDefine(ctxt, node);
48684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def == NULL)
48694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
48704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->type = XML_RELAXNG_OPTIONAL;
48714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (node->children == NULL) {
48724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
48734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Element %s is empty\n", node->name, NULL);
48744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
48754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def->content =
48764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGParsePatterns(ctxt, node->children, 1);
48774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
48786eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    } else if (IS_RELAXNG(node, "choice")) {
48794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGNewDefine(ctxt, node);
48804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def == NULL)
48814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
48824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->type = XML_RELAXNG_CHOICE;
48834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (node->children == NULL) {
48844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
48854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Element %s is empty\n", node->name, NULL);
48864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
48874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def->content =
48884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGParsePatterns(ctxt, node->children, 0);
48894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
48906eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    } else if (IS_RELAXNG(node, "group")) {
48914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGNewDefine(ctxt, node);
48924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def == NULL)
48934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
48944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->type = XML_RELAXNG_GROUP;
48954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (node->children == NULL) {
48964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
48974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Element %s is empty\n", node->name, NULL);
48984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
48994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def->content =
49004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGParsePatterns(ctxt, node->children, 0);
49014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
49026eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    } else if (IS_RELAXNG(node, "ref")) {
49034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGNewDefine(ctxt, node);
49044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def == NULL)
49054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
49064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->type = XML_RELAXNG_REF;
49074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->name = xmlGetProp(node, BAD_CAST "name");
49084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def->name == NULL) {
49094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_REF_NO_NAME, "ref has no name\n",
49104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       NULL, NULL);
49114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
49124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGNormExtSpace(def->name);
49134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (xmlValidateNCName(def->name, 0)) {
49144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, node, XML_RNGP_REF_NAME_INVALID,
49154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "ref name '%s' is not an NCName\n", def->name,
49164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL);
49174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
49184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
49194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (node->children != NULL) {
49204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_REF_NOT_EMPTY, "ref is not empty\n",
49214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       NULL, NULL);
49224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
49234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->grammar->refs == NULL)
49244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->grammar->refs = xmlHashCreate(10);
49254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->grammar->refs == NULL) {
49264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_REF_CREATE_FAILED,
49274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Could not create references hash\n", NULL, NULL);
49284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def = NULL;
49294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
49304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            int tmp;
49314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
49324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp = xmlHashAddEntry(ctxt->grammar->refs, def->name, def);
49334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (tmp < 0) {
49344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGDefinePtr prev;
49354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
49364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                prev = (xmlRelaxNGDefinePtr)
49374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlHashLookup(ctxt->grammar->refs, def->name);
49384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (prev == NULL) {
49394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (def->name != NULL) {
49406edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard		        xmlRngPErr(ctxt, node, XML_RNGP_REF_CREATE_FAILED,
49416edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard				   "Error refs definitions '%s'\n",
49426edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard				   def->name, NULL);
49434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    } else {
49446edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard		        xmlRngPErr(ctxt, node, XML_RNGP_REF_CREATE_FAILED,
49456edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard				   "Error refs definitions\n",
49466edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard				   NULL, NULL);
49474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
49484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    def = NULL;
49494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else {
49504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    def->nextHash = prev->nextHash;
49514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    prev->nextHash = def;
49524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
49534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
49544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
4955dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    } else if (IS_RELAXNG(node, "data")) {
49564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGParseData(ctxt, node);
4957edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    } else if (IS_RELAXNG(node, "value")) {
49584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGParseValue(ctxt, node);
4959c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    } else if (IS_RELAXNG(node, "list")) {
49604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGNewDefine(ctxt, node);
49614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def == NULL)
49624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
49634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->type = XML_RELAXNG_LIST;
49644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (node->children == NULL) {
49654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
49664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Element %s is empty\n", node->name, NULL);
49674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
49684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def->content =
49694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGParsePatterns(ctxt, node->children, 0);
49704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
4971fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    } else if (IS_RELAXNG(node, "interleave")) {
49724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGParseInterleave(ctxt, node);
4973d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    } else if (IS_RELAXNG(node, "externalRef")) {
49744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGProcessExternalRef(ctxt, node);
4975e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    } else if (IS_RELAXNG(node, "notAllowed")) {
49764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGNewDefine(ctxt, node);
49774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def == NULL)
49784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
49794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->type = XML_RELAXNG_NOT_ALLOWED;
49804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (node->children != NULL) {
49814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_NOTALLOWED_NOT_EMPTY,
49824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "xmlRelaxNGParse: notAllowed element is not empty\n",
49834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       NULL, NULL);
49844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
4985419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard    } else if (IS_RELAXNG(node, "grammar")) {
49864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGGrammarPtr grammar, old;
49874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGGrammarPtr oldparent;
4988419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard
4989c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard#ifdef DEBUG_GRAMMAR
49904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
49914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        "Found <grammar> pattern\n");
4992c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard#endif
4993c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard
49944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        oldparent = ctxt->parentgrammar;
49954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        old = ctxt->grammar;
49964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->parentgrammar = old;
49974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        grammar = xmlRelaxNGParseGrammar(ctxt, node->children);
49984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (old != NULL) {
49994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->grammar = old;
50004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->parentgrammar = oldparent;
5001c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard#if 0
50024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (grammar != NULL) {
50034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                grammar->next = old->next;
50044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                old->next = grammar;
50054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
5006c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard#endif
50074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
50084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (grammar != NULL)
50094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def = grammar->start;
50104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        else
50114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def = NULL;
5012419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard    } else if (IS_RELAXNG(node, "parentRef")) {
50134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->parentgrammar == NULL) {
50144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NO_PARENT,
50154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Use of parentRef without a parent grammar\n", NULL,
50164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       NULL);
50174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
50184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
50194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGNewDefine(ctxt, node);
50204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def == NULL)
50214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
50224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->type = XML_RELAXNG_PARENTREF;
50234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->name = xmlGetProp(node, BAD_CAST "name");
50244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def->name == NULL) {
50254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NO_NAME,
50264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "parentRef has no name\n", NULL, NULL);
50274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
50284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGNormExtSpace(def->name);
50294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (xmlValidateNCName(def->name, 0)) {
50304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NAME_INVALID,
50314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "parentRef name '%s' is not an NCName\n",
50324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           def->name, NULL);
50334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
50344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
50354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (node->children != NULL) {
50364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NOT_EMPTY,
50374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "parentRef is not empty\n", NULL, NULL);
50384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
50394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->parentgrammar->refs == NULL)
50404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->parentgrammar->refs = xmlHashCreate(10);
50414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->parentgrammar->refs == NULL) {
50424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_CREATE_FAILED,
50434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Could not create references hash\n", NULL, NULL);
50444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def = NULL;
50454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (def->name != NULL) {
50464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            int tmp;
50474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
50484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp =
50494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlHashAddEntry(ctxt->parentgrammar->refs, def->name, def);
50504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (tmp < 0) {
50514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGDefinePtr prev;
50524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
50534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                prev = (xmlRelaxNGDefinePtr)
50544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlHashLookup(ctxt->parentgrammar->refs, def->name);
50554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (prev == NULL) {
50564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_CREATE_FAILED,
50574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "Internal error parentRef definitions '%s'\n",
50584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               def->name, NULL);
50594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    def = NULL;
50604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else {
50614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    def->nextHash = prev->nextHash;
50624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    prev->nextHash = def;
50634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
50644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
50654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
5066d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    } else if (IS_RELAXNG(node, "mixed")) {
50674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (node->children == NULL) {
50684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT, "Mixed is empty\n",
50694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       NULL, NULL);
50704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def = NULL;
50714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
50724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def = xmlRelaxNGParseInterleave(ctxt, node);
50734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (def != NULL) {
50744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGDefinePtr tmp;
50754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
50764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((def->content != NULL) && (def->content->next != NULL)) {
50774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    tmp = xmlRelaxNGNewDefine(ctxt, node);
50784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (tmp != NULL) {
50794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        tmp->type = XML_RELAXNG_GROUP;
50804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        tmp->content = def->content;
50814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        def->content = tmp;
50824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
50834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
50844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
50854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp = xmlRelaxNGNewDefine(ctxt, node);
50864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (tmp == NULL)
50874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    return (def);
50884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp->type = XML_RELAXNG_TEXT;
50894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp->next = def->content;
50904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                def->content = tmp;
50914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
50924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
5093d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    } else {
50944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_CONSTRUCT,
50954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "Unexpected node %s is not a pattern\n", node->name,
50964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   NULL);
50974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = NULL;
50986eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
50994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (def);
51006eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
51016eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
51026eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
51036eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGParseAttribute:
51046eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG parser context
51056eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @node:  the element node
51066eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
51076eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * parse the content of a RelaxNG attribute node.
51086eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
51096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns the definition pointer or NULL in case of error.
51106eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
51116eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic xmlRelaxNGDefinePtr
51124c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
51134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
5114d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    xmlRelaxNGDefinePtr ret, cur;
51156eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlNodePtr child;
51166eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    int old_flags;
51176eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
5118fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    ret = xmlRelaxNGNewDefine(ctxt, node);
51196eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ret == NULL)
51204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
5121fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    ret->type = XML_RELAXNG_ATTRIBUTE;
512276fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    ret->parent = ctxt->def;
51236eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    child = node->children;
51246eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (child == NULL) {
51254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_EMPTY,
51264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "xmlRelaxNGParseattribute: attribute has no children\n",
51274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   NULL, NULL);
51284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (ret);
51294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
51306eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    old_flags = ctxt->flags;
51316eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ctxt->flags |= XML_RELAXNG_IN_ATTRIBUTE;
51323b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard    cur = xmlRelaxNGParseNameClass(ctxt, child, ret);
51333b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard    if (cur != NULL)
51344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        child = child->next;
51353b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard
5136d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    if (child != NULL) {
51374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = xmlRelaxNGParsePattern(ctxt, child);
51384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (cur != NULL) {
51394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            switch (cur->type) {
51404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_EMPTY:
51414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_NOT_ALLOWED:
51424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_TEXT:
51434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_ELEMENT:
51444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_DATATYPE:
51454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_VALUE:
51464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_LIST:
51474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_REF:
51484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_PARENTREF:
51494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_EXTERNALREF:
51504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_DEF:
51514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_ONEORMORE:
51524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_ZEROORMORE:
51534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_OPTIONAL:
51544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_CHOICE:
51554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_GROUP:
51564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_INTERLEAVE:
51574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_ATTRIBUTE:
51584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret->content = cur;
51594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    cur->parent = ret;
51604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    break;
51614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_START:
51624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_PARAM:
51634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_EXCEPT:
51644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_CONTENT,
51654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "attribute has invalid content\n", NULL,
51664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               NULL);
51674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    break;
51684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_NOOP:
51694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_NOOP,
51704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "RNG Internal error, noop found in attribute\n",
51714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               NULL, NULL);
51724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    break;
51734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
51744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
51754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        child = child->next;
51766eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
5177d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    if (child != NULL) {
51784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_CHILDREN,
51794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "attribute has multiple children\n", NULL, NULL);
5180d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    }
51816eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ctxt->flags = old_flags;
51824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
51836eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
51846eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
51856eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
51863b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard * xmlRelaxNGParseExceptNameClass:
51873b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard * @ctxt:  a Relax-NG parser context
51883b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard * @node:  the except node
5189144fae1635bc93a3e8519aa1895885d94c846758Daniel Veillard * @attr:  1 if within an attribute, 0 if within an element
51903b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard *
51913b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard * parse the content of a RelaxNG nameClass node.
51923b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard *
51933b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard * Returns the definition pointer or NULL in case of error.
51943b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard */
51953b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillardstatic xmlRelaxNGDefinePtr
5196144fae1635bc93a3e8519aa1895885d94c846758Daniel VeillardxmlRelaxNGParseExceptNameClass(xmlRelaxNGParserCtxtPtr ctxt,
51974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               xmlNodePtr node, int attr)
51984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
5199144fae1635bc93a3e8519aa1895885d94c846758Daniel Veillard    xmlRelaxNGDefinePtr ret, cur, last = NULL;
5200144fae1635bc93a3e8519aa1895885d94c846758Daniel Veillard    xmlNodePtr child;
5201144fae1635bc93a3e8519aa1895885d94c846758Daniel Veillard
5202d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    if (!IS_RELAXNG(node, "except")) {
52034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_EXCEPT_MISSING,
52044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "Expecting an except node\n", NULL, NULL);
52054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
5206d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    }
5207d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    if (node->next != NULL) {
52084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_EXCEPT_MULTIPLE,
52094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "exceptNameClass allows only a single except node\n",
52104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   NULL, NULL);
5211d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    }
5212144fae1635bc93a3e8519aa1895885d94c846758Daniel Veillard    if (node->children == NULL) {
52134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_EXCEPT_EMPTY, "except has no content\n",
52144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   NULL, NULL);
52154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
5216144fae1635bc93a3e8519aa1895885d94c846758Daniel Veillard    }
5217144fae1635bc93a3e8519aa1895885d94c846758Daniel Veillard
5218fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    ret = xmlRelaxNGNewDefine(ctxt, node);
5219144fae1635bc93a3e8519aa1895885d94c846758Daniel Veillard    if (ret == NULL)
52204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
5221fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    ret->type = XML_RELAXNG_EXCEPT;
5222144fae1635bc93a3e8519aa1895885d94c846758Daniel Veillard    child = node->children;
5223144fae1635bc93a3e8519aa1895885d94c846758Daniel Veillard    while (child != NULL) {
52244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = xmlRelaxNGNewDefine(ctxt, child);
52254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (cur == NULL)
52264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
52274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (attr)
52284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur->type = XML_RELAXNG_ATTRIBUTE;
52294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        else
52304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur->type = XML_RELAXNG_ELEMENT;
52314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
5232419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard        if (xmlRelaxNGParseNameClass(ctxt, child, cur) != NULL) {
52334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (last == NULL) {
52344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret->content = cur;
52354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
52364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                last->next = cur;
52374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
52384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            last = cur;
52394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
52404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        child = child->next;
5241144fae1635bc93a3e8519aa1895885d94c846758Daniel Veillard    }
5242144fae1635bc93a3e8519aa1895885d94c846758Daniel Veillard
52434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
52443b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard}
52453b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard
52463b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard/**
52473b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard * xmlRelaxNGParseNameClass:
52483b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard * @ctxt:  a Relax-NG parser context
52493b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard * @node:  the nameClass node
52503b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard * @def:  the current definition
52513b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard *
52523b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard * parse the content of a RelaxNG nameClass node.
52533b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard *
52543b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard * Returns the definition pointer or NULL in case of error.
52553b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard */
52563b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillardstatic xmlRelaxNGDefinePtr
52573b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel VeillardxmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node,
52584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         xmlRelaxNGDefinePtr def)
52594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
5260fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGDefinePtr ret, tmp;
52613b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard    xmlChar *val;
52623b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard
52632e9b165f9e0d15e6c1bef9953376377d0301fe5aDaniel Veillard    ret = def;
52644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if ((IS_RELAXNG(node, "name")) || (IS_RELAXNG(node, "anyName")) ||
52652e9b165f9e0d15e6c1bef9953376377d0301fe5aDaniel Veillard        (IS_RELAXNG(node, "nsName"))) {
52664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((def->type != XML_RELAXNG_ELEMENT) &&
52674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (def->type != XML_RELAXNG_ATTRIBUTE)) {
52684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGNewDefine(ctxt, node);
52694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret == NULL)
52704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (NULL);
52714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret->parent = def;
52724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE)
52734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret->type = XML_RELAXNG_ATTRIBUTE;
52744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            else
52754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret->type = XML_RELAXNG_ELEMENT;
52764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
52772e9b165f9e0d15e6c1bef9953376377d0301fe5aDaniel Veillard    }
52783b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard    if (IS_RELAXNG(node, "name")) {
52794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        val = xmlNodeGetContent(node);
52804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGNormExtSpace(val);
52814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (xmlValidateNCName(val, 0)) {
52826edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard	    if (node->parent != NULL)
52836edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard		xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_NAME,
52846edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard			   "Element %s name '%s' is not an NCName\n",
52856edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard			   node->parent->name, val);
52866edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard	    else
52876edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard		xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_NAME,
52886edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard			   "name '%s' is not an NCName\n",
52896edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard			   val, NULL);
52904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
52914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret->name = val;
52924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        val = xmlGetProp(node, BAD_CAST "ns");
52934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret->ns = val;
52944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE) &&
52954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (val != NULL) &&
52964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (xmlStrEqual(val, BAD_CAST "http://www.w3.org/2000/xmlns"))) {
52976edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard	    xmlRngPErr(ctxt, node, XML_RNGP_XML_NS,
52984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        "Attribute with namespace '%s' is not allowed\n",
52996edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard                        val, NULL);
53004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
53014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE) &&
53024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (val != NULL) &&
53034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (val[0] == 0) && (xmlStrEqual(ret->name, BAD_CAST "xmlns"))) {
53046edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard	    xmlRngPErr(ctxt, node, XML_RNGP_XMLNS_NAME,
53056edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard                       "Attribute with QName 'xmlns' is not allowed\n",
53066edbfbbe66e45fb6aab998b3a057fae28daf9ce6Daniel Veillard                       val, NULL);
53074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
53083b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard    } else if (IS_RELAXNG(node, "anyName")) {
53094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret->name = NULL;
53104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret->ns = NULL;
53114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (node->children != NULL) {
53124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret->nameClass =
53134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGParseExceptNameClass(ctxt, node->children,
53144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               (def->type ==
53154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                XML_RELAXNG_ATTRIBUTE));
53164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
53173b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard    } else if (IS_RELAXNG(node, "nsName")) {
53184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret->name = NULL;
53194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret->ns = xmlGetProp(node, BAD_CAST "ns");
53204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ret->ns == NULL) {
53214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_NSNAME_NO_NS,
53224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "nsName has no ns attribute\n", NULL, NULL);
53234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
53244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE) &&
53254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (ret->ns != NULL) &&
53264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (xmlStrEqual
53274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             (ret->ns, BAD_CAST "http://www.w3.org/2000/xmlns"))) {
53284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_XML_NS,
53294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Attribute with namespace '%s' is not allowed\n",
53304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       ret->ns, NULL);
53314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
53324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (node->children != NULL) {
53334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret->nameClass =
53344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGParseExceptNameClass(ctxt, node->children,
53354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               (def->type ==
53364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                XML_RELAXNG_ATTRIBUTE));
53374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
53383b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard    } else if (IS_RELAXNG(node, "choice")) {
53394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlNodePtr child;
53404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGDefinePtr last = NULL;
53414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
53424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = xmlRelaxNGNewDefine(ctxt, node);
53434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ret == NULL)
53444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
53454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret->parent = def;
53464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret->type = XML_RELAXNG_CHOICE;
53474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
53484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (node->children == NULL) {
53494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, node, XML_RNGP_CHOICE_EMPTY,
53504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Element choice is empty\n", NULL, NULL);
53514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
53524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
53534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            child = node->children;
53544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            while (child != NULL) {
53554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp = xmlRelaxNGParseNameClass(ctxt, child, ret);
53564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (tmp != NULL) {
53574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (last == NULL) {
53584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        last = ret->nameClass = tmp;
53594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    } else {
53604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        last->next = tmp;
53614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        last = tmp;
53624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
53634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
53644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                child = child->next;
53654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
53664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
53673b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard    } else {
53684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_CHOICE_CONTENT,
53694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "expecting name, anyName, nsName or choice : got %s\n",
5370a7a6a4b2f39b6bc2973eed8b0fb7cf917a171487Ben Walton                   (node == NULL ? (const xmlChar *) "nothing" : node->name),
5371a7a6a4b2f39b6bc2973eed8b0fb7cf917a171487Ben Walton		   NULL);
53724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
53733b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard    }
53742e9b165f9e0d15e6c1bef9953376377d0301fe5aDaniel Veillard    if (ret != def) {
53754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def->nameClass == NULL) {
53764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def->nameClass = ret;
53774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
53784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp = def->nameClass;
53794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            while (tmp->next != NULL) {
53804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp = tmp->next;
53814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
53824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp->next = ret;
53834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
53842e9b165f9e0d15e6c1bef9953376377d0301fe5aDaniel Veillard    }
53854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
53863b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard}
53873b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard
53883b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard/**
53896eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGParseElement:
53906eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG parser context
53916eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @node:  the element node
53926eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
53936eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * parse the content of a RelaxNG element node.
53946eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
53956eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns the definition pointer or NULL in case of error.
53966eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
53976eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic xmlRelaxNGDefinePtr
53984c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGParseElement(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
53994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
54006eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGDefinePtr ret, cur, last;
54016eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlNodePtr child;
5402276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard    const xmlChar *olddefine;
54036eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
5404fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    ret = xmlRelaxNGNewDefine(ctxt, node);
54056eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ret == NULL)
54064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
5407fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    ret->type = XML_RELAXNG_ELEMENT;
540876fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    ret->parent = ctxt->def;
54096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    child = node->children;
54106eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (child == NULL) {
54114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_EMPTY,
54124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "xmlRelaxNGParseElement: element has no children\n",
54134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   NULL, NULL);
54144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (ret);
54154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
54163b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard    cur = xmlRelaxNGParseNameClass(ctxt, child, ret);
54173b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard    if (cur != NULL)
54184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        child = child->next;
54193b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard
54206eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (child == NULL) {
54214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_NO_CONTENT,
54224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "xmlRelaxNGParseElement: element has no content\n",
54234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   NULL, NULL);
54244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (ret);
54254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
5426276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard    olddefine = ctxt->define;
5427276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard    ctxt->define = NULL;
54286eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    last = NULL;
54296eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    while (child != NULL) {
54304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = xmlRelaxNGParsePattern(ctxt, child);
54314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (cur != NULL) {
54324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur->parent = ret;
54334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            switch (cur->type) {
54344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_EMPTY:
54354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_NOT_ALLOWED:
54364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_TEXT:
54374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_ELEMENT:
54384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_DATATYPE:
54394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_VALUE:
54404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_LIST:
54414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_REF:
54424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_PARENTREF:
54434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_EXTERNALREF:
54444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_DEF:
54454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_ZEROORMORE:
54464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_ONEORMORE:
54474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_OPTIONAL:
54484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_CHOICE:
54494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_GROUP:
54504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_INTERLEAVE:
54514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (last == NULL) {
54524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ret->content = last = cur;
54534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    } else {
54544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if ((last->type == XML_RELAXNG_ELEMENT) &&
54554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            (ret->content == last)) {
54564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            ret->content = xmlRelaxNGNewDefine(ctxt, node);
54574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            if (ret->content != NULL) {
54584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                ret->content->type = XML_RELAXNG_GROUP;
54594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                ret->content->content = last;
54604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            } else {
54614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                ret->content = last;
54624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            }
54634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        }
54644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        last->next = cur;
54654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        last = cur;
54664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
54674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    break;
54684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_ATTRIBUTE:
54694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    cur->next = ret->attrs;
54704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret->attrs = cur;
54714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    break;
54724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_START:
54734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
54744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "RNG Internal error, start found in element\n",
54754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               NULL, NULL);
54764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    break;
54774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_PARAM:
54784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
54794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "RNG Internal error, param found in element\n",
54804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               NULL, NULL);
54814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    break;
54824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_EXCEPT:
54834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
54844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "RNG Internal error, except found in element\n",
54854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               NULL, NULL);
54864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    break;
54874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                case XML_RELAXNG_NOOP:
54884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
54894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "RNG Internal error, noop found in element\n",
54904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               NULL, NULL);
54914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    break;
54924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
54934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
54944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        child = child->next;
54956eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
5496276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard    ctxt->define = olddefine;
54974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
54986eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
54996eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
55006eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
55016eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGParsePatterns:
55026eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG parser context
55036eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @nodes:  list of nodes
5504154877e55495468de2e971531fb7f18a644a3412Daniel Veillard * @group:  use an implicit <group> for elements
55056eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
55066eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * parse the content of a RelaxNG start node.
55076eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
55086eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns the definition pointer or NULL in case of error.
55096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
55106eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic xmlRelaxNGDefinePtr
5511154877e55495468de2e971531fb7f18a644a3412Daniel VeillardxmlRelaxNGParsePatterns(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes,
55124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        int group)
55134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
551476fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    xmlRelaxNGDefinePtr def = NULL, last = NULL, cur, parent;
55156eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
551676fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    parent = ctxt->def;
55176eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    while (nodes != NULL) {
55184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (IS_RELAXNG(nodes, "element")) {
55194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur = xmlRelaxNGParseElement(ctxt, nodes);
55204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (def == NULL) {
55214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                def = last = cur;
55224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
55234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((group == 1) && (def->type == XML_RELAXNG_ELEMENT) &&
55244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (def == last)) {
55254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    def = xmlRelaxNGNewDefine(ctxt, nodes);
55264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    def->type = XML_RELAXNG_GROUP;
55274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    def->content = last;
55284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
55294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                last->next = cur;
55304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                last = cur;
55314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
55324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur->parent = parent;
55334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
55344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur = xmlRelaxNGParsePattern(ctxt, nodes);
55354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur != NULL) {
55364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (def == NULL) {
55374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    def = last = cur;
55384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else {
55394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    last->next = cur;
55404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    last = cur;
55414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
55424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
55434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
55444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        nodes = nodes->next;
55454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
55464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (def);
55474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard}
55484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
55494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard/**
55504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * xmlRelaxNGParseStart:
55514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @ctxt:  a Relax-NG parser context
55524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @nodes:  start children nodes
55534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard *
55544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * parse the content of a RelaxNG start node.
55554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard *
55566eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns 0 in case of success, -1 in case of error
55576eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
55586eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic int
55594c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGParseStart(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes)
55604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
55616eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    int ret = 0;
55622df2de225aeb241cbf7eb895698498ef3366d5d4Daniel Veillard    xmlRelaxNGDefinePtr def = NULL, last;
55636eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
5564d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    if (nodes == NULL) {
55654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, nodes, XML_RNGP_START_EMPTY, "start has no children\n",
55664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   NULL, NULL);
55674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
5568d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    }
5569d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    if (IS_RELAXNG(nodes, "empty")) {
55704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGNewDefine(ctxt, nodes);
55714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def == NULL)
55724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (-1);
55734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->type = XML_RELAXNG_EMPTY;
55744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (nodes->children != NULL) {
55754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, nodes, XML_RNGP_EMPTY_CONTENT,
55764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "element empty is not empty\n", NULL, NULL);
55774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
5578d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    } else if (IS_RELAXNG(nodes, "notAllowed")) {
55794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGNewDefine(ctxt, nodes);
55804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def == NULL)
55814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (-1);
55824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def->type = XML_RELAXNG_NOT_ALLOWED;
55834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (nodes->children != NULL) {
55844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, nodes, XML_RNGP_NOTALLOWED_NOT_EMPTY,
55854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "element notAllowed is not empty\n", NULL, NULL);
55864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
5587d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    } else {
55884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlRelaxNGParsePatterns(ctxt, nodes, 1);
55892df2de225aeb241cbf7eb895698498ef3366d5d4Daniel Veillard    }
55902df2de225aeb241cbf7eb895698498ef3366d5d4Daniel Veillard    if (ctxt->grammar->start != NULL) {
55914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        last = ctxt->grammar->start;
55924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        while (last->next != NULL)
55934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            last = last->next;
55944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        last->next = def;
55952df2de225aeb241cbf7eb895698498ef3366d5d4Daniel Veillard    } else {
55964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->grammar->start = def;
5597d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    }
5598d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    nodes = nodes->next;
5599d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    if (nodes != NULL) {
56004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, nodes, XML_RNGP_START_CONTENT,
56014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "start more than one children\n", NULL, NULL);
56024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
56036eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
56044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
56056eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
56066eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
56076eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
56086eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGParseGrammarContent:
56096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG parser context
56106eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @nodes:  grammar children nodes
56116eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
56126eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * parse the content of a RelaxNG grammar node.
56136eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
56146eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns 0 in case of success, -1 in case of error
56156eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
56166eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic int
56174c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGParseGrammarContent(xmlRelaxNGParserCtxtPtr ctxt,
56184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                              xmlNodePtr nodes)
56196eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard{
5620e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    int ret = 0, tmp;
56216eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
56226eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (nodes == NULL) {
56234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_EMPTY,
56244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "grammar has no children\n", NULL, NULL);
56254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
56266eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
56276eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    while (nodes != NULL) {
56284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (IS_RELAXNG(nodes, "start")) {
56294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (nodes->children == NULL) {
56304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, nodes, XML_RNGP_START_EMPTY,
56314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "start has no children\n", NULL, NULL);
56324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
56334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp = xmlRelaxNGParseStart(ctxt, nodes->children);
56344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (tmp != 0)
56354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret = -1;
56364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
56374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (IS_RELAXNG(nodes, "define")) {
56384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp = xmlRelaxNGParseDefine(ctxt, nodes);
56394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (tmp != 0)
56404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = -1;
56414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (IS_RELAXNG(nodes, "include")) {
56424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp = xmlRelaxNGParseInclude(ctxt, nodes);
56434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (tmp != 0)
56444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = -1;
56456eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        } else {
56464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_CONTENT,
56474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "grammar has unexpected child %s\n", nodes->name,
56484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       NULL);
56494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = -1;
56504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
56516eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        nodes = nodes->next;
56526eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
56536eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    return (ret);
56546eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
56556eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
56566eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
56576eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGCheckReference:
56586eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ref:  the ref
56596eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG parser context
56606eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @name:  the name associated to the defines
56616eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
56626eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Applies the 4.17. combine attribute rule for all the define
56636eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * element of a given grammar using the same name.
56646eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
56656eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic void
56666eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGCheckReference(xmlRelaxNGDefinePtr ref,
56674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         xmlRelaxNGParserCtxtPtr ctxt,
56684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         const xmlChar * name)
56694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
56706eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGGrammarPtr grammar;
5671276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard    xmlRelaxNGDefinePtr def, cur;
56726eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
5673aa422d9254f373141428bf0879f08af7ad15f3bfDaniel Veillard    /*
5674aa422d9254f373141428bf0879f08af7ad15f3bfDaniel Veillard     * Those rules don't apply to imported ref from xmlRelaxNGParseImportRef
5675aa422d9254f373141428bf0879f08af7ad15f3bfDaniel Veillard     */
5676aa422d9254f373141428bf0879f08af7ad15f3bfDaniel Veillard    if (ref->dflags & IS_EXTERNAL_REF)
5677aa422d9254f373141428bf0879f08af7ad15f3bfDaniel Veillard        return;
5678aa422d9254f373141428bf0879f08af7ad15f3bfDaniel Veillard
56796eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    grammar = ctxt->grammar;
56806eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (grammar == NULL) {
56814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, ref->node, XML_ERR_INTERNAL_ERROR,
56824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "Internal error: no grammar in CheckReference %s\n",
56834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   name, NULL);
56844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
56856eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
56866eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ref->content != NULL) {
56874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, ref->node, XML_ERR_INTERNAL_ERROR,
56884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "Internal error: reference has content in CheckReference %s\n",
56894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   name, NULL);
56904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
56916eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
56926eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (grammar->defs != NULL) {
56934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        def = xmlHashLookup(grammar->defs, name);
56944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (def != NULL) {
56954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur = ref;
56964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            while (cur != NULL) {
56974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur->content = def;
56984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur = cur->nextHash;
56994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
57004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
57014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, ref->node, XML_RNGP_REF_NO_DEF,
57024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Reference %s has no matching definition\n", name,
57034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       NULL);
57044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
5705d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard    } else {
57064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, ref->node, XML_RNGP_REF_NO_DEF,
57074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "Reference %s has no matching definition\n", name,
57084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   NULL);
57096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
57106eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
57116eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
57126eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
57136eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGCheckCombine:
57146eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @define:  the define(s) list
57156eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG parser context
57166eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @name:  the name associated to the defines
57176eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
57186eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Applies the 4.17. combine attribute rule for all the define
57196eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * element of a given grammar using the same name.
57206eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
57216eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic void
57226eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGCheckCombine(xmlRelaxNGDefinePtr define,
57234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * name)
57244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
57256eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlChar *combine;
57266eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    int choiceOrInterleave = -1;
57276eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    int missing = 0;
57286eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGDefinePtr cur, last, tmp, tmp2;
57296eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
57306eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (define->nextHash == NULL)
57314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
57326eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    cur = define;
57336eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    while (cur != NULL) {
57344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        combine = xmlGetProp(cur->node, BAD_CAST "combine");
57354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (combine != NULL) {
57364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (xmlStrEqual(combine, BAD_CAST "choice")) {
57374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (choiceOrInterleave == -1)
57384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    choiceOrInterleave = 1;
57394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                else if (choiceOrInterleave == 0) {
57404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, define->node, XML_RNGP_DEF_CHOICE_AND_INTERLEAVE,
57414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "Defines for %s use both 'choice' and 'interleave'\n",
57424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               name, NULL);
57434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
57444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else if (xmlStrEqual(combine, BAD_CAST "interleave")) {
57454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (choiceOrInterleave == -1)
57464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    choiceOrInterleave = 0;
57474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                else if (choiceOrInterleave == 1) {
57484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, define->node, XML_RNGP_DEF_CHOICE_AND_INTERLEAVE,
57494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "Defines for %s use both 'choice' and 'interleave'\n",
57504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               name, NULL);
57514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
57524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
57534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, define->node, XML_RNGP_UNKNOWN_COMBINE,
57544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Defines for %s use unknown combine value '%s''\n",
57554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           name, combine);
57564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
57574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlFree(combine);
57584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
57594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (missing == 0)
57604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                missing = 1;
57614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            else {
57624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, define->node, XML_RNGP_NEED_COMBINE,
57634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Some defines for %s needs the combine attribute\n",
57644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           name, NULL);
57654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
57664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
57674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
57684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = cur->nextHash;
57696eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
57706eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#ifdef DEBUG
57716eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlGenericError(xmlGenericErrorContext,
57724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    "xmlRelaxNGCheckCombine(): merging %s defines: %d\n",
57734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    name, choiceOrInterleave);
57746eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#endif
57756eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (choiceOrInterleave == -1)
57764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        choiceOrInterleave = 0;
5777fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    cur = xmlRelaxNGNewDefine(ctxt, define->node);
57786eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (cur == NULL)
57794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
57806eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (choiceOrInterleave == 0)
57814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur->type = XML_RELAXNG_INTERLEAVE;
5782fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    else
57834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur->type = XML_RELAXNG_CHOICE;
57846eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    tmp = define;
57856eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    last = NULL;
57866eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    while (tmp != NULL) {
57874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (tmp->content != NULL) {
57884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (tmp->content->next != NULL) {
57894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                /*
57904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 * we need first to create a wrapper.
57914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 */
57924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp2 = xmlRelaxNGNewDefine(ctxt, tmp->content->node);
57934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (tmp2 == NULL)
57944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    break;
57954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp2->type = XML_RELAXNG_GROUP;
57964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp2->content = tmp->content;
57974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
57984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp2 = tmp->content;
57994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
58004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (last == NULL) {
58014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur->content = tmp2;
58024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
58034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                last->next = tmp2;
58044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
58054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            last = tmp2;
58064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
58074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        tmp->content = cur;
58084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        tmp = tmp->nextHash;
58096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
58106eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    define->content = cur;
5811fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (choiceOrInterleave == 0) {
58124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->interleaves == NULL)
58134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->interleaves = xmlHashCreate(10);
58144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->interleaves == NULL) {
58154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, define->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
58164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Failed to create interleaves hash table\n", NULL,
58174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       NULL);
58184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
58194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            char tmpname[32];
58204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
58214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(tmpname, 32, "interleave%d", ctxt->nbInterleaves++);
58224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST tmpname, cur) <
58234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                0) {
58244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, define->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
58254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Failed to add %s to hash table\n",
58264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard			   (const xmlChar *) tmpname, NULL);
58274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
58284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
5829fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
58306eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
58316eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
58326eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
58336eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGCombineStart:
58346eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG parser context
58356eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @grammar:  the grammar
58366eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
58376eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Applies the 4.17. combine rule for all the start
58386eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * element of a given grammar.
58396eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
58406eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic void
58416eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGCombineStart(xmlRelaxNGParserCtxtPtr ctxt,
58424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       xmlRelaxNGGrammarPtr grammar)
58434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
58446eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGDefinePtr starts;
58456eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlChar *combine;
58466eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    int choiceOrInterleave = -1;
58476eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    int missing = 0;
58482df2de225aeb241cbf7eb895698498ef3366d5d4Daniel Veillard    xmlRelaxNGDefinePtr cur;
58496eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
58502df2de225aeb241cbf7eb895698498ef3366d5d4Daniel Veillard    starts = grammar->start;
58512df2de225aeb241cbf7eb895698498ef3366d5d4Daniel Veillard    if ((starts == NULL) || (starts->next == NULL))
58524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
58536eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    cur = starts;
58546eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    while (cur != NULL) {
58554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((cur->node == NULL) || (cur->node->parent == NULL) ||
58564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (!xmlStrEqual(cur->node->parent->name, BAD_CAST "start"))) {
58574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            combine = NULL;
58584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, cur->node, XML_RNGP_START_MISSING,
58594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Internal error: start element not found\n", NULL,
58604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       NULL);
58614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
58624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            combine = xmlGetProp(cur->node->parent, BAD_CAST "combine");
58634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
58644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
58654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (combine != NULL) {
58664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (xmlStrEqual(combine, BAD_CAST "choice")) {
58674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (choiceOrInterleave == -1)
58684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    choiceOrInterleave = 1;
58694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                else if (choiceOrInterleave == 0) {
58704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, cur->node, XML_RNGP_START_CHOICE_AND_INTERLEAVE,
58714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "<start> use both 'choice' and 'interleave'\n",
58724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               NULL, NULL);
58734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
58744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else if (xmlStrEqual(combine, BAD_CAST "interleave")) {
58754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (choiceOrInterleave == -1)
58764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    choiceOrInterleave = 0;
58774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                else if (choiceOrInterleave == 1) {
58784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, cur->node, XML_RNGP_START_CHOICE_AND_INTERLEAVE,
58794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "<start> use both 'choice' and 'interleave'\n",
58804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               NULL, NULL);
58814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
58824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
58834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_UNKNOWN_COMBINE,
58844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "<start> uses unknown combine value '%s''\n",
58854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           combine, NULL);
58864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
58874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlFree(combine);
58884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
58894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (missing == 0)
58904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                missing = 1;
58914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            else {
58924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_NEED_COMBINE,
58934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Some <start> element miss the combine attribute\n",
58944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
58954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
58964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
58974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
58984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = cur->next;
58996eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
59006eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#ifdef DEBUG
59016eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlGenericError(xmlGenericErrorContext,
59024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    "xmlRelaxNGCombineStart(): merging <start>: %d\n",
59034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    choiceOrInterleave);
59046eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#endif
59056eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (choiceOrInterleave == -1)
59064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        choiceOrInterleave = 0;
5907fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    cur = xmlRelaxNGNewDefine(ctxt, starts->node);
59086eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (cur == NULL)
59094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
59106eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (choiceOrInterleave == 0)
59114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur->type = XML_RELAXNG_INTERLEAVE;
5912fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    else
59134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur->type = XML_RELAXNG_CHOICE;
59142df2de225aeb241cbf7eb895698498ef3366d5d4Daniel Veillard    cur->content = grammar->start;
59152df2de225aeb241cbf7eb895698498ef3366d5d4Daniel Veillard    grammar->start = cur;
5916fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (choiceOrInterleave == 0) {
59174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->interleaves == NULL)
59184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->interleaves = xmlHashCreate(10);
59194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->interleaves == NULL) {
59204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, cur->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
59214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "Failed to create interleaves hash table\n", NULL,
59224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       NULL);
59234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
59244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            char tmpname[32];
59254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
59264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            snprintf(tmpname, 32, "interleave%d", ctxt->nbInterleaves++);
59274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST tmpname, cur) <
59284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                0) {
59294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
59304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Failed to add %s to hash table\n",
59314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard			   (const xmlChar *) tmpname, NULL);
59324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
59334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
5934fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
59356eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
59366eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
59376eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
5938d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard * xmlRelaxNGCheckCycles:
5939d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard * @ctxt:  a Relax-NG parser context
5940d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard * @nodes:  grammar children nodes
5941d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard * @depth:  the counter
5942d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard *
5943d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard * Check for cycles.
5944d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard *
5945d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard * Returns 0 if check passed, and -1 in case of error
5946d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard */
5947d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillardstatic int
59484c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGCheckCycles(xmlRelaxNGParserCtxtPtr ctxt,
59494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                      xmlRelaxNGDefinePtr cur, int depth)
59504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
5951d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard    int ret = 0;
5952d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard
5953d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard    while ((ret == 0) && (cur != NULL)) {
59544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((cur->type == XML_RELAXNG_REF) ||
59554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_PARENTREF)) {
59564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur->depth == -1) {
59574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur->depth = depth;
59584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth);
59594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur->depth = -2;
59604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else if (depth == cur->depth) {
59614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_CYCLE,
59624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Detected a cycle in %s references\n",
59634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           cur->name, NULL);
59644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (-1);
59654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
59664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (cur->type == XML_RELAXNG_ELEMENT) {
59674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth + 1);
59684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
59694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth);
59704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
59714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = cur->next;
59724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
59734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
5974d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard}
5975d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard
5976d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard/**
597777648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard * xmlRelaxNGTryUnlink:
597877648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard * @ctxt:  a Relax-NG parser context
597977648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard * @cur:  the definition to unlink
598077648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard * @parent:  the parent definition
598177648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard * @prev:  the previous sibling definition
598277648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard *
598377648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard * Try to unlink a definition. If not possble make it a NOOP
598477648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard *
598577648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard * Returns the new prev definition
598677648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard */
598777648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillardstatic xmlRelaxNGDefinePtr
59884c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGTryUnlink(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
59894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGDefinePtr cur,
59904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGDefinePtr parent, xmlRelaxNGDefinePtr prev)
59914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
5992fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (prev != NULL) {
59934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        prev->next = cur->next;
5994fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    } else {
59954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (parent != NULL) {
59964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (parent->content == cur)
59974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                parent->content = cur->next;
59984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            else if (parent->attrs == cur)
59994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                parent->attrs = cur->next;
60004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            else if (parent->nameClass == cur)
60014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                parent->nameClass = cur->next;
60024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
60034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur->type = XML_RELAXNG_NOOP;
60044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            prev = cur;
60054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
6006fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
60074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (prev);
600877648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard}
600977648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard
601077648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard/**
60114c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard * xmlRelaxNGSimplify:
60121c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard * @ctxt:  a Relax-NG parser context
60131c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard * @nodes:  grammar children nodes
60141c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard *
60151c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard * Check for simplification of empty and notAllowed
60161c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard */
60171c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillardstatic void
60184c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGSimplify(xmlRelaxNGParserCtxtPtr ctxt,
60194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   xmlRelaxNGDefinePtr cur, xmlRelaxNGDefinePtr parent)
60204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
6021fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGDefinePtr prev = NULL;
60221564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
6023fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    while (cur != NULL) {
60244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((cur->type == XML_RELAXNG_REF) ||
60254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_PARENTREF)) {
60264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur->depth != -3) {
60274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur->depth = -3;
60284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGSimplify(ctxt, cur->content, cur);
60294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
60304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (cur->type == XML_RELAXNG_NOT_ALLOWED) {
60314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur->parent = parent;
60324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((parent != NULL) &&
60334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ((parent->type == XML_RELAXNG_ATTRIBUTE) ||
60344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 (parent->type == XML_RELAXNG_LIST) ||
60354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 (parent->type == XML_RELAXNG_GROUP) ||
60364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 (parent->type == XML_RELAXNG_INTERLEAVE) ||
60374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 (parent->type == XML_RELAXNG_ONEORMORE) ||
60384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 (parent->type == XML_RELAXNG_ZEROORMORE))) {
60394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                parent->type = XML_RELAXNG_NOT_ALLOWED;
60404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
60414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
60424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((parent != NULL) && (parent->type == XML_RELAXNG_CHOICE)) {
60434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
60444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else
60454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                prev = cur;
60464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (cur->type == XML_RELAXNG_EMPTY) {
60474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur->parent = parent;
60484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((parent != NULL) &&
60494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ((parent->type == XML_RELAXNG_ONEORMORE) ||
60504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 (parent->type == XML_RELAXNG_ZEROORMORE))) {
60514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                parent->type = XML_RELAXNG_EMPTY;
60524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
60534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
60544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((parent != NULL) &&
60554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ((parent->type == XML_RELAXNG_GROUP) ||
60564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 (parent->type == XML_RELAXNG_INTERLEAVE))) {
60574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
60584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else
60594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                prev = cur;
60604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
60614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur->parent = parent;
60624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur->content != NULL)
60634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGSimplify(ctxt, cur->content, cur);
60644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((cur->type != XML_RELAXNG_VALUE) && (cur->attrs != NULL))
60654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGSimplify(ctxt, cur->attrs, cur);
60664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur->nameClass != NULL)
60674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGSimplify(ctxt, cur->nameClass, cur);
60684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /*
60694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * On Elements, try to move attribute only generating rules on
60704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * the attrs rules.
60714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             */
60724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur->type == XML_RELAXNG_ELEMENT) {
60734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                int attronly;
60744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGDefinePtr tmp, pre;
60754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
60764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (cur->content != NULL) {
60774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    attronly =
60784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGGenerateAttributes(ctxt, cur->content);
60794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (attronly == 1) {
60804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        /*
60814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         * migrate cur->content to attrs
60824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         */
60834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        tmp = cur->content;
60844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        cur->content = tmp->next;
60854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        tmp->next = cur->attrs;
60864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        cur->attrs = tmp;
60874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    } else {
60884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        /*
60894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         * cur->content can generate elements or text
60904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         */
60914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        break;
60924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
60934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
60944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                pre = cur->content;
60954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while ((pre != NULL) && (pre->next != NULL)) {
60964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    tmp = pre->next;
60974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    attronly = xmlRelaxNGGenerateAttributes(ctxt, tmp);
60984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (attronly == 1) {
60994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        /*
61004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         * migrate tmp to attrs
61014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         */
61024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        pre->next = tmp->next;
61034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        tmp->next = cur->attrs;
61044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        cur->attrs = tmp;
61054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    } else {
61064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        pre = tmp;
61074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
61084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
61094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
61104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /*
61114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * This may result in a simplification
61124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             */
61134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((cur->type == XML_RELAXNG_GROUP) ||
61144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                (cur->type == XML_RELAXNG_INTERLEAVE)) {
61154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (cur->content == NULL)
61164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    cur->type = XML_RELAXNG_EMPTY;
61174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                else if (cur->content->next == NULL) {
61184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if ((parent == NULL) && (prev == NULL)) {
61194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        cur->type = XML_RELAXNG_NOOP;
61204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    } else if (prev == NULL) {
61214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        parent->content = cur->content;
61224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        cur->content->next = cur->next;
61234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        cur = cur->content;
61244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    } else {
61254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        cur->content->next = cur->next;
61264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        prev->next = cur->content;
61274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        cur = cur->content;
61284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
61294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
61304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
61314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /*
61324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * the current node may have been transformed back
61334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             */
61344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((cur->type == XML_RELAXNG_EXCEPT) &&
61354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                (cur->content != NULL) &&
61364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                (cur->content->type == XML_RELAXNG_NOT_ALLOWED)) {
61374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
61384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else if (cur->type == XML_RELAXNG_NOT_ALLOWED) {
61394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((parent != NULL) &&
61404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ((parent->type == XML_RELAXNG_ATTRIBUTE) ||
61414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     (parent->type == XML_RELAXNG_LIST) ||
61424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     (parent->type == XML_RELAXNG_GROUP) ||
61434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     (parent->type == XML_RELAXNG_INTERLEAVE) ||
61444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     (parent->type == XML_RELAXNG_ONEORMORE) ||
61454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     (parent->type == XML_RELAXNG_ZEROORMORE))) {
61464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    parent->type = XML_RELAXNG_NOT_ALLOWED;
61474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    break;
61484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
61494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((parent != NULL) &&
61504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (parent->type == XML_RELAXNG_CHOICE)) {
61514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
61524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else
61534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    prev = cur;
61544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else if (cur->type == XML_RELAXNG_EMPTY) {
61554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((parent != NULL) &&
61564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ((parent->type == XML_RELAXNG_ONEORMORE) ||
61574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     (parent->type == XML_RELAXNG_ZEROORMORE))) {
61584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    parent->type = XML_RELAXNG_EMPTY;
61594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    break;
61604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
61614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((parent != NULL) &&
61624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ((parent->type == XML_RELAXNG_GROUP) ||
61634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     (parent->type == XML_RELAXNG_INTERLEAVE) ||
61644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     (parent->type == XML_RELAXNG_CHOICE))) {
61654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
61664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else
61674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    prev = cur;
61684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
61694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                prev = cur;
61704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
61714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
61724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = cur->next;
61731c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard    }
61741c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard}
61751c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard
61764c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard/**
61774c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard * xmlRelaxNGGroupContentType:
61784c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard * @ct1:  the first content type
61794c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard * @ct2:  the second content type
61804c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard *
61814c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard * Try to group 2 content types
61824c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard *
61834c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard * Returns the content type
61844c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard */
61854c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillardstatic xmlRelaxNGContentType
61864c5cf7092efe7d616cc748d66f0689593dc8e552Daniel VeillardxmlRelaxNGGroupContentType(xmlRelaxNGContentType ct1,
61874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           xmlRelaxNGContentType ct2)
61884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
61894c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard    if ((ct1 == XML_RELAXNG_CONTENT_ERROR) ||
61904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        (ct2 == XML_RELAXNG_CONTENT_ERROR))
61914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (XML_RELAXNG_CONTENT_ERROR);
61924c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard    if (ct1 == XML_RELAXNG_CONTENT_EMPTY)
61934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (ct2);
61944c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard    if (ct2 == XML_RELAXNG_CONTENT_EMPTY)
61954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (ct1);
61964c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard    if ((ct1 == XML_RELAXNG_CONTENT_COMPLEX) &&
61974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        (ct2 == XML_RELAXNG_CONTENT_COMPLEX))
61984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (XML_RELAXNG_CONTENT_COMPLEX);
61994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (XML_RELAXNG_CONTENT_ERROR);
62004c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard}
62014c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard
62024c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard/**
62034c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard * xmlRelaxNGMaxContentType:
62044c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard * @ct1:  the first content type
62054c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard * @ct2:  the second content type
62064c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard *
62074c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard * Compute the max content-type
62084c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard *
62094c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard * Returns the content type
62104c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard */
62114c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillardstatic xmlRelaxNGContentType
62124c5cf7092efe7d616cc748d66f0689593dc8e552Daniel VeillardxmlRelaxNGMaxContentType(xmlRelaxNGContentType ct1,
62134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         xmlRelaxNGContentType ct2)
62144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
62154c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard    if ((ct1 == XML_RELAXNG_CONTENT_ERROR) ||
62164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        (ct2 == XML_RELAXNG_CONTENT_ERROR))
62174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (XML_RELAXNG_CONTENT_ERROR);
62184c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard    if ((ct1 == XML_RELAXNG_CONTENT_SIMPLE) ||
62194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        (ct2 == XML_RELAXNG_CONTENT_SIMPLE))
62204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (XML_RELAXNG_CONTENT_SIMPLE);
62214c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard    if ((ct1 == XML_RELAXNG_CONTENT_COMPLEX) ||
62224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        (ct2 == XML_RELAXNG_CONTENT_COMPLEX))
62234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (XML_RELAXNG_CONTENT_COMPLEX);
62244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (XML_RELAXNG_CONTENT_EMPTY);
62254c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard}
622677648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard
62271c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard/**
62281c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard * xmlRelaxNGCheckRules:
62291c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard * @ctxt:  a Relax-NG parser context
62304c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard * @cur:  the current definition
623177648bbe612564a11a26dc6b72b656bd85cbe858Daniel Veillard * @flags:  some accumulated flags
6232fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @ptype:  the parent type
62331c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard *
62344c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard * Check for rules in section 7.1 and 7.2
62351c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard *
62364c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillard * Returns the content type of @cur
62371c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard */
62384c5cf7092efe7d616cc748d66f0689593dc8e552Daniel Veillardstatic xmlRelaxNGContentType
62394c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGCheckRules(xmlRelaxNGParserCtxtPtr ctxt,
62404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     xmlRelaxNGDefinePtr cur, int flags,
62414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     xmlRelaxNGType ptype)
62424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
6243d44b9364991bd0067d50c29bdff48305dfdad4ceDaniel Veillard    int nflags;
6244fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGContentType ret, tmp, val = XML_RELAXNG_CONTENT_EMPTY;
62451c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard
6246fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    while (cur != NULL) {
62474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = XML_RELAXNG_CONTENT_EMPTY;
62484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((cur->type == XML_RELAXNG_REF) ||
62494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_PARENTREF)) {
625063d68a37bec76d69425d1b0237ee1b00f3378f94Daniel Veillard           /*
625163d68a37bec76d69425d1b0237ee1b00f3378f94Daniel Veillard            * This should actually be caught by list//element(ref) at the
625263d68a37bec76d69425d1b0237ee1b00f3378f94Daniel Veillard            * element boundaries, c.f. Bug #159968 local refs are dropped
625363d68a37bec76d69425d1b0237ee1b00f3378f94Daniel Veillard            * in step 4.19.
625463d68a37bec76d69425d1b0237ee1b00f3378f94Daniel Veillard            */
625563d68a37bec76d69425d1b0237ee1b00f3378f94Daniel Veillard#if 0
62564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_LIST) {
62574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_REF,
62584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern list//ref\n", NULL,
62594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL);
62604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
626163d68a37bec76d69425d1b0237ee1b00f3378f94Daniel Veillard#endif
62624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
62634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_REF,
62644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern data/except//ref\n",
62654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
62664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
626781c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard            if (cur->content == NULL) {
626881c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                if (cur->type == XML_RELAXNG_PARENTREF)
626981c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                    xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF,
627081c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                               "Internal found no define for parent refs\n",
627181c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                               NULL, NULL);
627281c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                else
627381c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                    xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF,
627481c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                               "Internal found no define for ref %s\n",
6275a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard                               (cur->name ? cur->name: BAD_CAST "null"), NULL);
627681c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard            }
62774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur->depth > -4) {
62784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur->depth = -4;
62794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = xmlRelaxNGCheckRules(ctxt, cur->content,
62804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                           flags, cur->type);
62814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur->depth = ret - 15;
62824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else if (cur->depth == -4) {
62834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = XML_RELAXNG_CONTENT_COMPLEX;
62844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
62854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = (xmlRelaxNGContentType) (cur->depth + 15);
62864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
62874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (cur->type == XML_RELAXNG_ELEMENT) {
62884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /*
62894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * The 7.3 Attribute derivation rule for groups is plugged there
62904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             */
62914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGCheckGroupAttrs(ctxt, cur);
62924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
62934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_ELEM,
62944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern data/except//element(ref)\n",
62954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
62964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
62974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_LIST) {
62984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_ELEM,
62994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern list//element(ref)\n",
63004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
63014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
63024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
63034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ATTR_ELEM,
63044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern attribute//element(ref)\n",
63054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
63064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
63074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
63084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ATTR_ELEM,
63094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern attribute//element(ref)\n",
63104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
63114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
63124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /*
63134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * reset since in the simple form elements are only child
63144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * of grammar/define
63154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             */
63164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            nflags = 0;
63174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret =
63184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGCheckRules(ctxt, cur->attrs, nflags, cur->type);
63194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret != XML_RELAXNG_CONTENT_EMPTY) {
63204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_ELEM_CONTENT_EMPTY,
63214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Element %s attributes have a content type error\n",
63224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           cur->name, NULL);
63234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
63244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret =
63254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
63264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     cur->type);
63274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret == XML_RELAXNG_CONTENT_ERROR) {
63284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_ELEM_CONTENT_ERROR,
63294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Element %s has a content type error\n",
63304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           cur->name, NULL);
63314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
63324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = XML_RELAXNG_CONTENT_COMPLEX;
63334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
63344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (cur->type == XML_RELAXNG_ATTRIBUTE) {
63354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
63364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ATTR_ATTR,
63374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern attribute//attribute\n",
63384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
63394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
63404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_LIST) {
63414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_ATTR,
63424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern list//attribute\n",
63434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
63444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
63454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_OOMGROUP) {
63464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ONEMORE_GROUP_ATTR,
63474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern oneOrMore//group//attribute\n",
63484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
63494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
63504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_OOMINTERLEAVE) {
63514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ONEMORE_INTERLEAVE_ATTR,
63524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern oneOrMore//interleave//attribute\n",
63534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
63544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
63554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
63564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_ATTR,
63574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern data/except//attribute\n",
63584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
63594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
63604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_START) {
63614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_ATTR,
63624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern start//attribute\n",
63634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
63644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
63654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((!(flags & XML_RELAXNG_IN_ONEORMORE))
63664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                && (cur->name == NULL)) {
63674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (cur->ns == NULL) {
63684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, cur->node, XML_RNGP_ANYNAME_ATTR_ANCESTOR,
63694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "Found anyName attribute without oneOrMore ancestor\n",
63704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               NULL, NULL);
63714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else {
63724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, cur->node, XML_RNGP_NSNAME_ATTR_ANCESTOR,
63734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "Found nsName attribute without oneOrMore ancestor\n",
63744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               NULL, NULL);
63754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
63764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
63774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            nflags = flags | XML_RELAXNG_IN_ATTRIBUTE;
63784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGCheckRules(ctxt, cur->content, nflags, cur->type);
63794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = XML_RELAXNG_CONTENT_EMPTY;
63804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if ((cur->type == XML_RELAXNG_ONEORMORE) ||
63814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   (cur->type == XML_RELAXNG_ZEROORMORE)) {
63824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
63834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_ONEMORE,
63844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern data/except//oneOrMore\n",
63854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
63864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
63874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_START) {
63884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_ONEMORE,
63894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern start//oneOrMore\n",
63904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
63914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
63924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            nflags = flags | XML_RELAXNG_IN_ONEORMORE;
63934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret =
63944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
63954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     cur->type);
63964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGGroupContentType(ret, ret);
63974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (cur->type == XML_RELAXNG_LIST) {
63984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_LIST) {
63994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_LIST,
64004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern list//list\n", NULL,
64014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL);
64024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
64034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
64044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_LIST,
64054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern data/except//list\n",
64064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
64074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
64084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_START) {
64094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_LIST,
64104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern start//list\n", NULL,
64114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL);
64124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
64134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            nflags = flags | XML_RELAXNG_IN_LIST;
64144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret =
64154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
64164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     cur->type);
64174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (cur->type == XML_RELAXNG_GROUP) {
64184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
64194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_GROUP,
64204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern data/except//group\n",
64214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
64224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
64234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_START) {
64244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_GROUP,
64254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern start//group\n", NULL,
64264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL);
64274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
64284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_ONEORMORE)
64294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                nflags = flags | XML_RELAXNG_IN_OOMGROUP;
64304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            else
64314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                nflags = flags;
64324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret =
64334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
64344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     cur->type);
64354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /*
64364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * The 7.3 Attribute derivation rule for groups is plugged there
64374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             */
64384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGCheckGroupAttrs(ctxt, cur);
64394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (cur->type == XML_RELAXNG_INTERLEAVE) {
64404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_LIST) {
64414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_INTERLEAVE,
64424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern list//interleave\n",
64434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
64444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
64454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
64464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE,
64474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern data/except//interleave\n",
64484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
64494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
64504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_START) {
64514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE,
64524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern start//interleave\n",
64534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
64544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
64554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_ONEORMORE)
64564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                nflags = flags | XML_RELAXNG_IN_OOMINTERLEAVE;
64574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            else
64584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                nflags = flags;
64594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret =
64604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
64614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     cur->type);
64624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (cur->type == XML_RELAXNG_EXCEPT) {
64634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((cur->parent != NULL) &&
64644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                (cur->parent->type == XML_RELAXNG_DATATYPE))
64654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                nflags = flags | XML_RELAXNG_IN_DATAEXCEPT;
64664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            else
64674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                nflags = flags;
64684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret =
64694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
64704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     cur->type);
64714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (cur->type == XML_RELAXNG_DATATYPE) {
64724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_START) {
64734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_DATA,
64744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern start//data\n", NULL,
64754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL);
64764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
64774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
64784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = XML_RELAXNG_CONTENT_SIMPLE;
64794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (cur->type == XML_RELAXNG_VALUE) {
64804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_START) {
64814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_VALUE,
64824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern start//value\n", NULL,
64834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL);
64844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
64854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
64864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = XML_RELAXNG_CONTENT_SIMPLE;
64874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (cur->type == XML_RELAXNG_TEXT) {
64884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_LIST) {
64894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_TEXT,
64904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern list//text\n", NULL,
64914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL);
64924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
64934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
64944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_TEXT,
64954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern data/except//text\n",
64964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
64974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
64984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_START) {
64994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_TEXT,
65004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern start//text\n", NULL,
65014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL);
65024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
65034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = XML_RELAXNG_CONTENT_COMPLEX;
65044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (cur->type == XML_RELAXNG_EMPTY) {
65054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
65064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_EMPTY,
65074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern data/except//empty\n",
65084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL, NULL);
65094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
65104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (flags & XML_RELAXNG_IN_START) {
65114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_EMPTY,
65124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Found forbidden pattern start//empty\n", NULL,
65134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           NULL);
65144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
65154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = XML_RELAXNG_CONTENT_EMPTY;
65164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (cur->type == XML_RELAXNG_CHOICE) {
65174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGCheckChoiceDeterminism(ctxt, cur);
65184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret =
65194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
65204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
65214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret =
65224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
65234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
65244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = cur->next;
65254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ptype == XML_RELAXNG_GROUP) {
65264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            val = xmlRelaxNGGroupContentType(val, ret);
65274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (ptype == XML_RELAXNG_INTERLEAVE) {
6528594e5dfb48ee6fbac1b64155839063648022fc57Daniel Veillard            /*
6529594e5dfb48ee6fbac1b64155839063648022fc57Daniel Veillard             * TODO: scan complain that tmp is never used, seems on purpose
6530594e5dfb48ee6fbac1b64155839063648022fc57Daniel Veillard             *       need double-checking
6531594e5dfb48ee6fbac1b64155839063648022fc57Daniel Veillard             */
65324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp = xmlRelaxNGGroupContentType(val, ret);
65334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (tmp != XML_RELAXNG_CONTENT_ERROR)
65344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp = xmlRelaxNGMaxContentType(val, ret);
65354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (ptype == XML_RELAXNG_CHOICE) {
65364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            val = xmlRelaxNGMaxContentType(val, ret);
65374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (ptype == XML_RELAXNG_LIST) {
65384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            val = XML_RELAXNG_CONTENT_SIMPLE;
65394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (ptype == XML_RELAXNG_EXCEPT) {
65404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret == XML_RELAXNG_CONTENT_ERROR)
65414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                val = XML_RELAXNG_CONTENT_ERROR;
65424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            else
65434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                val = XML_RELAXNG_CONTENT_SIMPLE;
65444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
65454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            val = xmlRelaxNGGroupContentType(val, ret);
65464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
65474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
65484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    }
65494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (val);
65501c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard}
65511c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard
65521c745ade5d5766aae34f6b05bc2780ae2daa7483Daniel Veillard/**
65536eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGParseGrammar:
65546eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG parser context
65556eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @nodes:  grammar children nodes
65566eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
65576eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * parse a Relax-NG <grammar> node
65586eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
65596eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns the internal xmlRelaxNGGrammarPtr built or
65606eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *         NULL in case of error
65616eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
65626eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic xmlRelaxNGGrammarPtr
65634c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGParseGrammar(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes)
65644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
65656eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGGrammarPtr ret, tmp, old;
65666eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
6567c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard#ifdef DEBUG_GRAMMAR
6568c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard    xmlGenericError(xmlGenericErrorContext, "Parsing a new grammar\n");
6569c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard#endif
6570c482e261adb1c441f1a58d64122b9ef7b25131d0Daniel Veillard
65716eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ret = xmlRelaxNGNewGrammar(ctxt);
65726eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ret == NULL)
65734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
65746eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
65756eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    /*
65766eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard     * Link the new grammar in the tree
65776eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard     */
65786eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ret->parent = ctxt->grammar;
65796eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ctxt->grammar != NULL) {
65804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        tmp = ctxt->grammar->children;
65814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (tmp == NULL) {
65824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->grammar->children = ret;
65834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
65844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            while (tmp->next != NULL)
65854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp = tmp->next;
65864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp->next = ret;
65874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
65886eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
65896eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
65906eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    old = ctxt->grammar;
65916eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ctxt->grammar = ret;
65926eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGParseGrammarContent(ctxt, nodes);
65936eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ctxt->grammar = ret;
65942df2de225aeb241cbf7eb895698498ef3366d5d4Daniel Veillard    if (ctxt->grammar == NULL) {
65954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_CONTENT,
65964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "Failed to parse <grammar> content\n", NULL, NULL);
65972df2de225aeb241cbf7eb895698498ef3366d5d4Daniel Veillard    } else if (ctxt->grammar->start == NULL) {
65984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_NO_START,
65994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "Element <grammar> has no <start>\n", NULL, NULL);
66002df2de225aeb241cbf7eb895698498ef3366d5d4Daniel Veillard    }
66016eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
66026eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    /*
6603acace88c4ab87fb2cdd811b0f1b5e73f3d2a1b0eJan Pokorný     * Apply 4.17 merging rules to defines and starts
66046eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard     */
66056eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGCombineStart(ctxt, ret);
66066eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ret->defs != NULL) {
66074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlHashScan(ret->defs, (xmlHashScanner) xmlRelaxNGCheckCombine,
66084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ctxt);
66096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
66106eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
66116eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    /*
66126eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard     * link together defines and refs in this grammar
66136eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard     */
66146eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ret->refs != NULL) {
66154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlHashScan(ret->refs, (xmlHashScanner) xmlRelaxNGCheckReference,
66164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ctxt);
66176eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
6618952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard
661981c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard
662025a1ce91346f9f72727afadc07f7e0f9873dcda4Daniel Veillard    /* @@@@ */
662125a1ce91346f9f72727afadc07f7e0f9873dcda4Daniel Veillard
66226eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ctxt->grammar = old;
66234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
66246eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
66256eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
66266eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
66276eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGParseDocument:
66286eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG parser context
66296eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @node:  the root node of the RelaxNG schema
66306eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
66316eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * parse a Relax-NG definition resource and build an internal
66326eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNG struture which can be used to validate instances.
66336eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
66346eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns the internal XML RelaxNG structure built or
66356eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *         NULL in case of error
66366eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
66376eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic xmlRelaxNGPtr
66384c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGParseDocument(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
66394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
66406eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGPtr schema = NULL;
6641276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard    const xmlChar *olddefine;
6642e431a27d45a5e1709d56ba6ff3352d47cffd316fDaniel Veillard    xmlRelaxNGGrammarPtr old;
66436eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
66446eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if ((ctxt == NULL) || (node == NULL))
66456eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        return (NULL);
66466eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
66476eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    schema = xmlRelaxNGNewRelaxNG(ctxt);
66486eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (schema == NULL)
66494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
66506eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
6651276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard    olddefine = ctxt->define;
6652276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard    ctxt->define = NULL;
66536eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (IS_RELAXNG(node, "grammar")) {
66544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        schema->topgrammar = xmlRelaxNGParseGrammar(ctxt, node->children);
665542870f46ccf36f83a55fde03344657d360ba0793Daniel Veillard        if (schema->topgrammar == NULL) {
665642870f46ccf36f83a55fde03344657d360ba0793Daniel Veillard            xmlRelaxNGFree(schema);
665742870f46ccf36f83a55fde03344657d360ba0793Daniel Veillard            return (NULL);
665842870f46ccf36f83a55fde03344657d360ba0793Daniel Veillard        }
66596eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    } else {
66604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGGrammarPtr tmp, ret;
66614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
66624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        schema->topgrammar = ret = xmlRelaxNGNewGrammar(ctxt);
66634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (schema->topgrammar == NULL) {
666442870f46ccf36f83a55fde03344657d360ba0793Daniel Veillard            xmlRelaxNGFree(schema);
666542870f46ccf36f83a55fde03344657d360ba0793Daniel Veillard            return (NULL);
66664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
66674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        /*
66684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         * Link the new grammar in the tree
66694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         */
66704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret->parent = ctxt->grammar;
66714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->grammar != NULL) {
66724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp = ctxt->grammar->children;
66734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (tmp == NULL) {
66744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->grammar->children = ret;
66754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
66764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (tmp->next != NULL)
66774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    tmp = tmp->next;
66784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp->next = ret;
66794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
66804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
66814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        old = ctxt->grammar;
66824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->grammar = ret;
66834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGParseStart(ctxt, node);
66844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (old != NULL)
66854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->grammar = old;
66866eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
6687276be4a6e5aa2de82cafe8eeb524fb62cc7638f2Daniel Veillard    ctxt->define = olddefine;
6688d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard    if (schema->topgrammar->start != NULL) {
66894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGCheckCycles(ctxt, schema->topgrammar->start, 0);
66904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((ctxt->flags & XML_RELAXNG_IN_EXTERNALREF) == 0) {
66914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGSimplify(ctxt, schema->topgrammar->start, NULL);
66924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            while ((schema->topgrammar->start != NULL) &&
66934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   (schema->topgrammar->start->type == XML_RELAXNG_NOOP) &&
66944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   (schema->topgrammar->start->next != NULL))
66954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                schema->topgrammar->start =
66964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    schema->topgrammar->start->content;
66974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGCheckRules(ctxt, schema->topgrammar->start,
66984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                 XML_RELAXNG_IN_START, XML_RELAXNG_NOOP);
66994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
6700d431074c46d3b056b88c1be778960cb5ce43fe0fDaniel Veillard    }
67016eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#ifdef DEBUG
67026eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (schema == NULL)
67036eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
67046eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard                        "xmlRelaxNGParseDocument() failed\n");
67056eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#endif
67066eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
67076eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    return (schema);
67086eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
67096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
67106eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/************************************************************************
6711f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
6712f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *			Reading RelaxNGs				*
6713f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
67146eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard ************************************************************************/
67156eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
67166eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
67176eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGNewParserCtxt:
67186eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @URL:  the location of the schema
67196eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
67206eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Create an XML RelaxNGs parse context for that file/resource expected
67216eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * to contain an XML RelaxNGs file.
67226eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
67236eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns the parser context or NULL in case of error
67246eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
67256eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGParserCtxtPtr
67264c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGNewParserCtxt(const char *URL)
67274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
67286eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGParserCtxtPtr ret;
67296eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
67306eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (URL == NULL)
67314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
67326eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
67334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    ret =
67344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        (xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
67356eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ret == NULL) {
67364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErrMemory(NULL, "building parser\n");
67376eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        return (NULL);
67386eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
67396eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
67404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    ret->URL = xmlStrdup((const xmlChar *) URL);
67411703c5fc238e76532f654747259a20a29c769942Daniel Veillard    ret->error = xmlGenericError;
67421703c5fc238e76532f654747259a20a29c769942Daniel Veillard    ret->userData = xmlGenericErrorContext;
67436eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    return (ret);
67446eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
67456eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
67466eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
67476eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGNewMemParserCtxt:
67486eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @buffer:  a pointer to a char array containing the schemas
67496eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @size:  the size of the array
67506eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
67516eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Create an XML RelaxNGs parse context for that memory buffer expected
67526eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * to contain an XML RelaxNGs file.
67536eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
67546eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns the parser context or NULL in case of error
67556eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
67566eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGParserCtxtPtr
67574c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGNewMemParserCtxt(const char *buffer, int size)
67584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
67596eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGParserCtxtPtr ret;
67606eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
67616eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if ((buffer == NULL) || (size <= 0))
67624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
67636eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
67644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    ret =
67654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        (xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
67666eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ret == NULL) {
67674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErrMemory(NULL, "building parser\n");
67686eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        return (NULL);
67696eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
67706eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
67716eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ret->buffer = buffer;
67726eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ret->size = size;
67731703c5fc238e76532f654747259a20a29c769942Daniel Veillard    ret->error = xmlGenericError;
67741703c5fc238e76532f654747259a20a29c769942Daniel Veillard    ret->userData = xmlGenericErrorContext;
67756eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    return (ret);
67766eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
67776eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
67786eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
677933300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard * xmlRelaxNGNewDocParserCtxt:
678033300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard * @doc:  a preparsed document tree
678133300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard *
678233300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard * Create an XML RelaxNGs parser context for that document.
678333300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard * Note: since the process of compiling a RelaxNG schemas modifies the
678433300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard *       document, the @doc parameter is duplicated internally.
678533300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard *
678633300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard * Returns the parser context or NULL in case of error
678733300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard */
678833300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel VeillardxmlRelaxNGParserCtxtPtr
67894c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGNewDocParserCtxt(xmlDocPtr doc)
67904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
679133300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard    xmlRelaxNGParserCtxtPtr ret;
679233300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard    xmlDocPtr copy;
679333300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard
679433300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard    if (doc == NULL)
67954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
679633300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard    copy = xmlCopyDoc(doc, 1);
679733300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard    if (copy == NULL)
67984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
679933300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard
68004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    ret =
68014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        (xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
680233300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard    if (ret == NULL) {
68034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErrMemory(NULL, "building parser\n");
680433300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard        return (NULL);
680533300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard    }
680633300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard    memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
680733300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard    ret->document = copy;
68084259532303e96e089a185c6f55056cb7c4902d71Daniel Veillard    ret->freedoc = 1;
680933300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard    ret->userData = xmlGenericErrorContext;
681033300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard    return (ret);
681133300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard}
681233300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard
681333300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard/**
68146eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGFreeParserCtxt:
68156eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  the schema parser context
68166eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
68176eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Free the resources associated to the schema parser context
68186eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
68196eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardvoid
68204c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGFreeParserCtxt(xmlRelaxNGParserCtxtPtr ctxt)
68214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
68226eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ctxt == NULL)
68234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
68246eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ctxt->URL != NULL)
68254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(ctxt->URL);
68266eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ctxt->doc != NULL)
68274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeDocument(ctxt->doc);
682876fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    if (ctxt->interleaves != NULL)
682976fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard        xmlHashFree(ctxt->interleaves, NULL);
6830d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    if (ctxt->documents != NULL)
68314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeDocumentList(ctxt->documents);
68323ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard    if (ctxt->includes != NULL)
68334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeIncludeList(ctxt->includes);
6834d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    if (ctxt->docTab != NULL)
68354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(ctxt->docTab);
6836a9d912de798de5a88f3492e57e3330826a2f1247Daniel Veillard    if (ctxt->incTab != NULL)
68374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(ctxt->incTab);
6838419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard    if (ctxt->defTab != NULL) {
68394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        int i;
6840419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard
68414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        for (i = 0; i < ctxt->defNr; i++)
68424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGFreeDefine(ctxt->defTab[i]);
68434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(ctxt->defTab);
6844419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard    }
68454259532303e96e089a185c6f55056cb7c4902d71Daniel Veillard    if ((ctxt->document != NULL) && (ctxt->freedoc))
68464259532303e96e089a185c6f55056cb7c4902d71Daniel Veillard        xmlFreeDoc(ctxt->document);
68476eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlFree(ctxt);
68486eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
68496eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
68506eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
6851d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard * xmlRelaxNGNormExtSpace:
6852d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard * @value:  a value
6853d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard *
6854d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard * Removes the leading and ending spaces of the value
6855d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard * The string is modified "in situ"
6856d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard */
6857d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillardstatic void
68584c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGNormExtSpace(xmlChar * value)
68594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
6860d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    xmlChar *start = value;
6861d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    xmlChar *cur = value;
68624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
6863d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    if (value == NULL)
68644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
6865d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard
686676e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    while (IS_BLANK_CH(*cur))
68674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur++;
6868d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    if (cur == start) {
68694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        do {
687076e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack            while ((*cur != 0) && (!IS_BLANK_CH(*cur)))
68714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur++;
68724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (*cur == 0)
68734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return;
68744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            start = cur;
687576e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack            while (IS_BLANK_CH(*cur))
68764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur++;
68774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (*cur == 0) {
68784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                *start = 0;
68794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return;
68804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
68814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } while (1);
6882d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    } else {
68834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        do {
688476e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack            while ((*cur != 0) && (!IS_BLANK_CH(*cur)))
68854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                *start++ = *cur++;
68864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (*cur == 0) {
68874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                *start = 0;
68884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return;
68894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
68904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /* don't try to normalize the inner spaces */
689176e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack            while (IS_BLANK_CH(*cur))
68924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur++;
68934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (*cur == 0) {
68944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                *start = 0;
68954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return;
68964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
68974aede2e66b88ad782b506341c6ea40554456a8b4Daniel Veillard            *start++ = *cur++;
68984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } while (1);
6899d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    }
6900d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard}
6901d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard
6902d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard/**
69038de5c0bd79cceeca3d55d6dbf8f0248b7239e050Daniel Veillard * xmlRelaxNGCleanupAttributes:
6904d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard * @ctxt:  a Relax-NG parser context
6905d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard * @node:  a Relax-NG node
6906d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard *
6907d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard * Check all the attributes on the given node
6908d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard */
6909d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillardstatic void
69104c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGCleanupAttributes(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
69114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
6912d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    xmlAttrPtr cur, next;
6913d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard
6914d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    cur = node->properties;
6915d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    while (cur != NULL) {
69164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        next = cur->next;
69174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((cur->ns == NULL) ||
69184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (xmlStrEqual(cur->ns->href, xmlRelaxNGNs))) {
69194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (xmlStrEqual(cur->name, BAD_CAST "name")) {
69204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((!xmlStrEqual(node->name, BAD_CAST "element")) &&
69214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (!xmlStrEqual(node->name, BAD_CAST "attribute")) &&
69224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (!xmlStrEqual(node->name, BAD_CAST "ref")) &&
69234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (!xmlStrEqual(node->name, BAD_CAST "parentRef")) &&
69244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (!xmlStrEqual(node->name, BAD_CAST "param")) &&
69254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (!xmlStrEqual(node->name, BAD_CAST "define"))) {
69264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
69274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "Attribute %s is not allowed on %s\n",
69284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               cur->name, node->name);
69294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
69304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else if (xmlStrEqual(cur->name, BAD_CAST "type")) {
69314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((!xmlStrEqual(node->name, BAD_CAST "value")) &&
69324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (!xmlStrEqual(node->name, BAD_CAST "data"))) {
69334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
69344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "Attribute %s is not allowed on %s\n",
69354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               cur->name, node->name);
69364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
69374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else if (xmlStrEqual(cur->name, BAD_CAST "href")) {
69384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((!xmlStrEqual(node->name, BAD_CAST "externalRef")) &&
69394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (!xmlStrEqual(node->name, BAD_CAST "include"))) {
69404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
69414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "Attribute %s is not allowed on %s\n",
69424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               cur->name, node->name);
69434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
69444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else if (xmlStrEqual(cur->name, BAD_CAST "combine")) {
69454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((!xmlStrEqual(node->name, BAD_CAST "start")) &&
69464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (!xmlStrEqual(node->name, BAD_CAST "define"))) {
69474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
69484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "Attribute %s is not allowed on %s\n",
69494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               cur->name, node->name);
69504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
69514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else if (xmlStrEqual(cur->name, BAD_CAST "datatypeLibrary")) {
69524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlChar *val;
69534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlURIPtr uri;
69544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
69554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                val = xmlNodeListGetString(node->doc, cur->children, 1);
69564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (val != NULL) {
69574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (val[0] != 0) {
69584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        uri = xmlParseURI((const char *) val);
69594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if (uri == NULL) {
69604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlRngPErr(ctxt, node, XML_RNGP_INVALID_URI,
69614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                       "Attribute %s contains invalid URI %s\n",
69624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                       cur->name, val);
69634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        } else {
69644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            if (uri->scheme == NULL) {
69654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                xmlRngPErr(ctxt, node, XML_RNGP_URI_NOT_ABSOLUTE,
69664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                           "Attribute %s URI %s is not absolute\n",
69674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                           cur->name, val);
69684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            }
69694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            if (uri->fragment != NULL) {
69704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                xmlRngPErr(ctxt, node, XML_RNGP_URI_FRAGMENT,
69714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                           "Attribute %s URI %s has a fragment ID\n",
69724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                           cur->name, val);
69734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            }
69744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlFreeURI(uri);
69754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        }
69764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
69774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlFree(val);
69784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
69794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else if (!xmlStrEqual(cur->name, BAD_CAST "ns")) {
69804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_ATTRIBUTE,
69814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           "Unknown attribute %s on %s\n", cur->name,
69824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           node->name);
69834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
69844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
69854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = next;
6986d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard    }
6987d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard}
6988d2298791af5f9104e5cbd9f58c731f2116195bcdDaniel Veillard
69894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard/**
69904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * xmlRelaxNGCleanupTree:
69914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @ctxt:  a Relax-NG parser context
69924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * @root:  an xmlNodePtr subtree
69934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard *
69944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * Cleanup the subtree from unwanted nodes for parsing, resolve
69954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard * Include and externalRef lookups.
69964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard */
69974c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic void
69984c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGCleanupTree(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr root)
69994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
70004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    xmlNodePtr cur, delete;
70014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
70024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    delete = NULL;
70034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    cur = root;
70044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    while (cur != NULL) {
70054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (delete != NULL) {
70064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlUnlinkNode(delete);
70074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlFreeNode(delete);
70084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            delete = NULL;
70094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
70104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (cur->type == XML_ELEMENT_NODE) {
70114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /*
70124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * Simplification 4.1. Annotations
70134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             */
70144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((cur->ns == NULL) ||
70154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                (!xmlStrEqual(cur->ns->href, xmlRelaxNGNs))) {
70164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((cur->parent != NULL) &&
70174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (cur->parent->type == XML_ELEMENT_NODE) &&
70184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ((xmlStrEqual(cur->parent->name, BAD_CAST "name")) ||
70194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     (xmlStrEqual(cur->parent->name, BAD_CAST "value")) ||
70204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     (xmlStrEqual(cur->parent->name, BAD_CAST "param")))) {
70214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRngPErr(ctxt, cur, XML_RNGP_FOREIGN_ELEMENT,
70224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               "element %s doesn't allow foreign elements\n",
70234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               cur->parent->name, NULL);
70244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
70254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                delete = cur;
70264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                goto skip_children;
70274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
70284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGCleanupAttributes(ctxt, cur);
70294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (xmlStrEqual(cur->name, BAD_CAST "externalRef")) {
70304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlChar *href, *ns, *base, *URL;
70314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGDocumentPtr docu;
70324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlNodePtr tmp;
70336dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard		    xmlURIPtr uri;
70344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
70354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ns = xmlGetProp(cur, BAD_CAST "ns");
70364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ns == NULL) {
70374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        tmp = cur->parent;
70384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        while ((tmp != NULL) &&
70394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               (tmp->type == XML_ELEMENT_NODE)) {
70404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            ns = xmlGetProp(tmp, BAD_CAST "ns");
70414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            if (ns != NULL)
70424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                break;
70434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            tmp = tmp->parent;
70444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        }
70454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
70464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    href = xmlGetProp(cur, BAD_CAST "href");
70474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (href == NULL) {
70484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRngPErr(ctxt, cur, XML_RNGP_MISSING_HREF,
70494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   "xmlRelaxNGParse: externalRef has no href attribute\n",
70504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   NULL, NULL);
7051f2e066ac2ab9991341699c7ee3b58793c3b5358bDaniel Veillard                        if (ns != NULL)
7052f2e066ac2ab9991341699c7ee3b58793c3b5358bDaniel Veillard                            xmlFree(ns);
70534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        delete = cur;
70544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        goto skip_children;
70554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
70566dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard		    uri = xmlParseURI((const char *) href);
70576dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard		    if (uri == NULL) {
70586dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard                        xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
70596dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard                                   "Incorrect URI for externalRef %s\n",
70606dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard                                   href, NULL);
7061f2e066ac2ab9991341699c7ee3b58793c3b5358bDaniel Veillard                        if (ns != NULL)
7062f2e066ac2ab9991341699c7ee3b58793c3b5358bDaniel Veillard                            xmlFree(ns);
70636dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard                        if (href != NULL)
70646dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard                            xmlFree(href);
70656dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard                        delete = cur;
70666dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard                        goto skip_children;
70676dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard		    }
70686dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard		    if (uri->fragment != NULL) {
70696dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard                        xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
70706dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard			       "Fragment forbidden in URI for externalRef %s\n",
70716dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard                                   href, NULL);
7072f2e066ac2ab9991341699c7ee3b58793c3b5358bDaniel Veillard                        if (ns != NULL)
7073f2e066ac2ab9991341699c7ee3b58793c3b5358bDaniel Veillard                            xmlFree(ns);
70746dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard		        xmlFreeURI(uri);
70756dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard                        if (href != NULL)
70766dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard                            xmlFree(href);
70776dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard                        delete = cur;
70786dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard                        goto skip_children;
70796dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard		    }
70806dc91962d072fd434fec4673e9e4f2201a99df86Daniel Veillard		    xmlFreeURI(uri);
70814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    base = xmlNodeGetBase(cur->doc, cur);
70824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    URL = xmlBuildURI(href, base);
70834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (URL == NULL) {
70844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
70854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   "Failed to compute URL for externalRef %s\n",
70864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   href, NULL);
7087f2e066ac2ab9991341699c7ee3b58793c3b5358bDaniel Veillard                        if (ns != NULL)
7088f2e066ac2ab9991341699c7ee3b58793c3b5358bDaniel Veillard                            xmlFree(ns);
70894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if (href != NULL)
70904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlFree(href);
70914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if (base != NULL)
70924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlFree(base);
70934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        delete = cur;
70944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        goto skip_children;
70954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
70964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (href != NULL)
70974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlFree(href);
70984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (base != NULL)
70994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlFree(base);
71004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    docu = xmlRelaxNGLoadExternalRef(ctxt, URL, ns);
71014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (docu == NULL) {
71024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRngPErr(ctxt, cur, XML_RNGP_EXTERNAL_REF_FAILURE,
71034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   "Failed to load externalRef %s\n", URL,
71044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   NULL);
7105f2e066ac2ab9991341699c7ee3b58793c3b5358bDaniel Veillard                        if (ns != NULL)
7106f2e066ac2ab9991341699c7ee3b58793c3b5358bDaniel Veillard                            xmlFree(ns);
71074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlFree(URL);
71084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        delete = cur;
71094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        goto skip_children;
71104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
71114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ns != NULL)
71124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlFree(ns);
71134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlFree(URL);
7114807daf826510d2d0597fdd10314e51b4d56c5e96Daniel Veillard                    cur->psvi = docu;
71154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else if (xmlStrEqual(cur->name, BAD_CAST "include")) {
71164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlChar *href, *ns, *base, *URL;
71174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGIncludePtr incl;
71184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlNodePtr tmp;
71194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
71204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    href = xmlGetProp(cur, BAD_CAST "href");
71214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (href == NULL) {
71224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRngPErr(ctxt, cur, XML_RNGP_MISSING_HREF,
71234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   "xmlRelaxNGParse: include has no href attribute\n",
71244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   NULL, NULL);
71254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        delete = cur;
71264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        goto skip_children;
71274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
71284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    base = xmlNodeGetBase(cur->doc, cur);
71294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    URL = xmlBuildURI(href, base);
71304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (URL == NULL) {
71314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
71324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   "Failed to compute URL for include %s\n",
71334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   href, NULL);
71344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if (href != NULL)
71354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlFree(href);
71364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if (base != NULL)
71374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlFree(base);
71384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        delete = cur;
71394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        goto skip_children;
71404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
71414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (href != NULL)
71424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlFree(href);
71434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (base != NULL)
71444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlFree(base);
71454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ns = xmlGetProp(cur, BAD_CAST "ns");
71464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ns == NULL) {
71474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        tmp = cur->parent;
71484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        while ((tmp != NULL) &&
71494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               (tmp->type == XML_ELEMENT_NODE)) {
71504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            ns = xmlGetProp(tmp, BAD_CAST "ns");
71514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            if (ns != NULL)
71524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                break;
71534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            tmp = tmp->parent;
71544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        }
71554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
71564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    incl = xmlRelaxNGLoadInclude(ctxt, URL, cur, ns);
71574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ns != NULL)
71584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlFree(ns);
71594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (incl == NULL) {
71604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRngPErr(ctxt, cur, XML_RNGP_INCLUDE_FAILURE,
71614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   "Failed to load include %s\n", URL,
71624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   NULL);
71634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlFree(URL);
71644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        delete = cur;
71654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        goto skip_children;
71664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
71674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlFree(URL);
7168807daf826510d2d0597fdd10314e51b4d56c5e96Daniel Veillard                    cur->psvi = incl;
71694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else if ((xmlStrEqual(cur->name, BAD_CAST "element")) ||
71704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           (xmlStrEqual(cur->name, BAD_CAST "attribute")))
71714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                {
71724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlChar *name, *ns;
71734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlNodePtr text = NULL;
71744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
71754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    /*
71764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     * Simplification 4.8. name attribute of element
71774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     * and attribute elements
71784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     */
71794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    name = xmlGetProp(cur, BAD_CAST "name");
71804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (name != NULL) {
71814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if (cur->children == NULL) {
71824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            text =
71834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                xmlNewChild(cur, cur->ns, BAD_CAST "name",
71844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                            name);
71854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        } else {
71864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlNodePtr node;
71874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
718803a53c34db279cbe4a305d58969beb1f26ff3d19Daniel Veillard                            node = xmlNewDocNode(cur->doc, cur->ns,
718903a53c34db279cbe4a305d58969beb1f26ff3d19Daniel Veillard			                         BAD_CAST "name", NULL);
71904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            if (node != NULL) {
71914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                xmlAddPrevSibling(cur->children, node);
71924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                text = xmlNewText(name);
71934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                xmlAddChild(node, text);
71944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                text = node;
71954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            }
71964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        }
71974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if (text == NULL) {
71984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlRngPErr(ctxt, cur, XML_RNGP_CREATE_FAILURE,
71994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                       "Failed to create a name %s element\n",
72004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                       name, NULL);
72014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        }
72024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlUnsetProp(cur, BAD_CAST "name");
72034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlFree(name);
72044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ns = xmlGetProp(cur, BAD_CAST "ns");
72054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if (ns != NULL) {
72064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            if (text != NULL) {
72074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                xmlSetProp(text, BAD_CAST "ns", ns);
72084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                /* xmlUnsetProp(cur, BAD_CAST "ns"); */
72094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            }
72104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlFree(ns);
72114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        } else if (xmlStrEqual(cur->name,
72124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               BAD_CAST "attribute")) {
72134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlSetProp(text, BAD_CAST "ns", BAD_CAST "");
72144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        }
72154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
72164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else if ((xmlStrEqual(cur->name, BAD_CAST "name")) ||
72174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           (xmlStrEqual(cur->name, BAD_CAST "nsName")) ||
72184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           (xmlStrEqual(cur->name, BAD_CAST "value"))) {
72194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    /*
72204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     * Simplification 4.8. name attribute of element
72214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     * and attribute elements
72224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     */
72234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (xmlHasProp(cur, BAD_CAST "ns") == NULL) {
72244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlNodePtr node;
72254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlChar *ns = NULL;
72264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
72274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        node = cur->parent;
72284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        while ((node != NULL) &&
72294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               (node->type == XML_ELEMENT_NODE)) {
72304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            ns = xmlGetProp(node, BAD_CAST "ns");
72314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            if (ns != NULL) {
72324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                break;
72334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            }
72344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            node = node->parent;
72354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        }
72364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if (ns == NULL) {
72374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlSetProp(cur, BAD_CAST "ns", BAD_CAST "");
72384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        } else {
72394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlSetProp(cur, BAD_CAST "ns", ns);
72404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlFree(ns);
72414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        }
72424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
72434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (xmlStrEqual(cur->name, BAD_CAST "name")) {
72444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlChar *name, *local, *prefix;
72454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
72464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        /*
72474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         * Simplification: 4.10. QNames
72484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         */
72494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        name = xmlNodeGetContent(cur);
72504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if (name != NULL) {
72514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            local = xmlSplitQName2(name, &prefix);
72524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            if (local != NULL) {
72534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                xmlNsPtr ns;
72544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
72554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                ns = xmlSearchNs(cur->doc, cur, prefix);
72564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                if (ns == NULL) {
72574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                    xmlRngPErr(ctxt, cur,
72584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               XML_RNGP_PREFIX_UNDEFINED,
72594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               "xmlRelaxNGParse: no namespace for prefix %s\n",
72604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               prefix, NULL);
72614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                } else {
72624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                    xmlSetProp(cur, BAD_CAST "ns",
72634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                               ns->href);
72644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                    xmlNodeSetContent(cur, local);
72654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                }
72664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                xmlFree(local);
72674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                xmlFree(prefix);
72684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            }
72694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlFree(name);
72704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        }
72714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
72724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    /*
72734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     * 4.16
72744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     */
72754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (xmlStrEqual(cur->name, BAD_CAST "nsName")) {
72764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if (ctxt->flags & XML_RELAXNG_IN_NSEXCEPT) {
72774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlRngPErr(ctxt, cur,
72784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                       XML_RNGP_PAT_NSNAME_EXCEPT_NSNAME,
72794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                       "Found nsName/except//nsName forbidden construct\n",
72804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                       NULL, NULL);
72814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        }
72824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
72834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else if ((xmlStrEqual(cur->name, BAD_CAST "except")) &&
72844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           (cur != root)) {
72854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    int oldflags = ctxt->flags;
72864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
72874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    /*
72884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     * 4.16
72894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     */
72904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if ((cur->parent != NULL) &&
72914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        (xmlStrEqual
72924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         (cur->parent->name, BAD_CAST "anyName"))) {
72934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ctxt->flags |= XML_RELAXNG_IN_ANYEXCEPT;
72944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGCleanupTree(ctxt, cur);
72954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ctxt->flags = oldflags;
72964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        goto skip_children;
72974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    } else if ((cur->parent != NULL) &&
72984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               (xmlStrEqual
72994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                (cur->parent->name, BAD_CAST "nsName"))) {
73004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ctxt->flags |= XML_RELAXNG_IN_NSEXCEPT;
73014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGCleanupTree(ctxt, cur);
73024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ctxt->flags = oldflags;
73034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        goto skip_children;
73044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
73054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else if (xmlStrEqual(cur->name, BAD_CAST "anyName")) {
73064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    /*
73074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     * 4.16
73084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     */
73094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ctxt->flags & XML_RELAXNG_IN_ANYEXCEPT) {
73104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRngPErr(ctxt, cur,
73114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   XML_RNGP_PAT_ANYNAME_EXCEPT_ANYNAME,
73124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   "Found anyName/except//anyName forbidden construct\n",
73134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   NULL, NULL);
73144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    } else if (ctxt->flags & XML_RELAXNG_IN_NSEXCEPT) {
73154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRngPErr(ctxt, cur,
73164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   XML_RNGP_PAT_NSNAME_EXCEPT_ANYNAME,
73174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   "Found nsName/except//anyName forbidden construct\n",
73184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   NULL, NULL);
73194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
73204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
73214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                /*
7322acace88c4ab87fb2cdd811b0f1b5e73f3d2a1b0eJan Pokorný                 * This is not an else since "include" is transformed
73234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 * into a div
73244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 */
73254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (xmlStrEqual(cur->name, BAD_CAST "div")) {
73264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlChar *ns;
73274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlNodePtr child, ins, tmp;
73284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
73294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    /*
73304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     * implements rule 4.11
73314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     */
73324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
73334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ns = xmlGetProp(cur, BAD_CAST "ns");
73344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
73354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    child = cur->children;
73364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ins = cur;
73374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    while (child != NULL) {
73384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if (ns != NULL) {
73394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            if (!xmlHasProp(child, BAD_CAST "ns")) {
73404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                xmlSetProp(child, BAD_CAST "ns", ns);
73414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            }
73424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        }
73434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        tmp = child->next;
73444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlUnlinkNode(child);
73454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ins = xmlAddNextSibling(ins, child);
73464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        child = tmp;
73474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
73484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ns != NULL)
73494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlFree(ns);
73508eabb05d1ab45372f83f358bce11d9eda639cb89William M. Brack		    /*
735154c4b1aa719beb83d6fa34181d33b5496e26f4daGaurav Gupta		     * Since we are about to delete cur, if its nsDef is non-NULL we
73528eabb05d1ab45372f83f358bce11d9eda639cb89William M. Brack		     * need to preserve it (it contains the ns definitions for the
73538eabb05d1ab45372f83f358bce11d9eda639cb89William M. Brack		     * children we just moved).  We'll just stick it on to the end
73548eabb05d1ab45372f83f358bce11d9eda639cb89William M. Brack		     * of cur->parent's list, since it's never going to be re-serialized
73558eabb05d1ab45372f83f358bce11d9eda639cb89William M. Brack		     * (bug 143738).
73568eabb05d1ab45372f83f358bce11d9eda639cb89William M. Brack		     */
735754c4b1aa719beb83d6fa34181d33b5496e26f4daGaurav Gupta		    if ((cur->nsDef != NULL) && (cur->parent != NULL)) {
73588eabb05d1ab45372f83f358bce11d9eda639cb89William M. Brack			xmlNsPtr parDef = (xmlNsPtr)&cur->parent->nsDef;
73598eabb05d1ab45372f83f358bce11d9eda639cb89William M. Brack			while (parDef->next != NULL)
73608eabb05d1ab45372f83f358bce11d9eda639cb89William M. Brack			    parDef = parDef->next;
73618eabb05d1ab45372f83f358bce11d9eda639cb89William M. Brack			parDef->next = cur->nsDef;
73628eabb05d1ab45372f83f358bce11d9eda639cb89William M. Brack			cur->nsDef = NULL;
73638eabb05d1ab45372f83f358bce11d9eda639cb89William M. Brack		    }
73644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    delete = cur;
73654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    goto skip_children;
73664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
73674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
73684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
73694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        /*
73704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         * Simplification 4.2 whitespaces
73714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         */
73724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        else if ((cur->type == XML_TEXT_NODE) ||
73734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 (cur->type == XML_CDATA_SECTION_NODE)) {
73744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (IS_BLANK_NODE(cur)) {
737554c4b1aa719beb83d6fa34181d33b5496e26f4daGaurav Gupta                if ((cur->parent != NULL) &&
737654c4b1aa719beb83d6fa34181d33b5496e26f4daGaurav Gupta		    (cur->parent->type == XML_ELEMENT_NODE)) {
73774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if ((!xmlStrEqual(cur->parent->name, BAD_CAST "value"))
73784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        &&
73794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        (!xmlStrEqual
73804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         (cur->parent->name, BAD_CAST "param")))
73814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        delete = cur;
73824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else {
73834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    delete = cur;
73844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    goto skip_children;
73854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
73864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
73874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
73884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            delete = cur;
73894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            goto skip_children;
73904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
73914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
73924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        /*
73934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         * Skip to next node
73944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         */
73954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (cur->children != NULL) {
73964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((cur->children->type != XML_ENTITY_DECL) &&
73974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                (cur->children->type != XML_ENTITY_REF_NODE) &&
73984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                (cur->children->type != XML_ENTITY_NODE)) {
73994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur = cur->children;
74004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                continue;
74014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
74024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
74034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard      skip_children:
74044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (cur->next != NULL) {
74054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur = cur->next;
74064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            continue;
74074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
74086eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
74094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        do {
74104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur = cur->parent;
74114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur == NULL)
74124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
74134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur == root) {
74144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur = NULL;
74154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
74164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
74174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur->next != NULL) {
74184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur = cur->next;
74194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
74204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
74214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } while (cur != NULL);
74221564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    }
74231564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    if (delete != NULL) {
74244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlUnlinkNode(delete);
74254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFreeNode(delete);
74264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        delete = NULL;
74271564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    }
74281564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard}
74291564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
74301564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard/**
74311564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * xmlRelaxNGCleanupDoc:
74321564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * @ctxt:  a Relax-NG parser context
74331564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * @doc:  an xmldocPtr document pointer
74341564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard *
74351564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * Cleanup the document from unwanted nodes for parsing, resolve
74361564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * Include and externalRef lookups.
74371564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard *
74381564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * Returns the cleaned up document or NULL in case of error
74391564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard */
74401564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillardstatic xmlDocPtr
74414c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt, xmlDocPtr doc)
74424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
74431564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    xmlNodePtr root;
74441564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
74451564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    /*
74461564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard     * Extract the root
74471564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard     */
74486eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    root = xmlDocGetRootElement(doc);
74496eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (root == NULL) {
74504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, (xmlNodePtr) doc, XML_RNGP_EMPTY, "xmlRelaxNGParse: %s is empty\n",
74514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   ctxt->URL, NULL);
74526eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        return (NULL);
74536eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
74541564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    xmlRelaxNGCleanupTree(ctxt, root);
74554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (doc);
74561564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard}
74571564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
74581564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard/**
74591564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * xmlRelaxNGParse:
74601564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * @ctxt:  a Relax-NG parser context
74611564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard *
74621564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * parse a schema definition resource and build an internal
74631564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * XML Shema struture which can be used to validate instances.
74641564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard *
74651564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * Returns the internal XML RelaxNG structure built from the resource or
74661564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard *         NULL in case of error
74671564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard */
74681564e6e52ef9a944c41736c74edb475671ae798cDaniel VeillardxmlRelaxNGPtr
74691564e6e52ef9a944c41736c74edb475671ae798cDaniel VeillardxmlRelaxNGParse(xmlRelaxNGParserCtxtPtr ctxt)
74701564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard{
74711564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    xmlRelaxNGPtr ret = NULL;
74721564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    xmlDocPtr doc;
74731564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    xmlNodePtr root;
74741564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
74751564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    xmlRelaxNGInitTypes();
74761564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
74771564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    if (ctxt == NULL)
74781564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard        return (NULL);
74791564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
74801564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    /*
74811564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard     * First step is to parse the input document into an DOM/Infoset
74821564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard     */
74831564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    if (ctxt->URL != NULL) {
748487247e87408561aee625b2e800ea3c13211af897Daniel Veillard        doc = xmlReadFile((const char *) ctxt->URL,NULL,0);
74854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (doc == NULL) {
74864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
74874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "xmlRelaxNGParse: could not load %s\n", ctxt->URL,
74884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       NULL);
74894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
74904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
74911564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    } else if (ctxt->buffer != NULL) {
749287247e87408561aee625b2e800ea3c13211af897Daniel Veillard        doc = xmlReadMemory(ctxt->buffer, ctxt->size,NULL,NULL,0);
74934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (doc == NULL) {
74944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
74954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       "xmlRelaxNGParse: could not parse schemas\n", NULL,
74964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       NULL);
74974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (NULL);
74984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
74994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        doc->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
75004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
750133300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard    } else if (ctxt->document != NULL) {
750233300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard        doc = ctxt->document;
75031564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    } else {
75044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, NULL, XML_RNGP_EMPTY,
75054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   "xmlRelaxNGParse: nothing to parse\n", NULL, NULL);
75064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
75073ebc7d43f73d67c54cc0ec1d3ca0aa1e4115f519Daniel Veillard    }
75081564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    ctxt->document = doc;
75096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
75106eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    /*
75111564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard     * Some preprocessing of the document content
75126eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard     */
75131564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    doc = xmlRelaxNGCleanupDoc(ctxt, doc);
75141564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    if (doc == NULL) {
75154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFreeDoc(ctxt->document);
75164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->document = NULL;
75174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
75181564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    }
75191564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
752076fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    /*
75211564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard     * Then do the parsing for good
752276fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard     */
75231564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    root = xmlDocGetRootElement(doc);
75241564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    if (root == NULL) {
75254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngPErr(ctxt, (xmlNodePtr) doc,
75264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard	           XML_RNGP_EMPTY, "xmlRelaxNGParse: %s is empty\n",
7527700f987fff19f76638ff1b2c9847abf63f4b19e8William M. Brack                   (ctxt->URL ? ctxt->URL : BAD_CAST "schemas"), NULL);
7528f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard
75293f845a99b984778269784281ab79489b251209f5Daniel Veillard        xmlFreeDoc(ctxt->document);
75303f845a99b984778269784281ab79489b251209f5Daniel Veillard        ctxt->document = NULL;
75311564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard        return (NULL);
75321564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    }
75331564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    ret = xmlRelaxNGParseDocument(ctxt, root);
75341564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    if (ret == NULL) {
75353f845a99b984778269784281ab79489b251209f5Daniel Veillard        xmlFreeDoc(ctxt->document);
75363f845a99b984778269784281ab79489b251209f5Daniel Veillard        ctxt->document = NULL;
75374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
753876fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard    }
75396eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
75406eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    /*
7541fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     * Check the ref/defines links
7542fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     */
7543fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    /*
7544fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     * try to preprocess interleaves
7545fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     */
7546fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (ctxt->interleaves != NULL) {
75474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlHashScan(ctxt->interleaves,
75484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (xmlHashScanner) xmlRelaxNGComputeInterleaves, ctxt);
7549fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
7550fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
7551fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    /*
75526eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard     * if there was a parsing error return NULL
75536eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard     */
75546eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ctxt->nbErrors > 0) {
75554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFree(ret);
75564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->document = NULL;
75574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFreeDoc(doc);
75584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
75596eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
75606eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
75616eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    /*
756252b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard     * try to compile (parts of) the schemas
756352b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard     */
7564ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    if ((ret->topgrammar != NULL) && (ret->topgrammar->start != NULL)) {
7565ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard        if (ret->topgrammar->start->type != XML_RELAXNG_START) {
75664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDefinePtr def;
7567f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
75684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            def = xmlRelaxNGNewDefine(ctxt, NULL);
75694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (def != NULL) {
75704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                def->type = XML_RELAXNG_START;
75714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                def->content = ret->topgrammar->start;
75724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret->topgrammar->start = def;
75734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
75744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
75754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGTryCompile(ctxt, ret->topgrammar->start);
7576f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
757752b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard
757852b48c7a7bfb338f434d39f9fc3e54768e301575Daniel Veillard    /*
75796eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard     * Transfer the pointer for cleanup at the schema level.
75806eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard     */
75816eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ret->doc = doc;
7582d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    ctxt->document = NULL;
7583d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    ret->documents = ctxt->documents;
7584d41f4f488864d962a42239eb4526729a2dadc685Daniel Veillard    ctxt->documents = NULL;
75854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
7586e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    ret->includes = ctxt->includes;
7587e2a5a08b0f09bac1d60b49875dced3c636060a88Daniel Veillard    ctxt->includes = NULL;
7588419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard    ret->defNr = ctxt->defNr;
7589419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard    ret->defTab = ctxt->defTab;
7590419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard    ctxt->defTab = NULL;
7591c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard    if (ctxt->idref == 1)
75924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret->idref = 1;
75936eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
75946eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    return (ret);
75956eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
75964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
75976eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
75986eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGSetParserErrors:
75996eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG validation context
76006eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @err:  the error callback
76016eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @warn:  the warning callback
76026eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctx:  contextual data for the callbacks
76036eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
76046eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Set the callback functions used to handle errors for a validation context
76056eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
76066eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardvoid
76076eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGSetParserErrors(xmlRelaxNGParserCtxtPtr ctxt,
76084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                          xmlRelaxNGValidityErrorFunc err,
76094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                          xmlRelaxNGValidityWarningFunc warn, void *ctx)
76104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
76116eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ctxt == NULL)
76124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
76136eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ctxt->error = err;
76146eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ctxt->warning = warn;
7615b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard    ctxt->serror = NULL;
76166eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ctxt->userData = ctx;
76176eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
7618409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard
7619409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard/**
7620409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard * xmlRelaxNGGetParserErrors:
7621409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard * @ctxt:  a Relax-NG validation context
7622409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard * @err:  the error callback result
7623409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard * @warn:  the warning callback result
7624409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard * @ctx:  contextual data for the callbacks result
7625409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard *
7626409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard * Get the callback information used to handle errors for a validation context
7627409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard *
7628409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard * Returns -1 in case of failure, 0 otherwise.
7629409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard */
7630409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillardint
7631409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel VeillardxmlRelaxNGGetParserErrors(xmlRelaxNGParserCtxtPtr ctxt,
76324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                          xmlRelaxNGValidityErrorFunc * err,
76334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                          xmlRelaxNGValidityWarningFunc * warn, void **ctx)
76344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
7635409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard    if (ctxt == NULL)
76364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
76374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (err != NULL)
76384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        *err = ctxt->error;
76394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (warn != NULL)
76404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        *warn = ctxt->warning;
76414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (ctx != NULL)
76424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        *ctx = ctxt->userData;
76434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (0);
7644409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard}
7645409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard
7646b2f8f1de7a02900f3e62a8170618ac35bd189269Daniel Veillard/**
7647b2f8f1de7a02900f3e62a8170618ac35bd189269Daniel Veillard * xmlRelaxNGSetParserStructuredErrors:
7648b2f8f1de7a02900f3e62a8170618ac35bd189269Daniel Veillard * @ctxt:  a Relax-NG parser context
7649b2f8f1de7a02900f3e62a8170618ac35bd189269Daniel Veillard * @serror:  the error callback
7650b2f8f1de7a02900f3e62a8170618ac35bd189269Daniel Veillard * @ctx:  contextual data for the callbacks
7651b2f8f1de7a02900f3e62a8170618ac35bd189269Daniel Veillard *
7652b2f8f1de7a02900f3e62a8170618ac35bd189269Daniel Veillard * Set the callback functions used to handle errors for a parsing context
7653b2f8f1de7a02900f3e62a8170618ac35bd189269Daniel Veillard */
7654a930fbec6bac9b0f702af56572639c9a16438ce2Kasimier T. Buchcikvoid
7655b2f8f1de7a02900f3e62a8170618ac35bd189269Daniel VeillardxmlRelaxNGSetParserStructuredErrors(xmlRelaxNGParserCtxtPtr ctxt,
7656a930fbec6bac9b0f702af56572639c9a16438ce2Kasimier T. Buchcik				    xmlStructuredErrorFunc serror,
7657a930fbec6bac9b0f702af56572639c9a16438ce2Kasimier T. Buchcik				    void *ctx)
7658a930fbec6bac9b0f702af56572639c9a16438ce2Kasimier T. Buchcik{
7659a930fbec6bac9b0f702af56572639c9a16438ce2Kasimier T. Buchcik    if (ctxt == NULL)
7660a930fbec6bac9b0f702af56572639c9a16438ce2Kasimier T. Buchcik        return;
7661a930fbec6bac9b0f702af56572639c9a16438ce2Kasimier T. Buchcik    ctxt->serror = serror;
7662a930fbec6bac9b0f702af56572639c9a16438ce2Kasimier T. Buchcik    ctxt->error = NULL;
7663a930fbec6bac9b0f702af56572639c9a16438ce2Kasimier T. Buchcik    ctxt->warning = NULL;
7664a930fbec6bac9b0f702af56572639c9a16438ce2Kasimier T. Buchcik    ctxt->userData = ctx;
7665a930fbec6bac9b0f702af56572639c9a16438ce2Kasimier T. Buchcik}
7666a930fbec6bac9b0f702af56572639c9a16438ce2Kasimier T. Buchcik
7667a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#ifdef LIBXML_OUTPUT_ENABLED
76684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
76696eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/************************************************************************
7670f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
7671f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *			Dump back a compiled form			*
7672f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
76736eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard ************************************************************************/
76744c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic void xmlRelaxNGDumpDefine(FILE * output,
76754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                 xmlRelaxNGDefinePtr define);
76766eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
76776eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
76786eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGDumpDefines:
76796eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @output:  the file output
76806eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @defines:  a list of define structures
76816eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
76826eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Dump a RelaxNG structure back
76836eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
76846eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic void
76854c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGDumpDefines(FILE * output, xmlRelaxNGDefinePtr defines)
76864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
76876eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    while (defines != NULL) {
76884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGDumpDefine(output, defines);
76894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        defines = defines->next;
76906eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
76916eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
76926eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
76936eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
76946eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGDumpDefine:
76956eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @output:  the file output
76966eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @define:  a define structure
76976eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
76986eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Dump a RelaxNG structure back
76996eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
77006eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic void
77014c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGDumpDefine(FILE * output, xmlRelaxNGDefinePtr define)
77024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
77036eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (define == NULL)
77044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
77054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    switch (define->type) {
77066eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        case XML_RELAXNG_EMPTY:
77074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "<empty/>\n");
77084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
77096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        case XML_RELAXNG_NOT_ALLOWED:
77104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "<notAllowed/>\n");
77114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
77126eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        case XML_RELAXNG_TEXT:
77134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "<text/>\n");
77144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
77156eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        case XML_RELAXNG_ELEMENT:
77164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "<element>\n");
77174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (define->name != NULL) {
77184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                fprintf(output, "<name");
77194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (define->ns != NULL)
77204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    fprintf(output, " ns=\"%s\"", define->ns);
77214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                fprintf(output, ">%s</name>\n", define->name);
77224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
77234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpDefines(output, define->attrs);
77244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpDefines(output, define->content);
77254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "</element>\n");
77264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
77276eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        case XML_RELAXNG_LIST:
77284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "<list>\n");
77294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpDefines(output, define->content);
77304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "</list>\n");
77314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
77326eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        case XML_RELAXNG_ONEORMORE:
77334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "<oneOrMore>\n");
77344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpDefines(output, define->content);
77354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "</oneOrMore>\n");
77364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
7737fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_ZEROORMORE:
77384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "<zeroOrMore>\n");
77394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpDefines(output, define->content);
77404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "</zeroOrMore>\n");
77414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
77426eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        case XML_RELAXNG_CHOICE:
77434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "<choice>\n");
77444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpDefines(output, define->content);
77454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "</choice>\n");
77464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
77476eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        case XML_RELAXNG_GROUP:
77484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "<group>\n");
77494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpDefines(output, define->content);
77504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "</group>\n");
77514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
77526eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        case XML_RELAXNG_INTERLEAVE:
77534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "<interleave>\n");
77544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpDefines(output, define->content);
77554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "</interleave>\n");
77564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
77574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_OPTIONAL:
77584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "<optional>\n");
77594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpDefines(output, define->content);
77604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "</optional>\n");
77614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
77626eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        case XML_RELAXNG_ATTRIBUTE:
77634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "<attribute>\n");
77644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpDefines(output, define->content);
77654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "</attribute>\n");
77664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
77676eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        case XML_RELAXNG_DEF:
77684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "<define");
77694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (define->name != NULL)
77704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                fprintf(output, " name=\"%s\"", define->name);
77714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, ">\n");
77724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpDefines(output, define->content);
77734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "</define>\n");
77744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
77756eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        case XML_RELAXNG_REF:
77764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "<ref");
77774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (define->name != NULL)
77784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                fprintf(output, " name=\"%s\"", define->name);
77794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, ">\n");
77804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpDefines(output, define->content);
77814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "</ref>\n");
77824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
7783419a7688d01dbd4f4234da6bcc57688ae2bb7a4cDaniel Veillard        case XML_RELAXNG_PARENTREF:
77844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "<parentRef");
77854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (define->name != NULL)
77864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                fprintf(output, " name=\"%s\"", define->name);
77874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, ">\n");
77884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpDefines(output, define->content);
77894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "</parentRef>\n");
77904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
77914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_EXTERNALREF:
77924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "<externalRef>");
77934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpDefines(output, define->content);
77944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, "</externalRef>\n");
77954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
7796e431a27d45a5e1709d56ba6ff3352d47cffd316fDaniel Veillard        case XML_RELAXNG_DATATYPE:
77976eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        case XML_RELAXNG_VALUE:
77984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            TODO break;
77994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_START:
78004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_EXCEPT:
78014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_PARAM:
78024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            TODO break;
78034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_NOOP:
78044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpDefines(output, define->content);
78054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
78066eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
78076eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
78084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
78096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
78106eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGDumpGrammar:
78116eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @output:  the file output
78126eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @grammar:  a grammar structure
7813f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * @top:  is this a top grammar
78146eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
78156eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Dump a RelaxNG structure back
78166eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
78176eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic void
78186eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGDumpGrammar(FILE * output, xmlRelaxNGGrammarPtr grammar, int top)
78196eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard{
78206eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (grammar == NULL)
78214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
78224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
78236eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    fprintf(output, "<grammar");
78246eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (top)
78254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(output, " xmlns=\"http://relaxng.org/ns/structure/1.0\"");
78264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    switch (grammar->combine) {
78274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_COMBINE_UNDEFINED:
78284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
78294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_COMBINE_CHOICE:
78304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, " combine=\"choice\"");
78314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
78324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_COMBINE_INTERLEAVE:
78334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, " combine=\"interleave\"");
78344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
78354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        default:
78364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            fprintf(output, " <!-- invalid combine value -->");
78376eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
78386eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    fprintf(output, ">\n");
78396eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (grammar->start == NULL) {
78404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(output, " <!-- grammar had no start -->");
78416eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    } else {
78424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(output, "<start>\n");
78434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGDumpDefine(output, grammar->start);
78444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(output, "</start>\n");
78456eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
78466eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    /* TODO ? Dump the defines ? */
78476eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    fprintf(output, "</grammar>\n");
78486eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
78496eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
78506eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
78516eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGDump:
78526eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @output:  the file output
78536eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @schema:  a schema structure
78546eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
78556eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Dump a RelaxNG structure back
78566eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
78576eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardvoid
78586eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGDump(FILE * output, xmlRelaxNGPtr schema)
78596eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard{
7860ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard    if (output == NULL)
7861ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard        return;
78626eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (schema == NULL) {
78634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(output, "RelaxNG empty or failed to compile\n");
78644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
78656eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
78666eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    fprintf(output, "RelaxNG: ");
78676eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (schema->doc == NULL) {
78684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(output, "no document\n");
78696eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    } else if (schema->doc->URL != NULL) {
78704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(output, "%s\n", schema->doc->URL);
78716eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    } else {
78724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(output, "\n");
78736eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
78746eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (schema->topgrammar == NULL) {
78754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(output, "RelaxNG has no top grammar\n");
78764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
78776eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
78786eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGDumpGrammar(output, schema->topgrammar, 1);
78796eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
78806eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
7881febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard/**
7882febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard * xmlRelaxNGDumpTree:
7883febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard * @output:  the file output
7884febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard * @schema:  a schema structure
7885febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard *
7886febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard * Dump the transformed RelaxNG tree.
7887febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard */
7888febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillardvoid
7889febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel VeillardxmlRelaxNGDumpTree(FILE * output, xmlRelaxNGPtr schema)
7890febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard{
7891ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard    if (output == NULL)
7892ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard        return;
7893febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard    if (schema == NULL) {
78944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(output, "RelaxNG empty or failed to compile\n");
78954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
7896febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard    }
7897febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard    if (schema->doc == NULL) {
78984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(output, "no document\n");
7899febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard    } else {
79004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlDocDump(output, schema->doc);
7901febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard    }
7902febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard}
7903a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#endif /* LIBXML_OUTPUT_ENABLED */
7904febcca40d43b41df4fb202d6c96104c5aae6c68dDaniel Veillard
79056eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/************************************************************************
7906f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
7907f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *		Validation of compiled content				*
7908f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
79096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard ************************************************************************/
79104c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic int xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,
79114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                        xmlRelaxNGDefinePtr define);
7912c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
7913c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard/**
7914c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard * xmlRelaxNGValidateCompiledCallback:
7915c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard * @exec:  the regular expression instance
7916c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard * @token:  the token which matched
7917c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard * @transdata:  callback data, the define for the subelement if available
7918c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard @ @inputdata:  callback data, the Relax NG validation context
7919c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard *
7920c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard * Handle the callback and if needed validate the element children.
7921c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard */
79224c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic void
7923c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel VeillardxmlRelaxNGValidateCompiledCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
79244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   const xmlChar * token,
79254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   void *transdata, void *inputdata)
79264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
7927c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    xmlRelaxNGValidCtxtPtr ctxt = (xmlRelaxNGValidCtxtPtr) inputdata;
7928c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    xmlRelaxNGDefinePtr define = (xmlRelaxNGDefinePtr) transdata;
7929c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    int ret;
7930c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
7931c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard#ifdef DEBUG_COMPILE
7932c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    xmlGenericError(xmlGenericErrorContext,
79334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    "Compiled callback for: '%s'\n", token);
7934c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard#endif
7935c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    if (ctxt == NULL) {
79364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(stderr, "callback on %s missing context\n", token);
79374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
7938c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    }
7939c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    if (define == NULL) {
7940c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        if (token[0] == '#')
79414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return;
79424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(stderr, "callback on %s missing define\n", token);
79434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
79444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
79454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
7946c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    }
7947c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    if ((ctxt == NULL) || (define == NULL)) {
79484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(stderr, "callback on %s missing info\n", token);
79494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
79504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
79514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
7952c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    } else if (define->type != XML_RELAXNG_ELEMENT) {
79534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(stderr, "callback on %s define is not element\n", token);
79544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->errNo == XML_RELAXNG_OK)
79554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
79564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
7957c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    }
7958c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    ret = xmlRelaxNGValidateDefinition(ctxt, define);
7959c1ffa0ab97d0724acfc947e20873959da72b1b5dDaniel Veillard    if (ret != 0)
7960c1ffa0ab97d0724acfc947e20873959da72b1b5dDaniel Veillard        ctxt->perr = ret;
7961c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard}
7962c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
7963c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard/**
7964c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard * xmlRelaxNGValidateCompiledContent:
7965c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard * @ctxt:  the RelaxNG validation context
7966c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard * @regexp:  the regular expression as compiled
7967c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard * @content:  list of children to test against the regexp
7968c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard *
7969c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard * Validate the content model of an element or start using the regexp
7970c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard *
7971c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard * Returns 0 in case of success, -1 in case of error.
7972c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard */
7973c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillardstatic int
7974c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel VeillardxmlRelaxNGValidateCompiledContent(xmlRelaxNGValidCtxtPtr ctxt,
79754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                  xmlRegexpPtr regexp, xmlNodePtr content)
79764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
7977c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    xmlRegExecCtxtPtr exec;
7978c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    xmlNodePtr cur;
7979621636042b200e70c410f3112e89bc0f8b6203c0Daniel Veillard    int ret = 0;
798014b5643947845df089376106517c4f7ba061e4b0Daniel Veillard    int oldperr;
7981c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
7982c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    if ((ctxt == NULL) || (regexp == NULL))
79834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
798414b5643947845df089376106517c4f7ba061e4b0Daniel Veillard    oldperr = ctxt->perr;
79854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    exec = xmlRegNewExecCtxt(regexp,
7986c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                             xmlRelaxNGValidateCompiledCallback, ctxt);
7987c1ffa0ab97d0724acfc947e20873959da72b1b5dDaniel Veillard    ctxt->perr = 0;
7988c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    cur = content;
7989c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    while (cur != NULL) {
7990c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        ctxt->state->seq = cur;
79914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        switch (cur->type) {
79924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            case XML_TEXT_NODE:
79934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            case XML_CDATA_SECTION_NODE:
79944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (xmlIsBlankNode(cur))
79954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    break;
79964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = xmlRegExecPushString(exec, BAD_CAST "#text", ctxt);
79974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ret < 0) {
79984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    VALID_ERR2(XML_RELAXNG_ERR_TEXTWRONG,
79994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               cur->parent->name);
80004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
80014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
80024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            case XML_ELEMENT_NODE:
80034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (cur->ns != NULL) {
80044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret = xmlRegExecPushString2(exec, cur->name,
80054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                cur->ns->href, ctxt);
80064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else {
80074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret = xmlRegExecPushString(exec, cur->name, ctxt);
80084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
80094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ret < 0) {
80104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    VALID_ERR2(XML_RELAXNG_ERR_ELEMWRONG, cur->name);
80114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
80124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
80134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            default:
80144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
80154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
80164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ret < 0)
80174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
80184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        /*
80194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         * Switch to next element
80204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         */
80214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = cur->next;
8022c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    }
8023c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    ret = xmlRegExecPushString(exec, NULL, NULL);
8024c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    if (ret == 1) {
8025c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        ret = 0;
80264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state->seq = NULL;
8027c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    } else if (ret == 0) {
8028c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        /*
80294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         * TODO: get some of the names needed to exit the current state of exec
80304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         */
80314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        VALID_ERR2(XML_RELAXNG_ERR_NOELEM, BAD_CAST "");
80324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = -1;
80334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
80344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpValidError(ctxt);
8035c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    } else {
8036c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        ret = -1;
8037c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    }
8038c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    xmlRegFreeExecCtxt(exec);
8039c1ffa0ab97d0724acfc947e20873959da72b1b5dDaniel Veillard    /*
8040c1ffa0ab97d0724acfc947e20873959da72b1b5dDaniel Veillard     * There might be content model errors outside of the pure
8041c1ffa0ab97d0724acfc947e20873959da72b1b5dDaniel Veillard     * regexp validation, e.g. for attribute values.
8042c1ffa0ab97d0724acfc947e20873959da72b1b5dDaniel Veillard     */
8043c1ffa0ab97d0724acfc947e20873959da72b1b5dDaniel Veillard    if ((ret == 0) && (ctxt->perr != 0)) {
8044c1ffa0ab97d0724acfc947e20873959da72b1b5dDaniel Veillard        ret = ctxt->perr;
8045c1ffa0ab97d0724acfc947e20873959da72b1b5dDaniel Veillard    }
8046c1ffa0ab97d0724acfc947e20873959da72b1b5dDaniel Veillard    ctxt->perr = oldperr;
80474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
8048c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard}
8049c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
8050c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard/************************************************************************
8051f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
8052f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *		Progressive validation of when possible			*
8053f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
8054c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard ************************************************************************/
80554c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic int xmlRelaxNGValidateAttributeList(xmlRelaxNGValidCtxtPtr ctxt,
80564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                           xmlRelaxNGDefinePtr defines);
80574c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic int xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt,
8058272693c7e127a43dbcd5bc39c1cec4bfcdabcd2aWilliam M. Brack                                        int dolog);
80591ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillardstatic void xmlRelaxNGLogBestError(xmlRelaxNGValidCtxtPtr ctxt);
8060f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
8061f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard/**
8062f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * xmlRelaxNGElemPush:
8063f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * @ctxt:  the validation context
8064f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * @exec:  the regexp runtime for the new content model
8065f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard *
8066f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * Push a new regexp for the current node content model on the stack
8067f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard *
8068f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * Returns 0 in case of success and -1 in case of error.
8069f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard */
8070f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillardstatic int
80714c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGElemPush(xmlRelaxNGValidCtxtPtr ctxt, xmlRegExecCtxtPtr exec)
80724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
8073f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (ctxt->elemTab == NULL) {
80744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->elemMax = 10;
80754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->elemTab = (xmlRegExecCtxtPtr *) xmlMalloc(ctxt->elemMax *
80764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                        sizeof
80774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                        (xmlRegExecCtxtPtr));
8078f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        if (ctxt->elemTab == NULL) {
80794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngVErrMemory(ctxt, "validating\n");
80804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (-1);
80814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
8082f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
8083f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (ctxt->elemNr >= ctxt->elemMax) {
80844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->elemMax *= 2;
8085f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        ctxt->elemTab = (xmlRegExecCtxtPtr *) xmlRealloc(ctxt->elemTab,
80864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                         ctxt->elemMax *
80874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                         sizeof
80884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                         (xmlRegExecCtxtPtr));
8089f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        if (ctxt->elemTab == NULL) {
80904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRngVErrMemory(ctxt, "validating\n");
80914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (-1);
80924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
8093f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
8094f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    ctxt->elemTab[ctxt->elemNr++] = exec;
8095f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    ctxt->elem = exec;
80964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (0);
8097f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard}
8098f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
8099f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard/**
8100f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * xmlRelaxNGElemPop:
8101f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * @ctxt:  the validation context
8102f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard *
8103f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * Pop the regexp of the current node content model from the stack
8104f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard *
8105f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * Returns the exec or NULL if empty
8106f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard */
8107f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillardstatic xmlRegExecCtxtPtr
81084c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGElemPop(xmlRelaxNGValidCtxtPtr ctxt)
81094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
8110f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    xmlRegExecCtxtPtr ret;
8111f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
81124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (ctxt->elemNr <= 0)
81134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
8114f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    ctxt->elemNr--;
8115f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    ret = ctxt->elemTab[ctxt->elemNr];
8116f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    ctxt->elemTab[ctxt->elemNr] = NULL;
81174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (ctxt->elemNr > 0)
8118f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        ctxt->elem = ctxt->elemTab[ctxt->elemNr - 1];
8119f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    else
81204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->elem = NULL;
81214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
8122f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard}
8123f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
8124f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard/**
8125f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * xmlRelaxNGValidateProgressiveCallback:
8126f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * @exec:  the regular expression instance
8127f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * @token:  the token which matched
8128f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * @transdata:  callback data, the define for the subelement if available
8129f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard @ @inputdata:  callback data, the Relax NG validation context
8130f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard *
8131f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * Handle the callback and if needed validate the element children.
8132f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * some of the in/out informations are passed via the context in @inputdata.
8133f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard */
81344c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic void
81354c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGValidateProgressiveCallback(xmlRegExecCtxtPtr exec
81364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                      ATTRIBUTE_UNUSED,
81374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                      const xmlChar * token,
81384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                      void *transdata, void *inputdata)
81394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
8140f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    xmlRelaxNGValidCtxtPtr ctxt = (xmlRelaxNGValidCtxtPtr) inputdata;
8141f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    xmlRelaxNGDefinePtr define = (xmlRelaxNGDefinePtr) transdata;
8142ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    xmlRelaxNGValidStatePtr state, oldstate;
814314b5643947845df089376106517c4f7ba061e4b0Daniel Veillard    xmlNodePtr node;
8144c3ca5ba4057ef61012d687c5a48af5ed93e41494Daniel Veillard    int ret = 0, oldflags;
8145f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
8146f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#ifdef DEBUG_PROGRESSIVE
8147f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    xmlGenericError(xmlGenericErrorContext,
81484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    "Progressive callback for: '%s'\n", token);
8149f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#endif
8150f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (ctxt == NULL) {
81514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(stderr, "callback on %s missing context\n", token);
81524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
8153f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
815414b5643947845df089376106517c4f7ba061e4b0Daniel Veillard    node = ctxt->pnode;
8155f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    ctxt->pstate = 1;
8156f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (define == NULL) {
8157f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        if (token[0] == '#')
81584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return;
81594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(stderr, "callback on %s missing define\n", token);
81604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
81614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
81624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->pstate = -1;
81634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
8164f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
8165f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if ((ctxt == NULL) || (define == NULL)) {
81664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(stderr, "callback on %s missing info\n", token);
81674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
81684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
81694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->pstate = -1;
81704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
8171f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    } else if (define->type != XML_RELAXNG_ELEMENT) {
81724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        fprintf(stderr, "callback on %s define is not element\n", token);
81734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->errNo == XML_RELAXNG_OK)
81744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
81754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->pstate = -1;
81764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
8177f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
8178f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (node->type != XML_ELEMENT_NODE) {
81794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        VALID_ERR(XML_RELAXNG_ERR_NOTELEM);
81804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
81814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpValidError(ctxt);
81824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->pstate = -1;
81834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
8184f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
8185f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (define->contModel == NULL) {
8186f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        /*
81874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         * this node cannot be validated in a streamable fashion
81884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         */
8189f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#ifdef DEBUG_PROGRESSIVE
81904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
81914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        "Element '%s' validation is not streamable\n",
81924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        token);
8193f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#endif
81944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->pstate = 0;
81954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->pdef = define;
81964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
8197f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
8198f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    exec = xmlRegNewExecCtxt(define->contModel,
81994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                             xmlRelaxNGValidateProgressiveCallback, ctxt);
8200f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (exec == NULL) {
82014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->pstate = -1;
82024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
8203f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
8204f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    xmlRelaxNGElemPush(ctxt, exec);
8205f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
8206f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    /*
8207f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard     * Validate the attributes part of the content.
8208f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard     */
8209f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    state = xmlRelaxNGNewValidState(ctxt, node);
8210f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (state == NULL) {
82114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->pstate = -1;
82124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
8213f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
8214ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    oldstate = ctxt->state;
8215f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    ctxt->state = state;
8216f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (define->attrs != NULL) {
82174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = xmlRelaxNGValidateAttributeList(ctxt, define->attrs);
82184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ret != 0) {
82194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->pstate = -1;
82204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            VALID_ERR2(XML_RELAXNG_ERR_ATTRVALID, node->name);
82214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
8222f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
8223ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    if (ctxt->state != NULL) {
82244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state->seq = NULL;
82254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
82264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ret != 0) {
82274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->pstate = -1;
82284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
82294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeValidState(ctxt, ctxt->state);
8230ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    } else if (ctxt->states != NULL) {
82314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        int tmp = -1, i;
8232ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard
8233ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard        oldflags = ctxt->flags;
8234ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard
82354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        for (i = 0; i < ctxt->states->nbState; i++) {
82364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            state = ctxt->states->tabState[i];
82374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->state = state;
82384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->state->seq = NULL;
82394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
82404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
82414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp = 0;
82424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
82434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
82444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
82454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (tmp != 0) {
82464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /*
82474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * validation error, log the message for the "best" one
82484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             */
82494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->flags |= FLAGS_IGNORABLE;
82504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGLogBestError(ctxt);
82514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
82524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        for (i = 0; i < ctxt->states->nbState; i++) {
82534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGFreeValidState(ctxt, ctxt->states->tabState[i]);
82544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
82554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeStates(ctxt, ctxt->states);
82564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->states = NULL;
82574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((ret == 0) && (tmp == -1))
82584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->pstate = -1;
82594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->flags = oldflags;
8260f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
8261ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    if (ctxt->pstate == -1) {
82624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((ctxt->flags & FLAGS_IGNORABLE) == 0) {
82634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGDumpValidError(ctxt);
82644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
8265ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    }
8266ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    ctxt->state = oldstate;
8267f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard}
8268f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
8269f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard/**
8270f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * xmlRelaxNGValidatePushElement:
8271f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * @ctxt:  the validation context
8272f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * @doc:  a document instance
8273f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * @elem:  an element instance
8274f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard *
8275f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * Push a new element start on the RelaxNG validation stack.
8276f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard *
8277f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * returns 1 if no validation problem was found or 0 if validating the
8278f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard *         element requires a full node, and -1 in case of error.
8279f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard */
8280f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillardint
828133300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel VeillardxmlRelaxNGValidatePushElement(xmlRelaxNGValidCtxtPtr ctxt,
828233300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard                              xmlDocPtr doc ATTRIBUTE_UNUSED,
8283f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard                              xmlNodePtr elem)
8284f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard{
8285f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    int ret = 1;
8286f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
8287f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if ((ctxt == NULL) || (elem == NULL))
8288f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        return (-1);
8289f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
8290f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#ifdef DEBUG_PROGRESSIVE
8291f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    xmlGenericError(xmlGenericErrorContext, "PushElem %s\n", elem->name);
8292f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#endif
8293f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (ctxt->elem == 0) {
8294f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        xmlRelaxNGPtr schema;
8295f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        xmlRelaxNGGrammarPtr grammar;
8296f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        xmlRegExecCtxtPtr exec;
8297f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        xmlRelaxNGDefinePtr define;
8298f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
8299f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        schema = ctxt->schema;
8300f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        if (schema == NULL) {
8301f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard            VALID_ERR(XML_RELAXNG_ERR_NOGRAMMAR);
8302f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard            return (-1);
8303f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        }
8304f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        grammar = schema->topgrammar;
8305f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        if ((grammar == NULL) || (grammar->start == NULL)) {
8306f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard            VALID_ERR(XML_RELAXNG_ERR_NOGRAMMAR);
8307f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard            return (-1);
8308f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        }
8309f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        define = grammar->start;
8310f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        if (define->contModel == NULL) {
83114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->pdef = define;
8312f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard            return (0);
8313f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        }
8314f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        exec = xmlRegNewExecCtxt(define->contModel,
8315f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard                                 xmlRelaxNGValidateProgressiveCallback,
8316f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard                                 ctxt);
8317f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        if (exec == NULL) {
8318f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard            return (-1);
8319f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        }
8320f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        xmlRelaxNGElemPush(ctxt, exec);
8321f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
8322f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    ctxt->pnode = elem;
8323f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    ctxt->pstate = 0;
8324f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (elem->ns != NULL) {
8325f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        ret =
8326f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard            xmlRegExecPushString2(ctxt->elem, elem->name, elem->ns->href,
8327f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard                                  ctxt);
8328f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    } else {
8329f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        ret = xmlRegExecPushString(ctxt->elem, elem->name, ctxt);
8330f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
8331f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (ret < 0) {
8332f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        VALID_ERR2(XML_RELAXNG_ERR_ELEMWRONG, elem->name);
8333f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    } else {
8334f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        if (ctxt->pstate == 0)
83354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = 0;
8336f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        else if (ctxt->pstate < 0)
83374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = -1;
83384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        else
83394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = 1;
8340f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
8341f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#ifdef DEBUG_PROGRESSIVE
8342f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (ret < 0)
83434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlGenericError(xmlGenericErrorContext, "PushElem %s failed\n",
83444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        elem->name);
8345f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#endif
8346f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    return (ret);
8347f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard}
8348f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
8349f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard/**
8350f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * xmlRelaxNGValidatePushCData:
8351f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * @ctxt:  the RelaxNG validation context
8352f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * @data:  some character data read
8353fb27e2cd204ddb2cb0163b4b6418cc494889d279Michael Wood * @len:  the length of the data
8354f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard *
8355f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * check the CData parsed for validation in the current stack
8356f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard *
8357f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * returns 1 if no validation problem was found or -1 otherwise
8358f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard */
8359f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillardint
8360f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel VeillardxmlRelaxNGValidatePushCData(xmlRelaxNGValidCtxtPtr ctxt,
83614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            const xmlChar * data, int len ATTRIBUTE_UNUSED)
8362f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard{
8363f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    int ret = 1;
8364f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
8365f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if ((ctxt == NULL) || (ctxt->elem == NULL) || (data == NULL))
8366f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        return (-1);
8367f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
8368f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#ifdef DEBUG_PROGRESSIVE
8369f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    xmlGenericError(xmlGenericErrorContext, "CDATA %s %d\n", data, len);
8370f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#endif
8371f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
8372f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    while (*data != 0) {
837376e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack        if (!IS_BLANK_CH(*data))
8374f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard            break;
8375f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        data++;
8376f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
8377f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (*data == 0)
83784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (1);
8379f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
8380f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    ret = xmlRegExecPushString(ctxt->elem, BAD_CAST "#text", ctxt);
8381f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (ret < 0) {
838233300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard        VALID_ERR2(XML_RELAXNG_ERR_TEXTWRONG, BAD_CAST " TODO ");
8383f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#ifdef DEBUG_PROGRESSIVE
83844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlGenericError(xmlGenericErrorContext, "CDATA failed\n");
8385f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#endif
8386f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
83874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
8388f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
83894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (1);
8390f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard}
8391f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
8392f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard/**
8393f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * xmlRelaxNGValidatePopElement:
8394f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * @ctxt:  the RelaxNG validation context
8395f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * @doc:  a document instance
8396f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * @elem:  an element instance
8397f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard *
8398f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * Pop the element end from the RelaxNG validation stack.
8399f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard *
8400f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * returns 1 if no validation problem was found or 0 otherwise
8401f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard */
8402f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillardint
8403f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel VeillardxmlRelaxNGValidatePopElement(xmlRelaxNGValidCtxtPtr ctxt,
8404f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard                             xmlDocPtr doc ATTRIBUTE_UNUSED,
84054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                             xmlNodePtr elem)
84064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
8407f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    int ret;
8408f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    xmlRegExecCtxtPtr exec;
8409f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
84104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if ((ctxt == NULL) || (ctxt->elem == NULL) || (elem == NULL))
84114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
8412f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#ifdef DEBUG_PROGRESSIVE
8413f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    xmlGenericError(xmlGenericErrorContext, "PopElem %s\n", elem->name);
8414f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#endif
8415f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    /*
8416f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard     * verify that we reached a terminal state of the content model.
8417f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard     */
8418f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    exec = xmlRelaxNGElemPop(ctxt);
8419f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    ret = xmlRegExecPushString(exec, NULL, NULL);
8420f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (ret == 0) {
8421f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        /*
84224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         * TODO: get some of the names needed to exit the current state of exec
84234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         */
84244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        VALID_ERR2(XML_RELAXNG_ERR_NOELEM, BAD_CAST "");
84254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = -1;
8426f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    } else if (ret < 0) {
8427f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        ret = -1;
8428f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    } else {
8429f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        ret = 1;
8430f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
8431f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    xmlRegFreeExecCtxt(exec);
8432f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#ifdef DEBUG_PROGRESSIVE
8433f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (ret < 0)
84344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlGenericError(xmlGenericErrorContext, "PopElem %s failed\n",
84354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        elem->name);
8436f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#endif
84374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
8438f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard}
8439f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
8440f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard/**
8441f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * xmlRelaxNGValidateFullElement:
8442f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * @ctxt:  the validation context
8443f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * @doc:  a document instance
8444f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * @elem:  an element instance
8445f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard *
8446f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * Validate a full subtree when xmlRelaxNGValidatePushElement() returned
8447f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * 0 and the content of the node has been expanded.
8448f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard *
8449f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard * returns 1 if no validation problem was found or -1 in case of error.
8450f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard */
8451f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillardint
845233300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel VeillardxmlRelaxNGValidateFullElement(xmlRelaxNGValidCtxtPtr ctxt,
845333300b49f0801f5efe6363bd6b85b3bb5ace70fdDaniel Veillard                              xmlDocPtr doc ATTRIBUTE_UNUSED,
84544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                              xmlNodePtr elem)
84554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
8456f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    int ret;
8457f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    xmlRelaxNGValidStatePtr state;
8458f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
84594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if ((ctxt == NULL) || (ctxt->pdef == NULL) || (elem == NULL))
84604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
8461f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#ifdef DEBUG_PROGRESSIVE
8462f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    xmlGenericError(xmlGenericErrorContext, "FullElem %s\n", elem->name);
8463f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#endif
8464f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    state = xmlRelaxNGNewValidState(ctxt, elem->parent);
8465f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (state == NULL) {
84664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
8467f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
8468f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    state->seq = elem;
8469f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    ctxt->state = state;
8470f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    ctxt->errNo = XML_RELAXNG_OK;
8471f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    ret = xmlRelaxNGValidateDefinition(ctxt, ctxt->pdef);
84724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if ((ret != 0) || (ctxt->errNo != XML_RELAXNG_OK))
84734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = -1;
84744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    else
84754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = 1;
84769fcd462f271fb7bf49b6c7c6993cf42dcf879377Daniel Veillard    xmlRelaxNGFreeValidState(ctxt, ctxt->state);
8477f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    ctxt->state = NULL;
8478f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#ifdef DEBUG_PROGRESSIVE
8479f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (ret < 0)
84804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlGenericError(xmlGenericErrorContext, "FullElem %s failed\n",
84814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        elem->name);
8482f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard#endif
84834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
8484f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard}
8485f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
8486c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard/************************************************************************
8487f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
8488f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *		Generic interpreted validation implementation		*
8489f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
8490c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard ************************************************************************/
84914c0041471199f283c4e696526c73e2809da54e21Daniel Veillardstatic int xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
84924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                   xmlRelaxNGDefinePtr define);
84936eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
84946eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
84956eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGSkipIgnored:
84966eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a schema validation context
84976eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @node:  the top node.
84986eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
84996eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Skip ignorable nodes in that context
85006eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
85016eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns the new sibling or NULL in case of error.
85026eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
85036eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic xmlNodePtr
85046eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGSkipIgnored(xmlRelaxNGValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
85054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                      xmlNodePtr node)
85064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
85076eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    /*
85086eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard     * TODO complete and handle entities
85096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard     */
85106eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    while ((node != NULL) &&
85114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard           ((node->type == XML_COMMENT_NODE) ||
85124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (node->type == XML_PI_NODE) ||
85137217c86b81cdcf7e81ff7b1beb2a7fbae0f573ecWilliam M. Brack	    (node->type == XML_XINCLUDE_START) ||
85147217c86b81cdcf7e81ff7b1beb2a7fbae0f573ecWilliam M. Brack	    (node->type == XML_XINCLUDE_END) ||
85154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (((node->type == XML_TEXT_NODE) ||
85164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard              (node->type == XML_CDATA_SECTION_NODE)) &&
85174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             ((ctxt->flags & FLAGS_MIXED_CONTENT) ||
85184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard              (IS_BLANK_NODE(node)))))) {
85194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        node = node->next;
85206eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
85214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (node);
85226eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
85236eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
85246eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
8525edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard * xmlRelaxNGNormalize:
8526edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard * @ctxt:  a schema validation context
8527edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard * @str:  the string to normalize
8528edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard *
8529edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard * Implements the  normalizeWhiteSpace( s ) function from
8530edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard * section 6.2.9 of the spec
8531edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard *
8532edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard * Returns the new string or NULL in case of error.
8533edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard */
8534edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillardstatic xmlChar *
85354c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt, const xmlChar * str)
85364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
8537edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    xmlChar *ret, *p;
8538edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    const xmlChar *tmp;
8539edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    int len;
85404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
8541edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    if (str == NULL)
85424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
8543edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    tmp = str;
85444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    while (*tmp != 0)
85454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        tmp++;
8546edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    len = tmp - str;
8547edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard
85483c908dca479ed50dca24b8593bca90e40dbde6b8Daniel Veillard    ret = (xmlChar *) xmlMallocAtomic((len + 1) * sizeof(xmlChar));
8549edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    if (ret == NULL) {
85504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngVErrMemory(ctxt, "validating\n");
85514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (NULL);
8552edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    }
8553edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    p = ret;
855476e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    while (IS_BLANK_CH(*str))
85554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        str++;
8556edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    while (*str != 0) {
855776e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack        if (IS_BLANK_CH(*str)) {
855876e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack            while (IS_BLANK_CH(*str))
85594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                str++;
85604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (*str == 0)
85614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
85624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            *p++ = ' ';
85634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else
85644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            *p++ = *str++;
8565edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    }
8566edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    *p = 0;
85674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
8568edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard}
8569edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard
8570edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard/**
8571dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * xmlRelaxNGValidateDatatype:
8572dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @ctxt:  a Relax-NG validation context
8573dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @value:  the string value
8574dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * @type:  the datatype definition
8575c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard * @node:  the node
8576dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
8577dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Validate the given value against the dataype
8578dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard *
8579dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard * Returns 0 if the validation succeeded or an error code.
8580dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard */
8581dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillardstatic int
85824c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGValidateDatatype(xmlRelaxNGValidCtxtPtr ctxt,
85834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           const xmlChar * value,
85844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           xmlRelaxNGDefinePtr define, xmlNodePtr node)
85854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
85868bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    int ret, tmp;
8587dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    xmlRelaxNGTypeLibraryPtr lib;
85888bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    void *result = NULL;
85898bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    xmlRelaxNGDefinePtr cur;
8590dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
8591dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if ((define == NULL) || (define->data == NULL)) {
85924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
8593dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    }
8594dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    lib = (xmlRelaxNGTypeLibraryPtr) define->data;
85958bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    if (lib->check != NULL) {
85964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((define->attrs != NULL) &&
85974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (define->attrs->type == XML_RELAXNG_PARAM)) {
85984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret =
85994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                lib->check(lib->data, define->name, value, &result, node);
86004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
86014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = lib->check(lib->data, define->name, value, NULL, node);
86024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
86034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    } else
86044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = -1;
8605dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    if (ret < 0) {
86064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        VALID_ERR2(XML_RELAXNG_ERR_TYPE, define->name);
86074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((result != NULL) && (lib != NULL) && (lib->freef != NULL))
86084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            lib->freef(lib->data, result);
86094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
8610dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    } else if (ret == 1) {
86114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = 0;
8612c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard    } else if (ret == 2) {
86134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        VALID_ERR2P(XML_RELAXNG_ERR_DUPID, value);
8614dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    } else {
86154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        VALID_ERR3P(XML_RELAXNG_ERR_TYPEVAL, define->name, value);
86164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = -1;
8617dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard    }
8618fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    cur = define->attrs;
86198bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    while ((ret == 0) && (cur != NULL) && (cur->type == XML_RELAXNG_PARAM)) {
86204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (lib->facet != NULL) {
86214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp = lib->facet(lib->data, define->name, cur->name,
86224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                             cur->value, value, result);
86238bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard            if (tmp != 0)
86244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = -1;
86254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
86264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = cur->next;
86278bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    }
8628416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard    if ((ret == 0) && (define->content != NULL)) {
86294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        const xmlChar *oldvalue, *oldendvalue;
8630416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard
86314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        oldvalue = ctxt->state->value;
86324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        oldendvalue = ctxt->state->endvalue;
86334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state->value = (xmlChar *) value;
86344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state->endvalue = NULL;
86354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = xmlRelaxNGValidateValue(ctxt, define->content);
86364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state->value = (xmlChar *) oldvalue;
86374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state->endvalue = (xmlChar *) oldendvalue;
8638416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard    }
86398bc6cf9a80cdba7f060b5bcb20f82572270af727Daniel Veillard    if ((result != NULL) && (lib != NULL) && (lib->freef != NULL))
86404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        lib->freef(lib->data, result);
86414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
8642dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard}
8643dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard
8644dd1655c5798045a3580ca1187b8fdc4b25c31293Daniel Veillard/**
8645c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard * xmlRelaxNGNextValue:
8646c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard * @ctxt:  a Relax-NG validation context
8647c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard *
8648c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard * Skip to the next value when validating within a list
8649c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard *
8650c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard * Returns 0 if the operation succeeded or an error code.
8651c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard */
8652c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillardstatic int
86534c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGNextValue(xmlRelaxNGValidCtxtPtr ctxt)
86544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
8655c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    xmlChar *cur;
8656c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard
8657c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    cur = ctxt->state->value;
8658c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    if ((cur == NULL) || (ctxt->state->endvalue == NULL)) {
86594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state->value = NULL;
86604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state->endvalue = NULL;
86614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (0);
8662c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    }
86634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    while (*cur != 0)
86644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur++;
86654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    while ((cur != ctxt->state->endvalue) && (*cur == 0))
86664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur++;
8667c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    if (cur == ctxt->state->endvalue)
86684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state->value = NULL;
8669c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    else
86704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state->value = cur;
86714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (0);
8672c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard}
8673c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard
8674c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard/**
8675c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard * xmlRelaxNGValidateValueList:
8676c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard * @ctxt:  a Relax-NG validation context
8677c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard * @defines:  the list of definitions to verify
8678c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard *
8679c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard * Validate the given set of definitions for the current value
8680c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard *
8681c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard * Returns 0 if the validation succeeded or an error code.
8682c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard */
8683c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillardstatic int
86844c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGValidateValueList(xmlRelaxNGValidCtxtPtr ctxt,
86854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlRelaxNGDefinePtr defines)
86864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
8687c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    int ret = 0;
8688c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard
8689c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    while (defines != NULL) {
86904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = xmlRelaxNGValidateValue(ctxt, defines);
86914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ret != 0)
86924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
86934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        defines = defines->next;
8694c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard    }
86954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
8696c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard}
8697c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard
8698c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard/**
86996eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGValidateValue:
87006eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG validation context
87016eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @define:  the definition to verify
87026eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
87036eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Validate the given definition for the current value
87046eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
87056eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns 0 if the validation succeeded or an error code.
87066eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
87076eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic int
87084c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
87094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGDefinePtr define)
87104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
8711edc91928dc3b93041920e138167f65c09f6c4d3cDaniel Veillard    int ret = 0, oldflags;
87126eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlChar *value;
87136eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
87146eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    value = ctxt->state->value;
87156eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    switch (define->type) {
87164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_EMPTY:{
87174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((value != NULL) && (value[0] != 0)) {
87184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    int idx = 0;
87194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
872076e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack                    while (IS_BLANK_CH(value[idx]))
87214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        idx++;
87224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (value[idx] != 0)
87234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ret = -1;
87244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
87254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
87264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
87274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_TEXT:
87284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
87294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_VALUE:{
87304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (!xmlStrEqual(value, define->value)) {
87314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (define->name != NULL) {
87324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGTypeLibraryPtr lib;
87334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
87344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        lib = (xmlRelaxNGTypeLibraryPtr) define->data;
87354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if ((lib != NULL) && (lib->comp != NULL)) {
87364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            ret = lib->comp(lib->data, define->name,
87374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                            define->value, define->node,
87384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                            (void *) define->attrs,
87394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                            value, ctxt->state->node);
87404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        } else
87414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            ret = -1;
87424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if (ret < 0) {
87434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            VALID_ERR2(XML_RELAXNG_ERR_TYPECMP,
87444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                       define->name);
87454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            return (-1);
87464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        } else if (ret == 1) {
87474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            ret = 0;
87484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        } else {
87494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            ret = -1;
87504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        }
87514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    } else {
87524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlChar *nval, *nvalue;
87534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
87544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        /*
87554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         * TODO: trivial optimizations are possible by
87564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         * computing at compile-time
87574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         */
87584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        nval = xmlRelaxNGNormalize(ctxt, define->value);
87594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        nvalue = xmlRelaxNGNormalize(ctxt, value);
87604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
87614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if ((nval == NULL) || (nvalue == NULL) ||
87624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            (!xmlStrEqual(nval, nvalue)))
87634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            ret = -1;
87644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if (nval != NULL)
87654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlFree(nval);
87664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        if (nvalue != NULL)
87674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlFree(nvalue);
87684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
87694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
87704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ret == 0)
87714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGNextValue(ctxt);
87724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
87734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
87744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_DATATYPE:{
87754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = xmlRelaxNGValidateDatatype(ctxt, value, define,
87764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                 ctxt->state->seq);
87774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ret == 0)
87784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGNextValue(ctxt);
87794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
87804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
87814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
87824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_CHOICE:{
87834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGDefinePtr list = define->content;
87844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlChar *oldvalue;
87854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
87864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                oldflags = ctxt->flags;
87874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->flags |= FLAGS_IGNORABLE;
87884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
87894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                oldvalue = ctxt->state->value;
87904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (list != NULL) {
87914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret = xmlRelaxNGValidateValue(ctxt, list);
87924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ret == 0) {
87934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        break;
87944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
87954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ctxt->state->value = oldvalue;
87964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    list = list->next;
87974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
87984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->flags = oldflags;
87994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ret != 0) {
88004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
88014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGDumpValidError(ctxt);
88024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else {
88034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ctxt->errNr > 0)
88044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGPopErrors(ctxt, 0);
88054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
88064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
88074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
88084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_LIST:{
88094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGDefinePtr list = define->content;
88104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlChar *oldvalue, *oldend, *val, *cur;
88114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
8812416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard#ifdef DEBUG_LIST
88134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                int nb_values = 0;
8814416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard#endif
8815c6e997c9a8521f331b7d354b32cf7373f76cb548Daniel Veillard
88164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                oldvalue = ctxt->state->value;
88174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                oldend = ctxt->state->endvalue;
88184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
88194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                val = xmlStrdup(oldvalue);
88204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (val == NULL) {
88214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    val = xmlStrdup(BAD_CAST "");
88224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
88234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (val == NULL) {
88244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    VALID_ERR(XML_RELAXNG_ERR_NOSTATE);
88254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    return (-1);
88264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
88274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur = val;
88284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (*cur != 0) {
882976e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack                    if (IS_BLANK_CH(*cur)) {
88304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        *cur = 0;
88314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        cur++;
8832416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard#ifdef DEBUG_LIST
88334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        nb_values++;
8834416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard#endif
883576e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack                        while (IS_BLANK_CH(*cur))
88364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            *cur++ = 0;
88374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    } else
88384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        cur++;
88394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
8840416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard#ifdef DEBUG_LIST
88414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlGenericError(xmlGenericErrorContext,
88424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                "list value: '%s' found %d items\n",
88434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                oldvalue, nb_values);
88444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                nb_values = 0;
88454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard#endif
88464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state->endvalue = cur;
88474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur = val;
88484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while ((*cur == 0) && (cur != ctxt->state->endvalue))
88494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    cur++;
88504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
88514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state->value = cur;
88524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
88534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (list != NULL) {
88544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ctxt->state->value == ctxt->state->endvalue)
88554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ctxt->state->value = NULL;
88564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret = xmlRelaxNGValidateValue(ctxt, list);
88574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ret != 0) {
8858fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard#ifdef DEBUG_LIST
88594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlGenericError(xmlGenericErrorContext,
88604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                        "Failed to validate value: '%s' with %d rule\n",
88614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                        ctxt->state->value, nb_values);
8862fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard#endif
88634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        break;
88644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
8865fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard#ifdef DEBUG_LIST
88664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    nb_values++;
8867fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard#endif
88684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    list = list->next;
88694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
88704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
88714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((ret == 0) && (ctxt->state->value != NULL) &&
88724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (ctxt->state->value != ctxt->state->endvalue)) {
88734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    VALID_ERR2(XML_RELAXNG_ERR_LISTEXTRA,
88744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               ctxt->state->value);
88754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret = -1;
88764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
88774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlFree(val);
88784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state->value = oldvalue;
88794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state->endvalue = oldend;
88804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
88814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
8882fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_ONEORMORE:
88834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGValidateValueList(ctxt, define->content);
88844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret != 0) {
88854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
88864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
88874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /* no break on purpose */
88884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_ZEROORMORE:{
88894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlChar *cur, *temp;
88904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
88917dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                if ((ctxt->state->value == NULL) ||
88927dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                    (*ctxt->state->value == 0)) {
88937dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                    ret = 0;
88947dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                    break;
88957dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                }
88964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                oldflags = ctxt->flags;
88974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->flags |= FLAGS_IGNORABLE;
88984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur = ctxt->state->value;
88994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                temp = NULL;
89004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while ((cur != NULL) && (cur != ctxt->state->endvalue) &&
89014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       (temp != cur)) {
89024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    temp = cur;
89034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret =
89044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGValidateValueList(ctxt, define->content);
89054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ret != 0) {
89064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ctxt->state->value = temp;
89074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ret = 0;
89084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        break;
89094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
89104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    cur = ctxt->state->value;
89114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
89124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->flags = oldflags;
891314b5643947845df089376106517c4f7ba061e4b0Daniel Veillard		if (ctxt->errNr > 0)
891414b5643947845df089376106517c4f7ba061e4b0Daniel Veillard		    xmlRelaxNGPopErrors(ctxt, 0);
89154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
89164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
89177dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard        case XML_RELAXNG_OPTIONAL:{
89187dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                xmlChar *temp;
89197dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard
89207dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                if ((ctxt->state->value == NULL) ||
89217dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                    (*ctxt->state->value == 0)) {
89227dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                    ret = 0;
89237dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                    break;
89247dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                }
89257dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                oldflags = ctxt->flags;
89267dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                ctxt->flags |= FLAGS_IGNORABLE;
89277dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                temp = ctxt->state->value;
89287dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                ret = xmlRelaxNGValidateValue(ctxt, define->content);
89297dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                ctxt->flags = oldflags;
89307dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                if (ret != 0) {
89317dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                    ctxt->state->value = temp;
89327dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                    if (ctxt->errNr > 0)
89337dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                        xmlRelaxNGPopErrors(ctxt, 0);
89347dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                    ret = 0;
89357dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                    break;
89367dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                }
89377dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard		if (ctxt->errNr > 0)
89387dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard		    xmlRelaxNGPopErrors(ctxt, 0);
89397dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard                break;
89407dd0d916c6a92ca4a398b8bc56fb0d7f98df00b6Daniel Veillard            }
89414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_EXCEPT:{
89424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGDefinePtr list;
89434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
89444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                list = define->content;
89454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (list != NULL) {
89464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret = xmlRelaxNGValidateValue(ctxt, list);
89474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ret == 0) {
89484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ret = -1;
89494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        break;
89504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    } else
89514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ret = 0;
89524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    list = list->next;
89534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
89544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
89554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
8956fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_DEF:
89574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        case XML_RELAXNG_GROUP:{
89584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGDefinePtr list;
89594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
89604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                list = define->content;
89614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                while (list != NULL) {
89624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret = xmlRelaxNGValidateValue(ctxt, list);
89634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (ret != 0) {
89644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ret = -1;
89654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        break;
89664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    } else
89674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ret = 0;
89684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    list = list->next;
89694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
89704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
89714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
8972463a5479a825acf0df4501446d4dcd6b10f7e248Daniel Veillard        case XML_RELAXNG_REF:
8973463a5479a825acf0df4501446d4dcd6b10f7e248Daniel Veillard        case XML_RELAXNG_PARENTREF:
897425a1ce91346f9f72727afadc07f7e0f9873dcda4Daniel Veillard	    if (define->content == NULL) {
897581c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                VALID_ERR(XML_RELAXNG_ERR_NODEFINE);
897681c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                ret = -1;
897781c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard	    } else {
897881c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard                ret = xmlRelaxNGValidateValue(ctxt, define->content);
897981c51e174df3095c2b7bb590fc070165d7a6ac9eDaniel Veillard            }
89804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
89814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        default:
89824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            TODO ret = -1;
89836eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
89844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
89856eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
89866eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
89876eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
89886eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGValidateValueContent:
89896eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG validation context
89906eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @defines:  the list of definitions to verify
89916eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
89926eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Validate the given definitions for the current value
89936eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
89946eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns 0 if the validation succeeded or an error code.
89956eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
89966eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic int
89974c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGValidateValueContent(xmlRelaxNGValidCtxtPtr ctxt,
89984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                               xmlRelaxNGDefinePtr defines)
89994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
90006eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    int ret = 0;
90016eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
90026eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    while (defines != NULL) {
90034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = xmlRelaxNGValidateValue(ctxt, defines);
90044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ret != 0)
90054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
90064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        defines = defines->next;
90076eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
90084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
90096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
90106eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
90116eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
9012fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGAttributeMatch:
9013fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @ctxt:  a Relax-NG validation context
9014fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @define:  the definition to check
9015fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @prop:  the attribute
9016fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *
9017fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Check if the attribute matches the definition nameClass
9018fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *
9019fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Returns 1 if the attribute matches, 0 if no, or -1 in case of error
9020fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard */
9021fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillardstatic int
90224c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGAttributeMatch(xmlRelaxNGValidCtxtPtr ctxt,
90234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         xmlRelaxNGDefinePtr define, xmlAttrPtr prop)
90244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
9025fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    int ret;
9026fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
9027fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (define->name != NULL) {
90284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (!xmlStrEqual(define->name, prop->name))
90294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (0);
9030fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
9031fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (define->ns != NULL) {
90324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (define->ns[0] == 0) {
90334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (prop->ns != NULL)
90344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (0);
90354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
90364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((prop->ns == NULL) ||
90374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                (!xmlStrEqual(define->ns, prop->ns->href)))
90384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (0);
90394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
9040fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
9041fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (define->nameClass == NULL)
90424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (1);
9043fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    define = define->nameClass;
9044fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (define->type == XML_RELAXNG_EXCEPT) {
90454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGDefinePtr list;
90464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
90474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        list = define->content;
90484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        while (list != NULL) {
90494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGAttributeMatch(ctxt, list, prop);
90504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret == 1)
90514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (0);
90524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret < 0)
90534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (ret);
90544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            list = list->next;
90554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
90566473a41a49601da8355c4b407b99474ada170213Shaun McCance    } else if (define->type == XML_RELAXNG_CHOICE) {
90576473a41a49601da8355c4b407b99474ada170213Shaun McCance        xmlRelaxNGDefinePtr list;
90586473a41a49601da8355c4b407b99474ada170213Shaun McCance
90596473a41a49601da8355c4b407b99474ada170213Shaun McCance        list = define->nameClass;
90606473a41a49601da8355c4b407b99474ada170213Shaun McCance        while (list != NULL) {
90616473a41a49601da8355c4b407b99474ada170213Shaun McCance            ret = xmlRelaxNGAttributeMatch(ctxt, list, prop);
90626473a41a49601da8355c4b407b99474ada170213Shaun McCance            if (ret == 1)
90636473a41a49601da8355c4b407b99474ada170213Shaun McCance                return (1);
90646473a41a49601da8355c4b407b99474ada170213Shaun McCance            if (ret < 0)
90656473a41a49601da8355c4b407b99474ada170213Shaun McCance                return (ret);
90666473a41a49601da8355c4b407b99474ada170213Shaun McCance            list = list->next;
90676473a41a49601da8355c4b407b99474ada170213Shaun McCance        }
90686473a41a49601da8355c4b407b99474ada170213Shaun McCance        return (0);
9069fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    } else {
90704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    TODO}
90714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (1);
9072fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard}
9073fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
9074fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard/**
90756eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGValidateAttribute:
90766eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG validation context
90776eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @define:  the definition to verify
90786eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
90796eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Validate the given attribute definition for that node
90806eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
90816eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns 0 if the validation succeeded or an error code.
90826eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
90836eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic int
90844c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGValidateAttribute(xmlRelaxNGValidCtxtPtr ctxt,
90854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            xmlRelaxNGDefinePtr define)
90864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
90876eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    int ret = 0, i;
90886eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlChar *value, *oldvalue;
90896eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlAttrPtr prop = NULL, tmp;
9090c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard    xmlNodePtr oldseq;
90916eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
90921ed7f364bdb278e583b8d7663d7cc0f90307b6bbDaniel Veillard    if (ctxt->state->nbAttrLeft <= 0)
90934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
90946eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (define->name != NULL) {
90954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        for (i = 0; i < ctxt->state->nbAttrs; i++) {
90964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp = ctxt->state->attrs[i];
90974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((tmp != NULL) && (xmlStrEqual(define->name, tmp->name))) {
90984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((((define->ns == NULL) || (define->ns[0] == 0)) &&
90994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     (tmp->ns == NULL)) ||
91004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ((tmp->ns != NULL) &&
91014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                     (xmlStrEqual(define->ns, tmp->ns->href)))) {
91024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    prop = tmp;
91034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    break;
91044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
91054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
91064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
91074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (prop != NULL) {
91084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            value = xmlNodeListGetString(prop->doc, prop->children, 1);
91094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            oldvalue = ctxt->state->value;
91104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            oldseq = ctxt->state->seq;
91114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->state->seq = (xmlNodePtr) prop;
91124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->state->value = value;
91134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->state->endvalue = NULL;
91144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGValidateValueContent(ctxt, define->content);
91154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ctxt->state->value != NULL)
91164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                value = ctxt->state->value;
91174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (value != NULL)
91184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlFree(value);
91194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->state->value = oldvalue;
91204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->state->seq = oldseq;
91214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret == 0) {
91224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                /*
91234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 * flag the attribute as processed
91244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 */
91254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state->attrs[i] = NULL;
91264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state->nbAttrLeft--;
91274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
91284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
91294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = -1;
91304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
91316eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#ifdef DEBUG
91324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
91334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        "xmlRelaxNGValidateAttribute(%s): %d\n",
91344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        define->name, ret);
91356eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#endif
9136144fae1635bc93a3e8519aa1895885d94c846758Daniel Veillard    } else {
91374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        for (i = 0; i < ctxt->state->nbAttrs; i++) {
91384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp = ctxt->state->attrs[i];
91394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((tmp != NULL) &&
91404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                (xmlRelaxNGAttributeMatch(ctxt, define, tmp) == 1)) {
91414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                prop = tmp;
91424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
91434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
91444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
91454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (prop != NULL) {
91464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            value = xmlNodeListGetString(prop->doc, prop->children, 1);
91474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            oldvalue = ctxt->state->value;
91484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            oldseq = ctxt->state->seq;
91494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->state->seq = (xmlNodePtr) prop;
91504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->state->value = value;
91514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGValidateValueContent(ctxt, define->content);
91524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ctxt->state->value != NULL)
91534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                value = ctxt->state->value;
91544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (value != NULL)
91554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlFree(value);
91564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->state->value = oldvalue;
91574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->state->seq = oldseq;
91584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret == 0) {
91594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                /*
91604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 * flag the attribute as processed
91614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 */
91624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state->attrs[i] = NULL;
91634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state->nbAttrLeft--;
91644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
91654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
91664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = -1;
91674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
91683b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard#ifdef DEBUG
91694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (define->ns != NULL) {
91704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
91714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            "xmlRelaxNGValidateAttribute(nsName ns = %s): %d\n",
91724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            define->ns, ret);
91734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
91744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
91754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            "xmlRelaxNGValidateAttribute(anyName): %d\n",
91764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            ret);
91774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
91783b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard#endif
91796eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
91804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
91814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
91821564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard}
91831564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
91841564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard/**
9185fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGValidateAttributeList:
9186fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @ctxt:  a Relax-NG validation context
9187fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @define:  the list of definition to verify
9188fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *
9189fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Validate the given node against the list of attribute definitions
9190fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard *
9191fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Returns 0 if the validation succeeded or an error code.
9192fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard */
9193fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillardstatic int
91944c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGValidateAttributeList(xmlRelaxNGValidCtxtPtr ctxt,
91954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                xmlRelaxNGDefinePtr defines)
91964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
9197ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    int ret = 0, res;
9198ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    int needmore = 0;
9199ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    xmlRelaxNGDefinePtr cur;
9200ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard
9201ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    cur = defines;
9202ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    while (cur != NULL) {
9203ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard        if (cur->type == XML_RELAXNG_ATTRIBUTE) {
92044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (xmlRelaxNGValidateAttribute(ctxt, cur) != 0)
92054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = -1;
92064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else
92074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            needmore = 1;
9208ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard        cur = cur->next;
9209fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
9210ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    if (!needmore)
92114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (ret);
9212ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    cur = defines;
9213ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    while (cur != NULL) {
9214ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard        if (cur->type != XML_RELAXNG_ATTRIBUTE) {
92154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((ctxt->state != NULL) || (ctxt->states != NULL)) {
92164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                res = xmlRelaxNGValidateDefinition(ctxt, cur);
92174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (res < 0)
92184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret = -1;
92194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
92204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                VALID_ERR(XML_RELAXNG_ERR_NOSTATE);
92214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (-1);
92224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
92234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (res == -1)      /* continues on -2 */
92244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                break;
92254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
9226ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard        cur = cur->next;
9227ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard    }
92284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
92294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
9230fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard}
9231fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
9232fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard/**
92331564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * xmlRelaxNGNodeMatchesList:
92341564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * @node:  the node
92351564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * @list:  a NULL terminated array of definitions
92361564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard *
92371564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * Check if a node can be matched by one of the definitions
92381564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard *
92391564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * Returns 1 if matches 0 otherwise
92401564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard */
92411564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillardstatic int
92424c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGNodeMatchesList(xmlNodePtr node, xmlRelaxNGDefinePtr * list)
92434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
92441564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    xmlRelaxNGDefinePtr cur;
92450e3d3ce2676ddff2c1b35a583c5a40d31c807128Daniel Veillard    int i = 0, tmp;
92461564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
92471564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    if ((node == NULL) || (list == NULL))
92484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (0);
92491564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
92501564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    cur = list[i++];
92511564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    while (cur != NULL) {
92524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((node->type == XML_ELEMENT_NODE) &&
92534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            (cur->type == XML_RELAXNG_ELEMENT)) {
92544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp = xmlRelaxNGElementMatch(NULL, cur, node);
92554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (tmp == 1)
92564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (1);
92574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (((node->type == XML_TEXT_NODE) ||
92584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    (node->type == XML_CDATA_SECTION_NODE)) &&
92594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   (cur->type == XML_RELAXNG_TEXT)) {
92604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (1);
92614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
92624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = list[i++];
92631564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    }
92644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (0);
92651564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard}
92661564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
92671564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard/**
9268fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGValidateInterleave:
92691564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * @ctxt:  a Relax-NG validation context
92701564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * @define:  the definition to verify
92711564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard *
9272fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Validate an interleave definition for a node.
92731564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard *
92741564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * Returns 0 if the validation succeeded or an error code.
92751564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard */
92761564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillardstatic int
92774c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt,
92784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                             xmlRelaxNGDefinePtr define)
92794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
9280779af00750fa86045e94422287d67a2cf5723f65William M. Brack    int ret = 0, i, nbgroups;
9281fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    int errNr = ctxt->errNr;
9282249d7bbee28570177a8573a99eab4aa9e27384d9Daniel Veillard    int oldflags;
9283fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
9284fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGValidStatePtr oldstate;
9285fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGPartitionPtr partitions;
9286fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGInterleaveGroupPtr group = NULL;
9287fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlNodePtr cur, start, last = NULL, lastchg = NULL, lastelem;
9288fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlNodePtr *list = NULL, *lasts = NULL;
9289fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
9290fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (define->data != NULL) {
92914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        partitions = (xmlRelaxNGPartitionPtr) define->data;
92924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        nbgroups = partitions->nbgroups;
9293fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    } else {
92944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        VALID_ERR(XML_RELAXNG_ERR_INTERNODATA);
92954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
92961564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    }
9297249d7bbee28570177a8573a99eab4aa9e27384d9Daniel Veillard    /*
9298249d7bbee28570177a8573a99eab4aa9e27384d9Daniel Veillard     * Optimizations for MIXED
9299249d7bbee28570177a8573a99eab4aa9e27384d9Daniel Veillard     */
9300249d7bbee28570177a8573a99eab4aa9e27384d9Daniel Veillard    oldflags = ctxt->flags;
9301e063f4829d4403ff90b3fab6f47ff4a37b9325d1Daniel Veillard    if (define->dflags & IS_MIXED) {
93024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->flags |= FLAGS_MIXED_CONTENT;
93034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (nbgroups == 2) {
93044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            /*
93054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             * this is a pure <mixed> case
93064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard             */
93074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ctxt->state != NULL)
93084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt,
93094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                         ctxt->state->seq);
93104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (partitions->groups[0]->rule->type == XML_RELAXNG_TEXT)
93114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = xmlRelaxNGValidateDefinition(ctxt,
93124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                   partitions->groups[1]->
93134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                   rule);
93144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            else
93154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = xmlRelaxNGValidateDefinition(ctxt,
93164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                   partitions->groups[0]->
93174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                   rule);
93184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret == 0) {
93194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ctxt->state != NULL)
93204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt,
93214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                             ctxt->state->
93224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                             seq);
93234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
93244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->flags = oldflags;
93254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (ret);
93264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
9327249d7bbee28570177a8573a99eab4aa9e27384d9Daniel Veillard    }
93281564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
9329fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    /*
9330fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     * Build arrays to store the first and last node of the chain
9331fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     * pertaining to each group
9332fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     */
9333fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    list = (xmlNodePtr *) xmlMalloc(nbgroups * sizeof(xmlNodePtr));
9334fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (list == NULL) {
93354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngVErrMemory(ctxt, "validating\n");
93364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
93371564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    }
9338fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    memset(list, 0, nbgroups * sizeof(xmlNodePtr));
9339fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    lasts = (xmlNodePtr *) xmlMalloc(nbgroups * sizeof(xmlNodePtr));
9340fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (lasts == NULL) {
93414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngVErrMemory(ctxt, "validating\n");
93424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
93431564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    }
9344fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    memset(lasts, 0, nbgroups * sizeof(xmlNodePtr));
93451564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
9346fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    /*
9347fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     * Walk the sequence of children finding the right group and
9348fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     * sorting them in sequences.
9349fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     */
9350fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    cur = ctxt->state->seq;
9351fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    cur = xmlRelaxNGSkipIgnored(ctxt, cur);
9352fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    start = cur;
9353fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    while (cur != NULL) {
93544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state->seq = cur;
93554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((partitions->triage != NULL) &&
9356bbb78b5d6d18b008bbd14edefecde4156d85f949Daniel Veillard            (partitions->flags & IS_DETERMINIST)) {
93574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            void *tmp = NULL;
93584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
93594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((cur->type == XML_TEXT_NODE) ||
93604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                (cur->type == XML_CDATA_SECTION_NODE)) {
93614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp = xmlHashLookup2(partitions->triage, BAD_CAST "#text",
93624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                     NULL);
93634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else if (cur->type == XML_ELEMENT_NODE) {
93644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (cur->ns != NULL) {
93654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    tmp = xmlHashLookup2(partitions->triage, cur->name,
93664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                         cur->ns->href);
93674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (tmp == NULL)
93684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        tmp = xmlHashLookup2(partitions->triage,
93694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                             BAD_CAST "#any",
93704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                             cur->ns->href);
93714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else
93724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    tmp =
93734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlHashLookup2(partitions->triage, cur->name,
93744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                       NULL);
93754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (tmp == NULL)
93764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    tmp =
93774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlHashLookup2(partitions->triage, BAD_CAST "#any",
93784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                       NULL);
93794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
93804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
93814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (tmp == NULL) {
93824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                i = nbgroups;
93834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
93844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                i = ((long) tmp) - 1;
93854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (partitions->flags & IS_NEEDCHECK) {
93864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    group = partitions->groups[i];
93874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (!xmlRelaxNGNodeMatchesList(cur, group->defs))
93884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        i = nbgroups;
93894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
93904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
93914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
93924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            for (i = 0; i < nbgroups; i++) {
93934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                group = partitions->groups[i];
93944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (group == NULL)
93954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    continue;
93964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (xmlRelaxNGNodeMatchesList(cur, group->defs))
93974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    break;
93984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
93994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
94004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        /*
94014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         * We break as soon as an element not matched is found
94024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         */
94034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (i >= nbgroups) {
94044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
94054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
94064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (lasts[i] != NULL) {
94074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            lasts[i]->next = cur;
94084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            lasts[i] = cur;
94094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
94104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            list[i] = cur;
94114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            lasts[i] = cur;
94124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
94134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (cur->next != NULL)
94144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            lastchg = cur->next;
94154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        else
94164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            lastchg = cur;
94174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = xmlRelaxNGSkipIgnored(ctxt, cur->next);
94181564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    }
9419fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (ret != 0) {
94204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        VALID_ERR(XML_RELAXNG_ERR_INTERSEQ);
94214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = -1;
94224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        goto done;
9423fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
9424fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    lastelem = cur;
9425fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    oldstate = ctxt->state;
94264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    for (i = 0; i < nbgroups; i++) {
94274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state = xmlRelaxNGCopyValidState(ctxt, oldstate);
94286d753994b9cdfccec5d0075d5685cae9ad06bec1Gaurav Gupta	if (ctxt->state == NULL) {
94296d753994b9cdfccec5d0075d5685cae9ad06bec1Gaurav Gupta	    ret = -1;
94306d753994b9cdfccec5d0075d5685cae9ad06bec1Gaurav Gupta	    break;
94316d753994b9cdfccec5d0075d5685cae9ad06bec1Gaurav Gupta	}
94324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        group = partitions->groups[i];
94334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (lasts[i] != NULL) {
94344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            last = lasts[i]->next;
94354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            lasts[i]->next = NULL;
94364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
94374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state->seq = list[i];
94384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = xmlRelaxNGValidateDefinition(ctxt, group->rule);
94394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ret != 0)
94404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
94414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->state != NULL) {
94424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur = ctxt->state->seq;
94434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            cur = xmlRelaxNGSkipIgnored(ctxt, cur);
94444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGFreeValidState(ctxt, oldstate);
94454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            oldstate = ctxt->state;
94464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->state = NULL;
94474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (cur != NULL) {
94484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name);
94494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = -1;
94504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state = oldstate;
94514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                goto done;
94524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
94534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (ctxt->states != NULL) {
94544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            int j;
94554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            int found = 0;
945687254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard	    int best = -1;
945787254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard	    int lowattr = -1;
945887254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard
945987254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard	    /*
946087254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard	     * PBM: what happen if there is attributes checks in the interleaves
946187254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard	     */
94624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
94634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            for (j = 0; j < ctxt->states->nbState; j++) {
94644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur = ctxt->states->tabState[j]->seq;
94654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                cur = xmlRelaxNGSkipIgnored(ctxt, cur);
94664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (cur == NULL) {
946787254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		    if (found == 0) {
946887254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		        lowattr = ctxt->states->tabState[j]->nbAttrLeft;
946987254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard			best = j;
947087254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		    }
94714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    found = 1;
947287254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		    if (ctxt->states->tabState[j]->nbAttrLeft <= lowattr) {
947387254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		        /* try  to keep the latest one to mach old heuristic */
947487254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		        lowattr = ctxt->states->tabState[j]->nbAttrLeft;
947587254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard			best = j;
947687254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		    }
947787254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard                    if (lowattr == 0)
947887254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		        break;
947987254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard                } else if (found == 0) {
948087254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard                    if (lowattr == -1) {
948187254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		        lowattr = ctxt->states->tabState[j]->nbAttrLeft;
948287254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard			best = j;
948387254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		    } else
948487254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		    if (ctxt->states->tabState[j]->nbAttrLeft <= lowattr)  {
948587254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		        /* try  to keep the latest one to mach old heuristic */
948687254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		        lowattr = ctxt->states->tabState[j]->nbAttrLeft;
948787254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard			best = j;
948887254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		    }
948987254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		}
94904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
949187254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard	    /*
949287254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard	     * BIG PBM: here we pick only one restarting point :-(
949387254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard	     */
94944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ctxt->states->nbState > 0) {
94954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGFreeValidState(ctxt, oldstate);
949687254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		if (best != -1) {
949787254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		    oldstate = ctxt->states->tabState[best];
949887254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		    ctxt->states->tabState[best] = NULL;
949987254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		} else {
950087254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		    oldstate =
950187254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard			ctxt->states->tabState[ctxt->states->nbState - 1];
950287254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard                    ctxt->states->tabState[ctxt->states->nbState - 1] = NULL;
95039fcd462f271fb7bf49b6c7c6993cf42dcf879377Daniel Veillard                    ctxt->states->nbState--;
950487254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard		}
95054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
950687254c8497f199ebecc7c98b1658c209d4a2328eDaniel Veillard            for (j = 0; j < ctxt->states->nbState ; j++) {
95074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGFreeValidState(ctxt, ctxt->states->tabState[j]);
95084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
95094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGFreeStates(ctxt, ctxt->states);
95104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->states = NULL;
95114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (found == 0) {
951276d364583ecb6a48bd4a4087f3cef9fc7838b481Daniel Veillard                if (cur == NULL) {
9513a7a6a4b2f39b6bc2973eed8b0fb7cf917a171487Ben Walton		    VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA,
9514a7a6a4b2f39b6bc2973eed8b0fb7cf917a171487Ben Walton			       (const xmlChar *) "noname");
951576d364583ecb6a48bd4a4087f3cef9fc7838b481Daniel Veillard                } else {
951676d364583ecb6a48bd4a4087f3cef9fc7838b481Daniel Veillard                    VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name);
951776d364583ecb6a48bd4a4087f3cef9fc7838b481Daniel Veillard                }
95184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = -1;
95194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state = oldstate;
95204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                goto done;
95214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
95224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
95234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = -1;
95244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
95254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
95264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (lasts[i] != NULL) {
95274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            lasts[i]->next = last;
95284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
9529fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
9530fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (ctxt->state != NULL)
95314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeValidState(ctxt, ctxt->state);
9532fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    ctxt->state = oldstate;
9533fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    ctxt->state->seq = lastelem;
9534fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (ret != 0) {
95354c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        VALID_ERR(XML_RELAXNG_ERR_INTERSEQ);
95364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = -1;
95374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        goto done;
9538fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
95391564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
95404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard  done:
9541249d7bbee28570177a8573a99eab4aa9e27384d9Daniel Veillard    ctxt->flags = oldflags;
9542fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    /*
9543fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     * builds the next links chain from the prev one
9544fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     */
9545fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    cur = lastchg;
9546fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    while (cur != NULL) {
95474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((cur == start) || (cur->prev == NULL))
95484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
95494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur->prev->next = cur;
95504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        cur = cur->prev;
95516eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
9552fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (ret == 0) {
95534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->errNr > errNr)
95544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGPopErrors(ctxt, errNr);
95551564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    }
95566eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
9557fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlFree(list);
9558fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlFree(lasts);
95594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
95601564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard}
956176fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard
95621564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard/**
9563fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGValidateDefinitionList:
95641564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * @ctxt:  a Relax-NG validation context
9565fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @define:  the list of definition to verify
95661564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard *
9567fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Validate the given node content against the (list) of definitions
95681564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard *
9569fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Returns 0 if the validation succeeded or an error code.
95701564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard */
9571fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillardstatic int
95724c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGValidateDefinitionList(xmlRelaxNGValidCtxtPtr ctxt,
95734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                 xmlRelaxNGDefinePtr defines)
95744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
9575fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    int ret = 0, res;
957676fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard
957776fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard
9578952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard    if (defines == NULL) {
95794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        VALID_ERR2(XML_RELAXNG_ERR_INTERNAL,
95804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                   BAD_CAST "NULL definition list");
95814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
9582952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard    }
9583fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    while (defines != NULL) {
95844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((ctxt->state != NULL) || (ctxt->states != NULL)) {
95854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            res = xmlRelaxNGValidateDefinition(ctxt, defines);
95864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (res < 0)
95874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = -1;
95884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
95894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            VALID_ERR(XML_RELAXNG_ERR_NOSTATE);
95904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (-1);
95914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
95924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (res == -1)          /* continues on -2 */
95934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            break;
95944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        defines = defines->next;
9595fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
959676fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard
95974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
95981564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard}
9599c64b8e984c13a0d989dea436c13128b289a4d4d6Daniel Veillard
96001564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard/**
9601fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGElementMatch:
96021564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * @ctxt:  a Relax-NG validation context
9603fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @define:  the definition to check
9604fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * @elem:  the element
96051564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard *
9606fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Check if the element matches the definition nameClass
96071564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard *
9608fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Returns 1 if the element matches, 0 if no, or -1 in case of error
96091564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard */
9610fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillardstatic int
96114c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,
96124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       xmlRelaxNGDefinePtr define, xmlNodePtr elem)
96134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
9614580ced8ee28ecd99374da9383897678e4ba6c358Daniel Veillard    int ret = 0, oldflags = 0;
961576fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard
9616fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (define->name != NULL) {
96174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (!xmlStrEqual(elem->name, define->name)) {
96184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            VALID_ERR3(XML_RELAXNG_ERR_ELEMNAME, define->name, elem->name);
96194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (0);
96204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
9621fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
9622fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if ((define->ns != NULL) && (define->ns[0] != 0)) {
96234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (elem->ns == NULL) {
96244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            VALID_ERR2(XML_RELAXNG_ERR_ELEMNONS, elem->name);
96254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (0);
96264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else if (!xmlStrEqual(elem->ns->href, define->ns)) {
96274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            VALID_ERR3(XML_RELAXNG_ERR_ELEMWRONGNS,
96284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                       elem->name, define->ns);
96294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (0);
96304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
9631fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    } else if ((elem->ns != NULL) && (define->ns != NULL) &&
96324c0041471199f283c4e696526c73e2809da54e21Daniel Veillard               (define->name == NULL)) {
96334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        VALID_ERR2(XML_RELAXNG_ERR_ELEMEXTRANS, elem->name);
96344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (0);
9635fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    } else if ((elem->ns != NULL) && (define->name != NULL)) {
96364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        VALID_ERR2(XML_RELAXNG_ERR_ELEMEXTRANS, define->name);
96374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (0);
9638fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
963976fc5edab66ac2069a0dab6ee3d4d844c958ea10Daniel Veillard
9640fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (define->nameClass == NULL)
96414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (1);
96426eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
9643fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    define = define->nameClass;
9644fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (define->type == XML_RELAXNG_EXCEPT) {
96454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGDefinePtr list;
96464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
96474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt != NULL) {
96484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            oldflags = ctxt->flags;
96494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->flags |= FLAGS_IGNORABLE;
96504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
96514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
96524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        list = define->content;
96534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        while (list != NULL) {
96544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGElementMatch(ctxt, list, elem);
96554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret == 1) {
96564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ctxt != NULL)
96574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ctxt->flags = oldflags;
96584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (0);
96594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
96604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret < 0) {
96614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ctxt != NULL)
96624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ctxt->flags = oldflags;
96634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (ret);
96644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
96654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            list = list->next;
96664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
96674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = 1;
96684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt != NULL) {
96694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->flags = oldflags;
96704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
9671fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    } else if (define->type == XML_RELAXNG_CHOICE) {
96724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGDefinePtr list;
96734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
96744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt != NULL) {
96754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            oldflags = ctxt->flags;
96764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->flags |= FLAGS_IGNORABLE;
96774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
96784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
96794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        list = define->nameClass;
96804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        while (list != NULL) {
96814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = xmlRelaxNGElementMatch(ctxt, list, elem);
96824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret == 1) {
96834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ctxt != NULL)
96844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ctxt->flags = oldflags;
96854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (1);
96864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
96874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret < 0) {
96884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ctxt != NULL)
96894c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ctxt->flags = oldflags;
96904c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                return (ret);
96914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
96924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            list = list->next;
96934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
96944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt != NULL) {
96954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret != 0) {
96964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
96974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGDumpValidError(ctxt);
96984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
96994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (ctxt->errNr > 0)
97004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGPopErrors(ctxt, 0);
97014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
97024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
97034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = 0;
97044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt != NULL) {
97054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->flags = oldflags;
97064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
97071564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    } else {
97084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        TODO ret = -1;
97096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
97104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
97116eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
9712fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
97136eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
97141ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard * xmlRelaxNGBestState:
97151ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard * @ctxt:  a Relax-NG validation context
97161ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard *
97171ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard * Find the "best" state in the ctxt->states list of states to report
97181ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard * errors about. I.e. a state with no element left in the child list
97191ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard * or the one with the less attributes left.
97201ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard * This is called only if a falidation error was detected
97211ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard *
97221ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard * Returns the index of the "best" state or -1 in case of error
97231ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard */
97241ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillardstatic int
97254c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGBestState(xmlRelaxNGValidCtxtPtr ctxt)
97264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
97271ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    xmlRelaxNGValidStatePtr state;
97281ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    int i, tmp;
97291ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    int best = -1;
97301ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    int value = 1000000;
97311ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
97321ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    if ((ctxt == NULL) || (ctxt->states == NULL) ||
97331ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard        (ctxt->states->nbState <= 0))
97344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
97351ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
97364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    for (i = 0; i < ctxt->states->nbState; i++) {
97371ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard        state = ctxt->states->tabState[i];
97384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (state == NULL)
97394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            continue;
97404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (state->seq != NULL) {
97414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((best == -1) || (value > 100000)) {
97424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                value = 100000;
97434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                best = i;
97444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
97454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
97464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            tmp = state->nbAttrLeft;
97474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if ((best == -1) || (value > tmp)) {
97484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                value = tmp;
97494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                best = i;
97504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
97514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
97521ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
97534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (best);
97541ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard}
97551ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
97561ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard/**
97571ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard * xmlRelaxNGLogBestError:
97581ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard * @ctxt:  a Relax-NG validation context
97591ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard *
97601ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard * Find the "best" state in the ctxt->states list of states to report
97611ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard * errors about and log it.
97621ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard */
97631ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillardstatic void
97644c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGLogBestError(xmlRelaxNGValidCtxtPtr ctxt)
97654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
97661ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    int best;
97671ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
97681ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    if ((ctxt == NULL) || (ctxt->states == NULL) ||
97691ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard        (ctxt->states->nbState <= 0))
97704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
97711ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
97721ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    best = xmlRelaxNGBestState(ctxt);
97731ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    if ((best >= 0) && (best < ctxt->states->nbState)) {
97744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state = ctxt->states->tabState[best];
97751ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
97764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGValidateElementEnd(ctxt, 1);
97771ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    }
97781ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard}
97791ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard
97801ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard/**
9781fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGValidateElementEnd:
9782416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard * @ctxt:  a Relax-NG validation context
9783272693c7e127a43dbcd5bc39c1cec4bfcdabcd2aWilliam M. Brack * @dolog:  indicate that error logging should be done
9784416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard *
9785fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Validate the end of the element, implements check that
9786fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * there is nothing left not consumed in the element content
9787fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * or in the attribute list.
9788416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard *
9789fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Returns 0 if the validation succeeded or an error code.
9790416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard */
9791fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillardstatic int
9792272693c7e127a43dbcd5bc39c1cec4bfcdabcd2aWilliam M. BrackxmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt, int dolog)
97934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
97941ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard    int i;
9795fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGValidStatePtr state;
9796416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard
9797fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    state = ctxt->state;
9798fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (state->seq != NULL) {
97994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        state->seq = xmlRelaxNGSkipIgnored(ctxt, state->seq);
98004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (state->seq != NULL) {
9801272693c7e127a43dbcd5bc39c1cec4bfcdabcd2aWilliam M. Brack            if (dolog) {
98024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                VALID_ERR3(XML_RELAXNG_ERR_EXTRACONTENT,
98034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           state->node->name, state->seq->name);
98044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
98054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (-1);
98064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
9807fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
98084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    for (i = 0; i < state->nbAttrs; i++) {
98094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (state->attrs[i] != NULL) {
9810272693c7e127a43dbcd5bc39c1cec4bfcdabcd2aWilliam M. Brack            if (dolog) {
98114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                VALID_ERR3(XML_RELAXNG_ERR_INVALIDATTR,
98124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                           state->attrs[i]->name, state->node->name);
98134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
98144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            return (-1 - i);
98154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
9816416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard    }
98174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (0);
9818416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard}
9819416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard
9820416589ae78f9ea46ef8841559eaa7ded712c0b88Daniel Veillard/**
9821fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGValidateState:
98226eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG validation context
98236eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @define:  the definition to verify
98246eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
9825fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Validate the current state against the definition
98266eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
9827fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Returns 0 if the validation succeeded or an error code.
98286eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
9829fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillardstatic int
9830c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel VeillardxmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
9831c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        xmlRelaxNGDefinePtr define)
9832c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard{
9833fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlNodePtr node;
9834fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    int ret = 0, i, tmp, oldflags, errNr;
9835bbb78b5d6d18b008bbd14edefecde4156d85f949Daniel Veillard    xmlRelaxNGValidStatePtr oldstate = NULL, state;
98361564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
9837fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (define == NULL) {
9838c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        VALID_ERR(XML_RELAXNG_ERR_NODEFINE);
9839c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        return (-1);
9840fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
9841fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
9842fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (ctxt->state != NULL) {
9843c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        node = ctxt->state->seq;
9844fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    } else {
9845c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        node = NULL;
9846fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
9847231d791fc4d9bec385a726a7d556cb62b777614bDaniel Veillard#ifdef DEBUG
9848c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    for (i = 0; i < ctxt->depth; i++)
9849c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        xmlGenericError(xmlGenericErrorContext, " ");
9850fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlGenericError(xmlGenericErrorContext,
9851c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    "Start validating %s ", xmlRelaxNGDefName(define));
9852fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (define->name != NULL)
9853c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        xmlGenericError(xmlGenericErrorContext, "%s ", define->name);
9854fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if ((node != NULL) && (node->name != NULL))
9855c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        xmlGenericError(xmlGenericErrorContext, "on %s\n", node->name);
9856fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    else
9857c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        xmlGenericError(xmlGenericErrorContext, "\n");
9858231d791fc4d9bec385a726a7d556cb62b777614bDaniel Veillard#endif
9859fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    ctxt->depth++;
98606eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    switch (define->type) {
9861fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_EMPTY:
9862579410427fa11725ca411e45d3ac57db92586ac2Philip Withnall            xmlRelaxNGSkipIgnored(ctxt, node);
9863c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            ret = 0;
9864c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            break;
9865fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_NOT_ALLOWED:
9866c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            ret = -1;
9867c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            break;
9868fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_TEXT:
9869c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            while ((node != NULL) &&
9870c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                   ((node->type == XML_TEXT_NODE) ||
9871c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    (node->type == XML_COMMENT_NODE) ||
9872c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    (node->type == XML_PI_NODE) ||
9873c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    (node->type == XML_CDATA_SECTION_NODE)))
9874c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                node = node->next;
9875c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            ctxt->state->seq = node;
9876c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            break;
9877fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_ELEMENT:
9878c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            errNr = ctxt->errNr;
9879c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            node = xmlRelaxNGSkipIgnored(ctxt, node);
9880c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            if (node == NULL) {
9881c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                VALID_ERR2(XML_RELAXNG_ERR_NOELEM, define->name);
9882c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ret = -1;
9883c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
9884c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGDumpValidError(ctxt);
9885c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                break;
9886c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
9887c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            if (node->type != XML_ELEMENT_NODE) {
9888c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                VALID_ERR(XML_RELAXNG_ERR_NOTELEM);
9889c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ret = -1;
9890c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
9891c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGDumpValidError(ctxt);
9892c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                break;
9893c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
9894c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            /*
9895c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard             * This node was already validated successfully against
9896c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard             * this definition.
9897c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard             */
9898807daf826510d2d0597fdd10314e51b4d56c5e96Daniel Veillard            if (node->psvi == define) {
9899c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt, node->next);
9900c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (ctxt->errNr > errNr)
9901c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGPopErrors(ctxt, errNr);
9902c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (ctxt->errNr != 0) {
9903c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    while ((ctxt->err != NULL) &&
9904c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                           (((ctxt->err->err == XML_RELAXNG_ERR_ELEMNAME)
9905c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                             && (xmlStrEqual(ctxt->err->arg2, node->name)))
9906c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            ||
9907c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            ((ctxt->err->err ==
9908c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                              XML_RELAXNG_ERR_ELEMEXTRANS)
9909c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                             && (xmlStrEqual(ctxt->err->arg1, node->name)))
9910c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            || (ctxt->err->err == XML_RELAXNG_ERR_NOELEM)
9911c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            || (ctxt->err->err ==
9912c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                XML_RELAXNG_ERR_NOTELEM)))
9913c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        xmlRelaxNGValidErrorPop(ctxt);
9914c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
9915c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                break;
9916c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
9917c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
9918c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            ret = xmlRelaxNGElementMatch(ctxt, define, node);
9919c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            if (ret <= 0) {
9920c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ret = -1;
9921c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
9922c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGDumpValidError(ctxt);
9923c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                break;
9924c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
9925c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            ret = 0;
9926c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            if (ctxt->errNr != 0) {
9927c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (ctxt->errNr > errNr)
9928c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGPopErrors(ctxt, errNr);
9929c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                while ((ctxt->err != NULL) &&
9930c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                       (((ctxt->err->err == XML_RELAXNG_ERR_ELEMNAME) &&
9931c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                         (xmlStrEqual(ctxt->err->arg2, node->name))) ||
9932c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        ((ctxt->err->err == XML_RELAXNG_ERR_ELEMEXTRANS) &&
9933c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                         (xmlStrEqual(ctxt->err->arg1, node->name))) ||
9934c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        (ctxt->err->err == XML_RELAXNG_ERR_NOELEM) ||
9935c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        (ctxt->err->err == XML_RELAXNG_ERR_NOTELEM)))
9936c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGValidErrorPop(ctxt);
9937c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
9938c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            errNr = ctxt->errNr;
9939c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
9940c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            oldflags = ctxt->flags;
9941c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            if (ctxt->flags & FLAGS_MIXED_CONTENT) {
9942c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ctxt->flags -= FLAGS_MIXED_CONTENT;
9943c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
9944c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            state = xmlRelaxNGNewValidState(ctxt, node);
9945c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            if (state == NULL) {
9946c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ret = -1;
9947c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
9948c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGDumpValidError(ctxt);
9949c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                break;
9950c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
9951c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
9952c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            oldstate = ctxt->state;
9953c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            ctxt->state = state;
9954c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            if (define->attrs != NULL) {
9955c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                tmp = xmlRelaxNGValidateAttributeList(ctxt, define->attrs);
9956c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (tmp != 0) {
9957c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ret = -1;
9958c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    VALID_ERR2(XML_RELAXNG_ERR_ATTRVALID, node->name);
9959c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
9960c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
9961c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            if (define->contModel != NULL) {
99624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGValidStatePtr nstate, tmpstate = ctxt->state;
99634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGStatesPtr tmpstates = ctxt->states;
99644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlNodePtr nseq;
9965ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard
99664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                nstate = xmlRelaxNGNewValidState(ctxt, node);
99674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state = nstate;
99684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->states = NULL;
9969ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard
9970c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                tmp = xmlRelaxNGValidateCompiledContent(ctxt,
9971c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                        define->contModel,
9972c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                        ctxt->state->seq);
99734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                nseq = ctxt->state->seq;
99744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state = tmpstate;
99754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->states = tmpstates;
99764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGFreeValidState(ctxt, nstate);
9977ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard
9978c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard#ifdef DEBUG_COMPILE
99794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlGenericError(xmlGenericErrorContext,
99804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                "Validating content of '%s' : %d\n",
99814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                define->name, tmp);
9982c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard#endif
9983ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                if (tmp != 0)
99844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ret = -1;
9985ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard
9986ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                if (ctxt->states != NULL) {
9987ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                    tmp = -1;
9988ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard
9989ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                    for (i = 0; i < ctxt->states->nbState; i++) {
9990ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                        state = ctxt->states->tabState[i];
9991ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                        ctxt->state = state;
99924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ctxt->state->seq = nseq;
9993ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard
99941ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                        if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
9995ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                            tmp = 0;
99964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            break;
99974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        }
99984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
99994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (tmp != 0) {
100004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        /*
100014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         * validation error, log the message for the "best" one
100024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         */
100034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ctxt->flags |= FLAGS_IGNORABLE;
100044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGLogBestError(ctxt);
100051ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                    }
100061ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                    for (i = 0; i < ctxt->states->nbState; i++) {
100071ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                        xmlRelaxNGFreeValidState(ctxt,
100084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                 ctxt->states->
100094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                 tabState[i]);
10010ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                    }
10011ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                    xmlRelaxNGFreeStates(ctxt, ctxt->states);
10012ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                    ctxt->flags = oldflags;
10013ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                    ctxt->states = NULL;
10014ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                    if ((ret == 0) && (tmp == -1))
10015ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                        ret = -1;
10016ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                } else {
10017ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                    state = ctxt->state;
10018d8ed1051faf3a8b2dba7eb1aefaaaf37eda39101Daniel Veillard		    if (ctxt->state != NULL)
10019d8ed1051faf3a8b2dba7eb1aefaaaf37eda39101Daniel Veillard			ctxt->state->seq = nseq;
10020ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                    if (ret == 0)
100211ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                        ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
10022ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                    xmlRelaxNGFreeValidState(ctxt, state);
10023ce192eb8a698c87a223a87b8c01739580f008a52Daniel Veillard                }
10024c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            } else {
10025c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (define->content != NULL) {
10026c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    tmp = xmlRelaxNGValidateDefinitionList(ctxt,
100274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                           define->
100284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                                           content);
10029c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (tmp != 0) {
10030c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        ret = -1;
10031c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        if (ctxt->state == NULL) {
10032c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            ctxt->state = oldstate;
10033c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            VALID_ERR2(XML_RELAXNG_ERR_CONTENTVALID,
10034c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                       node->name);
10035c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            ctxt->state = NULL;
10036c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        } else {
10037c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            VALID_ERR2(XML_RELAXNG_ERR_CONTENTVALID,
10038c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                       node->name);
10039c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        }
10040c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
10041c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    }
10042c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10043c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (ctxt->states != NULL) {
10044c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    tmp = -1;
10045c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
10046c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    for (i = 0; i < ctxt->states->nbState; i++) {
10047c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        state = ctxt->states->tabState[i];
10048c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        ctxt->state = state;
10049c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
100501ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                        if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
10051c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            tmp = 0;
100524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                            break;
100534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        }
100544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    }
100554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    if (tmp != 0) {
100564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        /*
100574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         * validation error, log the message for the "best" one
100584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         */
100594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        ctxt->flags |= FLAGS_IGNORABLE;
100604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGLogBestError(ctxt);
100611ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                    }
100621ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                    for (i = 0; i < ctxt->states->nbState; i++) {
100631ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                        xmlRelaxNGFreeValidState(ctxt,
100649fcd462f271fb7bf49b6c7c6993cf42dcf879377Daniel Veillard                                                 ctxt->states->tabState[i]);
100659fcd462f271fb7bf49b6c7c6993cf42dcf879377Daniel Veillard                        ctxt->states->tabState[i] = NULL;
10066c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    }
10067c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGFreeStates(ctxt, ctxt->states);
10068c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ctxt->flags = oldflags;
10069c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ctxt->states = NULL;
10070c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if ((ret == 0) && (tmp == -1))
10071c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        ret = -1;
10072c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                } else {
10073c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    state = ctxt->state;
10074c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (ret == 0)
100751ac24d36b12487995b659a8fc23a02b9460edb36Daniel Veillard                        ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
10076c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGFreeValidState(ctxt, state);
10077c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10078c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
10079c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            if (ret == 0) {
10080807daf826510d2d0597fdd10314e51b4d56c5e96Daniel Veillard                node->psvi = define;
10081c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
10082c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            ctxt->flags = oldflags;
10083c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            ctxt->state = oldstate;
10084c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            if (oldstate != NULL)
10085c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                oldstate->seq = xmlRelaxNGSkipIgnored(ctxt, node->next);
10086c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            if (ret != 0) {
10087c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if ((ctxt->flags & FLAGS_IGNORABLE) == 0) {
10088c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGDumpValidError(ctxt);
10089c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ret = 0;
10090fa0d094ae34a16649d7abb8f0354048bbcff591bDaniel Veillard#if 0
10091c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                } else {
10092c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ret = -2;
10093fa0d094ae34a16649d7abb8f0354048bbcff591bDaniel Veillard#endif
10094c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10095c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            } else {
10096c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (ctxt->errNr > errNr)
10097c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGPopErrors(ctxt, errNr);
10098c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
10099fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
10100fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard#ifdef DEBUG
10101c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
10102c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            "xmlRelaxNGValidateDefinition(): validated %s : %d",
10103c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            node->name, ret);
10104c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            if (oldstate == NULL)
10105c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                xmlGenericError(xmlGenericErrorContext, ": no state\n");
10106c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            else if (oldstate->seq == NULL)
10107c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                xmlGenericError(xmlGenericErrorContext, ": done\n");
10108c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            else if (oldstate->seq->type == XML_ELEMENT_NODE)
10109c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                xmlGenericError(xmlGenericErrorContext, ": next elem %s\n",
10110c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                oldstate->seq->name);
10111c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            else
10112c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                xmlGenericError(xmlGenericErrorContext, ": next %s %d\n",
10113c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                oldstate->seq->name, oldstate->seq->type);
10114fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard#endif
10115c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            break;
10116c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        case XML_RELAXNG_OPTIONAL:{
10117c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                errNr = ctxt->errNr;
10118c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                oldflags = ctxt->flags;
10119c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ctxt->flags |= FLAGS_IGNORABLE;
10120c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                oldstate = xmlRelaxNGCopyValidState(ctxt, ctxt->state);
10121c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ret =
10122c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGValidateDefinitionList(ctxt,
10123c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                     define->content);
10124c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (ret != 0) {
10125c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (ctxt->state != NULL)
10126c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        xmlRelaxNGFreeValidState(ctxt, ctxt->state);
10127c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ctxt->state = oldstate;
10128c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ctxt->flags = oldflags;
10129c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ret = 0;
10130c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (ctxt->errNr > errNr)
10131c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        xmlRelaxNGPopErrors(ctxt, errNr);
10132c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    break;
10133c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10134c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (ctxt->states != NULL) {
10135c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGAddStates(ctxt, ctxt->states, oldstate);
10136c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                } else {
10137c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ctxt->states = xmlRelaxNGNewStates(ctxt, 1);
10138c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (ctxt->states == NULL) {
10139c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        xmlRelaxNGFreeValidState(ctxt, oldstate);
10140c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        ctxt->flags = oldflags;
10141c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        ret = -1;
10142c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        if (ctxt->errNr > errNr)
10143c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            xmlRelaxNGPopErrors(ctxt, errNr);
10144c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        break;
10145c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    }
10146c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGAddStates(ctxt, ctxt->states, oldstate);
10147c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGAddStates(ctxt, ctxt->states, ctxt->state);
10148c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ctxt->state = NULL;
10149c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10150c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ctxt->flags = oldflags;
10151c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ret = 0;
10152c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (ctxt->errNr > errNr)
10153c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGPopErrors(ctxt, errNr);
10154c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                break;
10155c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
10156fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_ONEORMORE:
10157c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            errNr = ctxt->errNr;
10158c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            ret = xmlRelaxNGValidateDefinitionList(ctxt, define->content);
10159c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            if (ret != 0) {
10160c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                break;
10161c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
10162c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            if (ctxt->errNr > errNr)
10163c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                xmlRelaxNGPopErrors(ctxt, errNr);
10164c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            /* no break on purpose */
10165c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        case XML_RELAXNG_ZEROORMORE:{
10166c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                int progress;
10167c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                xmlRelaxNGStatesPtr states = NULL, res = NULL;
10168c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                int base, j;
10169c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
10170c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                errNr = ctxt->errNr;
10171c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                res = xmlRelaxNGNewStates(ctxt, 1);
10172c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (res == NULL) {
10173c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ret = -1;
10174c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    break;
10175c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10176c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                /*
10177c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                 * All the input states are also exit states
10178c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                 */
10179c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (ctxt->state != NULL) {
10180c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGAddStates(ctxt, res,
10181c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                        xmlRelaxNGCopyValidState(ctxt,
10182c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                                 ctxt->
10183c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                                 state));
10184c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                } else {
10185c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    for (j = 0; j < ctxt->states->nbState; j++) {
10186c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        xmlRelaxNGAddStates(ctxt, res,
101879fcd462f271fb7bf49b6c7c6993cf42dcf879377Daniel Veillard                            xmlRelaxNGCopyValidState(ctxt,
101889fcd462f271fb7bf49b6c7c6993cf42dcf879377Daniel Veillard                                            ctxt->states->tabState[j]));
10189c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    }
10190c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10191c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                oldflags = ctxt->flags;
10192c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ctxt->flags |= FLAGS_IGNORABLE;
10193c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                do {
10194c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    progress = 0;
10195c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    base = res->nbState;
10196c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
10197c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (ctxt->states != NULL) {
10198c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        states = ctxt->states;
10199c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        for (i = 0; i < states->nbState; i++) {
10200c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            ctxt->state = states->tabState[i];
10201c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            ctxt->states = NULL;
10202c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            ret = xmlRelaxNGValidateDefinitionList(ctxt,
10203c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                                   define->
10204c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                                   content);
10205c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            if (ret == 0) {
10206c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                if (ctxt->state != NULL) {
10207c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                    tmp = xmlRelaxNGAddStates(ctxt, res,
10208c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                              ctxt->state);
10209c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                    ctxt->state = NULL;
10210c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                    if (tmp == 1)
10211c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                        progress = 1;
10212c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                } else if (ctxt->states != NULL) {
10213c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                    for (j = 0; j < ctxt->states->nbState;
10214c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                         j++) {
10215c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                        tmp =
10216c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                            xmlRelaxNGAddStates(ctxt, res,
102179fcd462f271fb7bf49b6c7c6993cf42dcf879377Daniel Veillard                                                   ctxt->states->tabState[j]);
10218c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                        if (tmp == 1)
10219c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                            progress = 1;
10220c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                    }
10221c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                    xmlRelaxNGFreeStates(ctxt,
10222c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                         ctxt->states);
10223c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                    ctxt->states = NULL;
10224c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                }
10225c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            } else {
10226c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                if (ctxt->state != NULL) {
10227c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                    xmlRelaxNGFreeValidState(ctxt,
10228c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                             ctxt->state);
10229c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                    ctxt->state = NULL;
10230c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                }
10231c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            }
10232c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        }
10233c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    } else {
10234c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        ret = xmlRelaxNGValidateDefinitionList(ctxt,
10235c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                               define->
10236c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                               content);
10237c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        if (ret != 0) {
10238c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            xmlRelaxNGFreeValidState(ctxt, ctxt->state);
10239c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            ctxt->state = NULL;
10240c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        } else {
10241c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            base = res->nbState;
10242c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            if (ctxt->state != NULL) {
10243c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                tmp = xmlRelaxNGAddStates(ctxt, res,
10244c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                          ctxt->state);
10245c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                ctxt->state = NULL;
10246c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                if (tmp == 1)
10247c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                    progress = 1;
10248c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            } else if (ctxt->states != NULL) {
10249c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                for (j = 0; j < ctxt->states->nbState; j++) {
10250c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                    tmp = xmlRelaxNGAddStates(ctxt, res,
102519fcd462f271fb7bf49b6c7c6993cf42dcf879377Daniel Veillard                                               ctxt->states->tabState[j]);
10252c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                    if (tmp == 1)
10253c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                        progress = 1;
10254c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                }
10255c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                if (states == NULL) {
10256c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                    states = ctxt->states;
10257c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                } else {
10258c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                    xmlRelaxNGFreeStates(ctxt,
10259c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                         ctxt->states);
10260c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                }
10261c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                ctxt->states = NULL;
10262c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            }
10263c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        }
10264c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    }
10265c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (progress) {
10266c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        /*
10267c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                         * Collect all the new nodes added at that step
10268c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                         * and make them the new node set
10269c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                         */
10270c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        if (res->nbState - base == 1) {
10271c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            ctxt->state = xmlRelaxNGCopyValidState(ctxt,
10272c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                                   res->
10273c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                                   tabState
10274c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                                   [base]);
10275c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        } else {
10276c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            if (states == NULL) {
10277c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                xmlRelaxNGNewStates(ctxt,
10278c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                    res->nbState - base);
1027914b5643947845df089376106517c4f7ba061e4b0Daniel Veillard			        states = ctxt->states;
1028014b5643947845df089376106517c4f7ba061e4b0Daniel Veillard				if (states == NULL) {
1028114b5643947845df089376106517c4f7ba061e4b0Daniel Veillard				    progress = 0;
1028214b5643947845df089376106517c4f7ba061e4b0Daniel Veillard				    break;
1028314b5643947845df089376106517c4f7ba061e4b0Daniel Veillard				}
10284c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            }
10285c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            states->nbState = 0;
10286c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            for (i = base; i < res->nbState; i++)
10287c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                xmlRelaxNGAddStates(ctxt, states,
10288c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                    xmlRelaxNGCopyValidState
102899fcd462f271fb7bf49b6c7c6993cf42dcf879377Daniel Veillard                                                    (ctxt, res->tabState[i]));
10290c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            ctxt->states = states;
10291c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        }
10292c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    }
10293c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                } while (progress == 1);
10294c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (states != NULL) {
10295c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGFreeStates(ctxt, states);
10296c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10297c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ctxt->states = res;
10298c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ctxt->flags = oldflags;
10299c1ffa0ab97d0724acfc947e20873959da72b1b5dDaniel Veillard#if 0
10300c1ffa0ab97d0724acfc947e20873959da72b1b5dDaniel Veillard                /*
103014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 * errors may have to be propagated back...
103024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                 */
10303c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (ctxt->errNr > errNr)
10304c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGPopErrors(ctxt, errNr);
10305c1ffa0ab97d0724acfc947e20873959da72b1b5dDaniel Veillard#endif
10306c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ret = 0;
10307c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                break;
10308c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
10309c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        case XML_RELAXNG_CHOICE:{
10310c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                xmlRelaxNGDefinePtr list = NULL;
10311c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                xmlRelaxNGStatesPtr states = NULL;
10312c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
10313c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                node = xmlRelaxNGSkipIgnored(ctxt, node);
10314c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
10315c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                errNr = ctxt->errNr;
103169186a1fdb637c71a7fbeb76e0bbe6104ee345de3Daniel Veillard                if ((define->dflags & IS_TRIABLE) && (define->data != NULL) &&
103179186a1fdb637c71a7fbeb76e0bbe6104ee345de3Daniel Veillard		    (node != NULL)) {
103189186a1fdb637c71a7fbeb76e0bbe6104ee345de3Daniel Veillard		    /*
103199186a1fdb637c71a7fbeb76e0bbe6104ee345de3Daniel Veillard		     * node == NULL can't be optimized since IS_TRIABLE
103209186a1fdb637c71a7fbeb76e0bbe6104ee345de3Daniel Veillard		     * doesn't account for choice which may lead to
103219186a1fdb637c71a7fbeb76e0bbe6104ee345de3Daniel Veillard		     * only attributes.
103229186a1fdb637c71a7fbeb76e0bbe6104ee345de3Daniel Veillard		     */
10323c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlHashTablePtr triage =
10324c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        (xmlHashTablePtr) define->data;
10325c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
10326c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    /*
10327c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                     * Something we can optimize cleanly there is only one
10328c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                     * possble branch out !
10329c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                     */
10330c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if ((node->type == XML_TEXT_NODE) ||
10331c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        (node->type == XML_CDATA_SECTION_NODE)) {
10332c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        list =
10333c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            xmlHashLookup2(triage, BAD_CAST "#text", NULL);
10334c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    } else if (node->type == XML_ELEMENT_NODE) {
10335c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        if (node->ns != NULL) {
10336c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            list = xmlHashLookup2(triage, node->name,
10337c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                  node->ns->href);
10338c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            if (list == NULL)
10339c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                list =
10340c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                    xmlHashLookup2(triage, BAD_CAST "#any",
10341c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                   node->ns->href);
10342c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        } else
10343c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            list =
10344c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                xmlHashLookup2(triage, node->name, NULL);
10345c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        if (list == NULL)
10346c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            list =
10347c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                xmlHashLookup2(triage, BAD_CAST "#any",
10348c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                               NULL);
10349c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    }
10350c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (list == NULL) {
10351c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        ret = -1;
103522f07606d109eabf6e19431d9b9e907b604f1bc45William M. Brack			VALID_ERR2(XML_RELAXNG_ERR_ELEMWRONG, node->name);
10353c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        break;
10354c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    }
10355c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ret = xmlRelaxNGValidateDefinition(ctxt, list);
10356c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (ret == 0) {
10357c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    }
10358c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    break;
10359c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10360c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
10361c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                list = define->content;
10362c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                oldflags = ctxt->flags;
10363c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ctxt->flags |= FLAGS_IGNORABLE;
10364c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
10365c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                while (list != NULL) {
10366c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    oldstate = xmlRelaxNGCopyValidState(ctxt, ctxt->state);
10367c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ret = xmlRelaxNGValidateDefinition(ctxt, list);
10368c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (ret == 0) {
10369c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        if (states == NULL) {
10370c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            states = xmlRelaxNGNewStates(ctxt, 1);
10371c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        }
10372c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        if (ctxt->state != NULL) {
10373c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            xmlRelaxNGAddStates(ctxt, states, ctxt->state);
10374c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        } else if (ctxt->states != NULL) {
10375c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            for (i = 0; i < ctxt->states->nbState; i++) {
10376c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                xmlRelaxNGAddStates(ctxt, states,
10377c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                    ctxt->states->
10378c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                    tabState[i]);
10379c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            }
10380c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            xmlRelaxNGFreeStates(ctxt, ctxt->states);
10381c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                            ctxt->states = NULL;
10382c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        }
10383c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    } else {
10384c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        xmlRelaxNGFreeValidState(ctxt, ctxt->state);
10385c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    }
10386c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ctxt->state = oldstate;
10387c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    list = list->next;
10388c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10389c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (states != NULL) {
10390c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlRelaxNGFreeValidState(ctxt, oldstate);
10391c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ctxt->states = states;
10392c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ctxt->state = NULL;
10393c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ret = 0;
10394c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                } else {
10395c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ctxt->states = NULL;
10396c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10397c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ctxt->flags = oldflags;
10398c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (ret != 0) {
10399c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if ((ctxt->flags & FLAGS_IGNORABLE) == 0) {
10400c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        xmlRelaxNGDumpValidError(ctxt);
10401c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    }
10402c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                } else {
10403c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (ctxt->errNr > errNr)
10404c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        xmlRelaxNGPopErrors(ctxt, errNr);
10405c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10406c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                break;
10407c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
10408fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_DEF:
10409fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_GROUP:
10410c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            ret = xmlRelaxNGValidateDefinitionList(ctxt, define->content);
10411c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            break;
10412fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_INTERLEAVE:
10413c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            ret = xmlRelaxNGValidateInterleave(ctxt, define);
10414c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            break;
10415fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_ATTRIBUTE:
10416c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            ret = xmlRelaxNGValidateAttribute(ctxt, define);
10417c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            break;
10418f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        case XML_RELAXNG_START:
10419c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        case XML_RELAXNG_NOOP:
10420fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard        case XML_RELAXNG_REF:
10421c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        case XML_RELAXNG_EXTERNALREF:
10422952379b780ff6071f8276b02f776ac1db3721b58Daniel Veillard        case XML_RELAXNG_PARENTREF:
10423c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            ret = xmlRelaxNGValidateDefinition(ctxt, define->content);
10424c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            break;
10425c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        case XML_RELAXNG_DATATYPE:{
10426c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                xmlNodePtr child;
10427c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                xmlChar *content = NULL;
10428c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
10429c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                child = node;
10430c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                while (child != NULL) {
10431c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (child->type == XML_ELEMENT_NODE) {
10432c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        VALID_ERR2(XML_RELAXNG_ERR_DATAELEM,
10433c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                   node->parent->name);
10434c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        ret = -1;
10435c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        break;
10436c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    } else if ((child->type == XML_TEXT_NODE) ||
10437c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                               (child->type == XML_CDATA_SECTION_NODE)) {
10438c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        content = xmlStrcat(content, child->content);
10439c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    }
10440c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    /* TODO: handle entities ... */
10441c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    child = child->next;
10442c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10443c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (ret == -1) {
10444c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (content != NULL)
10445c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        xmlFree(content);
10446c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    break;
10447c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10448c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (content == NULL) {
10449c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    content = xmlStrdup(BAD_CAST "");
10450c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (content == NULL) {
104514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRngVErrMemory(ctxt, "validating\n");
10452c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        ret = -1;
10453c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        break;
10454c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    }
10455c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10456c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ret = xmlRelaxNGValidateDatatype(ctxt, content, define,
10457c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                                 ctxt->state->seq);
10458c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (ret == -1) {
10459c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    VALID_ERR2(XML_RELAXNG_ERR_DATATYPE, define->name);
10460c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                } else if (ret == 0) {
10461c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ctxt->state->seq = NULL;
10462c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10463c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (content != NULL)
10464c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlFree(content);
10465c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                break;
10466c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
10467c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        case XML_RELAXNG_VALUE:{
10468c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                xmlChar *content = NULL;
10469c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                xmlChar *oldvalue;
10470c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                xmlNodePtr child;
10471c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
10472c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                child = node;
10473c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                while (child != NULL) {
10474c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (child->type == XML_ELEMENT_NODE) {
10475c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        VALID_ERR2(XML_RELAXNG_ERR_VALELEM,
10476c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                   node->parent->name);
10477c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        ret = -1;
10478c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        break;
10479c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    } else if ((child->type == XML_TEXT_NODE) ||
10480c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                               (child->type == XML_CDATA_SECTION_NODE)) {
10481c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        content = xmlStrcat(content, child->content);
10482c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    }
10483c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    /* TODO: handle entities ... */
10484c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    child = child->next;
10485c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10486c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (ret == -1) {
10487c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (content != NULL)
10488c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        xmlFree(content);
10489c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    break;
10490c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10491c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (content == NULL) {
10492c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    content = xmlStrdup(BAD_CAST "");
10493c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (content == NULL) {
104944c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRngVErrMemory(ctxt, "validating\n");
10495c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        ret = -1;
10496c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        break;
10497c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    }
10498c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10499c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                oldvalue = ctxt->state->value;
10500c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ctxt->state->value = content;
10501c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ret = xmlRelaxNGValidateValue(ctxt, define);
10502c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ctxt->state->value = oldvalue;
10503c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (ret == -1) {
10504c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    VALID_ERR2(XML_RELAXNG_ERR_VALUE, define->name);
10505c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                } else if (ret == 0) {
10506c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ctxt->state->seq = NULL;
10507c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10508c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (content != NULL)
10509c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlFree(content);
10510c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                break;
10511c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
10512c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        case XML_RELAXNG_LIST:{
10513c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                xmlChar *content;
10514c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                xmlNodePtr child;
10515c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                xmlChar *oldvalue, *oldendvalue;
10516c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                int len;
10517c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
10518c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                /*
10519c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                 * Make sure it's only text nodes
10520c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                 */
10521c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard
10522c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                content = NULL;
10523c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                child = node;
10524c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                while (child != NULL) {
10525c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (child->type == XML_ELEMENT_NODE) {
10526c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        VALID_ERR2(XML_RELAXNG_ERR_LISTELEM,
10527c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                                   node->parent->name);
10528c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        ret = -1;
10529c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        break;
10530c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    } else if ((child->type == XML_TEXT_NODE) ||
10531c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                               (child->type == XML_CDATA_SECTION_NODE)) {
10532c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        content = xmlStrcat(content, child->content);
10533c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    }
10534c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    /* TODO: handle entities ... */
10535c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    child = child->next;
10536c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10537c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (ret == -1) {
10538c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (content != NULL)
10539c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        xmlFree(content);
10540c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    break;
10541c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10542c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (content == NULL) {
10543c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    content = xmlStrdup(BAD_CAST "");
10544c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    if (content == NULL) {
105454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRngVErrMemory(ctxt, "validating\n");
10546c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        ret = -1;
10547c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                        break;
10548c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    }
10549c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10550c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                len = xmlStrlen(content);
10551c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                oldvalue = ctxt->state->value;
10552c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                oldendvalue = ctxt->state->endvalue;
10553c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ctxt->state->value = content;
10554c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ctxt->state->endvalue = content + len;
10555c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ret = xmlRelaxNGValidateValue(ctxt, define);
10556c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ctxt->state->value = oldvalue;
10557c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                ctxt->state->endvalue = oldendvalue;
10558c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (ret == -1) {
10559c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    VALID_ERR(XML_RELAXNG_ERR_LIST);
10560c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                } else if ((ret == 0) && (node != NULL)) {
10561c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    ctxt->state->seq = node->next;
10562c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                }
10563c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                if (content != NULL)
10564c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    xmlFree(content);
10565c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                break;
10566c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            }
10567c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        case XML_RELAXNG_EXCEPT:
10568c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        case XML_RELAXNG_PARAM:
10569c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            TODO ret = -1;
10570c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard            break;
105711564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    }
10572fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    ctxt->depth--;
105731564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard#ifdef DEBUG
10574c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    for (i = 0; i < ctxt->depth; i++)
10575c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        xmlGenericError(xmlGenericErrorContext, " ");
10576fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlGenericError(xmlGenericErrorContext,
10577c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard                    "Validating %s ", xmlRelaxNGDefName(define));
10578fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (define->name != NULL)
10579c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        xmlGenericError(xmlGenericErrorContext, "%s ", define->name);
10580fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (ret == 0)
10581c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        xmlGenericError(xmlGenericErrorContext, "suceeded\n");
10582fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    else
10583c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard        xmlGenericError(xmlGenericErrorContext, "failed\n");
105841564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard#endif
10585c58f4efbd44a4b155e5399cbe97525570ebc8385Daniel Veillard    return (ret);
105861564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard}
105871564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
105881564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard/**
10589fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * xmlRelaxNGValidateDefinition:
105901564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * @ctxt:  a Relax-NG validation context
105911564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard * @define:  the definition to verify
105921564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard *
10593fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Validate the current node lists against the definition
105941564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard *
10595fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard * Returns 0 if the validation succeeded or an error code.
105961564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard */
10597fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillardstatic int
105984c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,
105994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                             xmlRelaxNGDefinePtr define)
106004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
10601fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlRelaxNGStatesPtr states, res;
10602fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    int i, j, k, ret, oldflags;
106031564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
10604fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    /*
10605fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     * We should NOT have both ctxt->state and ctxt->states
10606fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard     */
10607fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
106084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
106094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state = NULL;
106101564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    }
106111564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard
10612fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if ((ctxt->states == NULL) || (ctxt->states->nbState == 1)) {
106134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->states != NULL) {
106144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->state = ctxt->states->tabState[0];
106154c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGFreeStates(ctxt, ctxt->states);
106164c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->states = NULL;
106174c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
106184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = xmlRelaxNGValidateState(ctxt, define);
106194c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
106204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
106214c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->state = NULL;
106224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
106234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((ctxt->states != NULL) && (ctxt->states->nbState == 1)) {
106244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->state = ctxt->states->tabState[0];
106254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGFreeStates(ctxt, ctxt->states);
106264c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->states = NULL;
106274c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
106284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (ret);
10629fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
10630fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard
10631fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    states = ctxt->states;
10632fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    ctxt->states = NULL;
10633fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    res = NULL;
10634fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    j = 0;
10635fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    oldflags = ctxt->flags;
10636fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    ctxt->flags |= FLAGS_IGNORABLE;
106374c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    for (i = 0; i < states->nbState; i++) {
106384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state = states->tabState[i];
106394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->states = NULL;
106404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = xmlRelaxNGValidateState(ctxt, define);
106414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        /*
106424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         * We should NOT have both ctxt->state and ctxt->states
106434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard         */
106444c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
106454c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
106464c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->state = NULL;
106474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
106484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ret == 0) {
106494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ctxt->states == NULL) {
106504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (res != NULL) {
106514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    /* add the state to the container */
106524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGAddStates(ctxt, res, ctxt->state);
106534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ctxt->state = NULL;
106544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else {
106554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    /* add the state directly in states */
106564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    states->tabState[j++] = ctxt->state;
106574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ctxt->state = NULL;
106584c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
106594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else {
106604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                if (res == NULL) {
106614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    /* make it the new container and copy other results */
106624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    res = ctxt->states;
106634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ctxt->states = NULL;
106644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    for (k = 0; k < j; k++)
106654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGAddStates(ctxt, res,
106664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                            states->tabState[k]);
106674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                } else {
106684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    /* add all the new results to res and reff the container */
106694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    for (k = 0; k < ctxt->states->nbState; k++)
106704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                        xmlRelaxNGAddStates(ctxt, res,
106714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                            ctxt->states->tabState[k]);
106724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGFreeStates(ctxt, ctxt->states);
106734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ctxt->states = NULL;
106744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                }
106754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
106764c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        } else {
106774c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ctxt->state != NULL) {
106784c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGFreeValidState(ctxt, ctxt->state);
106794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->state = NULL;
106804c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            } else if (ctxt->states != NULL) {
106814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                for (k = 0; k < ctxt->states->nbState; k++)
106824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    xmlRelaxNGFreeValidState(ctxt,
106834c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                                             ctxt->states->tabState[k]);
106844c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                xmlRelaxNGFreeStates(ctxt, ctxt->states);
106854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ctxt->states = NULL;
106864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
106874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
106886eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
10689fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    ctxt->flags = oldflags;
10690fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (res != NULL) {
106914c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeStates(ctxt, states);
106924c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->states = res;
106934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = 0;
10694fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    } else if (j > 1) {
106954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        states->nbState = j;
106964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->states = states;
106974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = 0;
10698fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    } else if (j == 1) {
106994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state = states->tabState[0];
107004c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeStates(ctxt, states);
107014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = 0;
10702fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    } else {
107034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = -1;
107044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeStates(ctxt, states);
107054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (ctxt->states != NULL) {
107064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGFreeStates(ctxt, ctxt->states);
107074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ctxt->states = NULL;
107084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
10709fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    }
10710fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
107114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
107124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state = NULL;
107131564e6e52ef9a944c41736c74edb475671ae798cDaniel Veillard    }
107144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
107156eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
107166eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
107176eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
107186eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGValidateDocument:
107196eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG validation context
107206eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @doc:  the document
107216eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
107226eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Validate the given document
107236eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
107246eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns 0 if the validation succeeded or an error code.
107256eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
107266eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardstatic int
107274c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGValidateDocument(xmlRelaxNGValidCtxtPtr ctxt, xmlDocPtr doc)
107284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
107296eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    int ret;
107306eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGPtr schema;
107316eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGGrammarPtr grammar;
107326eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGValidStatePtr state;
10733fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    xmlNodePtr node;
107346eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
107356eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if ((ctxt == NULL) || (ctxt->schema == NULL) || (doc == NULL))
107364c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
107376eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
10738a507fbf3c2fce830a71445f4684383b9754ab83cDaniel Veillard    ctxt->errNo = XML_RELAXNG_OK;
107396eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    schema = ctxt->schema;
107406eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    grammar = schema->topgrammar;
107416eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (grammar == NULL) {
107424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        VALID_ERR(XML_RELAXNG_ERR_NOGRAMMAR);
107434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
107446eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
107456eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    state = xmlRelaxNGNewValidState(ctxt, NULL);
107466eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ctxt->state = state;
107476eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ret = xmlRelaxNGValidateDefinition(ctxt, grammar->start);
10748fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if ((ctxt->state != NULL) && (state->seq != NULL)) {
107494c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        state = ctxt->state;
107504c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        node = state->seq;
107514c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        node = xmlRelaxNGSkipIgnored(ctxt, node);
107524c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (node != NULL) {
107534c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret != -1) {
107544c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                VALID_ERR(XML_RELAXNG_ERR_EXTRADATA);
107554c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = -1;
107564c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
107574c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
10758fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    } else if (ctxt->states != NULL) {
107594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        int i;
107604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        int tmp = -1;
107614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
107624c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        for (i = 0; i < ctxt->states->nbState; i++) {
107634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            state = ctxt->states->tabState[i];
107644c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            node = state->seq;
107654c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            node = xmlRelaxNGSkipIgnored(ctxt, node);
107664c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (node == NULL)
107674c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                tmp = 0;
107684c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGFreeValidState(ctxt, state);
107694c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
107704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (tmp == -1) {
107714c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            if (ret != -1) {
107724c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                VALID_ERR(XML_RELAXNG_ERR_EXTRADATA);
107734c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                ret = -1;
107744c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            }
107754c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
107766eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
10777bbb78b5d6d18b008bbd14edefecde4156d85f949Daniel Veillard    if (ctxt->state != NULL) {
10778bbb78b5d6d18b008bbd14edefecde4156d85f949Daniel Veillard        xmlRelaxNGFreeValidState(ctxt, ctxt->state);
107794c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->state = NULL;
10780bbb78b5d6d18b008bbd14edefecde4156d85f949Daniel Veillard    }
107814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (ret != 0)
107824c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGDumpValidError(ctxt);
10783580ced8ee28ecd99374da9383897678e4ba6c358Daniel Veillard#ifdef DEBUG
10784580ced8ee28ecd99374da9383897678e4ba6c358Daniel Veillard    else if (ctxt->errNr != 0) {
107854c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ctxt->error(ctxt->userData,
107864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    "%d Extra error messages left on stack !\n",
107874c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                    ctxt->errNr);
107884c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGDumpValidError(ctxt);
10789580ced8ee28ecd99374da9383897678e4ba6c358Daniel Veillard    }
10790580ced8ee28ecd99374da9383897678e4ba6c358Daniel Veillard#endif
10791f54cd533d8014ab04e9601ca8b05ee8a6b5c6e3fDaniel Veillard#ifdef LIBXML_VALID_ENABLED
10792c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard    if (ctxt->idref == 1) {
107934c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlValidCtxt vctxt;
10794c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard
107954c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        memset(&vctxt, 0, sizeof(xmlValidCtxt));
107964c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        vctxt.valid = 1;
107974c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        vctxt.error = ctxt->error;
107984c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        vctxt.warning = ctxt->warning;
107994c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        vctxt.userData = ctxt->userData;
10800c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard
108014c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        if (xmlValidateDocumentFinal(&vctxt, doc) != 1)
108024c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            ret = -1;
10803c3da18a148ac4abf9209f6af738cb9e2b65e5a24Daniel Veillard    }
10804f54cd533d8014ab04e9601ca8b05ee8a6b5c6e3fDaniel Veillard#endif /* LIBXML_VALID_ENABLED */
10805a507fbf3c2fce830a71445f4684383b9754ab83cDaniel Veillard    if ((ret == 0) && (ctxt->errNo != XML_RELAXNG_OK))
108064c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        ret = -1;
108076eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
108084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
108096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
108106eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
10811a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard/**
10812a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard * xmlRelaxNGCleanPSVI:
10813a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard * @node:  an input element or document
10814a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard *
10815a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard * Call this routine to speed up XPath computation on static documents.
10816a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard * This stamps all the element nodes with the document order
10817a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard * Like for line information, the order is kept in the element->content
10818a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard * field, the value stored is actually - the node number (starting at -1)
10819a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard * to be able to differentiate from line numbers.
10820a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard *
10821a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard * Returns the number of elements found in the document or -1 in case
10822a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard *    of error.
10823a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard */
10824a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillardstatic void
10825a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel VeillardxmlRelaxNGCleanPSVI(xmlNodePtr node) {
10826a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard    xmlNodePtr cur;
10827a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard
10828a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard    if ((node == NULL) ||
10829a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard        ((node->type != XML_ELEMENT_NODE) &&
10830a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard         (node->type != XML_DOCUMENT_NODE) &&
10831a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard         (node->type != XML_HTML_DOCUMENT_NODE)))
10832a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	return;
10833a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard    if (node->type == XML_ELEMENT_NODE)
10834a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard        node->psvi = NULL;
10835a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard
10836a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard    cur = node->children;
10837a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard    while (cur != NULL) {
10838a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	if (cur->type == XML_ELEMENT_NODE) {
10839a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	    cur->psvi = NULL;
10840a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	    if (cur->children != NULL) {
10841a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard		cur = cur->children;
10842a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard		continue;
10843a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	    }
10844a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	}
10845a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	if (cur->next != NULL) {
10846a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	    cur = cur->next;
10847a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	    continue;
10848a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	}
10849a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	do {
10850a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	    cur = cur->parent;
10851a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	    if (cur == NULL)
10852a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard		break;
10853a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	    if (cur == node) {
10854a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard		cur = NULL;
10855a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard		break;
10856a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	    }
10857a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	    if (cur->next != NULL) {
10858a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard		cur = cur->next;
10859a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard		break;
10860a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	    }
10861a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard	} while (cur != NULL);
10862a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard    }
10863a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard    return;
10864a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard}
10865fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard/************************************************************************
10866f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
10867f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *			Validation interfaces				*
10868f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard *									*
10869fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard ************************************************************************/
108704c0041471199f283c4e696526c73e2809da54e21Daniel Veillard
108716eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
108726eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGNewValidCtxt:
108736eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @schema:  a precompiled XML RelaxNGs
108746eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
108756eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Create an XML RelaxNGs validation context based on the given schema
108766eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
108776eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns the validation context or NULL in case of error
108786eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
108796eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGValidCtxtPtr
108804c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGNewValidCtxt(xmlRelaxNGPtr schema)
108814c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
108826eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlRelaxNGValidCtxtPtr ret;
108836eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
108846eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ret = (xmlRelaxNGValidCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGValidCtxt));
108856eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ret == NULL) {
108864c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRngVErrMemory(NULL, "building context\n");
108876eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard        return (NULL);
108886eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    }
108896eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    memset(ret, 0, sizeof(xmlRelaxNGValidCtxt));
108906eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ret->schema = schema;
108911703c5fc238e76532f654747259a20a29c769942Daniel Veillard    ret->error = xmlGenericError;
108921703c5fc238e76532f654747259a20a29c769942Daniel Veillard    ret->userData = xmlGenericErrorContext;
1089342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    ret->errNr = 0;
1089442f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    ret->errMax = 0;
1089542f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    ret->err = NULL;
1089642f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    ret->errTab = NULL;
10897b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard    if (schema != NULL)
10898b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard	ret->idref = schema->idref;
10899798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    ret->states = NULL;
10900798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    ret->freeState = NULL;
10901798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    ret->freeStates = NULL;
10902a507fbf3c2fce830a71445f4684383b9754ab83cDaniel Veillard    ret->errNo = XML_RELAXNG_OK;
109036eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    return (ret);
109046eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
109056eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
109066eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
109076eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGFreeValidCtxt:
109086eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  the schema validation context
109096eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
109106eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Free the resources associated to the schema validation context
109116eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
109126eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardvoid
109134c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGFreeValidCtxt(xmlRelaxNGValidCtxtPtr ctxt)
109144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
10915798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    int k;
10916798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard
109176eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ctxt == NULL)
109184c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
10919fd573f18a53ab92101471a9c95af6cca5e4e3b1eDaniel Veillard    if (ctxt->states != NULL)
109204c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeStates(NULL, ctxt->states);
10921798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    if (ctxt->freeState != NULL) {
109224c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        for (k = 0; k < ctxt->freeState->nbState; k++) {
109234c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGFreeValidState(NULL, ctxt->freeState->tabState[k]);
109244c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
109254c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlRelaxNGFreeStates(NULL, ctxt->freeState);
10926798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    }
10927798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    if (ctxt->freeStates != NULL) {
109284c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        for (k = 0; k < ctxt->freeStatesNr; k++) {
109294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRelaxNGFreeStates(NULL, ctxt->freeStates[k]);
109304c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
109314c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(ctxt->freeStates);
10932798024a1106a00891a12e5a56ee1a0048697ed46Daniel Veillard    }
1093342f12e99d17a2979d26b6b2237b21a096c0e98b6Daniel Veillard    if (ctxt->errTab != NULL)
109344c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(ctxt->errTab);
10935f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    if (ctxt->elemTab != NULL) {
10936f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard        xmlRegExecCtxtPtr exec;
10937f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard
109384c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        exec = xmlRelaxNGElemPop(ctxt);
109394c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        while (exec != NULL) {
109404c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            xmlRegFreeExecCtxt(exec);
109414c0041471199f283c4e696526c73e2809da54e21Daniel Veillard            exec = xmlRelaxNGElemPop(ctxt);
109424c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        }
109434c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        xmlFree(ctxt->elemTab);
10944f4e5576f8f34362b6bec9396ab073fac839dfb22Daniel Veillard    }
109456eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    xmlFree(ctxt);
109466eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
109476eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
109486eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
109496eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGSetValidErrors:
109506eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG validation context
109516eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @err:  the error function
109526eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @warn: the warning function
109536eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctx: the functions context
109546eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
109556eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Set the error and warning callback informations
109566eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
109576eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardvoid
109586eadf63ca646866fde6e4df8720e4bdced351a42Daniel VeillardxmlRelaxNGSetValidErrors(xmlRelaxNGValidCtxtPtr ctxt,
109594c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         xmlRelaxNGValidityErrorFunc err,
109604c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         xmlRelaxNGValidityWarningFunc warn, void *ctx)
109614c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
109626eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if (ctxt == NULL)
109634c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return;
109646eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ctxt->error = err;
109656eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ctxt->warning = warn;
109666eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ctxt->userData = ctx;
10967b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard    ctxt->serror = NULL;
109686eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
109696eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
109706eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard/**
10971da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel Veillard * xmlRelaxNGSetValidStructuredErrors:
10972da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel Veillard * @ctxt:  a Relax-NG validation context
10973da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel Veillard * @serror:  the structured error function
10974da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel Veillard * @ctx: the functions context
10975da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel Veillard *
10976da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel Veillard * Set the structured error callback
10977da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel Veillard */
10978da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel Veillardvoid
10979da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel VeillardxmlRelaxNGSetValidStructuredErrors(xmlRelaxNGValidCtxtPtr ctxt,
10980b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard                                   xmlStructuredErrorFunc serror, void *ctx)
10981da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel Veillard{
10982da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel Veillard    if (ctxt == NULL)
10983da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel Veillard        return;
10984b30ca313b571ee705e9b78a0ccec009746238c9bDaniel Veillard    ctxt->serror = serror;
10985da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel Veillard    ctxt->error = NULL;
10986da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel Veillard    ctxt->warning = NULL;
10987da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel Veillard    ctxt->userData = ctx;
10988da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel Veillard}
10989da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel Veillard
10990da0aa4cfdbd9b71e01bc452c95d044bbe66e1b5aDaniel Veillard/**
10991409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard * xmlRelaxNGGetValidErrors:
10992409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard * @ctxt:  a Relax-NG validation context
10993409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard * @err:  the error function result
10994409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard * @warn: the warning function result
10995409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard * @ctx: the functions context result
10996409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard *
10997409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard * Get the error and warning callback informations
10998409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard *
10999409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard * Returns -1 in case of error and 0 otherwise
11000409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard */
11001409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillardint
11002409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel VeillardxmlRelaxNGGetValidErrors(xmlRelaxNGValidCtxtPtr ctxt,
110034c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         xmlRelaxNGValidityErrorFunc * err,
110044c0041471199f283c4e696526c73e2809da54e21Daniel Veillard                         xmlRelaxNGValidityWarningFunc * warn, void **ctx)
110054c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
11006409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard    if (ctxt == NULL)
110074c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
110084c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (err != NULL)
110094c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        *err = ctxt->error;
110104c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (warn != NULL)
110114c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        *warn = ctxt->warning;
110124c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    if (ctx != NULL)
110134c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        *ctx = ctxt->userData;
110144c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (0);
11015409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard}
11016409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard
11017409a8147c1b5784f6c860ec6de7d94fd59a130ceDaniel Veillard/**
110186eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * xmlRelaxNGValidateDoc:
110196eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @ctxt:  a Relax-NG validation context
110206eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * @doc:  a parsed document tree
110216eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
110226eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Validate a document tree in memory.
110236eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *
110246eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard * Returns 0 if the document is valid, a positive error code
110256eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard *     number otherwise and -1 in case of internal or API error.
110266eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard */
110276eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillardint
110284c0041471199f283c4e696526c73e2809da54e21Daniel VeillardxmlRelaxNGValidateDoc(xmlRelaxNGValidCtxtPtr ctxt, xmlDocPtr doc)
110294c0041471199f283c4e696526c73e2809da54e21Daniel Veillard{
110306eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    int ret;
110316eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
110326eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    if ((ctxt == NULL) || (doc == NULL))
110334c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (-1);
110346eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
110356eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ctxt->doc = doc;
110366eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
110376eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard    ret = xmlRelaxNGValidateDocument(ctxt, doc);
1103871531f33450f9a809eab050104e55c84b77b2a9eDaniel Veillard    /*
11039a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard     * Remove all left PSVI
11040a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard     */
11041a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard    xmlRelaxNGCleanPSVI((xmlNodePtr) doc);
11042a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard
11043a4f27cb649896b37a6f3ae8511caa20a1f709176Daniel Veillard    /*
1104471531f33450f9a809eab050104e55c84b77b2a9eDaniel Veillard     * TODO: build error codes
1104571531f33450f9a809eab050104e55c84b77b2a9eDaniel Veillard     */
1104671531f33450f9a809eab050104e55c84b77b2a9eDaniel Veillard    if (ret == -1)
110474c0041471199f283c4e696526c73e2809da54e21Daniel Veillard        return (1);
110484c0041471199f283c4e696526c73e2809da54e21Daniel Veillard    return (ret);
110496eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard}
110506eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard
110515d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#define bottom_relaxng
110525d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#include "elfgcchack.h"
110536eadf63ca646866fde6e4df8720e4bdced351a42Daniel Veillard#endif /* LIBXML_SCHEMAS_ENABLED */
11054