1*7c568831SAndroid Build Coastguard Worker /*
2*7c568831SAndroid Build Coastguard Worker * relaxng.c : implementation of the Relax-NG handling and validity checking
3*7c568831SAndroid Build Coastguard Worker *
4*7c568831SAndroid Build Coastguard Worker * See Copyright for the status of this software.
5*7c568831SAndroid Build Coastguard Worker *
6*7c568831SAndroid Build Coastguard Worker * Daniel Veillard <[email protected]>
7*7c568831SAndroid Build Coastguard Worker */
8*7c568831SAndroid Build Coastguard Worker
9*7c568831SAndroid Build Coastguard Worker /**
10*7c568831SAndroid Build Coastguard Worker * TODO:
11*7c568831SAndroid Build Coastguard Worker * - add support for DTD compatibility spec
12*7c568831SAndroid Build Coastguard Worker * http://www.oasis-open.org/committees/relax-ng/compatibility-20011203.html
13*7c568831SAndroid Build Coastguard Worker * - report better mem allocations pbms at runtime and abort immediately.
14*7c568831SAndroid Build Coastguard Worker */
15*7c568831SAndroid Build Coastguard Worker
16*7c568831SAndroid Build Coastguard Worker #define IN_LIBXML
17*7c568831SAndroid Build Coastguard Worker #include "libxml.h"
18*7c568831SAndroid Build Coastguard Worker
19*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_SCHEMAS_ENABLED
20*7c568831SAndroid Build Coastguard Worker
21*7c568831SAndroid Build Coastguard Worker #include <string.h>
22*7c568831SAndroid Build Coastguard Worker #include <stdio.h>
23*7c568831SAndroid Build Coastguard Worker #include <stddef.h>
24*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlmemory.h>
25*7c568831SAndroid Build Coastguard Worker #include <libxml/parser.h>
26*7c568831SAndroid Build Coastguard Worker #include <libxml/parserInternals.h>
27*7c568831SAndroid Build Coastguard Worker #include <libxml/hash.h>
28*7c568831SAndroid Build Coastguard Worker #include <libxml/uri.h>
29*7c568831SAndroid Build Coastguard Worker
30*7c568831SAndroid Build Coastguard Worker #include <libxml/relaxng.h>
31*7c568831SAndroid Build Coastguard Worker
32*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlschemastypes.h>
33*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlautomata.h>
34*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlregexp.h>
35*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlschemastypes.h>
36*7c568831SAndroid Build Coastguard Worker
37*7c568831SAndroid Build Coastguard Worker #include "private/error.h"
38*7c568831SAndroid Build Coastguard Worker #include "private/regexp.h"
39*7c568831SAndroid Build Coastguard Worker #include "private/string.h"
40*7c568831SAndroid Build Coastguard Worker
41*7c568831SAndroid Build Coastguard Worker /*
42*7c568831SAndroid Build Coastguard Worker * The Relax-NG namespace
43*7c568831SAndroid Build Coastguard Worker */
44*7c568831SAndroid Build Coastguard Worker static const xmlChar *xmlRelaxNGNs = (const xmlChar *)
45*7c568831SAndroid Build Coastguard Worker "http://relaxng.org/ns/structure/1.0";
46*7c568831SAndroid Build Coastguard Worker
47*7c568831SAndroid Build Coastguard Worker #define IS_RELAXNG(node, typ) \
48*7c568831SAndroid Build Coastguard Worker ((node != NULL) && (node->ns != NULL) && \
49*7c568831SAndroid Build Coastguard Worker (node->type == XML_ELEMENT_NODE) && \
50*7c568831SAndroid Build Coastguard Worker (xmlStrEqual(node->name, (const xmlChar *) typ)) && \
51*7c568831SAndroid Build Coastguard Worker (xmlStrEqual(node->ns->href, xmlRelaxNGNs)))
52*7c568831SAndroid Build Coastguard Worker
53*7c568831SAndroid Build Coastguard Worker
54*7c568831SAndroid Build Coastguard Worker #define MAX_ERROR 5
55*7c568831SAndroid Build Coastguard Worker
56*7c568831SAndroid Build Coastguard Worker typedef struct _xmlRelaxNGSchema xmlRelaxNGSchema;
57*7c568831SAndroid Build Coastguard Worker typedef xmlRelaxNGSchema *xmlRelaxNGSchemaPtr;
58*7c568831SAndroid Build Coastguard Worker
59*7c568831SAndroid Build Coastguard Worker typedef struct _xmlRelaxNGDefine xmlRelaxNGDefine;
60*7c568831SAndroid Build Coastguard Worker typedef xmlRelaxNGDefine *xmlRelaxNGDefinePtr;
61*7c568831SAndroid Build Coastguard Worker
62*7c568831SAndroid Build Coastguard Worker typedef struct _xmlRelaxNGDocument xmlRelaxNGDocument;
63*7c568831SAndroid Build Coastguard Worker typedef xmlRelaxNGDocument *xmlRelaxNGDocumentPtr;
64*7c568831SAndroid Build Coastguard Worker
65*7c568831SAndroid Build Coastguard Worker typedef struct _xmlRelaxNGInclude xmlRelaxNGInclude;
66*7c568831SAndroid Build Coastguard Worker typedef xmlRelaxNGInclude *xmlRelaxNGIncludePtr;
67*7c568831SAndroid Build Coastguard Worker
68*7c568831SAndroid Build Coastguard Worker typedef enum {
69*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_COMBINE_UNDEFINED = 0, /* undefined */
70*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_COMBINE_CHOICE, /* choice */
71*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_COMBINE_INTERLEAVE /* interleave */
72*7c568831SAndroid Build Coastguard Worker } xmlRelaxNGCombine;
73*7c568831SAndroid Build Coastguard Worker
74*7c568831SAndroid Build Coastguard Worker typedef enum {
75*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_CONTENT_ERROR = -1,
76*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_CONTENT_EMPTY = 0,
77*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_CONTENT_SIMPLE,
78*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_CONTENT_COMPLEX
79*7c568831SAndroid Build Coastguard Worker } xmlRelaxNGContentType;
80*7c568831SAndroid Build Coastguard Worker
81*7c568831SAndroid Build Coastguard Worker typedef struct _xmlRelaxNGGrammar xmlRelaxNGGrammar;
82*7c568831SAndroid Build Coastguard Worker typedef xmlRelaxNGGrammar *xmlRelaxNGGrammarPtr;
83*7c568831SAndroid Build Coastguard Worker
84*7c568831SAndroid Build Coastguard Worker struct _xmlRelaxNGGrammar {
85*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGrammarPtr parent; /* the parent grammar if any */
86*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGrammarPtr children; /* the children grammar if any */
87*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGrammarPtr next; /* the next grammar if any */
88*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr start; /* <start> content */
89*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCombine combine; /* the default combine value */
90*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr startList; /* list of <start> definitions */
91*7c568831SAndroid Build Coastguard Worker xmlHashTablePtr defs; /* define* */
92*7c568831SAndroid Build Coastguard Worker xmlHashTablePtr refs; /* references */
93*7c568831SAndroid Build Coastguard Worker };
94*7c568831SAndroid Build Coastguard Worker
95*7c568831SAndroid Build Coastguard Worker
96*7c568831SAndroid Build Coastguard Worker typedef enum {
97*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_NOOP = -1, /* a no operation from simplification */
98*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_EMPTY = 0, /* an empty pattern */
99*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_NOT_ALLOWED, /* not allowed top */
100*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_EXCEPT, /* except present in nameclass defs */
101*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_TEXT, /* textual content */
102*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_ELEMENT, /* an element */
103*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_DATATYPE, /* external data type definition */
104*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_PARAM, /* external data type parameter */
105*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_VALUE, /* value from an external data type definition */
106*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_LIST, /* a list of patterns */
107*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_ATTRIBUTE, /* an attribute following a pattern */
108*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_DEF, /* a definition */
109*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_REF, /* reference to a definition */
110*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_EXTERNALREF, /* reference to an external def */
111*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_PARENTREF, /* reference to a def in the parent grammar */
112*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_OPTIONAL, /* optional patterns */
113*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_ZEROORMORE, /* zero or more non empty patterns */
114*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_ONEORMORE, /* one or more non empty patterns */
115*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_CHOICE, /* a choice between non empty patterns */
116*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_GROUP, /* a pair/group of non empty patterns */
117*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_INTERLEAVE, /* interleaving choice of non-empty patterns */
118*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_START /* Used to keep track of starts on grammars */
119*7c568831SAndroid Build Coastguard Worker } xmlRelaxNGType;
120*7c568831SAndroid Build Coastguard Worker
121*7c568831SAndroid Build Coastguard Worker #define IS_NULLABLE (1 << 0)
122*7c568831SAndroid Build Coastguard Worker #define IS_NOT_NULLABLE (1 << 1)
123*7c568831SAndroid Build Coastguard Worker #define IS_INDETERMINIST (1 << 2)
124*7c568831SAndroid Build Coastguard Worker #define IS_MIXED (1 << 3)
125*7c568831SAndroid Build Coastguard Worker #define IS_TRIABLE (1 << 4)
126*7c568831SAndroid Build Coastguard Worker #define IS_PROCESSED (1 << 5)
127*7c568831SAndroid Build Coastguard Worker #define IS_COMPILABLE (1 << 6)
128*7c568831SAndroid Build Coastguard Worker #define IS_NOT_COMPILABLE (1 << 7)
129*7c568831SAndroid Build Coastguard Worker #define IS_EXTERNAL_REF (1 << 8)
130*7c568831SAndroid Build Coastguard Worker
131*7c568831SAndroid Build Coastguard Worker struct _xmlRelaxNGDefine {
132*7c568831SAndroid Build Coastguard Worker xmlRelaxNGType type; /* the type of definition */
133*7c568831SAndroid Build Coastguard Worker xmlNodePtr node; /* the node in the source */
134*7c568831SAndroid Build Coastguard Worker xmlChar *name; /* the element local name if present */
135*7c568831SAndroid Build Coastguard Worker xmlChar *ns; /* the namespace local name if present */
136*7c568831SAndroid Build Coastguard Worker xmlChar *value; /* value when available */
137*7c568831SAndroid Build Coastguard Worker void *data; /* data lib or specific pointer */
138*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr content; /* the expected content */
139*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr parent; /* the parent definition, if any */
140*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr next; /* list within grouping sequences */
141*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr attrs; /* list of attributes for elements */
142*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr nameClass; /* the nameClass definition if any */
143*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr nextHash; /* next define in defs/refs hash tables */
144*7c568831SAndroid Build Coastguard Worker short depth; /* used for the cycle detection */
145*7c568831SAndroid Build Coastguard Worker short dflags; /* define related flags */
146*7c568831SAndroid Build Coastguard Worker xmlRegexpPtr contModel; /* a compiled content model if available */
147*7c568831SAndroid Build Coastguard Worker };
148*7c568831SAndroid Build Coastguard Worker
149*7c568831SAndroid Build Coastguard Worker /**
150*7c568831SAndroid Build Coastguard Worker * _xmlRelaxNG:
151*7c568831SAndroid Build Coastguard Worker *
152*7c568831SAndroid Build Coastguard Worker * A RelaxNGs definition
153*7c568831SAndroid Build Coastguard Worker */
154*7c568831SAndroid Build Coastguard Worker struct _xmlRelaxNG {
155*7c568831SAndroid Build Coastguard Worker void *_private; /* unused by the library for users or bindings */
156*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGrammarPtr topgrammar;
157*7c568831SAndroid Build Coastguard Worker xmlDocPtr doc;
158*7c568831SAndroid Build Coastguard Worker
159*7c568831SAndroid Build Coastguard Worker int idref; /* requires idref checking */
160*7c568831SAndroid Build Coastguard Worker
161*7c568831SAndroid Build Coastguard Worker xmlHashTablePtr defs; /* define */
162*7c568831SAndroid Build Coastguard Worker xmlHashTablePtr refs; /* references */
163*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDocumentPtr documents; /* all the documents loaded */
164*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIncludePtr includes; /* all the includes loaded */
165*7c568831SAndroid Build Coastguard Worker int defNr; /* number of defines used */
166*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr *defTab; /* pointer to the allocated definitions */
167*7c568831SAndroid Build Coastguard Worker
168*7c568831SAndroid Build Coastguard Worker };
169*7c568831SAndroid Build Coastguard Worker
170*7c568831SAndroid Build Coastguard Worker #define XML_RELAXNG_IN_ATTRIBUTE (1 << 0)
171*7c568831SAndroid Build Coastguard Worker #define XML_RELAXNG_IN_ONEORMORE (1 << 1)
172*7c568831SAndroid Build Coastguard Worker #define XML_RELAXNG_IN_LIST (1 << 2)
173*7c568831SAndroid Build Coastguard Worker #define XML_RELAXNG_IN_DATAEXCEPT (1 << 3)
174*7c568831SAndroid Build Coastguard Worker #define XML_RELAXNG_IN_START (1 << 4)
175*7c568831SAndroid Build Coastguard Worker #define XML_RELAXNG_IN_OOMGROUP (1 << 5)
176*7c568831SAndroid Build Coastguard Worker #define XML_RELAXNG_IN_OOMINTERLEAVE (1 << 6)
177*7c568831SAndroid Build Coastguard Worker #define XML_RELAXNG_IN_EXTERNALREF (1 << 7)
178*7c568831SAndroid Build Coastguard Worker #define XML_RELAXNG_IN_ANYEXCEPT (1 << 8)
179*7c568831SAndroid Build Coastguard Worker #define XML_RELAXNG_IN_NSEXCEPT (1 << 9)
180*7c568831SAndroid Build Coastguard Worker
181*7c568831SAndroid Build Coastguard Worker struct _xmlRelaxNGParserCtxt {
182*7c568831SAndroid Build Coastguard Worker void *userData; /* user specific data block */
183*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidityErrorFunc error; /* the callback in case of errors */
184*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidityWarningFunc warning; /* the callback in case of warning */
185*7c568831SAndroid Build Coastguard Worker xmlStructuredErrorFunc serror;
186*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidErr err;
187*7c568831SAndroid Build Coastguard Worker
188*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPtr schema; /* The schema in use */
189*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGrammarPtr grammar; /* the current grammar */
190*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGrammarPtr parentgrammar; /* the parent grammar */
191*7c568831SAndroid Build Coastguard Worker int flags; /* parser flags */
192*7c568831SAndroid Build Coastguard Worker int nbErrors; /* number of errors at parse time */
193*7c568831SAndroid Build Coastguard Worker int nbWarnings; /* number of warnings at parse time */
194*7c568831SAndroid Build Coastguard Worker const xmlChar *define; /* the current define scope */
195*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def; /* the current define */
196*7c568831SAndroid Build Coastguard Worker
197*7c568831SAndroid Build Coastguard Worker int nbInterleaves;
198*7c568831SAndroid Build Coastguard Worker xmlHashTablePtr interleaves; /* keep track of all the interleaves */
199*7c568831SAndroid Build Coastguard Worker
200*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDocumentPtr documents; /* all the documents loaded */
201*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIncludePtr includes; /* all the includes loaded */
202*7c568831SAndroid Build Coastguard Worker xmlChar *URL;
203*7c568831SAndroid Build Coastguard Worker xmlDocPtr document;
204*7c568831SAndroid Build Coastguard Worker
205*7c568831SAndroid Build Coastguard Worker int defNr; /* number of defines used */
206*7c568831SAndroid Build Coastguard Worker int defMax; /* number of defines allocated */
207*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr *defTab; /* pointer to the allocated definitions */
208*7c568831SAndroid Build Coastguard Worker
209*7c568831SAndroid Build Coastguard Worker const char *buffer;
210*7c568831SAndroid Build Coastguard Worker int size;
211*7c568831SAndroid Build Coastguard Worker
212*7c568831SAndroid Build Coastguard Worker /* the document stack */
213*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDocumentPtr doc; /* Current parsed external ref */
214*7c568831SAndroid Build Coastguard Worker int docNr; /* Depth of the parsing stack */
215*7c568831SAndroid Build Coastguard Worker int docMax; /* Max depth of the parsing stack */
216*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDocumentPtr *docTab; /* array of docs */
217*7c568831SAndroid Build Coastguard Worker
218*7c568831SAndroid Build Coastguard Worker /* the include stack */
219*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIncludePtr inc; /* Current parsed include */
220*7c568831SAndroid Build Coastguard Worker int incNr; /* Depth of the include parsing stack */
221*7c568831SAndroid Build Coastguard Worker int incMax; /* Max depth of the parsing stack */
222*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIncludePtr *incTab; /* array of incs */
223*7c568831SAndroid Build Coastguard Worker
224*7c568831SAndroid Build Coastguard Worker int idref; /* requires idref checking */
225*7c568831SAndroid Build Coastguard Worker
226*7c568831SAndroid Build Coastguard Worker /* used to compile content models */
227*7c568831SAndroid Build Coastguard Worker xmlAutomataPtr am; /* the automata */
228*7c568831SAndroid Build Coastguard Worker xmlAutomataStatePtr state; /* used to build the automata */
229*7c568831SAndroid Build Coastguard Worker
230*7c568831SAndroid Build Coastguard Worker int crng; /* compact syntax and other flags */
231*7c568831SAndroid Build Coastguard Worker int freedoc; /* need to free the document */
232*7c568831SAndroid Build Coastguard Worker
233*7c568831SAndroid Build Coastguard Worker xmlResourceLoader resourceLoader;
234*7c568831SAndroid Build Coastguard Worker void *resourceCtxt;
235*7c568831SAndroid Build Coastguard Worker };
236*7c568831SAndroid Build Coastguard Worker
237*7c568831SAndroid Build Coastguard Worker #define FLAGS_IGNORABLE 1
238*7c568831SAndroid Build Coastguard Worker #define FLAGS_NEGATIVE 2
239*7c568831SAndroid Build Coastguard Worker #define FLAGS_MIXED_CONTENT 4
240*7c568831SAndroid Build Coastguard Worker #define FLAGS_NOERROR 8
241*7c568831SAndroid Build Coastguard Worker
242*7c568831SAndroid Build Coastguard Worker /**
243*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGInterleaveGroup:
244*7c568831SAndroid Build Coastguard Worker *
245*7c568831SAndroid Build Coastguard Worker * A RelaxNGs partition set associated to lists of definitions
246*7c568831SAndroid Build Coastguard Worker */
247*7c568831SAndroid Build Coastguard Worker typedef struct _xmlRelaxNGInterleaveGroup xmlRelaxNGInterleaveGroup;
248*7c568831SAndroid Build Coastguard Worker typedef xmlRelaxNGInterleaveGroup *xmlRelaxNGInterleaveGroupPtr;
249*7c568831SAndroid Build Coastguard Worker struct _xmlRelaxNGInterleaveGroup {
250*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr rule; /* the rule to satisfy */
251*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr *defs; /* the array of element definitions */
252*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr *attrs; /* the array of attributes definitions */
253*7c568831SAndroid Build Coastguard Worker };
254*7c568831SAndroid Build Coastguard Worker
255*7c568831SAndroid Build Coastguard Worker #define IS_DETERMINIST 1
256*7c568831SAndroid Build Coastguard Worker #define IS_NEEDCHECK 2
257*7c568831SAndroid Build Coastguard Worker
258*7c568831SAndroid Build Coastguard Worker /**
259*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGPartitions:
260*7c568831SAndroid Build Coastguard Worker *
261*7c568831SAndroid Build Coastguard Worker * A RelaxNGs partition associated to an interleave group
262*7c568831SAndroid Build Coastguard Worker */
263*7c568831SAndroid Build Coastguard Worker typedef struct _xmlRelaxNGPartition xmlRelaxNGPartition;
264*7c568831SAndroid Build Coastguard Worker typedef xmlRelaxNGPartition *xmlRelaxNGPartitionPtr;
265*7c568831SAndroid Build Coastguard Worker struct _xmlRelaxNGPartition {
266*7c568831SAndroid Build Coastguard Worker int nbgroups; /* number of groups in the partitions */
267*7c568831SAndroid Build Coastguard Worker xmlHashTablePtr triage; /* hash table used to direct nodes to the
268*7c568831SAndroid Build Coastguard Worker * right group when possible */
269*7c568831SAndroid Build Coastguard Worker int flags; /* determinist ? */
270*7c568831SAndroid Build Coastguard Worker xmlRelaxNGInterleaveGroupPtr *groups;
271*7c568831SAndroid Build Coastguard Worker };
272*7c568831SAndroid Build Coastguard Worker
273*7c568831SAndroid Build Coastguard Worker /**
274*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidState:
275*7c568831SAndroid Build Coastguard Worker *
276*7c568831SAndroid Build Coastguard Worker * A RelaxNGs validation state
277*7c568831SAndroid Build Coastguard Worker */
278*7c568831SAndroid Build Coastguard Worker #define MAX_ATTR 20
279*7c568831SAndroid Build Coastguard Worker typedef struct _xmlRelaxNGValidState xmlRelaxNGValidState;
280*7c568831SAndroid Build Coastguard Worker typedef xmlRelaxNGValidState *xmlRelaxNGValidStatePtr;
281*7c568831SAndroid Build Coastguard Worker struct _xmlRelaxNGValidState {
282*7c568831SAndroid Build Coastguard Worker xmlNodePtr node; /* the current node */
283*7c568831SAndroid Build Coastguard Worker xmlNodePtr seq; /* the sequence of children left to validate */
284*7c568831SAndroid Build Coastguard Worker int nbAttrs; /* the number of attributes */
285*7c568831SAndroid Build Coastguard Worker int maxAttrs; /* the size of attrs */
286*7c568831SAndroid Build Coastguard Worker int nbAttrLeft; /* the number of attributes left to validate */
287*7c568831SAndroid Build Coastguard Worker xmlChar *value; /* the value when operating on string */
288*7c568831SAndroid Build Coastguard Worker xmlChar *endvalue; /* the end value when operating on string */
289*7c568831SAndroid Build Coastguard Worker xmlAttrPtr *attrs; /* the array of attributes */
290*7c568831SAndroid Build Coastguard Worker };
291*7c568831SAndroid Build Coastguard Worker
292*7c568831SAndroid Build Coastguard Worker /**
293*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGStates:
294*7c568831SAndroid Build Coastguard Worker *
295*7c568831SAndroid Build Coastguard Worker * A RelaxNGs container for validation state
296*7c568831SAndroid Build Coastguard Worker */
297*7c568831SAndroid Build Coastguard Worker typedef struct _xmlRelaxNGStates xmlRelaxNGStates;
298*7c568831SAndroid Build Coastguard Worker typedef xmlRelaxNGStates *xmlRelaxNGStatesPtr;
299*7c568831SAndroid Build Coastguard Worker struct _xmlRelaxNGStates {
300*7c568831SAndroid Build Coastguard Worker int nbState; /* the number of states */
301*7c568831SAndroid Build Coastguard Worker int maxState; /* the size of the array */
302*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr *tabState;
303*7c568831SAndroid Build Coastguard Worker };
304*7c568831SAndroid Build Coastguard Worker
305*7c568831SAndroid Build Coastguard Worker #define ERROR_IS_DUP 1
306*7c568831SAndroid Build Coastguard Worker
307*7c568831SAndroid Build Coastguard Worker /**
308*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidError:
309*7c568831SAndroid Build Coastguard Worker *
310*7c568831SAndroid Build Coastguard Worker * A RelaxNGs validation error
311*7c568831SAndroid Build Coastguard Worker */
312*7c568831SAndroid Build Coastguard Worker typedef struct _xmlRelaxNGValidError xmlRelaxNGValidError;
313*7c568831SAndroid Build Coastguard Worker typedef xmlRelaxNGValidError *xmlRelaxNGValidErrorPtr;
314*7c568831SAndroid Build Coastguard Worker struct _xmlRelaxNGValidError {
315*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidErr err; /* the error number */
316*7c568831SAndroid Build Coastguard Worker int flags; /* flags */
317*7c568831SAndroid Build Coastguard Worker xmlNodePtr node; /* the current node */
318*7c568831SAndroid Build Coastguard Worker xmlNodePtr seq; /* the current child */
319*7c568831SAndroid Build Coastguard Worker const xmlChar *arg1; /* first arg */
320*7c568831SAndroid Build Coastguard Worker const xmlChar *arg2; /* second arg */
321*7c568831SAndroid Build Coastguard Worker };
322*7c568831SAndroid Build Coastguard Worker
323*7c568831SAndroid Build Coastguard Worker /**
324*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidCtxt:
325*7c568831SAndroid Build Coastguard Worker *
326*7c568831SAndroid Build Coastguard Worker * A RelaxNGs validation context
327*7c568831SAndroid Build Coastguard Worker */
328*7c568831SAndroid Build Coastguard Worker
329*7c568831SAndroid Build Coastguard Worker struct _xmlRelaxNGValidCtxt {
330*7c568831SAndroid Build Coastguard Worker void *userData; /* user specific data block */
331*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidityErrorFunc error; /* the callback in case of errors */
332*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidityWarningFunc warning; /* the callback in case of warning */
333*7c568831SAndroid Build Coastguard Worker xmlStructuredErrorFunc serror;
334*7c568831SAndroid Build Coastguard Worker int nbErrors; /* number of errors in validation */
335*7c568831SAndroid Build Coastguard Worker
336*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPtr schema; /* The schema in use */
337*7c568831SAndroid Build Coastguard Worker xmlDocPtr doc; /* the document being validated */
338*7c568831SAndroid Build Coastguard Worker int flags; /* validation flags */
339*7c568831SAndroid Build Coastguard Worker int depth; /* validation depth */
340*7c568831SAndroid Build Coastguard Worker int idref; /* requires idref checking */
341*7c568831SAndroid Build Coastguard Worker int errNo; /* the first error found */
342*7c568831SAndroid Build Coastguard Worker
343*7c568831SAndroid Build Coastguard Worker /*
344*7c568831SAndroid Build Coastguard Worker * Errors accumulated in branches may have to be stacked to be
345*7c568831SAndroid Build Coastguard Worker * provided back when it's sure they affect validation.
346*7c568831SAndroid Build Coastguard Worker */
347*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidErrorPtr err; /* Last error */
348*7c568831SAndroid Build Coastguard Worker int errNr; /* Depth of the error stack */
349*7c568831SAndroid Build Coastguard Worker int errMax; /* Max depth of the error stack */
350*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidErrorPtr errTab; /* stack of errors */
351*7c568831SAndroid Build Coastguard Worker
352*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr state; /* the current validation state */
353*7c568831SAndroid Build Coastguard Worker xmlRelaxNGStatesPtr states; /* the accumulated state list */
354*7c568831SAndroid Build Coastguard Worker
355*7c568831SAndroid Build Coastguard Worker xmlRelaxNGStatesPtr freeState; /* the pool of free valid states */
356*7c568831SAndroid Build Coastguard Worker int freeStatesNr;
357*7c568831SAndroid Build Coastguard Worker int freeStatesMax;
358*7c568831SAndroid Build Coastguard Worker xmlRelaxNGStatesPtr *freeStates; /* the pool of free state groups */
359*7c568831SAndroid Build Coastguard Worker
360*7c568831SAndroid Build Coastguard Worker /*
361*7c568831SAndroid Build Coastguard Worker * This is used for "progressive" validation
362*7c568831SAndroid Build Coastguard Worker */
363*7c568831SAndroid Build Coastguard Worker xmlRegExecCtxtPtr elem; /* the current element regexp */
364*7c568831SAndroid Build Coastguard Worker int elemNr; /* the number of element validated */
365*7c568831SAndroid Build Coastguard Worker int elemMax; /* the max depth of elements */
366*7c568831SAndroid Build Coastguard Worker xmlRegExecCtxtPtr *elemTab; /* the stack of regexp runtime */
367*7c568831SAndroid Build Coastguard Worker int pstate; /* progressive state */
368*7c568831SAndroid Build Coastguard Worker xmlNodePtr pnode; /* the current node */
369*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr pdef; /* the non-streamable definition */
370*7c568831SAndroid Build Coastguard Worker int perr; /* signal error in content model
371*7c568831SAndroid Build Coastguard Worker * outside the regexp */
372*7c568831SAndroid Build Coastguard Worker };
373*7c568831SAndroid Build Coastguard Worker
374*7c568831SAndroid Build Coastguard Worker /**
375*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGInclude:
376*7c568831SAndroid Build Coastguard Worker *
377*7c568831SAndroid Build Coastguard Worker * Structure associated to a RelaxNGs document element
378*7c568831SAndroid Build Coastguard Worker */
379*7c568831SAndroid Build Coastguard Worker struct _xmlRelaxNGInclude {
380*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIncludePtr next; /* keep a chain of includes */
381*7c568831SAndroid Build Coastguard Worker xmlChar *href; /* the normalized href value */
382*7c568831SAndroid Build Coastguard Worker xmlDocPtr doc; /* the associated XML document */
383*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr content; /* the definitions */
384*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPtr schema; /* the schema */
385*7c568831SAndroid Build Coastguard Worker };
386*7c568831SAndroid Build Coastguard Worker
387*7c568831SAndroid Build Coastguard Worker /**
388*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGDocument:
389*7c568831SAndroid Build Coastguard Worker *
390*7c568831SAndroid Build Coastguard Worker * Structure associated to a RelaxNGs document element
391*7c568831SAndroid Build Coastguard Worker */
392*7c568831SAndroid Build Coastguard Worker struct _xmlRelaxNGDocument {
393*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDocumentPtr next; /* keep a chain of documents */
394*7c568831SAndroid Build Coastguard Worker xmlChar *href; /* the normalized href value */
395*7c568831SAndroid Build Coastguard Worker xmlDocPtr doc; /* the associated XML document */
396*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr content; /* the definitions */
397*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPtr schema; /* the schema */
398*7c568831SAndroid Build Coastguard Worker int externalRef; /* 1 if an external ref */
399*7c568831SAndroid Build Coastguard Worker };
400*7c568831SAndroid Build Coastguard Worker
401*7c568831SAndroid Build Coastguard Worker
402*7c568831SAndroid Build Coastguard Worker /************************************************************************
403*7c568831SAndroid Build Coastguard Worker * *
404*7c568831SAndroid Build Coastguard Worker * Some factorized error routines *
405*7c568831SAndroid Build Coastguard Worker * *
406*7c568831SAndroid Build Coastguard Worker ************************************************************************/
407*7c568831SAndroid Build Coastguard Worker
408*7c568831SAndroid Build Coastguard Worker /**
409*7c568831SAndroid Build Coastguard Worker * xmlRngPErrMemory:
410*7c568831SAndroid Build Coastguard Worker * @ctxt: an Relax-NG parser context
411*7c568831SAndroid Build Coastguard Worker * @extra: extra information
412*7c568831SAndroid Build Coastguard Worker *
413*7c568831SAndroid Build Coastguard Worker * Handle a redefinition of attribute error
414*7c568831SAndroid Build Coastguard Worker */
415*7c568831SAndroid Build Coastguard Worker static void
xmlRngPErrMemory(xmlRelaxNGParserCtxtPtr ctxt)416*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(xmlRelaxNGParserCtxtPtr ctxt)
417*7c568831SAndroid Build Coastguard Worker {
418*7c568831SAndroid Build Coastguard Worker xmlStructuredErrorFunc schannel = NULL;
419*7c568831SAndroid Build Coastguard Worker xmlGenericErrorFunc channel = NULL;
420*7c568831SAndroid Build Coastguard Worker void *data = NULL;
421*7c568831SAndroid Build Coastguard Worker
422*7c568831SAndroid Build Coastguard Worker if (ctxt != NULL) {
423*7c568831SAndroid Build Coastguard Worker if (ctxt->serror != NULL)
424*7c568831SAndroid Build Coastguard Worker schannel = ctxt->serror;
425*7c568831SAndroid Build Coastguard Worker else
426*7c568831SAndroid Build Coastguard Worker channel = ctxt->error;
427*7c568831SAndroid Build Coastguard Worker data = ctxt->userData;
428*7c568831SAndroid Build Coastguard Worker ctxt->nbErrors++;
429*7c568831SAndroid Build Coastguard Worker }
430*7c568831SAndroid Build Coastguard Worker
431*7c568831SAndroid Build Coastguard Worker xmlRaiseMemoryError(schannel, channel, data, XML_FROM_RELAXNGP, NULL);
432*7c568831SAndroid Build Coastguard Worker }
433*7c568831SAndroid Build Coastguard Worker
434*7c568831SAndroid Build Coastguard Worker /**
435*7c568831SAndroid Build Coastguard Worker * xmlRngVErrMemory:
436*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
437*7c568831SAndroid Build Coastguard Worker * @extra: extra information
438*7c568831SAndroid Build Coastguard Worker *
439*7c568831SAndroid Build Coastguard Worker * Handle a redefinition of attribute error
440*7c568831SAndroid Build Coastguard Worker */
441*7c568831SAndroid Build Coastguard Worker static void
xmlRngVErrMemory(xmlRelaxNGValidCtxtPtr ctxt)442*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(xmlRelaxNGValidCtxtPtr ctxt)
443*7c568831SAndroid Build Coastguard Worker {
444*7c568831SAndroid Build Coastguard Worker xmlStructuredErrorFunc schannel = NULL;
445*7c568831SAndroid Build Coastguard Worker xmlGenericErrorFunc channel = NULL;
446*7c568831SAndroid Build Coastguard Worker void *data = NULL;
447*7c568831SAndroid Build Coastguard Worker
448*7c568831SAndroid Build Coastguard Worker if (ctxt != NULL) {
449*7c568831SAndroid Build Coastguard Worker if (ctxt->serror != NULL)
450*7c568831SAndroid Build Coastguard Worker schannel = ctxt->serror;
451*7c568831SAndroid Build Coastguard Worker else
452*7c568831SAndroid Build Coastguard Worker channel = ctxt->error;
453*7c568831SAndroid Build Coastguard Worker data = ctxt->userData;
454*7c568831SAndroid Build Coastguard Worker ctxt->nbErrors++;
455*7c568831SAndroid Build Coastguard Worker }
456*7c568831SAndroid Build Coastguard Worker
457*7c568831SAndroid Build Coastguard Worker xmlRaiseMemoryError(schannel, channel, data, XML_FROM_RELAXNGV, NULL);
458*7c568831SAndroid Build Coastguard Worker }
459*7c568831SAndroid Build Coastguard Worker
460*7c568831SAndroid Build Coastguard Worker /**
461*7c568831SAndroid Build Coastguard Worker * xmlRngPErr:
462*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
463*7c568831SAndroid Build Coastguard Worker * @node: the node raising the error
464*7c568831SAndroid Build Coastguard Worker * @error: the error code
465*7c568831SAndroid Build Coastguard Worker * @msg: message
466*7c568831SAndroid Build Coastguard Worker * @str1: extra info
467*7c568831SAndroid Build Coastguard Worker * @str2: extra info
468*7c568831SAndroid Build Coastguard Worker *
469*7c568831SAndroid Build Coastguard Worker * Handle a Relax NG Parsing error
470*7c568831SAndroid Build Coastguard Worker */
471*7c568831SAndroid Build Coastguard Worker static void LIBXML_ATTR_FORMAT(4,0)
xmlRngPErr(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr node,int error,const char * msg,const xmlChar * str1,const xmlChar * str2)472*7c568831SAndroid Build Coastguard Worker xmlRngPErr(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node, int error,
473*7c568831SAndroid Build Coastguard Worker const char *msg, const xmlChar * str1, const xmlChar * str2)
474*7c568831SAndroid Build Coastguard Worker {
475*7c568831SAndroid Build Coastguard Worker xmlStructuredErrorFunc schannel = NULL;
476*7c568831SAndroid Build Coastguard Worker xmlGenericErrorFunc channel = NULL;
477*7c568831SAndroid Build Coastguard Worker void *data = NULL;
478*7c568831SAndroid Build Coastguard Worker int res;
479*7c568831SAndroid Build Coastguard Worker
480*7c568831SAndroid Build Coastguard Worker if (ctxt != NULL) {
481*7c568831SAndroid Build Coastguard Worker if (ctxt->serror != NULL)
482*7c568831SAndroid Build Coastguard Worker schannel = ctxt->serror;
483*7c568831SAndroid Build Coastguard Worker else
484*7c568831SAndroid Build Coastguard Worker channel = ctxt->error;
485*7c568831SAndroid Build Coastguard Worker data = ctxt->userData;
486*7c568831SAndroid Build Coastguard Worker ctxt->nbErrors++;
487*7c568831SAndroid Build Coastguard Worker }
488*7c568831SAndroid Build Coastguard Worker
489*7c568831SAndroid Build Coastguard Worker if ((channel == NULL) && (schannel == NULL)) {
490*7c568831SAndroid Build Coastguard Worker channel = xmlGenericError;
491*7c568831SAndroid Build Coastguard Worker data = xmlGenericErrorContext;
492*7c568831SAndroid Build Coastguard Worker }
493*7c568831SAndroid Build Coastguard Worker
494*7c568831SAndroid Build Coastguard Worker res = xmlRaiseError(schannel, channel, data, NULL, node,
495*7c568831SAndroid Build Coastguard Worker XML_FROM_RELAXNGP, error, XML_ERR_ERROR, NULL, 0,
496*7c568831SAndroid Build Coastguard Worker (const char *) str1, (const char *) str2, NULL, 0, 0,
497*7c568831SAndroid Build Coastguard Worker msg, str1, str2);
498*7c568831SAndroid Build Coastguard Worker if (res < 0)
499*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
500*7c568831SAndroid Build Coastguard Worker }
501*7c568831SAndroid Build Coastguard Worker
502*7c568831SAndroid Build Coastguard Worker /**
503*7c568831SAndroid Build Coastguard Worker * xmlRngVErr:
504*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
505*7c568831SAndroid Build Coastguard Worker * @node: the node raising the error
506*7c568831SAndroid Build Coastguard Worker * @error: the error code
507*7c568831SAndroid Build Coastguard Worker * @msg: message
508*7c568831SAndroid Build Coastguard Worker * @str1: extra info
509*7c568831SAndroid Build Coastguard Worker * @str2: extra info
510*7c568831SAndroid Build Coastguard Worker *
511*7c568831SAndroid Build Coastguard Worker * Handle a Relax NG Validation error
512*7c568831SAndroid Build Coastguard Worker */
513*7c568831SAndroid Build Coastguard Worker static void LIBXML_ATTR_FORMAT(4,0)
xmlRngVErr(xmlRelaxNGValidCtxtPtr ctxt,xmlNodePtr node,int error,const char * msg,const xmlChar * str1,const xmlChar * str2)514*7c568831SAndroid Build Coastguard Worker xmlRngVErr(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node, int error,
515*7c568831SAndroid Build Coastguard Worker const char *msg, const xmlChar * str1, const xmlChar * str2)
516*7c568831SAndroid Build Coastguard Worker {
517*7c568831SAndroid Build Coastguard Worker xmlStructuredErrorFunc schannel = NULL;
518*7c568831SAndroid Build Coastguard Worker xmlGenericErrorFunc channel = NULL;
519*7c568831SAndroid Build Coastguard Worker void *data = NULL;
520*7c568831SAndroid Build Coastguard Worker int res;
521*7c568831SAndroid Build Coastguard Worker
522*7c568831SAndroid Build Coastguard Worker if (ctxt != NULL) {
523*7c568831SAndroid Build Coastguard Worker if (ctxt->serror != NULL)
524*7c568831SAndroid Build Coastguard Worker schannel = ctxt->serror;
525*7c568831SAndroid Build Coastguard Worker else
526*7c568831SAndroid Build Coastguard Worker channel = ctxt->error;
527*7c568831SAndroid Build Coastguard Worker data = ctxt->userData;
528*7c568831SAndroid Build Coastguard Worker ctxt->nbErrors++;
529*7c568831SAndroid Build Coastguard Worker }
530*7c568831SAndroid Build Coastguard Worker
531*7c568831SAndroid Build Coastguard Worker if ((channel == NULL) && (schannel == NULL)) {
532*7c568831SAndroid Build Coastguard Worker channel = xmlGenericError;
533*7c568831SAndroid Build Coastguard Worker data = xmlGenericErrorContext;
534*7c568831SAndroid Build Coastguard Worker }
535*7c568831SAndroid Build Coastguard Worker
536*7c568831SAndroid Build Coastguard Worker res = xmlRaiseError(schannel, channel, data, NULL, node,
537*7c568831SAndroid Build Coastguard Worker XML_FROM_RELAXNGV, error, XML_ERR_ERROR, NULL, 0,
538*7c568831SAndroid Build Coastguard Worker (const char *) str1, (const char *) str2, NULL, 0, 0,
539*7c568831SAndroid Build Coastguard Worker msg, str1, str2);
540*7c568831SAndroid Build Coastguard Worker if (res < 0)
541*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
542*7c568831SAndroid Build Coastguard Worker }
543*7c568831SAndroid Build Coastguard Worker
544*7c568831SAndroid Build Coastguard Worker /************************************************************************
545*7c568831SAndroid Build Coastguard Worker * *
546*7c568831SAndroid Build Coastguard Worker * Preliminary type checking interfaces *
547*7c568831SAndroid Build Coastguard Worker * *
548*7c568831SAndroid Build Coastguard Worker ************************************************************************/
549*7c568831SAndroid Build Coastguard Worker
550*7c568831SAndroid Build Coastguard Worker /**
551*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGTypeHave:
552*7c568831SAndroid Build Coastguard Worker * @data: data needed for the library
553*7c568831SAndroid Build Coastguard Worker * @type: the type name
554*7c568831SAndroid Build Coastguard Worker * @value: the value to check
555*7c568831SAndroid Build Coastguard Worker *
556*7c568831SAndroid Build Coastguard Worker * Function provided by a type library to check if a type is exported
557*7c568831SAndroid Build Coastguard Worker *
558*7c568831SAndroid Build Coastguard Worker * Returns 1 if yes, 0 if no and -1 in case of error.
559*7c568831SAndroid Build Coastguard Worker */
560*7c568831SAndroid Build Coastguard Worker typedef int (*xmlRelaxNGTypeHave) (void *data, const xmlChar * type);
561*7c568831SAndroid Build Coastguard Worker
562*7c568831SAndroid Build Coastguard Worker /**
563*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGTypeCheck:
564*7c568831SAndroid Build Coastguard Worker * @data: data needed for the library
565*7c568831SAndroid Build Coastguard Worker * @type: the type name
566*7c568831SAndroid Build Coastguard Worker * @value: the value to check
567*7c568831SAndroid Build Coastguard Worker * @result: place to store the result if needed
568*7c568831SAndroid Build Coastguard Worker *
569*7c568831SAndroid Build Coastguard Worker * Function provided by a type library to check if a value match a type
570*7c568831SAndroid Build Coastguard Worker *
571*7c568831SAndroid Build Coastguard Worker * Returns 1 if yes, 0 if no and -1 in case of error.
572*7c568831SAndroid Build Coastguard Worker */
573*7c568831SAndroid Build Coastguard Worker typedef int (*xmlRelaxNGTypeCheck) (void *data, const xmlChar * type,
574*7c568831SAndroid Build Coastguard Worker const xmlChar * value, void **result,
575*7c568831SAndroid Build Coastguard Worker xmlNodePtr node);
576*7c568831SAndroid Build Coastguard Worker
577*7c568831SAndroid Build Coastguard Worker /**
578*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGFacetCheck:
579*7c568831SAndroid Build Coastguard Worker * @data: data needed for the library
580*7c568831SAndroid Build Coastguard Worker * @type: the type name
581*7c568831SAndroid Build Coastguard Worker * @facet: the facet name
582*7c568831SAndroid Build Coastguard Worker * @val: the facet value
583*7c568831SAndroid Build Coastguard Worker * @strval: the string value
584*7c568831SAndroid Build Coastguard Worker * @value: the value to check
585*7c568831SAndroid Build Coastguard Worker *
586*7c568831SAndroid Build Coastguard Worker * Function provided by a type library to check a value facet
587*7c568831SAndroid Build Coastguard Worker *
588*7c568831SAndroid Build Coastguard Worker * Returns 1 if yes, 0 if no and -1 in case of error.
589*7c568831SAndroid Build Coastguard Worker */
590*7c568831SAndroid Build Coastguard Worker typedef int (*xmlRelaxNGFacetCheck) (void *data, const xmlChar * type,
591*7c568831SAndroid Build Coastguard Worker const xmlChar * facet,
592*7c568831SAndroid Build Coastguard Worker const xmlChar * val,
593*7c568831SAndroid Build Coastguard Worker const xmlChar * strval, void *value);
594*7c568831SAndroid Build Coastguard Worker
595*7c568831SAndroid Build Coastguard Worker /**
596*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGTypeFree:
597*7c568831SAndroid Build Coastguard Worker * @data: data needed for the library
598*7c568831SAndroid Build Coastguard Worker * @result: the value to free
599*7c568831SAndroid Build Coastguard Worker *
600*7c568831SAndroid Build Coastguard Worker * Function provided by a type library to free a returned result
601*7c568831SAndroid Build Coastguard Worker */
602*7c568831SAndroid Build Coastguard Worker typedef void (*xmlRelaxNGTypeFree) (void *data, void *result);
603*7c568831SAndroid Build Coastguard Worker
604*7c568831SAndroid Build Coastguard Worker /**
605*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGTypeCompare:
606*7c568831SAndroid Build Coastguard Worker * @data: data needed for the library
607*7c568831SAndroid Build Coastguard Worker * @type: the type name
608*7c568831SAndroid Build Coastguard Worker * @value1: the first value
609*7c568831SAndroid Build Coastguard Worker * @value2: the second value
610*7c568831SAndroid Build Coastguard Worker *
611*7c568831SAndroid Build Coastguard Worker * Function provided by a type library to compare two values accordingly
612*7c568831SAndroid Build Coastguard Worker * to a type.
613*7c568831SAndroid Build Coastguard Worker *
614*7c568831SAndroid Build Coastguard Worker * Returns 1 if yes, 0 if no and -1 in case of error.
615*7c568831SAndroid Build Coastguard Worker */
616*7c568831SAndroid Build Coastguard Worker typedef int (*xmlRelaxNGTypeCompare) (void *data, const xmlChar * type,
617*7c568831SAndroid Build Coastguard Worker const xmlChar * value1,
618*7c568831SAndroid Build Coastguard Worker xmlNodePtr ctxt1,
619*7c568831SAndroid Build Coastguard Worker void *comp1,
620*7c568831SAndroid Build Coastguard Worker const xmlChar * value2,
621*7c568831SAndroid Build Coastguard Worker xmlNodePtr ctxt2);
622*7c568831SAndroid Build Coastguard Worker typedef struct _xmlRelaxNGTypeLibrary xmlRelaxNGTypeLibrary;
623*7c568831SAndroid Build Coastguard Worker typedef xmlRelaxNGTypeLibrary *xmlRelaxNGTypeLibraryPtr;
624*7c568831SAndroid Build Coastguard Worker struct _xmlRelaxNGTypeLibrary {
625*7c568831SAndroid Build Coastguard Worker const xmlChar *namespace; /* the datatypeLibrary value */
626*7c568831SAndroid Build Coastguard Worker void *data; /* data needed for the library */
627*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTypeHave have; /* the export function */
628*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTypeCheck check; /* the checking function */
629*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTypeCompare comp; /* the compare function */
630*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFacetCheck facet; /* the facet check function */
631*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTypeFree freef; /* the freeing function */
632*7c568831SAndroid Build Coastguard Worker };
633*7c568831SAndroid Build Coastguard Worker
634*7c568831SAndroid Build Coastguard Worker /************************************************************************
635*7c568831SAndroid Build Coastguard Worker * *
636*7c568831SAndroid Build Coastguard Worker * Allocation functions *
637*7c568831SAndroid Build Coastguard Worker * *
638*7c568831SAndroid Build Coastguard Worker ************************************************************************/
639*7c568831SAndroid Build Coastguard Worker static void xmlRelaxNGFreeGrammar(xmlRelaxNGGrammarPtr grammar);
640*7c568831SAndroid Build Coastguard Worker static void xmlRelaxNGFreeDefine(xmlRelaxNGDefinePtr define);
641*7c568831SAndroid Build Coastguard Worker static void xmlRelaxNGNormExtSpace(xmlChar * value);
642*7c568831SAndroid Build Coastguard Worker static void xmlRelaxNGFreeInnerSchema(xmlRelaxNGPtr schema);
643*7c568831SAndroid Build Coastguard Worker static int xmlRelaxNGEqualValidState(xmlRelaxNGValidCtxtPtr ctxt
644*7c568831SAndroid Build Coastguard Worker ATTRIBUTE_UNUSED,
645*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr state1,
646*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr state2);
647*7c568831SAndroid Build Coastguard Worker static void xmlRelaxNGFreeValidState(xmlRelaxNGValidCtxtPtr ctxt,
648*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr state);
649*7c568831SAndroid Build Coastguard Worker
650*7c568831SAndroid Build Coastguard Worker /**
651*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGFreeDocument:
652*7c568831SAndroid Build Coastguard Worker * @docu: a document structure
653*7c568831SAndroid Build Coastguard Worker *
654*7c568831SAndroid Build Coastguard Worker * Deallocate a RelaxNG document structure.
655*7c568831SAndroid Build Coastguard Worker */
656*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGFreeDocument(xmlRelaxNGDocumentPtr docu)657*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeDocument(xmlRelaxNGDocumentPtr docu)
658*7c568831SAndroid Build Coastguard Worker {
659*7c568831SAndroid Build Coastguard Worker if (docu == NULL)
660*7c568831SAndroid Build Coastguard Worker return;
661*7c568831SAndroid Build Coastguard Worker
662*7c568831SAndroid Build Coastguard Worker if (docu->href != NULL)
663*7c568831SAndroid Build Coastguard Worker xmlFree(docu->href);
664*7c568831SAndroid Build Coastguard Worker if (docu->doc != NULL)
665*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(docu->doc);
666*7c568831SAndroid Build Coastguard Worker if (docu->schema != NULL)
667*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeInnerSchema(docu->schema);
668*7c568831SAndroid Build Coastguard Worker xmlFree(docu);
669*7c568831SAndroid Build Coastguard Worker }
670*7c568831SAndroid Build Coastguard Worker
671*7c568831SAndroid Build Coastguard Worker /**
672*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGFreeDocumentList:
673*7c568831SAndroid Build Coastguard Worker * @docu: a list of document structure
674*7c568831SAndroid Build Coastguard Worker *
675*7c568831SAndroid Build Coastguard Worker * Deallocate a RelaxNG document structures.
676*7c568831SAndroid Build Coastguard Worker */
677*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGFreeDocumentList(xmlRelaxNGDocumentPtr docu)678*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeDocumentList(xmlRelaxNGDocumentPtr docu)
679*7c568831SAndroid Build Coastguard Worker {
680*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDocumentPtr next;
681*7c568831SAndroid Build Coastguard Worker
682*7c568831SAndroid Build Coastguard Worker while (docu != NULL) {
683*7c568831SAndroid Build Coastguard Worker next = docu->next;
684*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeDocument(docu);
685*7c568831SAndroid Build Coastguard Worker docu = next;
686*7c568831SAndroid Build Coastguard Worker }
687*7c568831SAndroid Build Coastguard Worker }
688*7c568831SAndroid Build Coastguard Worker
689*7c568831SAndroid Build Coastguard Worker /**
690*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGFreeInclude:
691*7c568831SAndroid Build Coastguard Worker * @incl: a include structure
692*7c568831SAndroid Build Coastguard Worker *
693*7c568831SAndroid Build Coastguard Worker * Deallocate a RelaxNG include structure.
694*7c568831SAndroid Build Coastguard Worker */
695*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGFreeInclude(xmlRelaxNGIncludePtr incl)696*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeInclude(xmlRelaxNGIncludePtr incl)
697*7c568831SAndroid Build Coastguard Worker {
698*7c568831SAndroid Build Coastguard Worker if (incl == NULL)
699*7c568831SAndroid Build Coastguard Worker return;
700*7c568831SAndroid Build Coastguard Worker
701*7c568831SAndroid Build Coastguard Worker if (incl->href != NULL)
702*7c568831SAndroid Build Coastguard Worker xmlFree(incl->href);
703*7c568831SAndroid Build Coastguard Worker if (incl->doc != NULL)
704*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(incl->doc);
705*7c568831SAndroid Build Coastguard Worker if (incl->schema != NULL)
706*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFree(incl->schema);
707*7c568831SAndroid Build Coastguard Worker xmlFree(incl);
708*7c568831SAndroid Build Coastguard Worker }
709*7c568831SAndroid Build Coastguard Worker
710*7c568831SAndroid Build Coastguard Worker /**
711*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGFreeIncludeList:
712*7c568831SAndroid Build Coastguard Worker * @incl: a include structure list
713*7c568831SAndroid Build Coastguard Worker *
714*7c568831SAndroid Build Coastguard Worker * Deallocate a RelaxNG include structure.
715*7c568831SAndroid Build Coastguard Worker */
716*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGFreeIncludeList(xmlRelaxNGIncludePtr incl)717*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeIncludeList(xmlRelaxNGIncludePtr incl)
718*7c568831SAndroid Build Coastguard Worker {
719*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIncludePtr next;
720*7c568831SAndroid Build Coastguard Worker
721*7c568831SAndroid Build Coastguard Worker while (incl != NULL) {
722*7c568831SAndroid Build Coastguard Worker next = incl->next;
723*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeInclude(incl);
724*7c568831SAndroid Build Coastguard Worker incl = next;
725*7c568831SAndroid Build Coastguard Worker }
726*7c568831SAndroid Build Coastguard Worker }
727*7c568831SAndroid Build Coastguard Worker
728*7c568831SAndroid Build Coastguard Worker /**
729*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGNewRelaxNG:
730*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context (optional)
731*7c568831SAndroid Build Coastguard Worker *
732*7c568831SAndroid Build Coastguard Worker * Allocate a new RelaxNG structure.
733*7c568831SAndroid Build Coastguard Worker *
734*7c568831SAndroid Build Coastguard Worker * Returns the newly allocated structure or NULL in case or error
735*7c568831SAndroid Build Coastguard Worker */
736*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGPtr
xmlRelaxNGNewRelaxNG(xmlRelaxNGParserCtxtPtr ctxt)737*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNewRelaxNG(xmlRelaxNGParserCtxtPtr ctxt)
738*7c568831SAndroid Build Coastguard Worker {
739*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPtr ret;
740*7c568831SAndroid Build Coastguard Worker
741*7c568831SAndroid Build Coastguard Worker ret = (xmlRelaxNGPtr) xmlMalloc(sizeof(xmlRelaxNG));
742*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
743*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
744*7c568831SAndroid Build Coastguard Worker return (NULL);
745*7c568831SAndroid Build Coastguard Worker }
746*7c568831SAndroid Build Coastguard Worker memset(ret, 0, sizeof(xmlRelaxNG));
747*7c568831SAndroid Build Coastguard Worker
748*7c568831SAndroid Build Coastguard Worker return (ret);
749*7c568831SAndroid Build Coastguard Worker }
750*7c568831SAndroid Build Coastguard Worker
751*7c568831SAndroid Build Coastguard Worker /**
752*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGFreeInnerSchema:
753*7c568831SAndroid Build Coastguard Worker * @schema: a schema structure
754*7c568831SAndroid Build Coastguard Worker *
755*7c568831SAndroid Build Coastguard Worker * Deallocate a RelaxNG schema structure.
756*7c568831SAndroid Build Coastguard Worker */
757*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGFreeInnerSchema(xmlRelaxNGPtr schema)758*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeInnerSchema(xmlRelaxNGPtr schema)
759*7c568831SAndroid Build Coastguard Worker {
760*7c568831SAndroid Build Coastguard Worker if (schema == NULL)
761*7c568831SAndroid Build Coastguard Worker return;
762*7c568831SAndroid Build Coastguard Worker
763*7c568831SAndroid Build Coastguard Worker if (schema->doc != NULL)
764*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(schema->doc);
765*7c568831SAndroid Build Coastguard Worker if (schema->defTab != NULL) {
766*7c568831SAndroid Build Coastguard Worker int i;
767*7c568831SAndroid Build Coastguard Worker
768*7c568831SAndroid Build Coastguard Worker for (i = 0; i < schema->defNr; i++)
769*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeDefine(schema->defTab[i]);
770*7c568831SAndroid Build Coastguard Worker xmlFree(schema->defTab);
771*7c568831SAndroid Build Coastguard Worker }
772*7c568831SAndroid Build Coastguard Worker
773*7c568831SAndroid Build Coastguard Worker xmlFree(schema);
774*7c568831SAndroid Build Coastguard Worker }
775*7c568831SAndroid Build Coastguard Worker
776*7c568831SAndroid Build Coastguard Worker /**
777*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGFree:
778*7c568831SAndroid Build Coastguard Worker * @schema: a schema structure
779*7c568831SAndroid Build Coastguard Worker *
780*7c568831SAndroid Build Coastguard Worker * Deallocate a RelaxNG structure.
781*7c568831SAndroid Build Coastguard Worker */
782*7c568831SAndroid Build Coastguard Worker void
xmlRelaxNGFree(xmlRelaxNGPtr schema)783*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFree(xmlRelaxNGPtr schema)
784*7c568831SAndroid Build Coastguard Worker {
785*7c568831SAndroid Build Coastguard Worker if (schema == NULL)
786*7c568831SAndroid Build Coastguard Worker return;
787*7c568831SAndroid Build Coastguard Worker
788*7c568831SAndroid Build Coastguard Worker if (schema->topgrammar != NULL)
789*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeGrammar(schema->topgrammar);
790*7c568831SAndroid Build Coastguard Worker if (schema->doc != NULL)
791*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(schema->doc);
792*7c568831SAndroid Build Coastguard Worker if (schema->documents != NULL)
793*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeDocumentList(schema->documents);
794*7c568831SAndroid Build Coastguard Worker if (schema->includes != NULL)
795*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeIncludeList(schema->includes);
796*7c568831SAndroid Build Coastguard Worker if (schema->defTab != NULL) {
797*7c568831SAndroid Build Coastguard Worker int i;
798*7c568831SAndroid Build Coastguard Worker
799*7c568831SAndroid Build Coastguard Worker for (i = 0; i < schema->defNr; i++)
800*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeDefine(schema->defTab[i]);
801*7c568831SAndroid Build Coastguard Worker xmlFree(schema->defTab);
802*7c568831SAndroid Build Coastguard Worker }
803*7c568831SAndroid Build Coastguard Worker
804*7c568831SAndroid Build Coastguard Worker xmlFree(schema);
805*7c568831SAndroid Build Coastguard Worker }
806*7c568831SAndroid Build Coastguard Worker
807*7c568831SAndroid Build Coastguard Worker /**
808*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGNewGrammar:
809*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context (optional)
810*7c568831SAndroid Build Coastguard Worker *
811*7c568831SAndroid Build Coastguard Worker * Allocate a new RelaxNG grammar.
812*7c568831SAndroid Build Coastguard Worker *
813*7c568831SAndroid Build Coastguard Worker * Returns the newly allocated structure or NULL in case or error
814*7c568831SAndroid Build Coastguard Worker */
815*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGGrammarPtr
xmlRelaxNGNewGrammar(xmlRelaxNGParserCtxtPtr ctxt)816*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNewGrammar(xmlRelaxNGParserCtxtPtr ctxt)
817*7c568831SAndroid Build Coastguard Worker {
818*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGrammarPtr ret;
819*7c568831SAndroid Build Coastguard Worker
820*7c568831SAndroid Build Coastguard Worker ret = (xmlRelaxNGGrammarPtr) xmlMalloc(sizeof(xmlRelaxNGGrammar));
821*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
822*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
823*7c568831SAndroid Build Coastguard Worker return (NULL);
824*7c568831SAndroid Build Coastguard Worker }
825*7c568831SAndroid Build Coastguard Worker memset(ret, 0, sizeof(xmlRelaxNGGrammar));
826*7c568831SAndroid Build Coastguard Worker
827*7c568831SAndroid Build Coastguard Worker return (ret);
828*7c568831SAndroid Build Coastguard Worker }
829*7c568831SAndroid Build Coastguard Worker
830*7c568831SAndroid Build Coastguard Worker /**
831*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGFreeGrammar:
832*7c568831SAndroid Build Coastguard Worker * @grammar: a grammar structure
833*7c568831SAndroid Build Coastguard Worker *
834*7c568831SAndroid Build Coastguard Worker * Deallocate a RelaxNG grammar structure.
835*7c568831SAndroid Build Coastguard Worker */
836*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGFreeGrammar(xmlRelaxNGGrammarPtr grammar)837*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeGrammar(xmlRelaxNGGrammarPtr grammar)
838*7c568831SAndroid Build Coastguard Worker {
839*7c568831SAndroid Build Coastguard Worker if (grammar == NULL)
840*7c568831SAndroid Build Coastguard Worker return;
841*7c568831SAndroid Build Coastguard Worker
842*7c568831SAndroid Build Coastguard Worker if (grammar->children != NULL) {
843*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeGrammar(grammar->children);
844*7c568831SAndroid Build Coastguard Worker }
845*7c568831SAndroid Build Coastguard Worker if (grammar->next != NULL) {
846*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeGrammar(grammar->next);
847*7c568831SAndroid Build Coastguard Worker }
848*7c568831SAndroid Build Coastguard Worker if (grammar->refs != NULL) {
849*7c568831SAndroid Build Coastguard Worker xmlHashFree(grammar->refs, NULL);
850*7c568831SAndroid Build Coastguard Worker }
851*7c568831SAndroid Build Coastguard Worker if (grammar->defs != NULL) {
852*7c568831SAndroid Build Coastguard Worker xmlHashFree(grammar->defs, NULL);
853*7c568831SAndroid Build Coastguard Worker }
854*7c568831SAndroid Build Coastguard Worker
855*7c568831SAndroid Build Coastguard Worker xmlFree(grammar);
856*7c568831SAndroid Build Coastguard Worker }
857*7c568831SAndroid Build Coastguard Worker
858*7c568831SAndroid Build Coastguard Worker /**
859*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGNewDefine:
860*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
861*7c568831SAndroid Build Coastguard Worker * @node: the node in the input document.
862*7c568831SAndroid Build Coastguard Worker *
863*7c568831SAndroid Build Coastguard Worker * Allocate a new RelaxNG define.
864*7c568831SAndroid Build Coastguard Worker *
865*7c568831SAndroid Build Coastguard Worker * Returns the newly allocated structure or NULL in case or error
866*7c568831SAndroid Build Coastguard Worker */
867*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr
xmlRelaxNGNewDefine(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr node)868*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNewDefine(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
869*7c568831SAndroid Build Coastguard Worker {
870*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr ret;
871*7c568831SAndroid Build Coastguard Worker
872*7c568831SAndroid Build Coastguard Worker if (ctxt->defMax == 0) {
873*7c568831SAndroid Build Coastguard Worker ctxt->defMax = 16;
874*7c568831SAndroid Build Coastguard Worker ctxt->defNr = 0;
875*7c568831SAndroid Build Coastguard Worker ctxt->defTab = (xmlRelaxNGDefinePtr *)
876*7c568831SAndroid Build Coastguard Worker xmlMalloc(ctxt->defMax * sizeof(xmlRelaxNGDefinePtr));
877*7c568831SAndroid Build Coastguard Worker if (ctxt->defTab == NULL) {
878*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
879*7c568831SAndroid Build Coastguard Worker return (NULL);
880*7c568831SAndroid Build Coastguard Worker }
881*7c568831SAndroid Build Coastguard Worker } else if (ctxt->defMax <= ctxt->defNr) {
882*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr *tmp;
883*7c568831SAndroid Build Coastguard Worker
884*7c568831SAndroid Build Coastguard Worker ctxt->defMax *= 2;
885*7c568831SAndroid Build Coastguard Worker tmp = (xmlRelaxNGDefinePtr *) xmlRealloc(ctxt->defTab,
886*7c568831SAndroid Build Coastguard Worker ctxt->defMax *
887*7c568831SAndroid Build Coastguard Worker sizeof
888*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGDefinePtr));
889*7c568831SAndroid Build Coastguard Worker if (tmp == NULL) {
890*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
891*7c568831SAndroid Build Coastguard Worker return (NULL);
892*7c568831SAndroid Build Coastguard Worker }
893*7c568831SAndroid Build Coastguard Worker ctxt->defTab = tmp;
894*7c568831SAndroid Build Coastguard Worker }
895*7c568831SAndroid Build Coastguard Worker ret = (xmlRelaxNGDefinePtr) xmlMalloc(sizeof(xmlRelaxNGDefine));
896*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
897*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
898*7c568831SAndroid Build Coastguard Worker return (NULL);
899*7c568831SAndroid Build Coastguard Worker }
900*7c568831SAndroid Build Coastguard Worker memset(ret, 0, sizeof(xmlRelaxNGDefine));
901*7c568831SAndroid Build Coastguard Worker ctxt->defTab[ctxt->defNr++] = ret;
902*7c568831SAndroid Build Coastguard Worker ret->node = node;
903*7c568831SAndroid Build Coastguard Worker ret->depth = -1;
904*7c568831SAndroid Build Coastguard Worker return (ret);
905*7c568831SAndroid Build Coastguard Worker }
906*7c568831SAndroid Build Coastguard Worker
907*7c568831SAndroid Build Coastguard Worker /**
908*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGFreePartition:
909*7c568831SAndroid Build Coastguard Worker * @partitions: a partition set structure
910*7c568831SAndroid Build Coastguard Worker *
911*7c568831SAndroid Build Coastguard Worker * Deallocate RelaxNG partition set structures.
912*7c568831SAndroid Build Coastguard Worker */
913*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGFreePartition(xmlRelaxNGPartitionPtr partitions)914*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreePartition(xmlRelaxNGPartitionPtr partitions)
915*7c568831SAndroid Build Coastguard Worker {
916*7c568831SAndroid Build Coastguard Worker xmlRelaxNGInterleaveGroupPtr group;
917*7c568831SAndroid Build Coastguard Worker int j;
918*7c568831SAndroid Build Coastguard Worker
919*7c568831SAndroid Build Coastguard Worker if (partitions != NULL) {
920*7c568831SAndroid Build Coastguard Worker if (partitions->groups != NULL) {
921*7c568831SAndroid Build Coastguard Worker for (j = 0; j < partitions->nbgroups; j++) {
922*7c568831SAndroid Build Coastguard Worker group = partitions->groups[j];
923*7c568831SAndroid Build Coastguard Worker if (group != NULL) {
924*7c568831SAndroid Build Coastguard Worker if (group->defs != NULL)
925*7c568831SAndroid Build Coastguard Worker xmlFree(group->defs);
926*7c568831SAndroid Build Coastguard Worker if (group->attrs != NULL)
927*7c568831SAndroid Build Coastguard Worker xmlFree(group->attrs);
928*7c568831SAndroid Build Coastguard Worker xmlFree(group);
929*7c568831SAndroid Build Coastguard Worker }
930*7c568831SAndroid Build Coastguard Worker }
931*7c568831SAndroid Build Coastguard Worker xmlFree(partitions->groups);
932*7c568831SAndroid Build Coastguard Worker }
933*7c568831SAndroid Build Coastguard Worker if (partitions->triage != NULL) {
934*7c568831SAndroid Build Coastguard Worker xmlHashFree(partitions->triage, NULL);
935*7c568831SAndroid Build Coastguard Worker }
936*7c568831SAndroid Build Coastguard Worker xmlFree(partitions);
937*7c568831SAndroid Build Coastguard Worker }
938*7c568831SAndroid Build Coastguard Worker }
939*7c568831SAndroid Build Coastguard Worker
940*7c568831SAndroid Build Coastguard Worker /**
941*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGFreeDefine:
942*7c568831SAndroid Build Coastguard Worker * @define: a define structure
943*7c568831SAndroid Build Coastguard Worker *
944*7c568831SAndroid Build Coastguard Worker * Deallocate a RelaxNG define structure.
945*7c568831SAndroid Build Coastguard Worker */
946*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGFreeDefine(xmlRelaxNGDefinePtr define)947*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeDefine(xmlRelaxNGDefinePtr define)
948*7c568831SAndroid Build Coastguard Worker {
949*7c568831SAndroid Build Coastguard Worker if (define == NULL)
950*7c568831SAndroid Build Coastguard Worker return;
951*7c568831SAndroid Build Coastguard Worker
952*7c568831SAndroid Build Coastguard Worker if ((define->type == XML_RELAXNG_VALUE) && (define->attrs != NULL)) {
953*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTypeLibraryPtr lib;
954*7c568831SAndroid Build Coastguard Worker
955*7c568831SAndroid Build Coastguard Worker lib = (xmlRelaxNGTypeLibraryPtr) define->data;
956*7c568831SAndroid Build Coastguard Worker if ((lib != NULL) && (lib->freef != NULL))
957*7c568831SAndroid Build Coastguard Worker lib->freef(lib->data, (void *) define->attrs);
958*7c568831SAndroid Build Coastguard Worker }
959*7c568831SAndroid Build Coastguard Worker if ((define->data != NULL) && (define->type == XML_RELAXNG_INTERLEAVE))
960*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreePartition((xmlRelaxNGPartitionPtr) define->data);
961*7c568831SAndroid Build Coastguard Worker if ((define->data != NULL) && (define->type == XML_RELAXNG_CHOICE))
962*7c568831SAndroid Build Coastguard Worker xmlHashFree((xmlHashTablePtr) define->data, NULL);
963*7c568831SAndroid Build Coastguard Worker if (define->name != NULL)
964*7c568831SAndroid Build Coastguard Worker xmlFree(define->name);
965*7c568831SAndroid Build Coastguard Worker if (define->ns != NULL)
966*7c568831SAndroid Build Coastguard Worker xmlFree(define->ns);
967*7c568831SAndroid Build Coastguard Worker if (define->value != NULL)
968*7c568831SAndroid Build Coastguard Worker xmlFree(define->value);
969*7c568831SAndroid Build Coastguard Worker if (define->contModel != NULL)
970*7c568831SAndroid Build Coastguard Worker xmlRegFreeRegexp(define->contModel);
971*7c568831SAndroid Build Coastguard Worker xmlFree(define);
972*7c568831SAndroid Build Coastguard Worker }
973*7c568831SAndroid Build Coastguard Worker
974*7c568831SAndroid Build Coastguard Worker /**
975*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGNewStates:
976*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
977*7c568831SAndroid Build Coastguard Worker * @size: the default size for the container
978*7c568831SAndroid Build Coastguard Worker *
979*7c568831SAndroid Build Coastguard Worker * Allocate a new RelaxNG validation state container
980*7c568831SAndroid Build Coastguard Worker *
981*7c568831SAndroid Build Coastguard Worker * Returns the newly allocated structure or NULL in case or error
982*7c568831SAndroid Build Coastguard Worker */
983*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGStatesPtr
xmlRelaxNGNewStates(xmlRelaxNGValidCtxtPtr ctxt,int size)984*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNewStates(xmlRelaxNGValidCtxtPtr ctxt, int size)
985*7c568831SAndroid Build Coastguard Worker {
986*7c568831SAndroid Build Coastguard Worker xmlRelaxNGStatesPtr ret;
987*7c568831SAndroid Build Coastguard Worker
988*7c568831SAndroid Build Coastguard Worker if ((ctxt != NULL) &&
989*7c568831SAndroid Build Coastguard Worker (ctxt->freeStates != NULL) && (ctxt->freeStatesNr > 0)) {
990*7c568831SAndroid Build Coastguard Worker ctxt->freeStatesNr--;
991*7c568831SAndroid Build Coastguard Worker ret = ctxt->freeStates[ctxt->freeStatesNr];
992*7c568831SAndroid Build Coastguard Worker ret->nbState = 0;
993*7c568831SAndroid Build Coastguard Worker return (ret);
994*7c568831SAndroid Build Coastguard Worker }
995*7c568831SAndroid Build Coastguard Worker if (size < 16)
996*7c568831SAndroid Build Coastguard Worker size = 16;
997*7c568831SAndroid Build Coastguard Worker
998*7c568831SAndroid Build Coastguard Worker ret = (xmlRelaxNGStatesPtr) xmlMalloc(sizeof(xmlRelaxNGStates) +
999*7c568831SAndroid Build Coastguard Worker (size -
1000*7c568831SAndroid Build Coastguard Worker 1) *
1001*7c568831SAndroid Build Coastguard Worker sizeof(xmlRelaxNGValidStatePtr));
1002*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
1003*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
1004*7c568831SAndroid Build Coastguard Worker return (NULL);
1005*7c568831SAndroid Build Coastguard Worker }
1006*7c568831SAndroid Build Coastguard Worker ret->nbState = 0;
1007*7c568831SAndroid Build Coastguard Worker ret->maxState = size;
1008*7c568831SAndroid Build Coastguard Worker ret->tabState = (xmlRelaxNGValidStatePtr *) xmlMalloc((size) *
1009*7c568831SAndroid Build Coastguard Worker sizeof
1010*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGValidStatePtr));
1011*7c568831SAndroid Build Coastguard Worker if (ret->tabState == NULL) {
1012*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
1013*7c568831SAndroid Build Coastguard Worker xmlFree(ret);
1014*7c568831SAndroid Build Coastguard Worker return (NULL);
1015*7c568831SAndroid Build Coastguard Worker }
1016*7c568831SAndroid Build Coastguard Worker return (ret);
1017*7c568831SAndroid Build Coastguard Worker }
1018*7c568831SAndroid Build Coastguard Worker
1019*7c568831SAndroid Build Coastguard Worker /**
1020*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGAddStateUniq:
1021*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
1022*7c568831SAndroid Build Coastguard Worker * @states: the states container
1023*7c568831SAndroid Build Coastguard Worker * @state: the validation state
1024*7c568831SAndroid Build Coastguard Worker *
1025*7c568831SAndroid Build Coastguard Worker * Add a RelaxNG validation state to the container without checking
1026*7c568831SAndroid Build Coastguard Worker * for unicity.
1027*7c568831SAndroid Build Coastguard Worker *
1028*7c568831SAndroid Build Coastguard Worker * Return 1 in case of success and 0 if this is a duplicate and -1 on error
1029*7c568831SAndroid Build Coastguard Worker */
1030*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGAddStatesUniq(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGStatesPtr states,xmlRelaxNGValidStatePtr state)1031*7c568831SAndroid Build Coastguard Worker xmlRelaxNGAddStatesUniq(xmlRelaxNGValidCtxtPtr ctxt,
1032*7c568831SAndroid Build Coastguard Worker xmlRelaxNGStatesPtr states,
1033*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr state)
1034*7c568831SAndroid Build Coastguard Worker {
1035*7c568831SAndroid Build Coastguard Worker if (state == NULL) {
1036*7c568831SAndroid Build Coastguard Worker return (-1);
1037*7c568831SAndroid Build Coastguard Worker }
1038*7c568831SAndroid Build Coastguard Worker if (states->nbState >= states->maxState) {
1039*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr *tmp;
1040*7c568831SAndroid Build Coastguard Worker int size;
1041*7c568831SAndroid Build Coastguard Worker
1042*7c568831SAndroid Build Coastguard Worker size = states->maxState * 2;
1043*7c568831SAndroid Build Coastguard Worker tmp = (xmlRelaxNGValidStatePtr *) xmlRealloc(states->tabState,
1044*7c568831SAndroid Build Coastguard Worker (size) *
1045*7c568831SAndroid Build Coastguard Worker sizeof
1046*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGValidStatePtr));
1047*7c568831SAndroid Build Coastguard Worker if (tmp == NULL) {
1048*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
1049*7c568831SAndroid Build Coastguard Worker return (-1);
1050*7c568831SAndroid Build Coastguard Worker }
1051*7c568831SAndroid Build Coastguard Worker states->tabState = tmp;
1052*7c568831SAndroid Build Coastguard Worker states->maxState = size;
1053*7c568831SAndroid Build Coastguard Worker }
1054*7c568831SAndroid Build Coastguard Worker states->tabState[states->nbState++] = state;
1055*7c568831SAndroid Build Coastguard Worker return (1);
1056*7c568831SAndroid Build Coastguard Worker }
1057*7c568831SAndroid Build Coastguard Worker
1058*7c568831SAndroid Build Coastguard Worker /**
1059*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGAddState:
1060*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
1061*7c568831SAndroid Build Coastguard Worker * @states: the states container
1062*7c568831SAndroid Build Coastguard Worker * @state: the validation state
1063*7c568831SAndroid Build Coastguard Worker *
1064*7c568831SAndroid Build Coastguard Worker * Add a RelaxNG validation state to the container
1065*7c568831SAndroid Build Coastguard Worker *
1066*7c568831SAndroid Build Coastguard Worker * Return 1 in case of success and 0 if this is a duplicate and -1 on error
1067*7c568831SAndroid Build Coastguard Worker */
1068*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGAddStates(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGStatesPtr states,xmlRelaxNGValidStatePtr state)1069*7c568831SAndroid Build Coastguard Worker xmlRelaxNGAddStates(xmlRelaxNGValidCtxtPtr ctxt,
1070*7c568831SAndroid Build Coastguard Worker xmlRelaxNGStatesPtr states,
1071*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr state)
1072*7c568831SAndroid Build Coastguard Worker {
1073*7c568831SAndroid Build Coastguard Worker int i;
1074*7c568831SAndroid Build Coastguard Worker
1075*7c568831SAndroid Build Coastguard Worker if (state == NULL || states == NULL) {
1076*7c568831SAndroid Build Coastguard Worker return (-1);
1077*7c568831SAndroid Build Coastguard Worker }
1078*7c568831SAndroid Build Coastguard Worker if (states->nbState >= states->maxState) {
1079*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr *tmp;
1080*7c568831SAndroid Build Coastguard Worker int size;
1081*7c568831SAndroid Build Coastguard Worker
1082*7c568831SAndroid Build Coastguard Worker size = states->maxState * 2;
1083*7c568831SAndroid Build Coastguard Worker tmp = (xmlRelaxNGValidStatePtr *) xmlRealloc(states->tabState,
1084*7c568831SAndroid Build Coastguard Worker (size) *
1085*7c568831SAndroid Build Coastguard Worker sizeof
1086*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGValidStatePtr));
1087*7c568831SAndroid Build Coastguard Worker if (tmp == NULL) {
1088*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
1089*7c568831SAndroid Build Coastguard Worker return (-1);
1090*7c568831SAndroid Build Coastguard Worker }
1091*7c568831SAndroid Build Coastguard Worker states->tabState = tmp;
1092*7c568831SAndroid Build Coastguard Worker states->maxState = size;
1093*7c568831SAndroid Build Coastguard Worker }
1094*7c568831SAndroid Build Coastguard Worker for (i = 0; i < states->nbState; i++) {
1095*7c568831SAndroid Build Coastguard Worker if (xmlRelaxNGEqualValidState(ctxt, state, states->tabState[i])) {
1096*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, state);
1097*7c568831SAndroid Build Coastguard Worker return (0);
1098*7c568831SAndroid Build Coastguard Worker }
1099*7c568831SAndroid Build Coastguard Worker }
1100*7c568831SAndroid Build Coastguard Worker states->tabState[states->nbState++] = state;
1101*7c568831SAndroid Build Coastguard Worker return (1);
1102*7c568831SAndroid Build Coastguard Worker }
1103*7c568831SAndroid Build Coastguard Worker
1104*7c568831SAndroid Build Coastguard Worker /**
1105*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGFreeStates:
1106*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
1107*7c568831SAndroid Build Coastguard Worker * @states: the container
1108*7c568831SAndroid Build Coastguard Worker *
1109*7c568831SAndroid Build Coastguard Worker * Free a RelaxNG validation state container
1110*7c568831SAndroid Build Coastguard Worker */
1111*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGFreeStates(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGStatesPtr states)1112*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(xmlRelaxNGValidCtxtPtr ctxt,
1113*7c568831SAndroid Build Coastguard Worker xmlRelaxNGStatesPtr states)
1114*7c568831SAndroid Build Coastguard Worker {
1115*7c568831SAndroid Build Coastguard Worker if (states == NULL)
1116*7c568831SAndroid Build Coastguard Worker return;
1117*7c568831SAndroid Build Coastguard Worker if ((ctxt != NULL) && (ctxt->freeStates == NULL)) {
1118*7c568831SAndroid Build Coastguard Worker ctxt->freeStatesMax = 40;
1119*7c568831SAndroid Build Coastguard Worker ctxt->freeStatesNr = 0;
1120*7c568831SAndroid Build Coastguard Worker ctxt->freeStates = (xmlRelaxNGStatesPtr *)
1121*7c568831SAndroid Build Coastguard Worker xmlMalloc(ctxt->freeStatesMax * sizeof(xmlRelaxNGStatesPtr));
1122*7c568831SAndroid Build Coastguard Worker if (ctxt->freeStates == NULL) {
1123*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
1124*7c568831SAndroid Build Coastguard Worker }
1125*7c568831SAndroid Build Coastguard Worker } else if ((ctxt != NULL)
1126*7c568831SAndroid Build Coastguard Worker && (ctxt->freeStatesNr >= ctxt->freeStatesMax)) {
1127*7c568831SAndroid Build Coastguard Worker xmlRelaxNGStatesPtr *tmp;
1128*7c568831SAndroid Build Coastguard Worker
1129*7c568831SAndroid Build Coastguard Worker tmp = (xmlRelaxNGStatesPtr *) xmlRealloc(ctxt->freeStates,
1130*7c568831SAndroid Build Coastguard Worker 2 * ctxt->freeStatesMax *
1131*7c568831SAndroid Build Coastguard Worker sizeof
1132*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGStatesPtr));
1133*7c568831SAndroid Build Coastguard Worker if (tmp == NULL) {
1134*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
1135*7c568831SAndroid Build Coastguard Worker xmlFree(states->tabState);
1136*7c568831SAndroid Build Coastguard Worker xmlFree(states);
1137*7c568831SAndroid Build Coastguard Worker return;
1138*7c568831SAndroid Build Coastguard Worker }
1139*7c568831SAndroid Build Coastguard Worker ctxt->freeStates = tmp;
1140*7c568831SAndroid Build Coastguard Worker ctxt->freeStatesMax *= 2;
1141*7c568831SAndroid Build Coastguard Worker }
1142*7c568831SAndroid Build Coastguard Worker if ((ctxt == NULL) || (ctxt->freeStates == NULL)) {
1143*7c568831SAndroid Build Coastguard Worker xmlFree(states->tabState);
1144*7c568831SAndroid Build Coastguard Worker xmlFree(states);
1145*7c568831SAndroid Build Coastguard Worker } else {
1146*7c568831SAndroid Build Coastguard Worker ctxt->freeStates[ctxt->freeStatesNr++] = states;
1147*7c568831SAndroid Build Coastguard Worker }
1148*7c568831SAndroid Build Coastguard Worker }
1149*7c568831SAndroid Build Coastguard Worker
1150*7c568831SAndroid Build Coastguard Worker /**
1151*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGNewValidState:
1152*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
1153*7c568831SAndroid Build Coastguard Worker * @node: the current node or NULL for the document
1154*7c568831SAndroid Build Coastguard Worker *
1155*7c568831SAndroid Build Coastguard Worker * Allocate a new RelaxNG validation state
1156*7c568831SAndroid Build Coastguard Worker *
1157*7c568831SAndroid Build Coastguard Worker * Returns the newly allocated structure or NULL in case or error
1158*7c568831SAndroid Build Coastguard Worker */
1159*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGValidStatePtr
xmlRelaxNGNewValidState(xmlRelaxNGValidCtxtPtr ctxt,xmlNodePtr node)1160*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNewValidState(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node)
1161*7c568831SAndroid Build Coastguard Worker {
1162*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr ret;
1163*7c568831SAndroid Build Coastguard Worker xmlAttrPtr attr;
1164*7c568831SAndroid Build Coastguard Worker xmlAttrPtr attrs[MAX_ATTR];
1165*7c568831SAndroid Build Coastguard Worker int nbAttrs = 0;
1166*7c568831SAndroid Build Coastguard Worker xmlNodePtr root = NULL;
1167*7c568831SAndroid Build Coastguard Worker
1168*7c568831SAndroid Build Coastguard Worker if (node == NULL) {
1169*7c568831SAndroid Build Coastguard Worker root = xmlDocGetRootElement(ctxt->doc);
1170*7c568831SAndroid Build Coastguard Worker if (root == NULL)
1171*7c568831SAndroid Build Coastguard Worker return (NULL);
1172*7c568831SAndroid Build Coastguard Worker } else {
1173*7c568831SAndroid Build Coastguard Worker attr = node->properties;
1174*7c568831SAndroid Build Coastguard Worker while (attr != NULL) {
1175*7c568831SAndroid Build Coastguard Worker if (nbAttrs < MAX_ATTR)
1176*7c568831SAndroid Build Coastguard Worker attrs[nbAttrs++] = attr;
1177*7c568831SAndroid Build Coastguard Worker else
1178*7c568831SAndroid Build Coastguard Worker nbAttrs++;
1179*7c568831SAndroid Build Coastguard Worker attr = attr->next;
1180*7c568831SAndroid Build Coastguard Worker }
1181*7c568831SAndroid Build Coastguard Worker }
1182*7c568831SAndroid Build Coastguard Worker if ((ctxt->freeState != NULL) && (ctxt->freeState->nbState > 0)) {
1183*7c568831SAndroid Build Coastguard Worker ctxt->freeState->nbState--;
1184*7c568831SAndroid Build Coastguard Worker ret = ctxt->freeState->tabState[ctxt->freeState->nbState];
1185*7c568831SAndroid Build Coastguard Worker } else {
1186*7c568831SAndroid Build Coastguard Worker ret =
1187*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGValidStatePtr)
1188*7c568831SAndroid Build Coastguard Worker xmlMalloc(sizeof(xmlRelaxNGValidState));
1189*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
1190*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
1191*7c568831SAndroid Build Coastguard Worker return (NULL);
1192*7c568831SAndroid Build Coastguard Worker }
1193*7c568831SAndroid Build Coastguard Worker memset(ret, 0, sizeof(xmlRelaxNGValidState));
1194*7c568831SAndroid Build Coastguard Worker }
1195*7c568831SAndroid Build Coastguard Worker ret->value = NULL;
1196*7c568831SAndroid Build Coastguard Worker ret->endvalue = NULL;
1197*7c568831SAndroid Build Coastguard Worker if (node == NULL) {
1198*7c568831SAndroid Build Coastguard Worker ret->node = (xmlNodePtr) ctxt->doc;
1199*7c568831SAndroid Build Coastguard Worker ret->seq = root;
1200*7c568831SAndroid Build Coastguard Worker } else {
1201*7c568831SAndroid Build Coastguard Worker ret->node = node;
1202*7c568831SAndroid Build Coastguard Worker ret->seq = node->children;
1203*7c568831SAndroid Build Coastguard Worker }
1204*7c568831SAndroid Build Coastguard Worker ret->nbAttrs = 0;
1205*7c568831SAndroid Build Coastguard Worker if (nbAttrs > 0) {
1206*7c568831SAndroid Build Coastguard Worker if (ret->attrs == NULL) {
1207*7c568831SAndroid Build Coastguard Worker if (nbAttrs < 4)
1208*7c568831SAndroid Build Coastguard Worker ret->maxAttrs = 4;
1209*7c568831SAndroid Build Coastguard Worker else
1210*7c568831SAndroid Build Coastguard Worker ret->maxAttrs = nbAttrs;
1211*7c568831SAndroid Build Coastguard Worker ret->attrs = (xmlAttrPtr *) xmlMalloc(ret->maxAttrs *
1212*7c568831SAndroid Build Coastguard Worker sizeof(xmlAttrPtr));
1213*7c568831SAndroid Build Coastguard Worker if (ret->attrs == NULL) {
1214*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
1215*7c568831SAndroid Build Coastguard Worker return (ret);
1216*7c568831SAndroid Build Coastguard Worker }
1217*7c568831SAndroid Build Coastguard Worker } else if (ret->maxAttrs < nbAttrs) {
1218*7c568831SAndroid Build Coastguard Worker xmlAttrPtr *tmp;
1219*7c568831SAndroid Build Coastguard Worker
1220*7c568831SAndroid Build Coastguard Worker tmp = (xmlAttrPtr *) xmlRealloc(ret->attrs, nbAttrs *
1221*7c568831SAndroid Build Coastguard Worker sizeof(xmlAttrPtr));
1222*7c568831SAndroid Build Coastguard Worker if (tmp == NULL) {
1223*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
1224*7c568831SAndroid Build Coastguard Worker return (ret);
1225*7c568831SAndroid Build Coastguard Worker }
1226*7c568831SAndroid Build Coastguard Worker ret->attrs = tmp;
1227*7c568831SAndroid Build Coastguard Worker ret->maxAttrs = nbAttrs;
1228*7c568831SAndroid Build Coastguard Worker }
1229*7c568831SAndroid Build Coastguard Worker ret->nbAttrs = nbAttrs;
1230*7c568831SAndroid Build Coastguard Worker if (nbAttrs < MAX_ATTR) {
1231*7c568831SAndroid Build Coastguard Worker memcpy(ret->attrs, attrs, sizeof(xmlAttrPtr) * nbAttrs);
1232*7c568831SAndroid Build Coastguard Worker } else {
1233*7c568831SAndroid Build Coastguard Worker attr = node->properties;
1234*7c568831SAndroid Build Coastguard Worker nbAttrs = 0;
1235*7c568831SAndroid Build Coastguard Worker while (attr != NULL) {
1236*7c568831SAndroid Build Coastguard Worker ret->attrs[nbAttrs++] = attr;
1237*7c568831SAndroid Build Coastguard Worker attr = attr->next;
1238*7c568831SAndroid Build Coastguard Worker }
1239*7c568831SAndroid Build Coastguard Worker }
1240*7c568831SAndroid Build Coastguard Worker }
1241*7c568831SAndroid Build Coastguard Worker ret->nbAttrLeft = ret->nbAttrs;
1242*7c568831SAndroid Build Coastguard Worker return (ret);
1243*7c568831SAndroid Build Coastguard Worker }
1244*7c568831SAndroid Build Coastguard Worker
1245*7c568831SAndroid Build Coastguard Worker /**
1246*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGCopyValidState:
1247*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
1248*7c568831SAndroid Build Coastguard Worker * @state: a validation state
1249*7c568831SAndroid Build Coastguard Worker *
1250*7c568831SAndroid Build Coastguard Worker * Copy the validation state
1251*7c568831SAndroid Build Coastguard Worker *
1252*7c568831SAndroid Build Coastguard Worker * Returns the newly allocated structure or NULL in case or error
1253*7c568831SAndroid Build Coastguard Worker */
1254*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGValidStatePtr
xmlRelaxNGCopyValidState(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGValidStatePtr state)1255*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCopyValidState(xmlRelaxNGValidCtxtPtr ctxt,
1256*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr state)
1257*7c568831SAndroid Build Coastguard Worker {
1258*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr ret;
1259*7c568831SAndroid Build Coastguard Worker unsigned int maxAttrs;
1260*7c568831SAndroid Build Coastguard Worker xmlAttrPtr *attrs;
1261*7c568831SAndroid Build Coastguard Worker
1262*7c568831SAndroid Build Coastguard Worker if (state == NULL)
1263*7c568831SAndroid Build Coastguard Worker return (NULL);
1264*7c568831SAndroid Build Coastguard Worker if ((ctxt->freeState != NULL) && (ctxt->freeState->nbState > 0)) {
1265*7c568831SAndroid Build Coastguard Worker ctxt->freeState->nbState--;
1266*7c568831SAndroid Build Coastguard Worker ret = ctxt->freeState->tabState[ctxt->freeState->nbState];
1267*7c568831SAndroid Build Coastguard Worker } else {
1268*7c568831SAndroid Build Coastguard Worker ret =
1269*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGValidStatePtr)
1270*7c568831SAndroid Build Coastguard Worker xmlMalloc(sizeof(xmlRelaxNGValidState));
1271*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
1272*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
1273*7c568831SAndroid Build Coastguard Worker return (NULL);
1274*7c568831SAndroid Build Coastguard Worker }
1275*7c568831SAndroid Build Coastguard Worker memset(ret, 0, sizeof(xmlRelaxNGValidState));
1276*7c568831SAndroid Build Coastguard Worker }
1277*7c568831SAndroid Build Coastguard Worker attrs = ret->attrs;
1278*7c568831SAndroid Build Coastguard Worker maxAttrs = ret->maxAttrs;
1279*7c568831SAndroid Build Coastguard Worker memcpy(ret, state, sizeof(xmlRelaxNGValidState));
1280*7c568831SAndroid Build Coastguard Worker ret->attrs = attrs;
1281*7c568831SAndroid Build Coastguard Worker ret->maxAttrs = maxAttrs;
1282*7c568831SAndroid Build Coastguard Worker if (state->nbAttrs > 0) {
1283*7c568831SAndroid Build Coastguard Worker if (ret->attrs == NULL) {
1284*7c568831SAndroid Build Coastguard Worker ret->maxAttrs = state->maxAttrs;
1285*7c568831SAndroid Build Coastguard Worker ret->attrs = (xmlAttrPtr *) xmlMalloc(ret->maxAttrs *
1286*7c568831SAndroid Build Coastguard Worker sizeof(xmlAttrPtr));
1287*7c568831SAndroid Build Coastguard Worker if (ret->attrs == NULL) {
1288*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
1289*7c568831SAndroid Build Coastguard Worker ret->nbAttrs = 0;
1290*7c568831SAndroid Build Coastguard Worker return (ret);
1291*7c568831SAndroid Build Coastguard Worker }
1292*7c568831SAndroid Build Coastguard Worker } else if (ret->maxAttrs < state->nbAttrs) {
1293*7c568831SAndroid Build Coastguard Worker xmlAttrPtr *tmp;
1294*7c568831SAndroid Build Coastguard Worker
1295*7c568831SAndroid Build Coastguard Worker tmp = (xmlAttrPtr *) xmlRealloc(ret->attrs, state->maxAttrs *
1296*7c568831SAndroid Build Coastguard Worker sizeof(xmlAttrPtr));
1297*7c568831SAndroid Build Coastguard Worker if (tmp == NULL) {
1298*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
1299*7c568831SAndroid Build Coastguard Worker ret->nbAttrs = 0;
1300*7c568831SAndroid Build Coastguard Worker return (ret);
1301*7c568831SAndroid Build Coastguard Worker }
1302*7c568831SAndroid Build Coastguard Worker ret->maxAttrs = state->maxAttrs;
1303*7c568831SAndroid Build Coastguard Worker ret->attrs = tmp;
1304*7c568831SAndroid Build Coastguard Worker }
1305*7c568831SAndroid Build Coastguard Worker memcpy(ret->attrs, state->attrs,
1306*7c568831SAndroid Build Coastguard Worker state->nbAttrs * sizeof(xmlAttrPtr));
1307*7c568831SAndroid Build Coastguard Worker }
1308*7c568831SAndroid Build Coastguard Worker return (ret);
1309*7c568831SAndroid Build Coastguard Worker }
1310*7c568831SAndroid Build Coastguard Worker
1311*7c568831SAndroid Build Coastguard Worker /**
1312*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGEqualValidState:
1313*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
1314*7c568831SAndroid Build Coastguard Worker * @state1: a validation state
1315*7c568831SAndroid Build Coastguard Worker * @state2: a validation state
1316*7c568831SAndroid Build Coastguard Worker *
1317*7c568831SAndroid Build Coastguard Worker * Compare the validation states for equality
1318*7c568831SAndroid Build Coastguard Worker *
1319*7c568831SAndroid Build Coastguard Worker * Returns 1 if equal, 0 otherwise
1320*7c568831SAndroid Build Coastguard Worker */
1321*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGEqualValidState(xmlRelaxNGValidCtxtPtr ctxt ATTRIBUTE_UNUSED,xmlRelaxNGValidStatePtr state1,xmlRelaxNGValidStatePtr state2)1322*7c568831SAndroid Build Coastguard Worker xmlRelaxNGEqualValidState(xmlRelaxNGValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
1323*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr state1,
1324*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr state2)
1325*7c568831SAndroid Build Coastguard Worker {
1326*7c568831SAndroid Build Coastguard Worker int i;
1327*7c568831SAndroid Build Coastguard Worker
1328*7c568831SAndroid Build Coastguard Worker if ((state1 == NULL) || (state2 == NULL))
1329*7c568831SAndroid Build Coastguard Worker return (0);
1330*7c568831SAndroid Build Coastguard Worker if (state1 == state2)
1331*7c568831SAndroid Build Coastguard Worker return (1);
1332*7c568831SAndroid Build Coastguard Worker if (state1->node != state2->node)
1333*7c568831SAndroid Build Coastguard Worker return (0);
1334*7c568831SAndroid Build Coastguard Worker if (state1->seq != state2->seq)
1335*7c568831SAndroid Build Coastguard Worker return (0);
1336*7c568831SAndroid Build Coastguard Worker if (state1->nbAttrLeft != state2->nbAttrLeft)
1337*7c568831SAndroid Build Coastguard Worker return (0);
1338*7c568831SAndroid Build Coastguard Worker if (state1->nbAttrs != state2->nbAttrs)
1339*7c568831SAndroid Build Coastguard Worker return (0);
1340*7c568831SAndroid Build Coastguard Worker if (state1->endvalue != state2->endvalue)
1341*7c568831SAndroid Build Coastguard Worker return (0);
1342*7c568831SAndroid Build Coastguard Worker if ((state1->value != state2->value) &&
1343*7c568831SAndroid Build Coastguard Worker (!xmlStrEqual(state1->value, state2->value)))
1344*7c568831SAndroid Build Coastguard Worker return (0);
1345*7c568831SAndroid Build Coastguard Worker for (i = 0; i < state1->nbAttrs; i++) {
1346*7c568831SAndroid Build Coastguard Worker if (state1->attrs[i] != state2->attrs[i])
1347*7c568831SAndroid Build Coastguard Worker return (0);
1348*7c568831SAndroid Build Coastguard Worker }
1349*7c568831SAndroid Build Coastguard Worker return (1);
1350*7c568831SAndroid Build Coastguard Worker }
1351*7c568831SAndroid Build Coastguard Worker
1352*7c568831SAndroid Build Coastguard Worker /**
1353*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGFreeValidState:
1354*7c568831SAndroid Build Coastguard Worker * @state: a validation state structure
1355*7c568831SAndroid Build Coastguard Worker *
1356*7c568831SAndroid Build Coastguard Worker * Deallocate a RelaxNG validation state structure.
1357*7c568831SAndroid Build Coastguard Worker */
1358*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGFreeValidState(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGValidStatePtr state)1359*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(xmlRelaxNGValidCtxtPtr ctxt,
1360*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr state)
1361*7c568831SAndroid Build Coastguard Worker {
1362*7c568831SAndroid Build Coastguard Worker if (state == NULL)
1363*7c568831SAndroid Build Coastguard Worker return;
1364*7c568831SAndroid Build Coastguard Worker
1365*7c568831SAndroid Build Coastguard Worker if ((ctxt != NULL) && (ctxt->freeState == NULL)) {
1366*7c568831SAndroid Build Coastguard Worker ctxt->freeState = xmlRelaxNGNewStates(ctxt, 40);
1367*7c568831SAndroid Build Coastguard Worker }
1368*7c568831SAndroid Build Coastguard Worker if ((ctxt == NULL) || (ctxt->freeState == NULL)) {
1369*7c568831SAndroid Build Coastguard Worker if (state->attrs != NULL)
1370*7c568831SAndroid Build Coastguard Worker xmlFree(state->attrs);
1371*7c568831SAndroid Build Coastguard Worker xmlFree(state);
1372*7c568831SAndroid Build Coastguard Worker } else {
1373*7c568831SAndroid Build Coastguard Worker xmlRelaxNGAddStatesUniq(ctxt, ctxt->freeState, state);
1374*7c568831SAndroid Build Coastguard Worker }
1375*7c568831SAndroid Build Coastguard Worker }
1376*7c568831SAndroid Build Coastguard Worker
1377*7c568831SAndroid Build Coastguard Worker /************************************************************************
1378*7c568831SAndroid Build Coastguard Worker * *
1379*7c568831SAndroid Build Coastguard Worker * Semi internal functions *
1380*7c568831SAndroid Build Coastguard Worker * *
1381*7c568831SAndroid Build Coastguard Worker ************************************************************************/
1382*7c568831SAndroid Build Coastguard Worker
1383*7c568831SAndroid Build Coastguard Worker /**
1384*7c568831SAndroid Build Coastguard Worker * xmlRelaxParserSetFlag:
1385*7c568831SAndroid Build Coastguard Worker * @ctxt: a RelaxNG parser context
1386*7c568831SAndroid Build Coastguard Worker * @flags: a set of flags values
1387*7c568831SAndroid Build Coastguard Worker *
1388*7c568831SAndroid Build Coastguard Worker * Semi private function used to pass information to a parser context
1389*7c568831SAndroid Build Coastguard Worker * which are a combination of xmlRelaxNGParserFlag .
1390*7c568831SAndroid Build Coastguard Worker *
1391*7c568831SAndroid Build Coastguard Worker * Returns 0 if success and -1 in case of error
1392*7c568831SAndroid Build Coastguard Worker */
1393*7c568831SAndroid Build Coastguard Worker int
xmlRelaxParserSetFlag(xmlRelaxNGParserCtxtPtr ctxt,int flags)1394*7c568831SAndroid Build Coastguard Worker xmlRelaxParserSetFlag(xmlRelaxNGParserCtxtPtr ctxt, int flags)
1395*7c568831SAndroid Build Coastguard Worker {
1396*7c568831SAndroid Build Coastguard Worker if (ctxt == NULL) return(-1);
1397*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNGP_FREE_DOC) {
1398*7c568831SAndroid Build Coastguard Worker ctxt->crng |= XML_RELAXNGP_FREE_DOC;
1399*7c568831SAndroid Build Coastguard Worker flags -= XML_RELAXNGP_FREE_DOC;
1400*7c568831SAndroid Build Coastguard Worker }
1401*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNGP_CRNG) {
1402*7c568831SAndroid Build Coastguard Worker ctxt->crng |= XML_RELAXNGP_CRNG;
1403*7c568831SAndroid Build Coastguard Worker flags -= XML_RELAXNGP_CRNG;
1404*7c568831SAndroid Build Coastguard Worker }
1405*7c568831SAndroid Build Coastguard Worker if (flags != 0) return(-1);
1406*7c568831SAndroid Build Coastguard Worker return(0);
1407*7c568831SAndroid Build Coastguard Worker }
1408*7c568831SAndroid Build Coastguard Worker
1409*7c568831SAndroid Build Coastguard Worker /************************************************************************
1410*7c568831SAndroid Build Coastguard Worker * *
1411*7c568831SAndroid Build Coastguard Worker * Document functions *
1412*7c568831SAndroid Build Coastguard Worker * *
1413*7c568831SAndroid Build Coastguard Worker ************************************************************************/
1414*7c568831SAndroid Build Coastguard Worker static xmlDocPtr xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt,
1415*7c568831SAndroid Build Coastguard Worker xmlDocPtr doc);
1416*7c568831SAndroid Build Coastguard Worker
1417*7c568831SAndroid Build Coastguard Worker static xmlDoc *
xmlRelaxReadFile(xmlRelaxNGParserCtxtPtr ctxt,const char * filename)1418*7c568831SAndroid Build Coastguard Worker xmlRelaxReadFile(xmlRelaxNGParserCtxtPtr ctxt, const char *filename) {
1419*7c568831SAndroid Build Coastguard Worker xmlParserCtxtPtr pctxt;
1420*7c568831SAndroid Build Coastguard Worker xmlDocPtr doc;
1421*7c568831SAndroid Build Coastguard Worker
1422*7c568831SAndroid Build Coastguard Worker pctxt = xmlNewParserCtxt();
1423*7c568831SAndroid Build Coastguard Worker if (pctxt == NULL) {
1424*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
1425*7c568831SAndroid Build Coastguard Worker return(NULL);
1426*7c568831SAndroid Build Coastguard Worker }
1427*7c568831SAndroid Build Coastguard Worker if (ctxt->serror != NULL)
1428*7c568831SAndroid Build Coastguard Worker xmlCtxtSetErrorHandler(pctxt, ctxt->serror, ctxt->userData);
1429*7c568831SAndroid Build Coastguard Worker if (ctxt->resourceLoader != NULL)
1430*7c568831SAndroid Build Coastguard Worker xmlCtxtSetResourceLoader(pctxt, ctxt->resourceLoader,
1431*7c568831SAndroid Build Coastguard Worker ctxt->resourceCtxt);
1432*7c568831SAndroid Build Coastguard Worker doc = xmlCtxtReadFile(pctxt, filename, NULL, 0);
1433*7c568831SAndroid Build Coastguard Worker xmlFreeParserCtxt(pctxt);
1434*7c568831SAndroid Build Coastguard Worker
1435*7c568831SAndroid Build Coastguard Worker return(doc);
1436*7c568831SAndroid Build Coastguard Worker }
1437*7c568831SAndroid Build Coastguard Worker
1438*7c568831SAndroid Build Coastguard Worker static xmlDoc *
xmlRelaxReadMemory(xmlRelaxNGParserCtxtPtr ctxt,const char * buf,int size)1439*7c568831SAndroid Build Coastguard Worker xmlRelaxReadMemory(xmlRelaxNGParserCtxtPtr ctxt, const char *buf, int size) {
1440*7c568831SAndroid Build Coastguard Worker xmlParserCtxtPtr pctxt;
1441*7c568831SAndroid Build Coastguard Worker xmlDocPtr doc;
1442*7c568831SAndroid Build Coastguard Worker
1443*7c568831SAndroid Build Coastguard Worker pctxt = xmlNewParserCtxt();
1444*7c568831SAndroid Build Coastguard Worker if (pctxt == NULL) {
1445*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
1446*7c568831SAndroid Build Coastguard Worker return(NULL);
1447*7c568831SAndroid Build Coastguard Worker }
1448*7c568831SAndroid Build Coastguard Worker if (ctxt->serror != NULL)
1449*7c568831SAndroid Build Coastguard Worker xmlCtxtSetErrorHandler(pctxt, ctxt->serror, ctxt->userData);
1450*7c568831SAndroid Build Coastguard Worker if (ctxt->resourceLoader != NULL)
1451*7c568831SAndroid Build Coastguard Worker xmlCtxtSetResourceLoader(pctxt, ctxt->resourceLoader,
1452*7c568831SAndroid Build Coastguard Worker ctxt->resourceCtxt);
1453*7c568831SAndroid Build Coastguard Worker doc = xmlCtxtReadMemory(pctxt, buf, size, NULL, NULL, 0);
1454*7c568831SAndroid Build Coastguard Worker xmlFreeParserCtxt(pctxt);
1455*7c568831SAndroid Build Coastguard Worker
1456*7c568831SAndroid Build Coastguard Worker return(doc);
1457*7c568831SAndroid Build Coastguard Worker }
1458*7c568831SAndroid Build Coastguard Worker
1459*7c568831SAndroid Build Coastguard Worker /**
1460*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGIncludePush:
1461*7c568831SAndroid Build Coastguard Worker * @ctxt: the parser context
1462*7c568831SAndroid Build Coastguard Worker * @value: the element doc
1463*7c568831SAndroid Build Coastguard Worker *
1464*7c568831SAndroid Build Coastguard Worker * Pushes a new include on top of the include stack
1465*7c568831SAndroid Build Coastguard Worker *
1466*7c568831SAndroid Build Coastguard Worker * Returns 0 in case of error, the index in the stack otherwise
1467*7c568831SAndroid Build Coastguard Worker */
1468*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGIncludePush(xmlRelaxNGParserCtxtPtr ctxt,xmlRelaxNGIncludePtr value)1469*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIncludePush(xmlRelaxNGParserCtxtPtr ctxt,
1470*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIncludePtr value)
1471*7c568831SAndroid Build Coastguard Worker {
1472*7c568831SAndroid Build Coastguard Worker if (ctxt->incTab == NULL) {
1473*7c568831SAndroid Build Coastguard Worker ctxt->incMax = 4;
1474*7c568831SAndroid Build Coastguard Worker ctxt->incNr = 0;
1475*7c568831SAndroid Build Coastguard Worker ctxt->incTab =
1476*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGIncludePtr *) xmlMalloc(ctxt->incMax *
1477*7c568831SAndroid Build Coastguard Worker sizeof(ctxt->incTab[0]));
1478*7c568831SAndroid Build Coastguard Worker if (ctxt->incTab == NULL) {
1479*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
1480*7c568831SAndroid Build Coastguard Worker return (0);
1481*7c568831SAndroid Build Coastguard Worker }
1482*7c568831SAndroid Build Coastguard Worker }
1483*7c568831SAndroid Build Coastguard Worker if (ctxt->incNr >= ctxt->incMax) {
1484*7c568831SAndroid Build Coastguard Worker ctxt->incMax *= 2;
1485*7c568831SAndroid Build Coastguard Worker ctxt->incTab =
1486*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGIncludePtr *) xmlRealloc(ctxt->incTab,
1487*7c568831SAndroid Build Coastguard Worker ctxt->incMax *
1488*7c568831SAndroid Build Coastguard Worker sizeof(ctxt->incTab[0]));
1489*7c568831SAndroid Build Coastguard Worker if (ctxt->incTab == NULL) {
1490*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
1491*7c568831SAndroid Build Coastguard Worker return (0);
1492*7c568831SAndroid Build Coastguard Worker }
1493*7c568831SAndroid Build Coastguard Worker }
1494*7c568831SAndroid Build Coastguard Worker ctxt->incTab[ctxt->incNr] = value;
1495*7c568831SAndroid Build Coastguard Worker ctxt->inc = value;
1496*7c568831SAndroid Build Coastguard Worker return (ctxt->incNr++);
1497*7c568831SAndroid Build Coastguard Worker }
1498*7c568831SAndroid Build Coastguard Worker
1499*7c568831SAndroid Build Coastguard Worker /**
1500*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGIncludePop:
1501*7c568831SAndroid Build Coastguard Worker * @ctxt: the parser context
1502*7c568831SAndroid Build Coastguard Worker *
1503*7c568831SAndroid Build Coastguard Worker * Pops the top include from the include stack
1504*7c568831SAndroid Build Coastguard Worker *
1505*7c568831SAndroid Build Coastguard Worker * Returns the include just removed
1506*7c568831SAndroid Build Coastguard Worker */
1507*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGIncludePtr
xmlRelaxNGIncludePop(xmlRelaxNGParserCtxtPtr ctxt)1508*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIncludePop(xmlRelaxNGParserCtxtPtr ctxt)
1509*7c568831SAndroid Build Coastguard Worker {
1510*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIncludePtr ret;
1511*7c568831SAndroid Build Coastguard Worker
1512*7c568831SAndroid Build Coastguard Worker if (ctxt->incNr <= 0)
1513*7c568831SAndroid Build Coastguard Worker return (NULL);
1514*7c568831SAndroid Build Coastguard Worker ctxt->incNr--;
1515*7c568831SAndroid Build Coastguard Worker if (ctxt->incNr > 0)
1516*7c568831SAndroid Build Coastguard Worker ctxt->inc = ctxt->incTab[ctxt->incNr - 1];
1517*7c568831SAndroid Build Coastguard Worker else
1518*7c568831SAndroid Build Coastguard Worker ctxt->inc = NULL;
1519*7c568831SAndroid Build Coastguard Worker ret = ctxt->incTab[ctxt->incNr];
1520*7c568831SAndroid Build Coastguard Worker ctxt->incTab[ctxt->incNr] = NULL;
1521*7c568831SAndroid Build Coastguard Worker return (ret);
1522*7c568831SAndroid Build Coastguard Worker }
1523*7c568831SAndroid Build Coastguard Worker
1524*7c568831SAndroid Build Coastguard Worker /**
1525*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGRemoveRedefine:
1526*7c568831SAndroid Build Coastguard Worker * @ctxt: the parser context
1527*7c568831SAndroid Build Coastguard Worker * @URL: the normalized URL
1528*7c568831SAndroid Build Coastguard Worker * @target: the included target
1529*7c568831SAndroid Build Coastguard Worker * @name: the define name to eliminate
1530*7c568831SAndroid Build Coastguard Worker *
1531*7c568831SAndroid Build Coastguard Worker * Applies the elimination algorithm of 4.7
1532*7c568831SAndroid Build Coastguard Worker *
1533*7c568831SAndroid Build Coastguard Worker * Returns 0 in case of error, 1 in case of success.
1534*7c568831SAndroid Build Coastguard Worker */
1535*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGRemoveRedefine(xmlRelaxNGParserCtxtPtr ctxt,const xmlChar * URL ATTRIBUTE_UNUSED,xmlNodePtr target,const xmlChar * name)1536*7c568831SAndroid Build Coastguard Worker xmlRelaxNGRemoveRedefine(xmlRelaxNGParserCtxtPtr ctxt,
1537*7c568831SAndroid Build Coastguard Worker const xmlChar * URL ATTRIBUTE_UNUSED,
1538*7c568831SAndroid Build Coastguard Worker xmlNodePtr target, const xmlChar * name)
1539*7c568831SAndroid Build Coastguard Worker {
1540*7c568831SAndroid Build Coastguard Worker int found = 0;
1541*7c568831SAndroid Build Coastguard Worker xmlNodePtr tmp, tmp2;
1542*7c568831SAndroid Build Coastguard Worker xmlChar *name2;
1543*7c568831SAndroid Build Coastguard Worker
1544*7c568831SAndroid Build Coastguard Worker tmp = target;
1545*7c568831SAndroid Build Coastguard Worker while (tmp != NULL) {
1546*7c568831SAndroid Build Coastguard Worker tmp2 = tmp->next;
1547*7c568831SAndroid Build Coastguard Worker if ((name == NULL) && (IS_RELAXNG(tmp, "start"))) {
1548*7c568831SAndroid Build Coastguard Worker found = 1;
1549*7c568831SAndroid Build Coastguard Worker xmlUnlinkNode(tmp);
1550*7c568831SAndroid Build Coastguard Worker xmlFreeNode(tmp);
1551*7c568831SAndroid Build Coastguard Worker } else if ((name != NULL) && (IS_RELAXNG(tmp, "define"))) {
1552*7c568831SAndroid Build Coastguard Worker name2 = xmlGetProp(tmp, BAD_CAST "name");
1553*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNormExtSpace(name2);
1554*7c568831SAndroid Build Coastguard Worker if (name2 != NULL) {
1555*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual(name, name2)) {
1556*7c568831SAndroid Build Coastguard Worker found = 1;
1557*7c568831SAndroid Build Coastguard Worker xmlUnlinkNode(tmp);
1558*7c568831SAndroid Build Coastguard Worker xmlFreeNode(tmp);
1559*7c568831SAndroid Build Coastguard Worker }
1560*7c568831SAndroid Build Coastguard Worker xmlFree(name2);
1561*7c568831SAndroid Build Coastguard Worker }
1562*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(tmp, "include")) {
1563*7c568831SAndroid Build Coastguard Worker xmlChar *href = NULL;
1564*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDocumentPtr inc = tmp->psvi;
1565*7c568831SAndroid Build Coastguard Worker
1566*7c568831SAndroid Build Coastguard Worker if ((inc != NULL) && (inc->doc != NULL) &&
1567*7c568831SAndroid Build Coastguard Worker (inc->doc->children != NULL)) {
1568*7c568831SAndroid Build Coastguard Worker
1569*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual
1570*7c568831SAndroid Build Coastguard Worker (inc->doc->children->name, BAD_CAST "grammar")) {
1571*7c568831SAndroid Build Coastguard Worker if (xmlRelaxNGRemoveRedefine(ctxt, href,
1572*7c568831SAndroid Build Coastguard Worker xmlDocGetRootElement(inc->doc)->children,
1573*7c568831SAndroid Build Coastguard Worker name) == 1) {
1574*7c568831SAndroid Build Coastguard Worker found = 1;
1575*7c568831SAndroid Build Coastguard Worker }
1576*7c568831SAndroid Build Coastguard Worker }
1577*7c568831SAndroid Build Coastguard Worker }
1578*7c568831SAndroid Build Coastguard Worker if (xmlRelaxNGRemoveRedefine(ctxt, URL, tmp->children, name) == 1) {
1579*7c568831SAndroid Build Coastguard Worker found = 1;
1580*7c568831SAndroid Build Coastguard Worker }
1581*7c568831SAndroid Build Coastguard Worker }
1582*7c568831SAndroid Build Coastguard Worker tmp = tmp2;
1583*7c568831SAndroid Build Coastguard Worker }
1584*7c568831SAndroid Build Coastguard Worker return (found);
1585*7c568831SAndroid Build Coastguard Worker }
1586*7c568831SAndroid Build Coastguard Worker
1587*7c568831SAndroid Build Coastguard Worker /**
1588*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGLoadInclude:
1589*7c568831SAndroid Build Coastguard Worker * @ctxt: the parser context
1590*7c568831SAndroid Build Coastguard Worker * @URL: the normalized URL
1591*7c568831SAndroid Build Coastguard Worker * @node: the include node.
1592*7c568831SAndroid Build Coastguard Worker * @ns: the namespace passed from the context.
1593*7c568831SAndroid Build Coastguard Worker *
1594*7c568831SAndroid Build Coastguard Worker * First lookup if the document is already loaded into the parser context,
1595*7c568831SAndroid Build Coastguard Worker * check against recursion. If not found the resource is loaded and
1596*7c568831SAndroid Build Coastguard Worker * the content is preprocessed before being returned back to the caller.
1597*7c568831SAndroid Build Coastguard Worker *
1598*7c568831SAndroid Build Coastguard Worker * Returns the xmlRelaxNGIncludePtr or NULL in case of error
1599*7c568831SAndroid Build Coastguard Worker */
1600*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGIncludePtr
xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt,const xmlChar * URL,xmlNodePtr node,const xmlChar * ns)1601*7c568831SAndroid Build Coastguard Worker xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * URL,
1602*7c568831SAndroid Build Coastguard Worker xmlNodePtr node, const xmlChar * ns)
1603*7c568831SAndroid Build Coastguard Worker {
1604*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIncludePtr ret = NULL;
1605*7c568831SAndroid Build Coastguard Worker xmlDocPtr doc;
1606*7c568831SAndroid Build Coastguard Worker int i;
1607*7c568831SAndroid Build Coastguard Worker xmlNodePtr root, cur;
1608*7c568831SAndroid Build Coastguard Worker
1609*7c568831SAndroid Build Coastguard Worker /*
1610*7c568831SAndroid Build Coastguard Worker * check against recursion in the stack
1611*7c568831SAndroid Build Coastguard Worker */
1612*7c568831SAndroid Build Coastguard Worker for (i = 0; i < ctxt->incNr; i++) {
1613*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual(ctxt->incTab[i]->href, URL)) {
1614*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, NULL, XML_RNGP_INCLUDE_RECURSE,
1615*7c568831SAndroid Build Coastguard Worker "Detected an Include recursion for %s\n", URL,
1616*7c568831SAndroid Build Coastguard Worker NULL);
1617*7c568831SAndroid Build Coastguard Worker return (NULL);
1618*7c568831SAndroid Build Coastguard Worker }
1619*7c568831SAndroid Build Coastguard Worker }
1620*7c568831SAndroid Build Coastguard Worker
1621*7c568831SAndroid Build Coastguard Worker /*
1622*7c568831SAndroid Build Coastguard Worker * load the document
1623*7c568831SAndroid Build Coastguard Worker */
1624*7c568831SAndroid Build Coastguard Worker doc = xmlRelaxReadFile(ctxt, (const char *) URL);
1625*7c568831SAndroid Build Coastguard Worker if (doc == NULL) {
1626*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_PARSE_ERROR,
1627*7c568831SAndroid Build Coastguard Worker "xmlRelaxNG: could not load %s\n", URL, NULL);
1628*7c568831SAndroid Build Coastguard Worker return (NULL);
1629*7c568831SAndroid Build Coastguard Worker }
1630*7c568831SAndroid Build Coastguard Worker
1631*7c568831SAndroid Build Coastguard Worker /*
1632*7c568831SAndroid Build Coastguard Worker * Allocate the document structures and register it first.
1633*7c568831SAndroid Build Coastguard Worker */
1634*7c568831SAndroid Build Coastguard Worker ret = (xmlRelaxNGIncludePtr) xmlMalloc(sizeof(xmlRelaxNGInclude));
1635*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
1636*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
1637*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(doc);
1638*7c568831SAndroid Build Coastguard Worker return (NULL);
1639*7c568831SAndroid Build Coastguard Worker }
1640*7c568831SAndroid Build Coastguard Worker memset(ret, 0, sizeof(xmlRelaxNGInclude));
1641*7c568831SAndroid Build Coastguard Worker ret->doc = doc;
1642*7c568831SAndroid Build Coastguard Worker ret->href = xmlStrdup(URL);
1643*7c568831SAndroid Build Coastguard Worker ret->next = ctxt->includes;
1644*7c568831SAndroid Build Coastguard Worker ctxt->includes = ret;
1645*7c568831SAndroid Build Coastguard Worker
1646*7c568831SAndroid Build Coastguard Worker /*
1647*7c568831SAndroid Build Coastguard Worker * transmit the ns if needed
1648*7c568831SAndroid Build Coastguard Worker */
1649*7c568831SAndroid Build Coastguard Worker if (ns != NULL) {
1650*7c568831SAndroid Build Coastguard Worker root = xmlDocGetRootElement(doc);
1651*7c568831SAndroid Build Coastguard Worker if (root != NULL) {
1652*7c568831SAndroid Build Coastguard Worker if (xmlHasProp(root, BAD_CAST "ns") == NULL) {
1653*7c568831SAndroid Build Coastguard Worker xmlSetProp(root, BAD_CAST "ns", ns);
1654*7c568831SAndroid Build Coastguard Worker }
1655*7c568831SAndroid Build Coastguard Worker }
1656*7c568831SAndroid Build Coastguard Worker }
1657*7c568831SAndroid Build Coastguard Worker
1658*7c568831SAndroid Build Coastguard Worker /*
1659*7c568831SAndroid Build Coastguard Worker * push it on the stack
1660*7c568831SAndroid Build Coastguard Worker */
1661*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIncludePush(ctxt, ret);
1662*7c568831SAndroid Build Coastguard Worker
1663*7c568831SAndroid Build Coastguard Worker /*
1664*7c568831SAndroid Build Coastguard Worker * Some preprocessing of the document content, this include recursing
1665*7c568831SAndroid Build Coastguard Worker * in the include stack.
1666*7c568831SAndroid Build Coastguard Worker */
1667*7c568831SAndroid Build Coastguard Worker
1668*7c568831SAndroid Build Coastguard Worker doc = xmlRelaxNGCleanupDoc(ctxt, doc);
1669*7c568831SAndroid Build Coastguard Worker if (doc == NULL) {
1670*7c568831SAndroid Build Coastguard Worker ctxt->inc = NULL;
1671*7c568831SAndroid Build Coastguard Worker return (NULL);
1672*7c568831SAndroid Build Coastguard Worker }
1673*7c568831SAndroid Build Coastguard Worker
1674*7c568831SAndroid Build Coastguard Worker /*
1675*7c568831SAndroid Build Coastguard Worker * Pop up the include from the stack
1676*7c568831SAndroid Build Coastguard Worker */
1677*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIncludePop(ctxt);
1678*7c568831SAndroid Build Coastguard Worker
1679*7c568831SAndroid Build Coastguard Worker /*
1680*7c568831SAndroid Build Coastguard Worker * Check that the top element is a grammar
1681*7c568831SAndroid Build Coastguard Worker */
1682*7c568831SAndroid Build Coastguard Worker root = xmlDocGetRootElement(doc);
1683*7c568831SAndroid Build Coastguard Worker if (root == NULL) {
1684*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_EMPTY,
1685*7c568831SAndroid Build Coastguard Worker "xmlRelaxNG: included document is empty %s\n", URL,
1686*7c568831SAndroid Build Coastguard Worker NULL);
1687*7c568831SAndroid Build Coastguard Worker return (NULL);
1688*7c568831SAndroid Build Coastguard Worker }
1689*7c568831SAndroid Build Coastguard Worker if (!IS_RELAXNG(root, "grammar")) {
1690*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_GRAMMAR_MISSING,
1691*7c568831SAndroid Build Coastguard Worker "xmlRelaxNG: included document %s root is not a grammar\n",
1692*7c568831SAndroid Build Coastguard Worker URL, NULL);
1693*7c568831SAndroid Build Coastguard Worker return (NULL);
1694*7c568831SAndroid Build Coastguard Worker }
1695*7c568831SAndroid Build Coastguard Worker
1696*7c568831SAndroid Build Coastguard Worker /*
1697*7c568831SAndroid Build Coastguard Worker * Elimination of redefined rules in the include.
1698*7c568831SAndroid Build Coastguard Worker */
1699*7c568831SAndroid Build Coastguard Worker cur = node->children;
1700*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
1701*7c568831SAndroid Build Coastguard Worker if (IS_RELAXNG(cur, "start")) {
1702*7c568831SAndroid Build Coastguard Worker int found = 0;
1703*7c568831SAndroid Build Coastguard Worker
1704*7c568831SAndroid Build Coastguard Worker found =
1705*7c568831SAndroid Build Coastguard Worker xmlRelaxNGRemoveRedefine(ctxt, URL, root->children, NULL);
1706*7c568831SAndroid Build Coastguard Worker if (!found) {
1707*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_START_MISSING,
1708*7c568831SAndroid Build Coastguard Worker "xmlRelaxNG: include %s has a start but not the included grammar\n",
1709*7c568831SAndroid Build Coastguard Worker URL, NULL);
1710*7c568831SAndroid Build Coastguard Worker }
1711*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(cur, "define")) {
1712*7c568831SAndroid Build Coastguard Worker xmlChar *name;
1713*7c568831SAndroid Build Coastguard Worker
1714*7c568831SAndroid Build Coastguard Worker name = xmlGetProp(cur, BAD_CAST "name");
1715*7c568831SAndroid Build Coastguard Worker if (name == NULL) {
1716*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_NAME_MISSING,
1717*7c568831SAndroid Build Coastguard Worker "xmlRelaxNG: include %s has define without name\n",
1718*7c568831SAndroid Build Coastguard Worker URL, NULL);
1719*7c568831SAndroid Build Coastguard Worker } else {
1720*7c568831SAndroid Build Coastguard Worker int found;
1721*7c568831SAndroid Build Coastguard Worker
1722*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNormExtSpace(name);
1723*7c568831SAndroid Build Coastguard Worker found = xmlRelaxNGRemoveRedefine(ctxt, URL,
1724*7c568831SAndroid Build Coastguard Worker root->children, name);
1725*7c568831SAndroid Build Coastguard Worker if (!found) {
1726*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_MISSING,
1727*7c568831SAndroid Build Coastguard Worker "xmlRelaxNG: include %s has a define %s but not the included grammar\n",
1728*7c568831SAndroid Build Coastguard Worker URL, name);
1729*7c568831SAndroid Build Coastguard Worker }
1730*7c568831SAndroid Build Coastguard Worker xmlFree(name);
1731*7c568831SAndroid Build Coastguard Worker }
1732*7c568831SAndroid Build Coastguard Worker }
1733*7c568831SAndroid Build Coastguard Worker if (IS_RELAXNG(cur, "div") && cur->children != NULL) {
1734*7c568831SAndroid Build Coastguard Worker cur = cur->children;
1735*7c568831SAndroid Build Coastguard Worker } else {
1736*7c568831SAndroid Build Coastguard Worker if (cur->next != NULL) {
1737*7c568831SAndroid Build Coastguard Worker cur = cur->next;
1738*7c568831SAndroid Build Coastguard Worker } else {
1739*7c568831SAndroid Build Coastguard Worker while (cur->parent != node && cur->parent->next == NULL) {
1740*7c568831SAndroid Build Coastguard Worker cur = cur->parent;
1741*7c568831SAndroid Build Coastguard Worker }
1742*7c568831SAndroid Build Coastguard Worker cur = cur->parent != node ? cur->parent->next : NULL;
1743*7c568831SAndroid Build Coastguard Worker }
1744*7c568831SAndroid Build Coastguard Worker }
1745*7c568831SAndroid Build Coastguard Worker }
1746*7c568831SAndroid Build Coastguard Worker
1747*7c568831SAndroid Build Coastguard Worker
1748*7c568831SAndroid Build Coastguard Worker return (ret);
1749*7c568831SAndroid Build Coastguard Worker }
1750*7c568831SAndroid Build Coastguard Worker
1751*7c568831SAndroid Build Coastguard Worker /**
1752*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidErrorPush:
1753*7c568831SAndroid Build Coastguard Worker * @ctxt: the validation context
1754*7c568831SAndroid Build Coastguard Worker * @err: the error code
1755*7c568831SAndroid Build Coastguard Worker * @arg1: the first string argument
1756*7c568831SAndroid Build Coastguard Worker * @arg2: the second string argument
1757*7c568831SAndroid Build Coastguard Worker * @dup: arg need to be duplicated
1758*7c568831SAndroid Build Coastguard Worker *
1759*7c568831SAndroid Build Coastguard Worker * Pushes a new error on top of the error stack
1760*7c568831SAndroid Build Coastguard Worker *
1761*7c568831SAndroid Build Coastguard Worker * Returns 0 in case of error, the index in the stack otherwise
1762*7c568831SAndroid Build Coastguard Worker */
1763*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGValidErrorPush(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGValidErr err,const xmlChar * arg1,const xmlChar * arg2,int dup)1764*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidErrorPush(xmlRelaxNGValidCtxtPtr ctxt,
1765*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidErr err, const xmlChar * arg1,
1766*7c568831SAndroid Build Coastguard Worker const xmlChar * arg2, int dup)
1767*7c568831SAndroid Build Coastguard Worker {
1768*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidErrorPtr cur;
1769*7c568831SAndroid Build Coastguard Worker
1770*7c568831SAndroid Build Coastguard Worker if (ctxt->errTab == NULL) {
1771*7c568831SAndroid Build Coastguard Worker ctxt->errMax = 8;
1772*7c568831SAndroid Build Coastguard Worker ctxt->errNr = 0;
1773*7c568831SAndroid Build Coastguard Worker ctxt->errTab =
1774*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGValidErrorPtr) xmlMalloc(ctxt->errMax *
1775*7c568831SAndroid Build Coastguard Worker sizeof
1776*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGValidError));
1777*7c568831SAndroid Build Coastguard Worker if (ctxt->errTab == NULL) {
1778*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
1779*7c568831SAndroid Build Coastguard Worker return (0);
1780*7c568831SAndroid Build Coastguard Worker }
1781*7c568831SAndroid Build Coastguard Worker ctxt->err = NULL;
1782*7c568831SAndroid Build Coastguard Worker }
1783*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr >= ctxt->errMax) {
1784*7c568831SAndroid Build Coastguard Worker ctxt->errMax *= 2;
1785*7c568831SAndroid Build Coastguard Worker ctxt->errTab =
1786*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGValidErrorPtr) xmlRealloc(ctxt->errTab,
1787*7c568831SAndroid Build Coastguard Worker ctxt->errMax *
1788*7c568831SAndroid Build Coastguard Worker sizeof
1789*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGValidError));
1790*7c568831SAndroid Build Coastguard Worker if (ctxt->errTab == NULL) {
1791*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
1792*7c568831SAndroid Build Coastguard Worker return (0);
1793*7c568831SAndroid Build Coastguard Worker }
1794*7c568831SAndroid Build Coastguard Worker ctxt->err = &ctxt->errTab[ctxt->errNr - 1];
1795*7c568831SAndroid Build Coastguard Worker }
1796*7c568831SAndroid Build Coastguard Worker if ((ctxt->err != NULL) && (ctxt->state != NULL) &&
1797*7c568831SAndroid Build Coastguard Worker (ctxt->err->node == ctxt->state->node) && (ctxt->err->err == err))
1798*7c568831SAndroid Build Coastguard Worker return (ctxt->errNr);
1799*7c568831SAndroid Build Coastguard Worker cur = &ctxt->errTab[ctxt->errNr];
1800*7c568831SAndroid Build Coastguard Worker cur->err = err;
1801*7c568831SAndroid Build Coastguard Worker if (dup) {
1802*7c568831SAndroid Build Coastguard Worker cur->arg1 = xmlStrdup(arg1);
1803*7c568831SAndroid Build Coastguard Worker cur->arg2 = xmlStrdup(arg2);
1804*7c568831SAndroid Build Coastguard Worker cur->flags = ERROR_IS_DUP;
1805*7c568831SAndroid Build Coastguard Worker } else {
1806*7c568831SAndroid Build Coastguard Worker cur->arg1 = arg1;
1807*7c568831SAndroid Build Coastguard Worker cur->arg2 = arg2;
1808*7c568831SAndroid Build Coastguard Worker cur->flags = 0;
1809*7c568831SAndroid Build Coastguard Worker }
1810*7c568831SAndroid Build Coastguard Worker if (ctxt->state != NULL) {
1811*7c568831SAndroid Build Coastguard Worker cur->node = ctxt->state->node;
1812*7c568831SAndroid Build Coastguard Worker cur->seq = ctxt->state->seq;
1813*7c568831SAndroid Build Coastguard Worker } else {
1814*7c568831SAndroid Build Coastguard Worker cur->node = NULL;
1815*7c568831SAndroid Build Coastguard Worker cur->seq = NULL;
1816*7c568831SAndroid Build Coastguard Worker }
1817*7c568831SAndroid Build Coastguard Worker ctxt->err = cur;
1818*7c568831SAndroid Build Coastguard Worker return (ctxt->errNr++);
1819*7c568831SAndroid Build Coastguard Worker }
1820*7c568831SAndroid Build Coastguard Worker
1821*7c568831SAndroid Build Coastguard Worker /**
1822*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidErrorPop:
1823*7c568831SAndroid Build Coastguard Worker * @ctxt: the validation context
1824*7c568831SAndroid Build Coastguard Worker *
1825*7c568831SAndroid Build Coastguard Worker * Pops the top error from the error stack
1826*7c568831SAndroid Build Coastguard Worker */
1827*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGValidErrorPop(xmlRelaxNGValidCtxtPtr ctxt)1828*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidErrorPop(xmlRelaxNGValidCtxtPtr ctxt)
1829*7c568831SAndroid Build Coastguard Worker {
1830*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidErrorPtr cur;
1831*7c568831SAndroid Build Coastguard Worker
1832*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr <= 0) {
1833*7c568831SAndroid Build Coastguard Worker ctxt->err = NULL;
1834*7c568831SAndroid Build Coastguard Worker return;
1835*7c568831SAndroid Build Coastguard Worker }
1836*7c568831SAndroid Build Coastguard Worker ctxt->errNr--;
1837*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr > 0)
1838*7c568831SAndroid Build Coastguard Worker ctxt->err = &ctxt->errTab[ctxt->errNr - 1];
1839*7c568831SAndroid Build Coastguard Worker else
1840*7c568831SAndroid Build Coastguard Worker ctxt->err = NULL;
1841*7c568831SAndroid Build Coastguard Worker cur = &ctxt->errTab[ctxt->errNr];
1842*7c568831SAndroid Build Coastguard Worker if (cur->flags & ERROR_IS_DUP) {
1843*7c568831SAndroid Build Coastguard Worker if (cur->arg1 != NULL)
1844*7c568831SAndroid Build Coastguard Worker xmlFree((xmlChar *) cur->arg1);
1845*7c568831SAndroid Build Coastguard Worker cur->arg1 = NULL;
1846*7c568831SAndroid Build Coastguard Worker if (cur->arg2 != NULL)
1847*7c568831SAndroid Build Coastguard Worker xmlFree((xmlChar *) cur->arg2);
1848*7c568831SAndroid Build Coastguard Worker cur->arg2 = NULL;
1849*7c568831SAndroid Build Coastguard Worker cur->flags = 0;
1850*7c568831SAndroid Build Coastguard Worker }
1851*7c568831SAndroid Build Coastguard Worker }
1852*7c568831SAndroid Build Coastguard Worker
1853*7c568831SAndroid Build Coastguard Worker /**
1854*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGDocumentPush:
1855*7c568831SAndroid Build Coastguard Worker * @ctxt: the parser context
1856*7c568831SAndroid Build Coastguard Worker * @value: the element doc
1857*7c568831SAndroid Build Coastguard Worker *
1858*7c568831SAndroid Build Coastguard Worker * Pushes a new doc on top of the doc stack
1859*7c568831SAndroid Build Coastguard Worker *
1860*7c568831SAndroid Build Coastguard Worker * Returns 0 in case of error, the index in the stack otherwise
1861*7c568831SAndroid Build Coastguard Worker */
1862*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGDocumentPush(xmlRelaxNGParserCtxtPtr ctxt,xmlRelaxNGDocumentPtr value)1863*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDocumentPush(xmlRelaxNGParserCtxtPtr ctxt,
1864*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDocumentPtr value)
1865*7c568831SAndroid Build Coastguard Worker {
1866*7c568831SAndroid Build Coastguard Worker if (ctxt->docTab == NULL) {
1867*7c568831SAndroid Build Coastguard Worker ctxt->docMax = 4;
1868*7c568831SAndroid Build Coastguard Worker ctxt->docNr = 0;
1869*7c568831SAndroid Build Coastguard Worker ctxt->docTab =
1870*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGDocumentPtr *) xmlMalloc(ctxt->docMax *
1871*7c568831SAndroid Build Coastguard Worker sizeof(ctxt->docTab[0]));
1872*7c568831SAndroid Build Coastguard Worker if (ctxt->docTab == NULL) {
1873*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
1874*7c568831SAndroid Build Coastguard Worker return (0);
1875*7c568831SAndroid Build Coastguard Worker }
1876*7c568831SAndroid Build Coastguard Worker }
1877*7c568831SAndroid Build Coastguard Worker if (ctxt->docNr >= ctxt->docMax) {
1878*7c568831SAndroid Build Coastguard Worker ctxt->docMax *= 2;
1879*7c568831SAndroid Build Coastguard Worker ctxt->docTab =
1880*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGDocumentPtr *) xmlRealloc(ctxt->docTab,
1881*7c568831SAndroid Build Coastguard Worker ctxt->docMax *
1882*7c568831SAndroid Build Coastguard Worker sizeof(ctxt->docTab[0]));
1883*7c568831SAndroid Build Coastguard Worker if (ctxt->docTab == NULL) {
1884*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
1885*7c568831SAndroid Build Coastguard Worker return (0);
1886*7c568831SAndroid Build Coastguard Worker }
1887*7c568831SAndroid Build Coastguard Worker }
1888*7c568831SAndroid Build Coastguard Worker ctxt->docTab[ctxt->docNr] = value;
1889*7c568831SAndroid Build Coastguard Worker ctxt->doc = value;
1890*7c568831SAndroid Build Coastguard Worker return (ctxt->docNr++);
1891*7c568831SAndroid Build Coastguard Worker }
1892*7c568831SAndroid Build Coastguard Worker
1893*7c568831SAndroid Build Coastguard Worker /**
1894*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGDocumentPop:
1895*7c568831SAndroid Build Coastguard Worker * @ctxt: the parser context
1896*7c568831SAndroid Build Coastguard Worker *
1897*7c568831SAndroid Build Coastguard Worker * Pops the top doc from the doc stack
1898*7c568831SAndroid Build Coastguard Worker *
1899*7c568831SAndroid Build Coastguard Worker * Returns the doc just removed
1900*7c568831SAndroid Build Coastguard Worker */
1901*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDocumentPtr
xmlRelaxNGDocumentPop(xmlRelaxNGParserCtxtPtr ctxt)1902*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDocumentPop(xmlRelaxNGParserCtxtPtr ctxt)
1903*7c568831SAndroid Build Coastguard Worker {
1904*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDocumentPtr ret;
1905*7c568831SAndroid Build Coastguard Worker
1906*7c568831SAndroid Build Coastguard Worker if (ctxt->docNr <= 0)
1907*7c568831SAndroid Build Coastguard Worker return (NULL);
1908*7c568831SAndroid Build Coastguard Worker ctxt->docNr--;
1909*7c568831SAndroid Build Coastguard Worker if (ctxt->docNr > 0)
1910*7c568831SAndroid Build Coastguard Worker ctxt->doc = ctxt->docTab[ctxt->docNr - 1];
1911*7c568831SAndroid Build Coastguard Worker else
1912*7c568831SAndroid Build Coastguard Worker ctxt->doc = NULL;
1913*7c568831SAndroid Build Coastguard Worker ret = ctxt->docTab[ctxt->docNr];
1914*7c568831SAndroid Build Coastguard Worker ctxt->docTab[ctxt->docNr] = NULL;
1915*7c568831SAndroid Build Coastguard Worker return (ret);
1916*7c568831SAndroid Build Coastguard Worker }
1917*7c568831SAndroid Build Coastguard Worker
1918*7c568831SAndroid Build Coastguard Worker /**
1919*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGLoadExternalRef:
1920*7c568831SAndroid Build Coastguard Worker * @ctxt: the parser context
1921*7c568831SAndroid Build Coastguard Worker * @URL: the normalized URL
1922*7c568831SAndroid Build Coastguard Worker * @ns: the inherited ns if any
1923*7c568831SAndroid Build Coastguard Worker *
1924*7c568831SAndroid Build Coastguard Worker * First lookup if the document is already loaded into the parser context,
1925*7c568831SAndroid Build Coastguard Worker * check against recursion. If not found the resource is loaded and
1926*7c568831SAndroid Build Coastguard Worker * the content is preprocessed before being returned back to the caller.
1927*7c568831SAndroid Build Coastguard Worker *
1928*7c568831SAndroid Build Coastguard Worker * Returns the xmlRelaxNGDocumentPtr or NULL in case of error
1929*7c568831SAndroid Build Coastguard Worker */
1930*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDocumentPtr
xmlRelaxNGLoadExternalRef(xmlRelaxNGParserCtxtPtr ctxt,const xmlChar * URL,const xmlChar * ns)1931*7c568831SAndroid Build Coastguard Worker xmlRelaxNGLoadExternalRef(xmlRelaxNGParserCtxtPtr ctxt,
1932*7c568831SAndroid Build Coastguard Worker const xmlChar * URL, const xmlChar * ns)
1933*7c568831SAndroid Build Coastguard Worker {
1934*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDocumentPtr ret = NULL;
1935*7c568831SAndroid Build Coastguard Worker xmlDocPtr doc;
1936*7c568831SAndroid Build Coastguard Worker xmlNodePtr root;
1937*7c568831SAndroid Build Coastguard Worker int i;
1938*7c568831SAndroid Build Coastguard Worker
1939*7c568831SAndroid Build Coastguard Worker /*
1940*7c568831SAndroid Build Coastguard Worker * check against recursion in the stack
1941*7c568831SAndroid Build Coastguard Worker */
1942*7c568831SAndroid Build Coastguard Worker for (i = 0; i < ctxt->docNr; i++) {
1943*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual(ctxt->docTab[i]->href, URL)) {
1944*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, NULL, XML_RNGP_EXTERNALREF_RECURSE,
1945*7c568831SAndroid Build Coastguard Worker "Detected an externalRef recursion for %s\n", URL,
1946*7c568831SAndroid Build Coastguard Worker NULL);
1947*7c568831SAndroid Build Coastguard Worker return (NULL);
1948*7c568831SAndroid Build Coastguard Worker }
1949*7c568831SAndroid Build Coastguard Worker }
1950*7c568831SAndroid Build Coastguard Worker
1951*7c568831SAndroid Build Coastguard Worker /*
1952*7c568831SAndroid Build Coastguard Worker * load the document
1953*7c568831SAndroid Build Coastguard Worker */
1954*7c568831SAndroid Build Coastguard Worker doc = xmlRelaxReadFile(ctxt, (const char *) URL);
1955*7c568831SAndroid Build Coastguard Worker if (doc == NULL) {
1956*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
1957*7c568831SAndroid Build Coastguard Worker "xmlRelaxNG: could not load %s\n", URL, NULL);
1958*7c568831SAndroid Build Coastguard Worker return (NULL);
1959*7c568831SAndroid Build Coastguard Worker }
1960*7c568831SAndroid Build Coastguard Worker
1961*7c568831SAndroid Build Coastguard Worker /*
1962*7c568831SAndroid Build Coastguard Worker * Allocate the document structures and register it first.
1963*7c568831SAndroid Build Coastguard Worker */
1964*7c568831SAndroid Build Coastguard Worker ret = (xmlRelaxNGDocumentPtr) xmlMalloc(sizeof(xmlRelaxNGDocument));
1965*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
1966*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
1967*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(doc);
1968*7c568831SAndroid Build Coastguard Worker return (NULL);
1969*7c568831SAndroid Build Coastguard Worker }
1970*7c568831SAndroid Build Coastguard Worker memset(ret, 0, sizeof(xmlRelaxNGDocument));
1971*7c568831SAndroid Build Coastguard Worker ret->doc = doc;
1972*7c568831SAndroid Build Coastguard Worker ret->href = xmlStrdup(URL);
1973*7c568831SAndroid Build Coastguard Worker ret->next = ctxt->documents;
1974*7c568831SAndroid Build Coastguard Worker ret->externalRef = 1;
1975*7c568831SAndroid Build Coastguard Worker ctxt->documents = ret;
1976*7c568831SAndroid Build Coastguard Worker
1977*7c568831SAndroid Build Coastguard Worker /*
1978*7c568831SAndroid Build Coastguard Worker * transmit the ns if needed
1979*7c568831SAndroid Build Coastguard Worker */
1980*7c568831SAndroid Build Coastguard Worker if (ns != NULL) {
1981*7c568831SAndroid Build Coastguard Worker root = xmlDocGetRootElement(doc);
1982*7c568831SAndroid Build Coastguard Worker if (root != NULL) {
1983*7c568831SAndroid Build Coastguard Worker if (xmlHasProp(root, BAD_CAST "ns") == NULL) {
1984*7c568831SAndroid Build Coastguard Worker xmlSetProp(root, BAD_CAST "ns", ns);
1985*7c568831SAndroid Build Coastguard Worker }
1986*7c568831SAndroid Build Coastguard Worker }
1987*7c568831SAndroid Build Coastguard Worker }
1988*7c568831SAndroid Build Coastguard Worker
1989*7c568831SAndroid Build Coastguard Worker /*
1990*7c568831SAndroid Build Coastguard Worker * push it on the stack and register it in the hash table
1991*7c568831SAndroid Build Coastguard Worker */
1992*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDocumentPush(ctxt, ret);
1993*7c568831SAndroid Build Coastguard Worker
1994*7c568831SAndroid Build Coastguard Worker /*
1995*7c568831SAndroid Build Coastguard Worker * Some preprocessing of the document content
1996*7c568831SAndroid Build Coastguard Worker */
1997*7c568831SAndroid Build Coastguard Worker doc = xmlRelaxNGCleanupDoc(ctxt, doc);
1998*7c568831SAndroid Build Coastguard Worker if (doc == NULL) {
1999*7c568831SAndroid Build Coastguard Worker ctxt->doc = NULL;
2000*7c568831SAndroid Build Coastguard Worker return (NULL);
2001*7c568831SAndroid Build Coastguard Worker }
2002*7c568831SAndroid Build Coastguard Worker
2003*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDocumentPop(ctxt);
2004*7c568831SAndroid Build Coastguard Worker
2005*7c568831SAndroid Build Coastguard Worker return (ret);
2006*7c568831SAndroid Build Coastguard Worker }
2007*7c568831SAndroid Build Coastguard Worker
2008*7c568831SAndroid Build Coastguard Worker /************************************************************************
2009*7c568831SAndroid Build Coastguard Worker * *
2010*7c568831SAndroid Build Coastguard Worker * Error functions *
2011*7c568831SAndroid Build Coastguard Worker * *
2012*7c568831SAndroid Build Coastguard Worker ************************************************************************/
2013*7c568831SAndroid Build Coastguard Worker
2014*7c568831SAndroid Build Coastguard Worker #define VALID_ERR(a) xmlRelaxNGAddValidError(ctxt, a, NULL, NULL, 0);
2015*7c568831SAndroid Build Coastguard Worker #define VALID_ERR2(a, b) xmlRelaxNGAddValidError(ctxt, a, b, NULL, 0);
2016*7c568831SAndroid Build Coastguard Worker #define VALID_ERR3(a, b, c) xmlRelaxNGAddValidError(ctxt, a, b, c, 0);
2017*7c568831SAndroid Build Coastguard Worker #define VALID_ERR2P(a, b) xmlRelaxNGAddValidError(ctxt, a, b, NULL, 1);
2018*7c568831SAndroid Build Coastguard Worker #define VALID_ERR3P(a, b, c) xmlRelaxNGAddValidError(ctxt, a, b, c, 1);
2019*7c568831SAndroid Build Coastguard Worker
2020*7c568831SAndroid Build Coastguard Worker static const char *
xmlRelaxNGDefName(xmlRelaxNGDefinePtr def)2021*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefName(xmlRelaxNGDefinePtr def)
2022*7c568831SAndroid Build Coastguard Worker {
2023*7c568831SAndroid Build Coastguard Worker if (def == NULL)
2024*7c568831SAndroid Build Coastguard Worker return ("none");
2025*7c568831SAndroid Build Coastguard Worker switch (def->type) {
2026*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EMPTY:
2027*7c568831SAndroid Build Coastguard Worker return ("empty");
2028*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOT_ALLOWED:
2029*7c568831SAndroid Build Coastguard Worker return ("notAllowed");
2030*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXCEPT:
2031*7c568831SAndroid Build Coastguard Worker return ("except");
2032*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_TEXT:
2033*7c568831SAndroid Build Coastguard Worker return ("text");
2034*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ELEMENT:
2035*7c568831SAndroid Build Coastguard Worker return ("element");
2036*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DATATYPE:
2037*7c568831SAndroid Build Coastguard Worker return ("datatype");
2038*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_VALUE:
2039*7c568831SAndroid Build Coastguard Worker return ("value");
2040*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_LIST:
2041*7c568831SAndroid Build Coastguard Worker return ("list");
2042*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ATTRIBUTE:
2043*7c568831SAndroid Build Coastguard Worker return ("attribute");
2044*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DEF:
2045*7c568831SAndroid Build Coastguard Worker return ("def");
2046*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_REF:
2047*7c568831SAndroid Build Coastguard Worker return ("ref");
2048*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXTERNALREF:
2049*7c568831SAndroid Build Coastguard Worker return ("externalRef");
2050*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARENTREF:
2051*7c568831SAndroid Build Coastguard Worker return ("parentRef");
2052*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_OPTIONAL:
2053*7c568831SAndroid Build Coastguard Worker return ("optional");
2054*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ZEROORMORE:
2055*7c568831SAndroid Build Coastguard Worker return ("zeroOrMore");
2056*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ONEORMORE:
2057*7c568831SAndroid Build Coastguard Worker return ("oneOrMore");
2058*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_CHOICE:
2059*7c568831SAndroid Build Coastguard Worker return ("choice");
2060*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_GROUP:
2061*7c568831SAndroid Build Coastguard Worker return ("group");
2062*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_INTERLEAVE:
2063*7c568831SAndroid Build Coastguard Worker return ("interleave");
2064*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_START:
2065*7c568831SAndroid Build Coastguard Worker return ("start");
2066*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOOP:
2067*7c568831SAndroid Build Coastguard Worker return ("noop");
2068*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARAM:
2069*7c568831SAndroid Build Coastguard Worker return ("param");
2070*7c568831SAndroid Build Coastguard Worker }
2071*7c568831SAndroid Build Coastguard Worker return ("unknown");
2072*7c568831SAndroid Build Coastguard Worker }
2073*7c568831SAndroid Build Coastguard Worker
2074*7c568831SAndroid Build Coastguard Worker /**
2075*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGGetErrorString:
2076*7c568831SAndroid Build Coastguard Worker * @err: the error code
2077*7c568831SAndroid Build Coastguard Worker * @arg1: the first string argument
2078*7c568831SAndroid Build Coastguard Worker * @arg2: the second string argument
2079*7c568831SAndroid Build Coastguard Worker *
2080*7c568831SAndroid Build Coastguard Worker * computes a formatted error string for the given error code and args
2081*7c568831SAndroid Build Coastguard Worker *
2082*7c568831SAndroid Build Coastguard Worker * Returns the error string, it must be deallocated by the caller
2083*7c568831SAndroid Build Coastguard Worker */
2084*7c568831SAndroid Build Coastguard Worker static xmlChar *
xmlRelaxNGGetErrorString(xmlRelaxNGValidErr err,const xmlChar * arg1,const xmlChar * arg2)2085*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGetErrorString(xmlRelaxNGValidErr err, const xmlChar * arg1,
2086*7c568831SAndroid Build Coastguard Worker const xmlChar * arg2)
2087*7c568831SAndroid Build Coastguard Worker {
2088*7c568831SAndroid Build Coastguard Worker char msg[1000];
2089*7c568831SAndroid Build Coastguard Worker xmlChar *result;
2090*7c568831SAndroid Build Coastguard Worker
2091*7c568831SAndroid Build Coastguard Worker if (arg1 == NULL)
2092*7c568831SAndroid Build Coastguard Worker arg1 = BAD_CAST "";
2093*7c568831SAndroid Build Coastguard Worker if (arg2 == NULL)
2094*7c568831SAndroid Build Coastguard Worker arg2 = BAD_CAST "";
2095*7c568831SAndroid Build Coastguard Worker
2096*7c568831SAndroid Build Coastguard Worker msg[0] = 0;
2097*7c568831SAndroid Build Coastguard Worker switch (err) {
2098*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_OK:
2099*7c568831SAndroid Build Coastguard Worker return (NULL);
2100*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_MEMORY:
2101*7c568831SAndroid Build Coastguard Worker return (xmlCharStrdup("out of memory\n"));
2102*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_TYPE:
2103*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "failed to validate type %s\n", arg1);
2104*7c568831SAndroid Build Coastguard Worker break;
2105*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_TYPEVAL:
2106*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Type %s doesn't allow value '%s'\n", arg1,
2107*7c568831SAndroid Build Coastguard Worker arg2);
2108*7c568831SAndroid Build Coastguard Worker break;
2109*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_DUPID:
2110*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "ID %s redefined\n", arg1);
2111*7c568831SAndroid Build Coastguard Worker break;
2112*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_TYPECMP:
2113*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "failed to compare type %s\n", arg1);
2114*7c568831SAndroid Build Coastguard Worker break;
2115*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_NOSTATE:
2116*7c568831SAndroid Build Coastguard Worker return (xmlCharStrdup("Internal error: no state\n"));
2117*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_NODEFINE:
2118*7c568831SAndroid Build Coastguard Worker return (xmlCharStrdup("Internal error: no define\n"));
2119*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_INTERNAL:
2120*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Internal error: %s\n", arg1);
2121*7c568831SAndroid Build Coastguard Worker break;
2122*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_LISTEXTRA:
2123*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Extra data in list: %s\n", arg1);
2124*7c568831SAndroid Build Coastguard Worker break;
2125*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_INTERNODATA:
2126*7c568831SAndroid Build Coastguard Worker return (xmlCharStrdup
2127*7c568831SAndroid Build Coastguard Worker ("Internal: interleave block has no data\n"));
2128*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_INTERSEQ:
2129*7c568831SAndroid Build Coastguard Worker return (xmlCharStrdup("Invalid sequence in interleave\n"));
2130*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_INTEREXTRA:
2131*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Extra element %s in interleave\n", arg1);
2132*7c568831SAndroid Build Coastguard Worker break;
2133*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_ELEMNAME:
2134*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Expecting element %s, got %s\n", arg1,
2135*7c568831SAndroid Build Coastguard Worker arg2);
2136*7c568831SAndroid Build Coastguard Worker break;
2137*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_ELEMNONS:
2138*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Expecting a namespace for element %s\n",
2139*7c568831SAndroid Build Coastguard Worker arg1);
2140*7c568831SAndroid Build Coastguard Worker break;
2141*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_ELEMWRONGNS:
2142*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000,
2143*7c568831SAndroid Build Coastguard Worker "Element %s has wrong namespace: expecting %s\n", arg1,
2144*7c568831SAndroid Build Coastguard Worker arg2);
2145*7c568831SAndroid Build Coastguard Worker break;
2146*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_ELEMWRONG:
2147*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Did not expect element %s there\n", arg1);
2148*7c568831SAndroid Build Coastguard Worker break;
2149*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_TEXTWRONG:
2150*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000,
2151*7c568831SAndroid Build Coastguard Worker "Did not expect text in element %s content\n", arg1);
2152*7c568831SAndroid Build Coastguard Worker break;
2153*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_ELEMEXTRANS:
2154*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Expecting no namespace for element %s\n",
2155*7c568831SAndroid Build Coastguard Worker arg1);
2156*7c568831SAndroid Build Coastguard Worker break;
2157*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_ELEMNOTEMPTY:
2158*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Expecting element %s to be empty\n", arg1);
2159*7c568831SAndroid Build Coastguard Worker break;
2160*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_NOELEM:
2161*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Expecting an element %s, got nothing\n",
2162*7c568831SAndroid Build Coastguard Worker arg1);
2163*7c568831SAndroid Build Coastguard Worker break;
2164*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_NOTELEM:
2165*7c568831SAndroid Build Coastguard Worker return (xmlCharStrdup("Expecting an element got text\n"));
2166*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_ATTRVALID:
2167*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Element %s failed to validate attributes\n",
2168*7c568831SAndroid Build Coastguard Worker arg1);
2169*7c568831SAndroid Build Coastguard Worker break;
2170*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_CONTENTVALID:
2171*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Element %s failed to validate content\n",
2172*7c568831SAndroid Build Coastguard Worker arg1);
2173*7c568831SAndroid Build Coastguard Worker break;
2174*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_EXTRACONTENT:
2175*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Element %s has extra content: %s\n",
2176*7c568831SAndroid Build Coastguard Worker arg1, arg2);
2177*7c568831SAndroid Build Coastguard Worker break;
2178*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_INVALIDATTR:
2179*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Invalid attribute %s for element %s\n",
2180*7c568831SAndroid Build Coastguard Worker arg1, arg2);
2181*7c568831SAndroid Build Coastguard Worker break;
2182*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_LACKDATA:
2183*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Datatype element %s contains no data\n",
2184*7c568831SAndroid Build Coastguard Worker arg1);
2185*7c568831SAndroid Build Coastguard Worker break;
2186*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_DATAELEM:
2187*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Datatype element %s has child elements\n",
2188*7c568831SAndroid Build Coastguard Worker arg1);
2189*7c568831SAndroid Build Coastguard Worker break;
2190*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_VALELEM:
2191*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Value element %s has child elements\n",
2192*7c568831SAndroid Build Coastguard Worker arg1);
2193*7c568831SAndroid Build Coastguard Worker break;
2194*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_LISTELEM:
2195*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "List element %s has child elements\n",
2196*7c568831SAndroid Build Coastguard Worker arg1);
2197*7c568831SAndroid Build Coastguard Worker break;
2198*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_DATATYPE:
2199*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Error validating datatype %s\n", arg1);
2200*7c568831SAndroid Build Coastguard Worker break;
2201*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_VALUE:
2202*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Error validating value %s\n", arg1);
2203*7c568831SAndroid Build Coastguard Worker break;
2204*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_LIST:
2205*7c568831SAndroid Build Coastguard Worker return (xmlCharStrdup("Error validating list\n"));
2206*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_NOGRAMMAR:
2207*7c568831SAndroid Build Coastguard Worker return (xmlCharStrdup("No top grammar defined\n"));
2208*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ERR_EXTRADATA:
2209*7c568831SAndroid Build Coastguard Worker return (xmlCharStrdup("Extra data in the document\n"));
2210*7c568831SAndroid Build Coastguard Worker default:
2211*7c568831SAndroid Build Coastguard Worker return (xmlCharStrdup("Unknown error !\n"));
2212*7c568831SAndroid Build Coastguard Worker }
2213*7c568831SAndroid Build Coastguard Worker if (msg[0] == 0) {
2214*7c568831SAndroid Build Coastguard Worker snprintf(msg, 1000, "Unknown error code %d\n", err);
2215*7c568831SAndroid Build Coastguard Worker }
2216*7c568831SAndroid Build Coastguard Worker msg[1000 - 1] = 0;
2217*7c568831SAndroid Build Coastguard Worker result = xmlCharStrdup(msg);
2218*7c568831SAndroid Build Coastguard Worker return (xmlEscapeFormatString(&result));
2219*7c568831SAndroid Build Coastguard Worker }
2220*7c568831SAndroid Build Coastguard Worker
2221*7c568831SAndroid Build Coastguard Worker /**
2222*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGShowValidError:
2223*7c568831SAndroid Build Coastguard Worker * @ctxt: the validation context
2224*7c568831SAndroid Build Coastguard Worker * @err: the error number
2225*7c568831SAndroid Build Coastguard Worker * @node: the node
2226*7c568831SAndroid Build Coastguard Worker * @child: the node child generating the problem.
2227*7c568831SAndroid Build Coastguard Worker * @arg1: the first argument
2228*7c568831SAndroid Build Coastguard Worker * @arg2: the second argument
2229*7c568831SAndroid Build Coastguard Worker *
2230*7c568831SAndroid Build Coastguard Worker * Show a validation error.
2231*7c568831SAndroid Build Coastguard Worker */
2232*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGShowValidError(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGValidErr err,xmlNodePtr node,xmlNodePtr child,const xmlChar * arg1,const xmlChar * arg2)2233*7c568831SAndroid Build Coastguard Worker xmlRelaxNGShowValidError(xmlRelaxNGValidCtxtPtr ctxt,
2234*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidErr err, xmlNodePtr node,
2235*7c568831SAndroid Build Coastguard Worker xmlNodePtr child, const xmlChar * arg1,
2236*7c568831SAndroid Build Coastguard Worker const xmlChar * arg2)
2237*7c568831SAndroid Build Coastguard Worker {
2238*7c568831SAndroid Build Coastguard Worker xmlChar *msg;
2239*7c568831SAndroid Build Coastguard Worker
2240*7c568831SAndroid Build Coastguard Worker if (ctxt->flags & FLAGS_NOERROR)
2241*7c568831SAndroid Build Coastguard Worker return;
2242*7c568831SAndroid Build Coastguard Worker
2243*7c568831SAndroid Build Coastguard Worker msg = xmlRelaxNGGetErrorString(err, arg1, arg2);
2244*7c568831SAndroid Build Coastguard Worker if (msg == NULL)
2245*7c568831SAndroid Build Coastguard Worker return;
2246*7c568831SAndroid Build Coastguard Worker
2247*7c568831SAndroid Build Coastguard Worker if (ctxt->errNo == XML_RELAXNG_OK)
2248*7c568831SAndroid Build Coastguard Worker ctxt->errNo = err;
2249*7c568831SAndroid Build Coastguard Worker xmlRngVErr(ctxt, (child == NULL ? node : child), err,
2250*7c568831SAndroid Build Coastguard Worker (const char *) msg, arg1, arg2);
2251*7c568831SAndroid Build Coastguard Worker xmlFree(msg);
2252*7c568831SAndroid Build Coastguard Worker }
2253*7c568831SAndroid Build Coastguard Worker
2254*7c568831SAndroid Build Coastguard Worker /**
2255*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGPopErrors:
2256*7c568831SAndroid Build Coastguard Worker * @ctxt: the validation context
2257*7c568831SAndroid Build Coastguard Worker * @level: the error level in the stack
2258*7c568831SAndroid Build Coastguard Worker *
2259*7c568831SAndroid Build Coastguard Worker * pop and discard all errors until the given level is reached
2260*7c568831SAndroid Build Coastguard Worker */
2261*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGPopErrors(xmlRelaxNGValidCtxtPtr ctxt,int level)2262*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPopErrors(xmlRelaxNGValidCtxtPtr ctxt, int level)
2263*7c568831SAndroid Build Coastguard Worker {
2264*7c568831SAndroid Build Coastguard Worker int i;
2265*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidErrorPtr err;
2266*7c568831SAndroid Build Coastguard Worker
2267*7c568831SAndroid Build Coastguard Worker for (i = level; i < ctxt->errNr; i++) {
2268*7c568831SAndroid Build Coastguard Worker err = &ctxt->errTab[i];
2269*7c568831SAndroid Build Coastguard Worker if (err->flags & ERROR_IS_DUP) {
2270*7c568831SAndroid Build Coastguard Worker if (err->arg1 != NULL)
2271*7c568831SAndroid Build Coastguard Worker xmlFree((xmlChar *) err->arg1);
2272*7c568831SAndroid Build Coastguard Worker err->arg1 = NULL;
2273*7c568831SAndroid Build Coastguard Worker if (err->arg2 != NULL)
2274*7c568831SAndroid Build Coastguard Worker xmlFree((xmlChar *) err->arg2);
2275*7c568831SAndroid Build Coastguard Worker err->arg2 = NULL;
2276*7c568831SAndroid Build Coastguard Worker err->flags = 0;
2277*7c568831SAndroid Build Coastguard Worker }
2278*7c568831SAndroid Build Coastguard Worker }
2279*7c568831SAndroid Build Coastguard Worker ctxt->errNr = level;
2280*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr <= 0)
2281*7c568831SAndroid Build Coastguard Worker ctxt->err = NULL;
2282*7c568831SAndroid Build Coastguard Worker }
2283*7c568831SAndroid Build Coastguard Worker
2284*7c568831SAndroid Build Coastguard Worker /**
2285*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGDumpValidError:
2286*7c568831SAndroid Build Coastguard Worker * @ctxt: the validation context
2287*7c568831SAndroid Build Coastguard Worker *
2288*7c568831SAndroid Build Coastguard Worker * Show all validation error over a given index.
2289*7c568831SAndroid Build Coastguard Worker */
2290*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGDumpValidError(xmlRelaxNGValidCtxtPtr ctxt)2291*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpValidError(xmlRelaxNGValidCtxtPtr ctxt)
2292*7c568831SAndroid Build Coastguard Worker {
2293*7c568831SAndroid Build Coastguard Worker int i, j, k;
2294*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidErrorPtr err, dup;
2295*7c568831SAndroid Build Coastguard Worker
2296*7c568831SAndroid Build Coastguard Worker for (i = 0, k = 0; i < ctxt->errNr; i++) {
2297*7c568831SAndroid Build Coastguard Worker err = &ctxt->errTab[i];
2298*7c568831SAndroid Build Coastguard Worker if (k < MAX_ERROR) {
2299*7c568831SAndroid Build Coastguard Worker for (j = 0; j < i; j++) {
2300*7c568831SAndroid Build Coastguard Worker dup = &ctxt->errTab[j];
2301*7c568831SAndroid Build Coastguard Worker if ((err->err == dup->err) && (err->node == dup->node) &&
2302*7c568831SAndroid Build Coastguard Worker (xmlStrEqual(err->arg1, dup->arg1)) &&
2303*7c568831SAndroid Build Coastguard Worker (xmlStrEqual(err->arg2, dup->arg2))) {
2304*7c568831SAndroid Build Coastguard Worker goto skip;
2305*7c568831SAndroid Build Coastguard Worker }
2306*7c568831SAndroid Build Coastguard Worker }
2307*7c568831SAndroid Build Coastguard Worker xmlRelaxNGShowValidError(ctxt, err->err, err->node, err->seq,
2308*7c568831SAndroid Build Coastguard Worker err->arg1, err->arg2);
2309*7c568831SAndroid Build Coastguard Worker k++;
2310*7c568831SAndroid Build Coastguard Worker }
2311*7c568831SAndroid Build Coastguard Worker skip:
2312*7c568831SAndroid Build Coastguard Worker if (err->flags & ERROR_IS_DUP) {
2313*7c568831SAndroid Build Coastguard Worker if (err->arg1 != NULL)
2314*7c568831SAndroid Build Coastguard Worker xmlFree((xmlChar *) err->arg1);
2315*7c568831SAndroid Build Coastguard Worker err->arg1 = NULL;
2316*7c568831SAndroid Build Coastguard Worker if (err->arg2 != NULL)
2317*7c568831SAndroid Build Coastguard Worker xmlFree((xmlChar *) err->arg2);
2318*7c568831SAndroid Build Coastguard Worker err->arg2 = NULL;
2319*7c568831SAndroid Build Coastguard Worker err->flags = 0;
2320*7c568831SAndroid Build Coastguard Worker }
2321*7c568831SAndroid Build Coastguard Worker }
2322*7c568831SAndroid Build Coastguard Worker ctxt->errNr = 0;
2323*7c568831SAndroid Build Coastguard Worker }
2324*7c568831SAndroid Build Coastguard Worker
2325*7c568831SAndroid Build Coastguard Worker /**
2326*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGAddValidError:
2327*7c568831SAndroid Build Coastguard Worker * @ctxt: the validation context
2328*7c568831SAndroid Build Coastguard Worker * @err: the error number
2329*7c568831SAndroid Build Coastguard Worker * @arg1: the first argument
2330*7c568831SAndroid Build Coastguard Worker * @arg2: the second argument
2331*7c568831SAndroid Build Coastguard Worker * @dup: need to dup the args
2332*7c568831SAndroid Build Coastguard Worker *
2333*7c568831SAndroid Build Coastguard Worker * Register a validation error, either generating it if it's sure
2334*7c568831SAndroid Build Coastguard Worker * or stacking it for later handling if unsure.
2335*7c568831SAndroid Build Coastguard Worker */
2336*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGAddValidError(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGValidErr err,const xmlChar * arg1,const xmlChar * arg2,int dup)2337*7c568831SAndroid Build Coastguard Worker xmlRelaxNGAddValidError(xmlRelaxNGValidCtxtPtr ctxt,
2338*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidErr err, const xmlChar * arg1,
2339*7c568831SAndroid Build Coastguard Worker const xmlChar * arg2, int dup)
2340*7c568831SAndroid Build Coastguard Worker {
2341*7c568831SAndroid Build Coastguard Worker if (ctxt == NULL)
2342*7c568831SAndroid Build Coastguard Worker return;
2343*7c568831SAndroid Build Coastguard Worker if (ctxt->flags & FLAGS_NOERROR)
2344*7c568831SAndroid Build Coastguard Worker return;
2345*7c568831SAndroid Build Coastguard Worker
2346*7c568831SAndroid Build Coastguard Worker /*
2347*7c568831SAndroid Build Coastguard Worker * generate the error directly
2348*7c568831SAndroid Build Coastguard Worker */
2349*7c568831SAndroid Build Coastguard Worker if (((ctxt->flags & FLAGS_IGNORABLE) == 0) ||
2350*7c568831SAndroid Build Coastguard Worker (ctxt->flags & FLAGS_NEGATIVE)) {
2351*7c568831SAndroid Build Coastguard Worker xmlNodePtr node, seq;
2352*7c568831SAndroid Build Coastguard Worker
2353*7c568831SAndroid Build Coastguard Worker /*
2354*7c568831SAndroid Build Coastguard Worker * Flush first any stacked error which might be the
2355*7c568831SAndroid Build Coastguard Worker * real cause of the problem.
2356*7c568831SAndroid Build Coastguard Worker */
2357*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr != 0)
2358*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpValidError(ctxt);
2359*7c568831SAndroid Build Coastguard Worker if (ctxt->state != NULL) {
2360*7c568831SAndroid Build Coastguard Worker node = ctxt->state->node;
2361*7c568831SAndroid Build Coastguard Worker seq = ctxt->state->seq;
2362*7c568831SAndroid Build Coastguard Worker } else {
2363*7c568831SAndroid Build Coastguard Worker node = seq = NULL;
2364*7c568831SAndroid Build Coastguard Worker }
2365*7c568831SAndroid Build Coastguard Worker if ((node == NULL) && (seq == NULL)) {
2366*7c568831SAndroid Build Coastguard Worker node = ctxt->pnode;
2367*7c568831SAndroid Build Coastguard Worker }
2368*7c568831SAndroid Build Coastguard Worker xmlRelaxNGShowValidError(ctxt, err, node, seq, arg1, arg2);
2369*7c568831SAndroid Build Coastguard Worker }
2370*7c568831SAndroid Build Coastguard Worker /*
2371*7c568831SAndroid Build Coastguard Worker * Stack the error for later processing if needed
2372*7c568831SAndroid Build Coastguard Worker */
2373*7c568831SAndroid Build Coastguard Worker else {
2374*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidErrorPush(ctxt, err, arg1, arg2, dup);
2375*7c568831SAndroid Build Coastguard Worker }
2376*7c568831SAndroid Build Coastguard Worker }
2377*7c568831SAndroid Build Coastguard Worker
2378*7c568831SAndroid Build Coastguard Worker
2379*7c568831SAndroid Build Coastguard Worker /************************************************************************
2380*7c568831SAndroid Build Coastguard Worker * *
2381*7c568831SAndroid Build Coastguard Worker * Type library hooks *
2382*7c568831SAndroid Build Coastguard Worker * *
2383*7c568831SAndroid Build Coastguard Worker ************************************************************************/
2384*7c568831SAndroid Build Coastguard Worker static xmlChar *xmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt,
2385*7c568831SAndroid Build Coastguard Worker const xmlChar * str);
2386*7c568831SAndroid Build Coastguard Worker
2387*7c568831SAndroid Build Coastguard Worker /**
2388*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGSchemaTypeHave:
2389*7c568831SAndroid Build Coastguard Worker * @data: data needed for the library
2390*7c568831SAndroid Build Coastguard Worker * @type: the type name
2391*7c568831SAndroid Build Coastguard Worker *
2392*7c568831SAndroid Build Coastguard Worker * Check if the given type is provided by
2393*7c568831SAndroid Build Coastguard Worker * the W3C XMLSchema Datatype library.
2394*7c568831SAndroid Build Coastguard Worker *
2395*7c568831SAndroid Build Coastguard Worker * Returns 1 if yes, 0 if no and -1 in case of error.
2396*7c568831SAndroid Build Coastguard Worker */
2397*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGSchemaTypeHave(void * data ATTRIBUTE_UNUSED,const xmlChar * type)2398*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSchemaTypeHave(void *data ATTRIBUTE_UNUSED, const xmlChar * type)
2399*7c568831SAndroid Build Coastguard Worker {
2400*7c568831SAndroid Build Coastguard Worker xmlSchemaTypePtr typ;
2401*7c568831SAndroid Build Coastguard Worker
2402*7c568831SAndroid Build Coastguard Worker if (type == NULL)
2403*7c568831SAndroid Build Coastguard Worker return (-1);
2404*7c568831SAndroid Build Coastguard Worker typ = xmlSchemaGetPredefinedType(type,
2405*7c568831SAndroid Build Coastguard Worker BAD_CAST
2406*7c568831SAndroid Build Coastguard Worker "http://www.w3.org/2001/XMLSchema");
2407*7c568831SAndroid Build Coastguard Worker if (typ == NULL)
2408*7c568831SAndroid Build Coastguard Worker return (0);
2409*7c568831SAndroid Build Coastguard Worker return (1);
2410*7c568831SAndroid Build Coastguard Worker }
2411*7c568831SAndroid Build Coastguard Worker
2412*7c568831SAndroid Build Coastguard Worker /**
2413*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGSchemaTypeCheck:
2414*7c568831SAndroid Build Coastguard Worker * @data: data needed for the library
2415*7c568831SAndroid Build Coastguard Worker * @type: the type name
2416*7c568831SAndroid Build Coastguard Worker * @value: the value to check
2417*7c568831SAndroid Build Coastguard Worker * @node: the node
2418*7c568831SAndroid Build Coastguard Worker *
2419*7c568831SAndroid Build Coastguard Worker * Check if the given type and value are validated by
2420*7c568831SAndroid Build Coastguard Worker * the W3C XMLSchema Datatype library.
2421*7c568831SAndroid Build Coastguard Worker *
2422*7c568831SAndroid Build Coastguard Worker * Returns 1 if yes, 0 if no and -1 in case of error.
2423*7c568831SAndroid Build Coastguard Worker */
2424*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGSchemaTypeCheck(void * data ATTRIBUTE_UNUSED,const xmlChar * type,const xmlChar * value,void ** result,xmlNodePtr node)2425*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSchemaTypeCheck(void *data ATTRIBUTE_UNUSED,
2426*7c568831SAndroid Build Coastguard Worker const xmlChar * type,
2427*7c568831SAndroid Build Coastguard Worker const xmlChar * value,
2428*7c568831SAndroid Build Coastguard Worker void **result, xmlNodePtr node)
2429*7c568831SAndroid Build Coastguard Worker {
2430*7c568831SAndroid Build Coastguard Worker xmlSchemaTypePtr typ;
2431*7c568831SAndroid Build Coastguard Worker int ret;
2432*7c568831SAndroid Build Coastguard Worker
2433*7c568831SAndroid Build Coastguard Worker if ((type == NULL) || (value == NULL))
2434*7c568831SAndroid Build Coastguard Worker return (-1);
2435*7c568831SAndroid Build Coastguard Worker typ = xmlSchemaGetPredefinedType(type,
2436*7c568831SAndroid Build Coastguard Worker BAD_CAST
2437*7c568831SAndroid Build Coastguard Worker "http://www.w3.org/2001/XMLSchema");
2438*7c568831SAndroid Build Coastguard Worker if (typ == NULL)
2439*7c568831SAndroid Build Coastguard Worker return (-1);
2440*7c568831SAndroid Build Coastguard Worker ret = xmlSchemaValPredefTypeNode(typ, value,
2441*7c568831SAndroid Build Coastguard Worker (xmlSchemaValPtr *) result, node);
2442*7c568831SAndroid Build Coastguard Worker if (ret == 2) /* special ID error code */
2443*7c568831SAndroid Build Coastguard Worker return (2);
2444*7c568831SAndroid Build Coastguard Worker if (ret == 0)
2445*7c568831SAndroid Build Coastguard Worker return (1);
2446*7c568831SAndroid Build Coastguard Worker if (ret > 0)
2447*7c568831SAndroid Build Coastguard Worker return (0);
2448*7c568831SAndroid Build Coastguard Worker return (-1);
2449*7c568831SAndroid Build Coastguard Worker }
2450*7c568831SAndroid Build Coastguard Worker
2451*7c568831SAndroid Build Coastguard Worker /**
2452*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGSchemaFacetCheck:
2453*7c568831SAndroid Build Coastguard Worker * @data: data needed for the library
2454*7c568831SAndroid Build Coastguard Worker * @type: the type name
2455*7c568831SAndroid Build Coastguard Worker * @facet: the facet name
2456*7c568831SAndroid Build Coastguard Worker * @val: the facet value
2457*7c568831SAndroid Build Coastguard Worker * @strval: the string value
2458*7c568831SAndroid Build Coastguard Worker * @value: the value to check
2459*7c568831SAndroid Build Coastguard Worker *
2460*7c568831SAndroid Build Coastguard Worker * Function provided by a type library to check a value facet
2461*7c568831SAndroid Build Coastguard Worker *
2462*7c568831SAndroid Build Coastguard Worker * Returns 1 if yes, 0 if no and -1 in case of error.
2463*7c568831SAndroid Build Coastguard Worker */
2464*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGSchemaFacetCheck(void * data ATTRIBUTE_UNUSED,const xmlChar * type,const xmlChar * facetname,const xmlChar * val,const xmlChar * strval,void * value)2465*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSchemaFacetCheck(void *data ATTRIBUTE_UNUSED,
2466*7c568831SAndroid Build Coastguard Worker const xmlChar * type, const xmlChar * facetname,
2467*7c568831SAndroid Build Coastguard Worker const xmlChar * val, const xmlChar * strval,
2468*7c568831SAndroid Build Coastguard Worker void *value)
2469*7c568831SAndroid Build Coastguard Worker {
2470*7c568831SAndroid Build Coastguard Worker xmlSchemaFacetPtr facet;
2471*7c568831SAndroid Build Coastguard Worker xmlSchemaTypePtr typ;
2472*7c568831SAndroid Build Coastguard Worker int ret;
2473*7c568831SAndroid Build Coastguard Worker
2474*7c568831SAndroid Build Coastguard Worker if ((type == NULL) || (strval == NULL))
2475*7c568831SAndroid Build Coastguard Worker return (-1);
2476*7c568831SAndroid Build Coastguard Worker typ = xmlSchemaGetPredefinedType(type,
2477*7c568831SAndroid Build Coastguard Worker BAD_CAST
2478*7c568831SAndroid Build Coastguard Worker "http://www.w3.org/2001/XMLSchema");
2479*7c568831SAndroid Build Coastguard Worker if (typ == NULL)
2480*7c568831SAndroid Build Coastguard Worker return (-1);
2481*7c568831SAndroid Build Coastguard Worker
2482*7c568831SAndroid Build Coastguard Worker facet = xmlSchemaNewFacet();
2483*7c568831SAndroid Build Coastguard Worker if (facet == NULL)
2484*7c568831SAndroid Build Coastguard Worker return (-1);
2485*7c568831SAndroid Build Coastguard Worker
2486*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual(facetname, BAD_CAST "minInclusive")) {
2487*7c568831SAndroid Build Coastguard Worker facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
2488*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(facetname, BAD_CAST "minExclusive")) {
2489*7c568831SAndroid Build Coastguard Worker facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
2490*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(facetname, BAD_CAST "maxInclusive")) {
2491*7c568831SAndroid Build Coastguard Worker facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
2492*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(facetname, BAD_CAST "maxExclusive")) {
2493*7c568831SAndroid Build Coastguard Worker facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
2494*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(facetname, BAD_CAST "totalDigits")) {
2495*7c568831SAndroid Build Coastguard Worker facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
2496*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(facetname, BAD_CAST "fractionDigits")) {
2497*7c568831SAndroid Build Coastguard Worker facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
2498*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(facetname, BAD_CAST "pattern")) {
2499*7c568831SAndroid Build Coastguard Worker facet->type = XML_SCHEMA_FACET_PATTERN;
2500*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(facetname, BAD_CAST "enumeration")) {
2501*7c568831SAndroid Build Coastguard Worker facet->type = XML_SCHEMA_FACET_ENUMERATION;
2502*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(facetname, BAD_CAST "whiteSpace")) {
2503*7c568831SAndroid Build Coastguard Worker facet->type = XML_SCHEMA_FACET_WHITESPACE;
2504*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(facetname, BAD_CAST "length")) {
2505*7c568831SAndroid Build Coastguard Worker facet->type = XML_SCHEMA_FACET_LENGTH;
2506*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(facetname, BAD_CAST "maxLength")) {
2507*7c568831SAndroid Build Coastguard Worker facet->type = XML_SCHEMA_FACET_MAXLENGTH;
2508*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(facetname, BAD_CAST "minLength")) {
2509*7c568831SAndroid Build Coastguard Worker facet->type = XML_SCHEMA_FACET_MINLENGTH;
2510*7c568831SAndroid Build Coastguard Worker } else {
2511*7c568831SAndroid Build Coastguard Worker xmlSchemaFreeFacet(facet);
2512*7c568831SAndroid Build Coastguard Worker return (-1);
2513*7c568831SAndroid Build Coastguard Worker }
2514*7c568831SAndroid Build Coastguard Worker facet->value = val;
2515*7c568831SAndroid Build Coastguard Worker ret = xmlSchemaCheckFacet(facet, typ, NULL, type);
2516*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
2517*7c568831SAndroid Build Coastguard Worker xmlSchemaFreeFacet(facet);
2518*7c568831SAndroid Build Coastguard Worker return (-1);
2519*7c568831SAndroid Build Coastguard Worker }
2520*7c568831SAndroid Build Coastguard Worker ret = xmlSchemaValidateFacet(typ, facet, strval, value);
2521*7c568831SAndroid Build Coastguard Worker xmlSchemaFreeFacet(facet);
2522*7c568831SAndroid Build Coastguard Worker if (ret != 0)
2523*7c568831SAndroid Build Coastguard Worker return (-1);
2524*7c568831SAndroid Build Coastguard Worker return (0);
2525*7c568831SAndroid Build Coastguard Worker }
2526*7c568831SAndroid Build Coastguard Worker
2527*7c568831SAndroid Build Coastguard Worker /**
2528*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGSchemaFreeValue:
2529*7c568831SAndroid Build Coastguard Worker * @data: data needed for the library
2530*7c568831SAndroid Build Coastguard Worker * @value: the value to free
2531*7c568831SAndroid Build Coastguard Worker *
2532*7c568831SAndroid Build Coastguard Worker * Function provided by a type library to free a Schemas value
2533*7c568831SAndroid Build Coastguard Worker *
2534*7c568831SAndroid Build Coastguard Worker * Returns 1 if yes, 0 if no and -1 in case of error.
2535*7c568831SAndroid Build Coastguard Worker */
2536*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGSchemaFreeValue(void * data ATTRIBUTE_UNUSED,void * value)2537*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSchemaFreeValue(void *data ATTRIBUTE_UNUSED, void *value)
2538*7c568831SAndroid Build Coastguard Worker {
2539*7c568831SAndroid Build Coastguard Worker xmlSchemaFreeValue(value);
2540*7c568831SAndroid Build Coastguard Worker }
2541*7c568831SAndroid Build Coastguard Worker
2542*7c568831SAndroid Build Coastguard Worker /**
2543*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGSchemaTypeCompare:
2544*7c568831SAndroid Build Coastguard Worker * @data: data needed for the library
2545*7c568831SAndroid Build Coastguard Worker * @type: the type name
2546*7c568831SAndroid Build Coastguard Worker * @value1: the first value
2547*7c568831SAndroid Build Coastguard Worker * @value2: the second value
2548*7c568831SAndroid Build Coastguard Worker *
2549*7c568831SAndroid Build Coastguard Worker * Compare two values for equality accordingly a type from the W3C XMLSchema
2550*7c568831SAndroid Build Coastguard Worker * Datatype library.
2551*7c568831SAndroid Build Coastguard Worker *
2552*7c568831SAndroid Build Coastguard Worker * Returns 1 if equal, 0 if no and -1 in case of error.
2553*7c568831SAndroid Build Coastguard Worker */
2554*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGSchemaTypeCompare(void * data ATTRIBUTE_UNUSED,const xmlChar * type,const xmlChar * value1,xmlNodePtr ctxt1,void * comp1,const xmlChar * value2,xmlNodePtr ctxt2)2555*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSchemaTypeCompare(void *data ATTRIBUTE_UNUSED,
2556*7c568831SAndroid Build Coastguard Worker const xmlChar * type,
2557*7c568831SAndroid Build Coastguard Worker const xmlChar * value1,
2558*7c568831SAndroid Build Coastguard Worker xmlNodePtr ctxt1,
2559*7c568831SAndroid Build Coastguard Worker void *comp1,
2560*7c568831SAndroid Build Coastguard Worker const xmlChar * value2, xmlNodePtr ctxt2)
2561*7c568831SAndroid Build Coastguard Worker {
2562*7c568831SAndroid Build Coastguard Worker int ret;
2563*7c568831SAndroid Build Coastguard Worker xmlSchemaTypePtr typ;
2564*7c568831SAndroid Build Coastguard Worker xmlSchemaValPtr res1 = NULL, res2 = NULL;
2565*7c568831SAndroid Build Coastguard Worker
2566*7c568831SAndroid Build Coastguard Worker if ((type == NULL) || (value1 == NULL) || (value2 == NULL))
2567*7c568831SAndroid Build Coastguard Worker return (-1);
2568*7c568831SAndroid Build Coastguard Worker typ = xmlSchemaGetPredefinedType(type,
2569*7c568831SAndroid Build Coastguard Worker BAD_CAST
2570*7c568831SAndroid Build Coastguard Worker "http://www.w3.org/2001/XMLSchema");
2571*7c568831SAndroid Build Coastguard Worker if (typ == NULL)
2572*7c568831SAndroid Build Coastguard Worker return (-1);
2573*7c568831SAndroid Build Coastguard Worker if (comp1 == NULL) {
2574*7c568831SAndroid Build Coastguard Worker ret = xmlSchemaValPredefTypeNode(typ, value1, &res1, ctxt1);
2575*7c568831SAndroid Build Coastguard Worker if (ret != 0)
2576*7c568831SAndroid Build Coastguard Worker return (-1);
2577*7c568831SAndroid Build Coastguard Worker if (res1 == NULL)
2578*7c568831SAndroid Build Coastguard Worker return (-1);
2579*7c568831SAndroid Build Coastguard Worker } else {
2580*7c568831SAndroid Build Coastguard Worker res1 = (xmlSchemaValPtr) comp1;
2581*7c568831SAndroid Build Coastguard Worker }
2582*7c568831SAndroid Build Coastguard Worker ret = xmlSchemaValPredefTypeNode(typ, value2, &res2, ctxt2);
2583*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
2584*7c568831SAndroid Build Coastguard Worker if (res1 != (xmlSchemaValPtr) comp1)
2585*7c568831SAndroid Build Coastguard Worker xmlSchemaFreeValue(res1);
2586*7c568831SAndroid Build Coastguard Worker return (-1);
2587*7c568831SAndroid Build Coastguard Worker }
2588*7c568831SAndroid Build Coastguard Worker ret = xmlSchemaCompareValues(res1, res2);
2589*7c568831SAndroid Build Coastguard Worker if (res1 != (xmlSchemaValPtr) comp1)
2590*7c568831SAndroid Build Coastguard Worker xmlSchemaFreeValue(res1);
2591*7c568831SAndroid Build Coastguard Worker xmlSchemaFreeValue(res2);
2592*7c568831SAndroid Build Coastguard Worker if (ret == -2)
2593*7c568831SAndroid Build Coastguard Worker return (-1);
2594*7c568831SAndroid Build Coastguard Worker if (ret == 0)
2595*7c568831SAndroid Build Coastguard Worker return (1);
2596*7c568831SAndroid Build Coastguard Worker return (0);
2597*7c568831SAndroid Build Coastguard Worker }
2598*7c568831SAndroid Build Coastguard Worker
2599*7c568831SAndroid Build Coastguard Worker /**
2600*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGDefaultTypeHave:
2601*7c568831SAndroid Build Coastguard Worker * @data: data needed for the library
2602*7c568831SAndroid Build Coastguard Worker * @type: the type name
2603*7c568831SAndroid Build Coastguard Worker *
2604*7c568831SAndroid Build Coastguard Worker * Check if the given type is provided by
2605*7c568831SAndroid Build Coastguard Worker * the default datatype library.
2606*7c568831SAndroid Build Coastguard Worker *
2607*7c568831SAndroid Build Coastguard Worker * Returns 1 if yes, 0 if no and -1 in case of error.
2608*7c568831SAndroid Build Coastguard Worker */
2609*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGDefaultTypeHave(void * data ATTRIBUTE_UNUSED,const xmlChar * type)2610*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefaultTypeHave(void *data ATTRIBUTE_UNUSED,
2611*7c568831SAndroid Build Coastguard Worker const xmlChar * type)
2612*7c568831SAndroid Build Coastguard Worker {
2613*7c568831SAndroid Build Coastguard Worker if (type == NULL)
2614*7c568831SAndroid Build Coastguard Worker return (-1);
2615*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual(type, BAD_CAST "string"))
2616*7c568831SAndroid Build Coastguard Worker return (1);
2617*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual(type, BAD_CAST "token"))
2618*7c568831SAndroid Build Coastguard Worker return (1);
2619*7c568831SAndroid Build Coastguard Worker return (0);
2620*7c568831SAndroid Build Coastguard Worker }
2621*7c568831SAndroid Build Coastguard Worker
2622*7c568831SAndroid Build Coastguard Worker /**
2623*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGDefaultTypeCheck:
2624*7c568831SAndroid Build Coastguard Worker * @data: data needed for the library
2625*7c568831SAndroid Build Coastguard Worker * @type: the type name
2626*7c568831SAndroid Build Coastguard Worker * @value: the value to check
2627*7c568831SAndroid Build Coastguard Worker * @node: the node
2628*7c568831SAndroid Build Coastguard Worker *
2629*7c568831SAndroid Build Coastguard Worker * Check if the given type and value are validated by
2630*7c568831SAndroid Build Coastguard Worker * the default datatype library.
2631*7c568831SAndroid Build Coastguard Worker *
2632*7c568831SAndroid Build Coastguard Worker * Returns 1 if yes, 0 if no and -1 in case of error.
2633*7c568831SAndroid Build Coastguard Worker */
2634*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGDefaultTypeCheck(void * data ATTRIBUTE_UNUSED,const xmlChar * type ATTRIBUTE_UNUSED,const xmlChar * value ATTRIBUTE_UNUSED,void ** result ATTRIBUTE_UNUSED,xmlNodePtr node ATTRIBUTE_UNUSED)2635*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefaultTypeCheck(void *data ATTRIBUTE_UNUSED,
2636*7c568831SAndroid Build Coastguard Worker const xmlChar * type ATTRIBUTE_UNUSED,
2637*7c568831SAndroid Build Coastguard Worker const xmlChar * value ATTRIBUTE_UNUSED,
2638*7c568831SAndroid Build Coastguard Worker void **result ATTRIBUTE_UNUSED,
2639*7c568831SAndroid Build Coastguard Worker xmlNodePtr node ATTRIBUTE_UNUSED)
2640*7c568831SAndroid Build Coastguard Worker {
2641*7c568831SAndroid Build Coastguard Worker if (value == NULL)
2642*7c568831SAndroid Build Coastguard Worker return (-1);
2643*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual(type, BAD_CAST "string"))
2644*7c568831SAndroid Build Coastguard Worker return (1);
2645*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual(type, BAD_CAST "token")) {
2646*7c568831SAndroid Build Coastguard Worker return (1);
2647*7c568831SAndroid Build Coastguard Worker }
2648*7c568831SAndroid Build Coastguard Worker
2649*7c568831SAndroid Build Coastguard Worker return (0);
2650*7c568831SAndroid Build Coastguard Worker }
2651*7c568831SAndroid Build Coastguard Worker
2652*7c568831SAndroid Build Coastguard Worker /**
2653*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGDefaultTypeCompare:
2654*7c568831SAndroid Build Coastguard Worker * @data: data needed for the library
2655*7c568831SAndroid Build Coastguard Worker * @type: the type name
2656*7c568831SAndroid Build Coastguard Worker * @value1: the first value
2657*7c568831SAndroid Build Coastguard Worker * @value2: the second value
2658*7c568831SAndroid Build Coastguard Worker *
2659*7c568831SAndroid Build Coastguard Worker * Compare two values accordingly a type from the default
2660*7c568831SAndroid Build Coastguard Worker * datatype library.
2661*7c568831SAndroid Build Coastguard Worker *
2662*7c568831SAndroid Build Coastguard Worker * Returns 1 if yes, 0 if no and -1 in case of error.
2663*7c568831SAndroid Build Coastguard Worker */
2664*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGDefaultTypeCompare(void * data ATTRIBUTE_UNUSED,const xmlChar * type,const xmlChar * value1,xmlNodePtr ctxt1 ATTRIBUTE_UNUSED,void * comp1 ATTRIBUTE_UNUSED,const xmlChar * value2,xmlNodePtr ctxt2 ATTRIBUTE_UNUSED)2665*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefaultTypeCompare(void *data ATTRIBUTE_UNUSED,
2666*7c568831SAndroid Build Coastguard Worker const xmlChar * type,
2667*7c568831SAndroid Build Coastguard Worker const xmlChar * value1,
2668*7c568831SAndroid Build Coastguard Worker xmlNodePtr ctxt1 ATTRIBUTE_UNUSED,
2669*7c568831SAndroid Build Coastguard Worker void *comp1 ATTRIBUTE_UNUSED,
2670*7c568831SAndroid Build Coastguard Worker const xmlChar * value2,
2671*7c568831SAndroid Build Coastguard Worker xmlNodePtr ctxt2 ATTRIBUTE_UNUSED)
2672*7c568831SAndroid Build Coastguard Worker {
2673*7c568831SAndroid Build Coastguard Worker int ret = -1;
2674*7c568831SAndroid Build Coastguard Worker
2675*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual(type, BAD_CAST "string")) {
2676*7c568831SAndroid Build Coastguard Worker ret = xmlStrEqual(value1, value2);
2677*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(type, BAD_CAST "token")) {
2678*7c568831SAndroid Build Coastguard Worker if (!xmlStrEqual(value1, value2)) {
2679*7c568831SAndroid Build Coastguard Worker xmlChar *nval, *nvalue;
2680*7c568831SAndroid Build Coastguard Worker
2681*7c568831SAndroid Build Coastguard Worker /*
2682*7c568831SAndroid Build Coastguard Worker * TODO: trivial optimizations are possible by
2683*7c568831SAndroid Build Coastguard Worker * computing at compile-time
2684*7c568831SAndroid Build Coastguard Worker */
2685*7c568831SAndroid Build Coastguard Worker nval = xmlRelaxNGNormalize(NULL, value1);
2686*7c568831SAndroid Build Coastguard Worker nvalue = xmlRelaxNGNormalize(NULL, value2);
2687*7c568831SAndroid Build Coastguard Worker
2688*7c568831SAndroid Build Coastguard Worker if ((nval == NULL) || (nvalue == NULL))
2689*7c568831SAndroid Build Coastguard Worker ret = -1;
2690*7c568831SAndroid Build Coastguard Worker else if (xmlStrEqual(nval, nvalue))
2691*7c568831SAndroid Build Coastguard Worker ret = 1;
2692*7c568831SAndroid Build Coastguard Worker else
2693*7c568831SAndroid Build Coastguard Worker ret = 0;
2694*7c568831SAndroid Build Coastguard Worker if (nval != NULL)
2695*7c568831SAndroid Build Coastguard Worker xmlFree(nval);
2696*7c568831SAndroid Build Coastguard Worker if (nvalue != NULL)
2697*7c568831SAndroid Build Coastguard Worker xmlFree(nvalue);
2698*7c568831SAndroid Build Coastguard Worker } else
2699*7c568831SAndroid Build Coastguard Worker ret = 1;
2700*7c568831SAndroid Build Coastguard Worker }
2701*7c568831SAndroid Build Coastguard Worker return (ret);
2702*7c568831SAndroid Build Coastguard Worker }
2703*7c568831SAndroid Build Coastguard Worker
2704*7c568831SAndroid Build Coastguard Worker static int xmlRelaxNGTypeInitialized = 0;
2705*7c568831SAndroid Build Coastguard Worker static xmlHashTablePtr xmlRelaxNGRegisteredTypes = NULL;
2706*7c568831SAndroid Build Coastguard Worker
2707*7c568831SAndroid Build Coastguard Worker /**
2708*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGFreeTypeLibrary:
2709*7c568831SAndroid Build Coastguard Worker * @lib: the type library structure
2710*7c568831SAndroid Build Coastguard Worker * @namespace: the URI bound to the library
2711*7c568831SAndroid Build Coastguard Worker *
2712*7c568831SAndroid Build Coastguard Worker * Free the structure associated to the type library
2713*7c568831SAndroid Build Coastguard Worker */
2714*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGFreeTypeLibrary(void * payload,const xmlChar * namespace ATTRIBUTE_UNUSED)2715*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeTypeLibrary(void *payload,
2716*7c568831SAndroid Build Coastguard Worker const xmlChar * namespace ATTRIBUTE_UNUSED)
2717*7c568831SAndroid Build Coastguard Worker {
2718*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTypeLibraryPtr lib = (xmlRelaxNGTypeLibraryPtr) payload;
2719*7c568831SAndroid Build Coastguard Worker if (lib == NULL)
2720*7c568831SAndroid Build Coastguard Worker return;
2721*7c568831SAndroid Build Coastguard Worker if (lib->namespace != NULL)
2722*7c568831SAndroid Build Coastguard Worker xmlFree((xmlChar *) lib->namespace);
2723*7c568831SAndroid Build Coastguard Worker xmlFree(lib);
2724*7c568831SAndroid Build Coastguard Worker }
2725*7c568831SAndroid Build Coastguard Worker
2726*7c568831SAndroid Build Coastguard Worker /**
2727*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGRegisterTypeLibrary:
2728*7c568831SAndroid Build Coastguard Worker * @namespace: the URI bound to the library
2729*7c568831SAndroid Build Coastguard Worker * @data: data associated to the library
2730*7c568831SAndroid Build Coastguard Worker * @have: the provide function
2731*7c568831SAndroid Build Coastguard Worker * @check: the checking function
2732*7c568831SAndroid Build Coastguard Worker * @comp: the comparison function
2733*7c568831SAndroid Build Coastguard Worker *
2734*7c568831SAndroid Build Coastguard Worker * Register a new type library
2735*7c568831SAndroid Build Coastguard Worker *
2736*7c568831SAndroid Build Coastguard Worker * Returns 0 in case of success and -1 in case of error.
2737*7c568831SAndroid Build Coastguard Worker */
2738*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGRegisterTypeLibrary(const xmlChar * namespace,void * data,xmlRelaxNGTypeHave have,xmlRelaxNGTypeCheck check,xmlRelaxNGTypeCompare comp,xmlRelaxNGFacetCheck facet,xmlRelaxNGTypeFree freef)2739*7c568831SAndroid Build Coastguard Worker xmlRelaxNGRegisterTypeLibrary(const xmlChar * namespace, void *data,
2740*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTypeHave have,
2741*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTypeCheck check,
2742*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTypeCompare comp,
2743*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFacetCheck facet,
2744*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTypeFree freef)
2745*7c568831SAndroid Build Coastguard Worker {
2746*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTypeLibraryPtr lib;
2747*7c568831SAndroid Build Coastguard Worker int ret;
2748*7c568831SAndroid Build Coastguard Worker
2749*7c568831SAndroid Build Coastguard Worker if ((xmlRelaxNGRegisteredTypes == NULL) || (namespace == NULL) ||
2750*7c568831SAndroid Build Coastguard Worker (check == NULL) || (comp == NULL))
2751*7c568831SAndroid Build Coastguard Worker return (-1);
2752*7c568831SAndroid Build Coastguard Worker if (xmlHashLookup(xmlRelaxNGRegisteredTypes, namespace) != NULL)
2753*7c568831SAndroid Build Coastguard Worker return (-1);
2754*7c568831SAndroid Build Coastguard Worker lib =
2755*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGTypeLibraryPtr)
2756*7c568831SAndroid Build Coastguard Worker xmlMalloc(sizeof(xmlRelaxNGTypeLibrary));
2757*7c568831SAndroid Build Coastguard Worker if (lib == NULL) {
2758*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(NULL);
2759*7c568831SAndroid Build Coastguard Worker return (-1);
2760*7c568831SAndroid Build Coastguard Worker }
2761*7c568831SAndroid Build Coastguard Worker memset(lib, 0, sizeof(xmlRelaxNGTypeLibrary));
2762*7c568831SAndroid Build Coastguard Worker lib->namespace = xmlStrdup(namespace);
2763*7c568831SAndroid Build Coastguard Worker lib->data = data;
2764*7c568831SAndroid Build Coastguard Worker lib->have = have;
2765*7c568831SAndroid Build Coastguard Worker lib->comp = comp;
2766*7c568831SAndroid Build Coastguard Worker lib->check = check;
2767*7c568831SAndroid Build Coastguard Worker lib->facet = facet;
2768*7c568831SAndroid Build Coastguard Worker lib->freef = freef;
2769*7c568831SAndroid Build Coastguard Worker ret = xmlHashAddEntry(xmlRelaxNGRegisteredTypes, namespace, lib);
2770*7c568831SAndroid Build Coastguard Worker if (ret < 0) {
2771*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeTypeLibrary(lib, namespace);
2772*7c568831SAndroid Build Coastguard Worker return (-1);
2773*7c568831SAndroid Build Coastguard Worker }
2774*7c568831SAndroid Build Coastguard Worker return (0);
2775*7c568831SAndroid Build Coastguard Worker }
2776*7c568831SAndroid Build Coastguard Worker
2777*7c568831SAndroid Build Coastguard Worker /**
2778*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGInitTypes:
2779*7c568831SAndroid Build Coastguard Worker *
2780*7c568831SAndroid Build Coastguard Worker * Initialize the default type libraries.
2781*7c568831SAndroid Build Coastguard Worker *
2782*7c568831SAndroid Build Coastguard Worker * Returns 0 in case of success and -1 in case of error.
2783*7c568831SAndroid Build Coastguard Worker */
2784*7c568831SAndroid Build Coastguard Worker int
xmlRelaxNGInitTypes(void)2785*7c568831SAndroid Build Coastguard Worker xmlRelaxNGInitTypes(void)
2786*7c568831SAndroid Build Coastguard Worker {
2787*7c568831SAndroid Build Coastguard Worker if (xmlRelaxNGTypeInitialized != 0)
2788*7c568831SAndroid Build Coastguard Worker return (0);
2789*7c568831SAndroid Build Coastguard Worker xmlRelaxNGRegisteredTypes = xmlHashCreate(10);
2790*7c568831SAndroid Build Coastguard Worker if (xmlRelaxNGRegisteredTypes == NULL)
2791*7c568831SAndroid Build Coastguard Worker return (-1);
2792*7c568831SAndroid Build Coastguard Worker xmlRelaxNGRegisterTypeLibrary(BAD_CAST
2793*7c568831SAndroid Build Coastguard Worker "http://www.w3.org/2001/XMLSchema-datatypes",
2794*7c568831SAndroid Build Coastguard Worker NULL, xmlRelaxNGSchemaTypeHave,
2795*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSchemaTypeCheck,
2796*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSchemaTypeCompare,
2797*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSchemaFacetCheck,
2798*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSchemaFreeValue);
2799*7c568831SAndroid Build Coastguard Worker xmlRelaxNGRegisterTypeLibrary(xmlRelaxNGNs, NULL,
2800*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefaultTypeHave,
2801*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefaultTypeCheck,
2802*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefaultTypeCompare, NULL,
2803*7c568831SAndroid Build Coastguard Worker NULL);
2804*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTypeInitialized = 1;
2805*7c568831SAndroid Build Coastguard Worker return (0);
2806*7c568831SAndroid Build Coastguard Worker }
2807*7c568831SAndroid Build Coastguard Worker
2808*7c568831SAndroid Build Coastguard Worker /**
2809*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGCleanupTypes:
2810*7c568831SAndroid Build Coastguard Worker *
2811*7c568831SAndroid Build Coastguard Worker * DEPRECATED: This function will be made private. Call xmlCleanupParser
2812*7c568831SAndroid Build Coastguard Worker * to free global state but see the warnings there. xmlCleanupParser
2813*7c568831SAndroid Build Coastguard Worker * should be only called once at program exit. In most cases, you don't
2814*7c568831SAndroid Build Coastguard Worker * have call cleanup functions at all.
2815*7c568831SAndroid Build Coastguard Worker *
2816*7c568831SAndroid Build Coastguard Worker * Cleanup the default Schemas type library associated to RelaxNG
2817*7c568831SAndroid Build Coastguard Worker */
2818*7c568831SAndroid Build Coastguard Worker void
xmlRelaxNGCleanupTypes(void)2819*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCleanupTypes(void)
2820*7c568831SAndroid Build Coastguard Worker {
2821*7c568831SAndroid Build Coastguard Worker xmlSchemaCleanupTypes();
2822*7c568831SAndroid Build Coastguard Worker if (xmlRelaxNGTypeInitialized == 0)
2823*7c568831SAndroid Build Coastguard Worker return;
2824*7c568831SAndroid Build Coastguard Worker xmlHashFree(xmlRelaxNGRegisteredTypes, xmlRelaxNGFreeTypeLibrary);
2825*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTypeInitialized = 0;
2826*7c568831SAndroid Build Coastguard Worker }
2827*7c568831SAndroid Build Coastguard Worker
2828*7c568831SAndroid Build Coastguard Worker /************************************************************************
2829*7c568831SAndroid Build Coastguard Worker * *
2830*7c568831SAndroid Build Coastguard Worker * Compiling element content into regexp *
2831*7c568831SAndroid Build Coastguard Worker * *
2832*7c568831SAndroid Build Coastguard Worker * Sometime the element content can be compiled into a pure regexp, *
2833*7c568831SAndroid Build Coastguard Worker * This allows a faster execution and streamability at that level *
2834*7c568831SAndroid Build Coastguard Worker * *
2835*7c568831SAndroid Build Coastguard Worker ************************************************************************/
2836*7c568831SAndroid Build Coastguard Worker
2837*7c568831SAndroid Build Coastguard Worker static int xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt,
2838*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def);
2839*7c568831SAndroid Build Coastguard Worker
2840*7c568831SAndroid Build Coastguard Worker /**
2841*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGIsCompilable:
2842*7c568831SAndroid Build Coastguard Worker * @define: the definition to check
2843*7c568831SAndroid Build Coastguard Worker *
2844*7c568831SAndroid Build Coastguard Worker * Check if a definition is nullable.
2845*7c568831SAndroid Build Coastguard Worker *
2846*7c568831SAndroid Build Coastguard Worker * Returns 1 if yes, 0 if no and -1 in case of error
2847*7c568831SAndroid Build Coastguard Worker */
2848*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGIsCompilable(xmlRelaxNGDefinePtr def)2849*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIsCompilable(xmlRelaxNGDefinePtr def)
2850*7c568831SAndroid Build Coastguard Worker {
2851*7c568831SAndroid Build Coastguard Worker int ret = -1;
2852*7c568831SAndroid Build Coastguard Worker
2853*7c568831SAndroid Build Coastguard Worker if (def == NULL) {
2854*7c568831SAndroid Build Coastguard Worker return (-1);
2855*7c568831SAndroid Build Coastguard Worker }
2856*7c568831SAndroid Build Coastguard Worker if ((def->type != XML_RELAXNG_ELEMENT) &&
2857*7c568831SAndroid Build Coastguard Worker (def->dflags & IS_COMPILABLE))
2858*7c568831SAndroid Build Coastguard Worker return (1);
2859*7c568831SAndroid Build Coastguard Worker if ((def->type != XML_RELAXNG_ELEMENT) &&
2860*7c568831SAndroid Build Coastguard Worker (def->dflags & IS_NOT_COMPILABLE))
2861*7c568831SAndroid Build Coastguard Worker return (0);
2862*7c568831SAndroid Build Coastguard Worker switch (def->type) {
2863*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOOP:
2864*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGIsCompilable(def->content);
2865*7c568831SAndroid Build Coastguard Worker break;
2866*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_TEXT:
2867*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EMPTY:
2868*7c568831SAndroid Build Coastguard Worker ret = 1;
2869*7c568831SAndroid Build Coastguard Worker break;
2870*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ELEMENT:
2871*7c568831SAndroid Build Coastguard Worker /*
2872*7c568831SAndroid Build Coastguard Worker * Check if the element content is compilable
2873*7c568831SAndroid Build Coastguard Worker */
2874*7c568831SAndroid Build Coastguard Worker if (((def->dflags & IS_NOT_COMPILABLE) == 0) &&
2875*7c568831SAndroid Build Coastguard Worker ((def->dflags & IS_COMPILABLE) == 0)) {
2876*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr list;
2877*7c568831SAndroid Build Coastguard Worker
2878*7c568831SAndroid Build Coastguard Worker list = def->content;
2879*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
2880*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGIsCompilable(list);
2881*7c568831SAndroid Build Coastguard Worker if (ret != 1)
2882*7c568831SAndroid Build Coastguard Worker break;
2883*7c568831SAndroid Build Coastguard Worker list = list->next;
2884*7c568831SAndroid Build Coastguard Worker }
2885*7c568831SAndroid Build Coastguard Worker /*
2886*7c568831SAndroid Build Coastguard Worker * Because the routine is recursive, we must guard against
2887*7c568831SAndroid Build Coastguard Worker * discovering both COMPILABLE and NOT_COMPILABLE
2888*7c568831SAndroid Build Coastguard Worker */
2889*7c568831SAndroid Build Coastguard Worker if (ret == 0) {
2890*7c568831SAndroid Build Coastguard Worker def->dflags &= ~IS_COMPILABLE;
2891*7c568831SAndroid Build Coastguard Worker def->dflags |= IS_NOT_COMPILABLE;
2892*7c568831SAndroid Build Coastguard Worker }
2893*7c568831SAndroid Build Coastguard Worker if ((ret == 1) && !(def->dflags &= IS_NOT_COMPILABLE))
2894*7c568831SAndroid Build Coastguard Worker def->dflags |= IS_COMPILABLE;
2895*7c568831SAndroid Build Coastguard Worker }
2896*7c568831SAndroid Build Coastguard Worker /*
2897*7c568831SAndroid Build Coastguard Worker * All elements return a compilable status unless they
2898*7c568831SAndroid Build Coastguard Worker * are generic like anyName
2899*7c568831SAndroid Build Coastguard Worker */
2900*7c568831SAndroid Build Coastguard Worker if ((def->nameClass != NULL) || (def->name == NULL))
2901*7c568831SAndroid Build Coastguard Worker ret = 0;
2902*7c568831SAndroid Build Coastguard Worker else
2903*7c568831SAndroid Build Coastguard Worker ret = 1;
2904*7c568831SAndroid Build Coastguard Worker return (ret);
2905*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_REF:
2906*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXTERNALREF:
2907*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARENTREF:
2908*7c568831SAndroid Build Coastguard Worker if (def->depth == -20) {
2909*7c568831SAndroid Build Coastguard Worker return (1);
2910*7c568831SAndroid Build Coastguard Worker } else {
2911*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr list;
2912*7c568831SAndroid Build Coastguard Worker
2913*7c568831SAndroid Build Coastguard Worker def->depth = -20;
2914*7c568831SAndroid Build Coastguard Worker list = def->content;
2915*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
2916*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGIsCompilable(list);
2917*7c568831SAndroid Build Coastguard Worker if (ret != 1)
2918*7c568831SAndroid Build Coastguard Worker break;
2919*7c568831SAndroid Build Coastguard Worker list = list->next;
2920*7c568831SAndroid Build Coastguard Worker }
2921*7c568831SAndroid Build Coastguard Worker }
2922*7c568831SAndroid Build Coastguard Worker break;
2923*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_START:
2924*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_OPTIONAL:
2925*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ZEROORMORE:
2926*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ONEORMORE:
2927*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_CHOICE:
2928*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_GROUP:
2929*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DEF:{
2930*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr list;
2931*7c568831SAndroid Build Coastguard Worker
2932*7c568831SAndroid Build Coastguard Worker list = def->content;
2933*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
2934*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGIsCompilable(list);
2935*7c568831SAndroid Build Coastguard Worker if (ret != 1)
2936*7c568831SAndroid Build Coastguard Worker break;
2937*7c568831SAndroid Build Coastguard Worker list = list->next;
2938*7c568831SAndroid Build Coastguard Worker }
2939*7c568831SAndroid Build Coastguard Worker break;
2940*7c568831SAndroid Build Coastguard Worker }
2941*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXCEPT:
2942*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ATTRIBUTE:
2943*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_INTERLEAVE:
2944*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DATATYPE:
2945*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_LIST:
2946*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARAM:
2947*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_VALUE:
2948*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOT_ALLOWED:
2949*7c568831SAndroid Build Coastguard Worker ret = 0;
2950*7c568831SAndroid Build Coastguard Worker break;
2951*7c568831SAndroid Build Coastguard Worker }
2952*7c568831SAndroid Build Coastguard Worker if (ret == 0)
2953*7c568831SAndroid Build Coastguard Worker def->dflags |= IS_NOT_COMPILABLE;
2954*7c568831SAndroid Build Coastguard Worker if (ret == 1)
2955*7c568831SAndroid Build Coastguard Worker def->dflags |= IS_COMPILABLE;
2956*7c568831SAndroid Build Coastguard Worker return (ret);
2957*7c568831SAndroid Build Coastguard Worker }
2958*7c568831SAndroid Build Coastguard Worker
2959*7c568831SAndroid Build Coastguard Worker /**
2960*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGCompile:
2961*7c568831SAndroid Build Coastguard Worker * ctxt: the RelaxNG parser context
2962*7c568831SAndroid Build Coastguard Worker * @define: the definition tree to compile
2963*7c568831SAndroid Build Coastguard Worker *
2964*7c568831SAndroid Build Coastguard Worker * Compile the set of definitions, it works recursively, till the
2965*7c568831SAndroid Build Coastguard Worker * element boundaries, where it tries to compile the content if possible
2966*7c568831SAndroid Build Coastguard Worker *
2967*7c568831SAndroid Build Coastguard Worker * Returns 0 if success and -1 in case of error
2968*7c568831SAndroid Build Coastguard Worker */
2969*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGCompile(xmlRelaxNGParserCtxtPtr ctxt,xmlRelaxNGDefinePtr def)2970*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
2971*7c568831SAndroid Build Coastguard Worker {
2972*7c568831SAndroid Build Coastguard Worker int ret = 0;
2973*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr list;
2974*7c568831SAndroid Build Coastguard Worker
2975*7c568831SAndroid Build Coastguard Worker if ((ctxt == NULL) || (def == NULL))
2976*7c568831SAndroid Build Coastguard Worker return (-1);
2977*7c568831SAndroid Build Coastguard Worker
2978*7c568831SAndroid Build Coastguard Worker switch (def->type) {
2979*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_START:
2980*7c568831SAndroid Build Coastguard Worker if ((xmlRelaxNGIsCompilable(def) == 1) && (def->depth != -25)) {
2981*7c568831SAndroid Build Coastguard Worker xmlAutomataPtr oldam = ctxt->am;
2982*7c568831SAndroid Build Coastguard Worker xmlAutomataStatePtr oldstate = ctxt->state;
2983*7c568831SAndroid Build Coastguard Worker
2984*7c568831SAndroid Build Coastguard Worker def->depth = -25;
2985*7c568831SAndroid Build Coastguard Worker
2986*7c568831SAndroid Build Coastguard Worker list = def->content;
2987*7c568831SAndroid Build Coastguard Worker ctxt->am = xmlNewAutomata();
2988*7c568831SAndroid Build Coastguard Worker if (ctxt->am == NULL)
2989*7c568831SAndroid Build Coastguard Worker return (-1);
2990*7c568831SAndroid Build Coastguard Worker
2991*7c568831SAndroid Build Coastguard Worker /*
2992*7c568831SAndroid Build Coastguard Worker * assume identical strings but not same pointer are different
2993*7c568831SAndroid Build Coastguard Worker * atoms, needed for non-determinism detection
2994*7c568831SAndroid Build Coastguard Worker * That way if 2 elements with the same name are in a choice
2995*7c568831SAndroid Build Coastguard Worker * branch the automata is found non-deterministic and
2996*7c568831SAndroid Build Coastguard Worker * we fallback to the normal validation which does the right
2997*7c568831SAndroid Build Coastguard Worker * thing of exploring both choices.
2998*7c568831SAndroid Build Coastguard Worker */
2999*7c568831SAndroid Build Coastguard Worker xmlAutomataSetFlags(ctxt->am, 1);
3000*7c568831SAndroid Build Coastguard Worker
3001*7c568831SAndroid Build Coastguard Worker ctxt->state = xmlAutomataGetInitState(ctxt->am);
3002*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
3003*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCompile(ctxt, list);
3004*7c568831SAndroid Build Coastguard Worker list = list->next;
3005*7c568831SAndroid Build Coastguard Worker }
3006*7c568831SAndroid Build Coastguard Worker xmlAutomataSetFinalState(ctxt->am, ctxt->state);
3007*7c568831SAndroid Build Coastguard Worker if (xmlAutomataIsDeterminist(ctxt->am))
3008*7c568831SAndroid Build Coastguard Worker def->contModel = xmlAutomataCompile(ctxt->am);
3009*7c568831SAndroid Build Coastguard Worker
3010*7c568831SAndroid Build Coastguard Worker xmlFreeAutomata(ctxt->am);
3011*7c568831SAndroid Build Coastguard Worker ctxt->state = oldstate;
3012*7c568831SAndroid Build Coastguard Worker ctxt->am = oldam;
3013*7c568831SAndroid Build Coastguard Worker }
3014*7c568831SAndroid Build Coastguard Worker break;
3015*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ELEMENT:
3016*7c568831SAndroid Build Coastguard Worker if ((ctxt->am != NULL) && (def->name != NULL)) {
3017*7c568831SAndroid Build Coastguard Worker ctxt->state = xmlAutomataNewTransition2(ctxt->am,
3018*7c568831SAndroid Build Coastguard Worker ctxt->state, NULL,
3019*7c568831SAndroid Build Coastguard Worker def->name, def->ns,
3020*7c568831SAndroid Build Coastguard Worker def);
3021*7c568831SAndroid Build Coastguard Worker }
3022*7c568831SAndroid Build Coastguard Worker if ((def->dflags & IS_COMPILABLE) && (def->depth != -25)) {
3023*7c568831SAndroid Build Coastguard Worker xmlAutomataPtr oldam = ctxt->am;
3024*7c568831SAndroid Build Coastguard Worker xmlAutomataStatePtr oldstate = ctxt->state;
3025*7c568831SAndroid Build Coastguard Worker
3026*7c568831SAndroid Build Coastguard Worker def->depth = -25;
3027*7c568831SAndroid Build Coastguard Worker
3028*7c568831SAndroid Build Coastguard Worker list = def->content;
3029*7c568831SAndroid Build Coastguard Worker ctxt->am = xmlNewAutomata();
3030*7c568831SAndroid Build Coastguard Worker if (ctxt->am == NULL)
3031*7c568831SAndroid Build Coastguard Worker return (-1);
3032*7c568831SAndroid Build Coastguard Worker xmlAutomataSetFlags(ctxt->am, 1);
3033*7c568831SAndroid Build Coastguard Worker ctxt->state = xmlAutomataGetInitState(ctxt->am);
3034*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
3035*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCompile(ctxt, list);
3036*7c568831SAndroid Build Coastguard Worker list = list->next;
3037*7c568831SAndroid Build Coastguard Worker }
3038*7c568831SAndroid Build Coastguard Worker xmlAutomataSetFinalState(ctxt->am, ctxt->state);
3039*7c568831SAndroid Build Coastguard Worker def->contModel = xmlAutomataCompile(ctxt->am);
3040*7c568831SAndroid Build Coastguard Worker if (!xmlRegexpIsDeterminist(def->contModel)) {
3041*7c568831SAndroid Build Coastguard Worker /*
3042*7c568831SAndroid Build Coastguard Worker * we can only use the automata if it is determinist
3043*7c568831SAndroid Build Coastguard Worker */
3044*7c568831SAndroid Build Coastguard Worker xmlRegFreeRegexp(def->contModel);
3045*7c568831SAndroid Build Coastguard Worker def->contModel = NULL;
3046*7c568831SAndroid Build Coastguard Worker }
3047*7c568831SAndroid Build Coastguard Worker xmlFreeAutomata(ctxt->am);
3048*7c568831SAndroid Build Coastguard Worker ctxt->state = oldstate;
3049*7c568831SAndroid Build Coastguard Worker ctxt->am = oldam;
3050*7c568831SAndroid Build Coastguard Worker } else {
3051*7c568831SAndroid Build Coastguard Worker xmlAutomataPtr oldam = ctxt->am;
3052*7c568831SAndroid Build Coastguard Worker
3053*7c568831SAndroid Build Coastguard Worker /*
3054*7c568831SAndroid Build Coastguard Worker * we can't build the content model for this element content
3055*7c568831SAndroid Build Coastguard Worker * but it still might be possible to build it for some of its
3056*7c568831SAndroid Build Coastguard Worker * children, recurse.
3057*7c568831SAndroid Build Coastguard Worker */
3058*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGTryCompile(ctxt, def);
3059*7c568831SAndroid Build Coastguard Worker ctxt->am = oldam;
3060*7c568831SAndroid Build Coastguard Worker }
3061*7c568831SAndroid Build Coastguard Worker break;
3062*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOOP:
3063*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGCompile(ctxt, def->content);
3064*7c568831SAndroid Build Coastguard Worker break;
3065*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_OPTIONAL:{
3066*7c568831SAndroid Build Coastguard Worker xmlAutomataStatePtr oldstate = ctxt->state;
3067*7c568831SAndroid Build Coastguard Worker
3068*7c568831SAndroid Build Coastguard Worker list = def->content;
3069*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
3070*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCompile(ctxt, list);
3071*7c568831SAndroid Build Coastguard Worker list = list->next;
3072*7c568831SAndroid Build Coastguard Worker }
3073*7c568831SAndroid Build Coastguard Worker xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
3074*7c568831SAndroid Build Coastguard Worker break;
3075*7c568831SAndroid Build Coastguard Worker }
3076*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ZEROORMORE:{
3077*7c568831SAndroid Build Coastguard Worker xmlAutomataStatePtr oldstate;
3078*7c568831SAndroid Build Coastguard Worker
3079*7c568831SAndroid Build Coastguard Worker ctxt->state =
3080*7c568831SAndroid Build Coastguard Worker xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
3081*7c568831SAndroid Build Coastguard Worker oldstate = ctxt->state;
3082*7c568831SAndroid Build Coastguard Worker list = def->content;
3083*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
3084*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCompile(ctxt, list);
3085*7c568831SAndroid Build Coastguard Worker list = list->next;
3086*7c568831SAndroid Build Coastguard Worker }
3087*7c568831SAndroid Build Coastguard Worker xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldstate);
3088*7c568831SAndroid Build Coastguard Worker ctxt->state =
3089*7c568831SAndroid Build Coastguard Worker xmlAutomataNewEpsilon(ctxt->am, oldstate, NULL);
3090*7c568831SAndroid Build Coastguard Worker break;
3091*7c568831SAndroid Build Coastguard Worker }
3092*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ONEORMORE:{
3093*7c568831SAndroid Build Coastguard Worker xmlAutomataStatePtr oldstate;
3094*7c568831SAndroid Build Coastguard Worker
3095*7c568831SAndroid Build Coastguard Worker list = def->content;
3096*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
3097*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCompile(ctxt, list);
3098*7c568831SAndroid Build Coastguard Worker list = list->next;
3099*7c568831SAndroid Build Coastguard Worker }
3100*7c568831SAndroid Build Coastguard Worker oldstate = ctxt->state;
3101*7c568831SAndroid Build Coastguard Worker list = def->content;
3102*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
3103*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCompile(ctxt, list);
3104*7c568831SAndroid Build Coastguard Worker list = list->next;
3105*7c568831SAndroid Build Coastguard Worker }
3106*7c568831SAndroid Build Coastguard Worker xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldstate);
3107*7c568831SAndroid Build Coastguard Worker ctxt->state =
3108*7c568831SAndroid Build Coastguard Worker xmlAutomataNewEpsilon(ctxt->am, oldstate, NULL);
3109*7c568831SAndroid Build Coastguard Worker break;
3110*7c568831SAndroid Build Coastguard Worker }
3111*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_CHOICE:{
3112*7c568831SAndroid Build Coastguard Worker xmlAutomataStatePtr target = NULL;
3113*7c568831SAndroid Build Coastguard Worker xmlAutomataStatePtr oldstate = ctxt->state;
3114*7c568831SAndroid Build Coastguard Worker
3115*7c568831SAndroid Build Coastguard Worker list = def->content;
3116*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
3117*7c568831SAndroid Build Coastguard Worker ctxt->state = oldstate;
3118*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGCompile(ctxt, list);
3119*7c568831SAndroid Build Coastguard Worker if (ret != 0)
3120*7c568831SAndroid Build Coastguard Worker break;
3121*7c568831SAndroid Build Coastguard Worker if (target == NULL)
3122*7c568831SAndroid Build Coastguard Worker target = ctxt->state;
3123*7c568831SAndroid Build Coastguard Worker else {
3124*7c568831SAndroid Build Coastguard Worker xmlAutomataNewEpsilon(ctxt->am, ctxt->state,
3125*7c568831SAndroid Build Coastguard Worker target);
3126*7c568831SAndroid Build Coastguard Worker }
3127*7c568831SAndroid Build Coastguard Worker list = list->next;
3128*7c568831SAndroid Build Coastguard Worker }
3129*7c568831SAndroid Build Coastguard Worker ctxt->state = target;
3130*7c568831SAndroid Build Coastguard Worker
3131*7c568831SAndroid Build Coastguard Worker break;
3132*7c568831SAndroid Build Coastguard Worker }
3133*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_REF:
3134*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXTERNALREF:
3135*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARENTREF:
3136*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_GROUP:
3137*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DEF:
3138*7c568831SAndroid Build Coastguard Worker list = def->content;
3139*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
3140*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGCompile(ctxt, list);
3141*7c568831SAndroid Build Coastguard Worker if (ret != 0)
3142*7c568831SAndroid Build Coastguard Worker break;
3143*7c568831SAndroid Build Coastguard Worker list = list->next;
3144*7c568831SAndroid Build Coastguard Worker }
3145*7c568831SAndroid Build Coastguard Worker break;
3146*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_TEXT:{
3147*7c568831SAndroid Build Coastguard Worker xmlAutomataStatePtr oldstate;
3148*7c568831SAndroid Build Coastguard Worker
3149*7c568831SAndroid Build Coastguard Worker ctxt->state =
3150*7c568831SAndroid Build Coastguard Worker xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
3151*7c568831SAndroid Build Coastguard Worker oldstate = ctxt->state;
3152*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCompile(ctxt, def->content);
3153*7c568831SAndroid Build Coastguard Worker xmlAutomataNewTransition(ctxt->am, ctxt->state,
3154*7c568831SAndroid Build Coastguard Worker ctxt->state, BAD_CAST "#text",
3155*7c568831SAndroid Build Coastguard Worker NULL);
3156*7c568831SAndroid Build Coastguard Worker ctxt->state =
3157*7c568831SAndroid Build Coastguard Worker xmlAutomataNewEpsilon(ctxt->am, oldstate, NULL);
3158*7c568831SAndroid Build Coastguard Worker break;
3159*7c568831SAndroid Build Coastguard Worker }
3160*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EMPTY:
3161*7c568831SAndroid Build Coastguard Worker ctxt->state =
3162*7c568831SAndroid Build Coastguard Worker xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
3163*7c568831SAndroid Build Coastguard Worker break;
3164*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXCEPT:
3165*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ATTRIBUTE:
3166*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_INTERLEAVE:
3167*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOT_ALLOWED:
3168*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DATATYPE:
3169*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_LIST:
3170*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARAM:
3171*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_VALUE:
3172*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, NULL, XML_ERR_INTERNAL_ERROR,
3173*7c568831SAndroid Build Coastguard Worker "RNG internal error trying to compile %s\n",
3174*7c568831SAndroid Build Coastguard Worker BAD_CAST xmlRelaxNGDefName(def), NULL);
3175*7c568831SAndroid Build Coastguard Worker break;
3176*7c568831SAndroid Build Coastguard Worker }
3177*7c568831SAndroid Build Coastguard Worker return (ret);
3178*7c568831SAndroid Build Coastguard Worker }
3179*7c568831SAndroid Build Coastguard Worker
3180*7c568831SAndroid Build Coastguard Worker /**
3181*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGTryCompile:
3182*7c568831SAndroid Build Coastguard Worker * ctxt: the RelaxNG parser context
3183*7c568831SAndroid Build Coastguard Worker * @define: the definition tree to compile
3184*7c568831SAndroid Build Coastguard Worker *
3185*7c568831SAndroid Build Coastguard Worker * Try to compile the set of definitions, it works recursively,
3186*7c568831SAndroid Build Coastguard Worker * possibly ignoring parts which cannot be compiled.
3187*7c568831SAndroid Build Coastguard Worker *
3188*7c568831SAndroid Build Coastguard Worker * Returns 0 if success and -1 in case of error
3189*7c568831SAndroid Build Coastguard Worker */
3190*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt,xmlRelaxNGDefinePtr def)3191*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
3192*7c568831SAndroid Build Coastguard Worker {
3193*7c568831SAndroid Build Coastguard Worker int ret = 0;
3194*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr list;
3195*7c568831SAndroid Build Coastguard Worker
3196*7c568831SAndroid Build Coastguard Worker if ((ctxt == NULL) || (def == NULL))
3197*7c568831SAndroid Build Coastguard Worker return (-1);
3198*7c568831SAndroid Build Coastguard Worker
3199*7c568831SAndroid Build Coastguard Worker if ((def->type == XML_RELAXNG_START) ||
3200*7c568831SAndroid Build Coastguard Worker (def->type == XML_RELAXNG_ELEMENT)) {
3201*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGIsCompilable(def);
3202*7c568831SAndroid Build Coastguard Worker if ((def->dflags & IS_COMPILABLE) && (def->depth != -25)) {
3203*7c568831SAndroid Build Coastguard Worker ctxt->am = NULL;
3204*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGCompile(ctxt, def);
3205*7c568831SAndroid Build Coastguard Worker return (ret);
3206*7c568831SAndroid Build Coastguard Worker }
3207*7c568831SAndroid Build Coastguard Worker }
3208*7c568831SAndroid Build Coastguard Worker switch (def->type) {
3209*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOOP:
3210*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGTryCompile(ctxt, def->content);
3211*7c568831SAndroid Build Coastguard Worker break;
3212*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_TEXT:
3213*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DATATYPE:
3214*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_LIST:
3215*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARAM:
3216*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_VALUE:
3217*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EMPTY:
3218*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ELEMENT:
3219*7c568831SAndroid Build Coastguard Worker ret = 0;
3220*7c568831SAndroid Build Coastguard Worker break;
3221*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_OPTIONAL:
3222*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ZEROORMORE:
3223*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ONEORMORE:
3224*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_CHOICE:
3225*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_GROUP:
3226*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DEF:
3227*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_START:
3228*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_REF:
3229*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXTERNALREF:
3230*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARENTREF:
3231*7c568831SAndroid Build Coastguard Worker list = def->content;
3232*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
3233*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGTryCompile(ctxt, list);
3234*7c568831SAndroid Build Coastguard Worker if (ret != 0)
3235*7c568831SAndroid Build Coastguard Worker break;
3236*7c568831SAndroid Build Coastguard Worker list = list->next;
3237*7c568831SAndroid Build Coastguard Worker }
3238*7c568831SAndroid Build Coastguard Worker break;
3239*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXCEPT:
3240*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ATTRIBUTE:
3241*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_INTERLEAVE:
3242*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOT_ALLOWED:
3243*7c568831SAndroid Build Coastguard Worker ret = 0;
3244*7c568831SAndroid Build Coastguard Worker break;
3245*7c568831SAndroid Build Coastguard Worker }
3246*7c568831SAndroid Build Coastguard Worker return (ret);
3247*7c568831SAndroid Build Coastguard Worker }
3248*7c568831SAndroid Build Coastguard Worker
3249*7c568831SAndroid Build Coastguard Worker /************************************************************************
3250*7c568831SAndroid Build Coastguard Worker * *
3251*7c568831SAndroid Build Coastguard Worker * Parsing functions *
3252*7c568831SAndroid Build Coastguard Worker * *
3253*7c568831SAndroid Build Coastguard Worker ************************************************************************/
3254*7c568831SAndroid Build Coastguard Worker
3255*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr
3256*7c568831SAndroid Build Coastguard Worker ctxt, xmlNodePtr node);
3257*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr xmlRelaxNGParseElement(xmlRelaxNGParserCtxtPtr
3258*7c568831SAndroid Build Coastguard Worker ctxt, xmlNodePtr node);
3259*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr xmlRelaxNGParsePatterns(xmlRelaxNGParserCtxtPtr
3260*7c568831SAndroid Build Coastguard Worker ctxt, xmlNodePtr nodes,
3261*7c568831SAndroid Build Coastguard Worker int group);
3262*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr
3263*7c568831SAndroid Build Coastguard Worker ctxt, xmlNodePtr node);
3264*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGPtr xmlRelaxNGParseDocument(xmlRelaxNGParserCtxtPtr ctxt,
3265*7c568831SAndroid Build Coastguard Worker xmlNodePtr node);
3266*7c568831SAndroid Build Coastguard Worker static int xmlRelaxNGParseGrammarContent(xmlRelaxNGParserCtxtPtr ctxt,
3267*7c568831SAndroid Build Coastguard Worker xmlNodePtr nodes);
3268*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr
3269*7c568831SAndroid Build Coastguard Worker ctxt, xmlNodePtr node,
3270*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr
3271*7c568831SAndroid Build Coastguard Worker def);
3272*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGGrammarPtr xmlRelaxNGParseGrammar(xmlRelaxNGParserCtxtPtr
3273*7c568831SAndroid Build Coastguard Worker ctxt, xmlNodePtr nodes);
3274*7c568831SAndroid Build Coastguard Worker static int xmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,
3275*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr define,
3276*7c568831SAndroid Build Coastguard Worker xmlNodePtr elem);
3277*7c568831SAndroid Build Coastguard Worker
3278*7c568831SAndroid Build Coastguard Worker
3279*7c568831SAndroid Build Coastguard Worker #define IS_BLANK_NODE(n) (xmlRelaxNGIsBlank((n)->content))
3280*7c568831SAndroid Build Coastguard Worker
3281*7c568831SAndroid Build Coastguard Worker /**
3282*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGIsNullable:
3283*7c568831SAndroid Build Coastguard Worker * @define: the definition to verify
3284*7c568831SAndroid Build Coastguard Worker *
3285*7c568831SAndroid Build Coastguard Worker * Check if a definition is nullable.
3286*7c568831SAndroid Build Coastguard Worker *
3287*7c568831SAndroid Build Coastguard Worker * Returns 1 if yes, 0 if no and -1 in case of error
3288*7c568831SAndroid Build Coastguard Worker */
3289*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGIsNullable(xmlRelaxNGDefinePtr define)3290*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIsNullable(xmlRelaxNGDefinePtr define)
3291*7c568831SAndroid Build Coastguard Worker {
3292*7c568831SAndroid Build Coastguard Worker int ret;
3293*7c568831SAndroid Build Coastguard Worker
3294*7c568831SAndroid Build Coastguard Worker if (define == NULL)
3295*7c568831SAndroid Build Coastguard Worker return (-1);
3296*7c568831SAndroid Build Coastguard Worker
3297*7c568831SAndroid Build Coastguard Worker if (define->dflags & IS_NULLABLE)
3298*7c568831SAndroid Build Coastguard Worker return (1);
3299*7c568831SAndroid Build Coastguard Worker if (define->dflags & IS_NOT_NULLABLE)
3300*7c568831SAndroid Build Coastguard Worker return (0);
3301*7c568831SAndroid Build Coastguard Worker switch (define->type) {
3302*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EMPTY:
3303*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_TEXT:
3304*7c568831SAndroid Build Coastguard Worker ret = 1;
3305*7c568831SAndroid Build Coastguard Worker break;
3306*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOOP:
3307*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DEF:
3308*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_REF:
3309*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXTERNALREF:
3310*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARENTREF:
3311*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ONEORMORE:
3312*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGIsNullable(define->content);
3313*7c568831SAndroid Build Coastguard Worker break;
3314*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXCEPT:
3315*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOT_ALLOWED:
3316*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ELEMENT:
3317*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DATATYPE:
3318*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARAM:
3319*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_VALUE:
3320*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_LIST:
3321*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ATTRIBUTE:
3322*7c568831SAndroid Build Coastguard Worker ret = 0;
3323*7c568831SAndroid Build Coastguard Worker break;
3324*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_CHOICE:{
3325*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr list = define->content;
3326*7c568831SAndroid Build Coastguard Worker
3327*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
3328*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGIsNullable(list);
3329*7c568831SAndroid Build Coastguard Worker if (ret != 0)
3330*7c568831SAndroid Build Coastguard Worker goto done;
3331*7c568831SAndroid Build Coastguard Worker list = list->next;
3332*7c568831SAndroid Build Coastguard Worker }
3333*7c568831SAndroid Build Coastguard Worker ret = 0;
3334*7c568831SAndroid Build Coastguard Worker break;
3335*7c568831SAndroid Build Coastguard Worker }
3336*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_START:
3337*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_INTERLEAVE:
3338*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_GROUP:{
3339*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr list = define->content;
3340*7c568831SAndroid Build Coastguard Worker
3341*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
3342*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGIsNullable(list);
3343*7c568831SAndroid Build Coastguard Worker if (ret != 1)
3344*7c568831SAndroid Build Coastguard Worker goto done;
3345*7c568831SAndroid Build Coastguard Worker list = list->next;
3346*7c568831SAndroid Build Coastguard Worker }
3347*7c568831SAndroid Build Coastguard Worker return (1);
3348*7c568831SAndroid Build Coastguard Worker }
3349*7c568831SAndroid Build Coastguard Worker default:
3350*7c568831SAndroid Build Coastguard Worker return (-1);
3351*7c568831SAndroid Build Coastguard Worker }
3352*7c568831SAndroid Build Coastguard Worker done:
3353*7c568831SAndroid Build Coastguard Worker if (ret == 0)
3354*7c568831SAndroid Build Coastguard Worker define->dflags |= IS_NOT_NULLABLE;
3355*7c568831SAndroid Build Coastguard Worker if (ret == 1)
3356*7c568831SAndroid Build Coastguard Worker define->dflags |= IS_NULLABLE;
3357*7c568831SAndroid Build Coastguard Worker return (ret);
3358*7c568831SAndroid Build Coastguard Worker }
3359*7c568831SAndroid Build Coastguard Worker
3360*7c568831SAndroid Build Coastguard Worker /**
3361*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGIsBlank:
3362*7c568831SAndroid Build Coastguard Worker * @str: a string
3363*7c568831SAndroid Build Coastguard Worker *
3364*7c568831SAndroid Build Coastguard Worker * Check if a string is ignorable c.f. 4.2. Whitespace
3365*7c568831SAndroid Build Coastguard Worker *
3366*7c568831SAndroid Build Coastguard Worker * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
3367*7c568831SAndroid Build Coastguard Worker */
3368*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGIsBlank(xmlChar * str)3369*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIsBlank(xmlChar * str)
3370*7c568831SAndroid Build Coastguard Worker {
3371*7c568831SAndroid Build Coastguard Worker if (str == NULL)
3372*7c568831SAndroid Build Coastguard Worker return (1);
3373*7c568831SAndroid Build Coastguard Worker while (*str != 0) {
3374*7c568831SAndroid Build Coastguard Worker if (!(IS_BLANK_CH(*str)))
3375*7c568831SAndroid Build Coastguard Worker return (0);
3376*7c568831SAndroid Build Coastguard Worker str++;
3377*7c568831SAndroid Build Coastguard Worker }
3378*7c568831SAndroid Build Coastguard Worker return (1);
3379*7c568831SAndroid Build Coastguard Worker }
3380*7c568831SAndroid Build Coastguard Worker
3381*7c568831SAndroid Build Coastguard Worker /**
3382*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGGetDataTypeLibrary:
3383*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
3384*7c568831SAndroid Build Coastguard Worker * @node: the current data or value element
3385*7c568831SAndroid Build Coastguard Worker *
3386*7c568831SAndroid Build Coastguard Worker * Applies algorithm from 4.3. datatypeLibrary attribute
3387*7c568831SAndroid Build Coastguard Worker *
3388*7c568831SAndroid Build Coastguard Worker * Returns the datatypeLibrary value or NULL if not found
3389*7c568831SAndroid Build Coastguard Worker */
3390*7c568831SAndroid Build Coastguard Worker static xmlChar *
xmlRelaxNGGetDataTypeLibrary(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,xmlNodePtr node)3391*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGetDataTypeLibrary(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
3392*7c568831SAndroid Build Coastguard Worker xmlNodePtr node)
3393*7c568831SAndroid Build Coastguard Worker {
3394*7c568831SAndroid Build Coastguard Worker xmlChar *ret, *escape;
3395*7c568831SAndroid Build Coastguard Worker
3396*7c568831SAndroid Build Coastguard Worker if (node == NULL)
3397*7c568831SAndroid Build Coastguard Worker return(NULL);
3398*7c568831SAndroid Build Coastguard Worker
3399*7c568831SAndroid Build Coastguard Worker if ((IS_RELAXNG(node, "data")) || (IS_RELAXNG(node, "value"))) {
3400*7c568831SAndroid Build Coastguard Worker ret = xmlGetProp(node, BAD_CAST "datatypeLibrary");
3401*7c568831SAndroid Build Coastguard Worker if (ret != NULL) {
3402*7c568831SAndroid Build Coastguard Worker if (ret[0] == 0) {
3403*7c568831SAndroid Build Coastguard Worker xmlFree(ret);
3404*7c568831SAndroid Build Coastguard Worker return (NULL);
3405*7c568831SAndroid Build Coastguard Worker }
3406*7c568831SAndroid Build Coastguard Worker escape = xmlURIEscapeStr(ret, BAD_CAST ":/#?");
3407*7c568831SAndroid Build Coastguard Worker if (escape == NULL) {
3408*7c568831SAndroid Build Coastguard Worker return (ret);
3409*7c568831SAndroid Build Coastguard Worker }
3410*7c568831SAndroid Build Coastguard Worker xmlFree(ret);
3411*7c568831SAndroid Build Coastguard Worker return (escape);
3412*7c568831SAndroid Build Coastguard Worker }
3413*7c568831SAndroid Build Coastguard Worker }
3414*7c568831SAndroid Build Coastguard Worker node = node->parent;
3415*7c568831SAndroid Build Coastguard Worker while ((node != NULL) && (node->type == XML_ELEMENT_NODE)) {
3416*7c568831SAndroid Build Coastguard Worker ret = xmlGetProp(node, BAD_CAST "datatypeLibrary");
3417*7c568831SAndroid Build Coastguard Worker if (ret != NULL) {
3418*7c568831SAndroid Build Coastguard Worker if (ret[0] == 0) {
3419*7c568831SAndroid Build Coastguard Worker xmlFree(ret);
3420*7c568831SAndroid Build Coastguard Worker return (NULL);
3421*7c568831SAndroid Build Coastguard Worker }
3422*7c568831SAndroid Build Coastguard Worker escape = xmlURIEscapeStr(ret, BAD_CAST ":/#?");
3423*7c568831SAndroid Build Coastguard Worker if (escape == NULL) {
3424*7c568831SAndroid Build Coastguard Worker return (ret);
3425*7c568831SAndroid Build Coastguard Worker }
3426*7c568831SAndroid Build Coastguard Worker xmlFree(ret);
3427*7c568831SAndroid Build Coastguard Worker return (escape);
3428*7c568831SAndroid Build Coastguard Worker }
3429*7c568831SAndroid Build Coastguard Worker node = node->parent;
3430*7c568831SAndroid Build Coastguard Worker }
3431*7c568831SAndroid Build Coastguard Worker return (NULL);
3432*7c568831SAndroid Build Coastguard Worker }
3433*7c568831SAndroid Build Coastguard Worker
3434*7c568831SAndroid Build Coastguard Worker /**
3435*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParseValue:
3436*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
3437*7c568831SAndroid Build Coastguard Worker * @node: the data node.
3438*7c568831SAndroid Build Coastguard Worker *
3439*7c568831SAndroid Build Coastguard Worker * parse the content of a RelaxNG value node.
3440*7c568831SAndroid Build Coastguard Worker *
3441*7c568831SAndroid Build Coastguard Worker * Returns the definition pointer or NULL in case of error
3442*7c568831SAndroid Build Coastguard Worker */
3443*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr
xmlRelaxNGParseValue(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr node)3444*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseValue(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
3445*7c568831SAndroid Build Coastguard Worker {
3446*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def = NULL;
3447*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTypeLibraryPtr lib = NULL;
3448*7c568831SAndroid Build Coastguard Worker xmlChar *type;
3449*7c568831SAndroid Build Coastguard Worker xmlChar *library;
3450*7c568831SAndroid Build Coastguard Worker int success = 0;
3451*7c568831SAndroid Build Coastguard Worker
3452*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, node);
3453*7c568831SAndroid Build Coastguard Worker if (def == NULL)
3454*7c568831SAndroid Build Coastguard Worker return (NULL);
3455*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_VALUE;
3456*7c568831SAndroid Build Coastguard Worker
3457*7c568831SAndroid Build Coastguard Worker type = xmlGetProp(node, BAD_CAST "type");
3458*7c568831SAndroid Build Coastguard Worker if (type != NULL) {
3459*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNormExtSpace(type);
3460*7c568831SAndroid Build Coastguard Worker if (xmlValidateNCName(type, 0)) {
3461*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_TYPE_VALUE,
3462*7c568831SAndroid Build Coastguard Worker "value type '%s' is not an NCName\n", type, NULL);
3463*7c568831SAndroid Build Coastguard Worker }
3464*7c568831SAndroid Build Coastguard Worker library = xmlRelaxNGGetDataTypeLibrary(ctxt, node);
3465*7c568831SAndroid Build Coastguard Worker if (library == NULL)
3466*7c568831SAndroid Build Coastguard Worker library =
3467*7c568831SAndroid Build Coastguard Worker xmlStrdup(BAD_CAST "http://relaxng.org/ns/structure/1.0");
3468*7c568831SAndroid Build Coastguard Worker
3469*7c568831SAndroid Build Coastguard Worker def->name = type;
3470*7c568831SAndroid Build Coastguard Worker def->ns = library;
3471*7c568831SAndroid Build Coastguard Worker
3472*7c568831SAndroid Build Coastguard Worker lib = (xmlRelaxNGTypeLibraryPtr)
3473*7c568831SAndroid Build Coastguard Worker xmlHashLookup(xmlRelaxNGRegisteredTypes, library);
3474*7c568831SAndroid Build Coastguard Worker if (lib == NULL) {
3475*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_TYPE_LIB,
3476*7c568831SAndroid Build Coastguard Worker "Use of unregistered type library '%s'\n", library,
3477*7c568831SAndroid Build Coastguard Worker NULL);
3478*7c568831SAndroid Build Coastguard Worker def->data = NULL;
3479*7c568831SAndroid Build Coastguard Worker } else {
3480*7c568831SAndroid Build Coastguard Worker def->data = lib;
3481*7c568831SAndroid Build Coastguard Worker if (lib->have == NULL) {
3482*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_ERROR_TYPE_LIB,
3483*7c568831SAndroid Build Coastguard Worker "Internal error with type library '%s': no 'have'\n",
3484*7c568831SAndroid Build Coastguard Worker library, NULL);
3485*7c568831SAndroid Build Coastguard Worker } else {
3486*7c568831SAndroid Build Coastguard Worker success = lib->have(lib->data, def->name);
3487*7c568831SAndroid Build Coastguard Worker if (success != 1) {
3488*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_TYPE_NOT_FOUND,
3489*7c568831SAndroid Build Coastguard Worker "Error type '%s' is not exported by type library '%s'\n",
3490*7c568831SAndroid Build Coastguard Worker def->name, library);
3491*7c568831SAndroid Build Coastguard Worker }
3492*7c568831SAndroid Build Coastguard Worker }
3493*7c568831SAndroid Build Coastguard Worker }
3494*7c568831SAndroid Build Coastguard Worker }
3495*7c568831SAndroid Build Coastguard Worker if (node->children == NULL) {
3496*7c568831SAndroid Build Coastguard Worker def->value = xmlStrdup(BAD_CAST "");
3497*7c568831SAndroid Build Coastguard Worker } else if (((node->children->type != XML_TEXT_NODE) &&
3498*7c568831SAndroid Build Coastguard Worker (node->children->type != XML_CDATA_SECTION_NODE)) ||
3499*7c568831SAndroid Build Coastguard Worker (node->children->next != NULL)) {
3500*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_TEXT_EXPECTED,
3501*7c568831SAndroid Build Coastguard Worker "Expecting a single text value for <value>content\n",
3502*7c568831SAndroid Build Coastguard Worker NULL, NULL);
3503*7c568831SAndroid Build Coastguard Worker } else if (def != NULL) {
3504*7c568831SAndroid Build Coastguard Worker def->value = xmlNodeGetContent(node);
3505*7c568831SAndroid Build Coastguard Worker if (def->value == NULL) {
3506*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_VALUE_NO_CONTENT,
3507*7c568831SAndroid Build Coastguard Worker "Element <value> has no content\n", NULL, NULL);
3508*7c568831SAndroid Build Coastguard Worker } else if ((lib != NULL) && (lib->check != NULL) && (success == 1)) {
3509*7c568831SAndroid Build Coastguard Worker void *val = NULL;
3510*7c568831SAndroid Build Coastguard Worker
3511*7c568831SAndroid Build Coastguard Worker success =
3512*7c568831SAndroid Build Coastguard Worker lib->check(lib->data, def->name, def->value, &val, node);
3513*7c568831SAndroid Build Coastguard Worker if (success != 1) {
3514*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_INVALID_VALUE,
3515*7c568831SAndroid Build Coastguard Worker "Value '%s' is not acceptable for type '%s'\n",
3516*7c568831SAndroid Build Coastguard Worker def->value, def->name);
3517*7c568831SAndroid Build Coastguard Worker } else {
3518*7c568831SAndroid Build Coastguard Worker if (val != NULL)
3519*7c568831SAndroid Build Coastguard Worker def->attrs = val;
3520*7c568831SAndroid Build Coastguard Worker }
3521*7c568831SAndroid Build Coastguard Worker }
3522*7c568831SAndroid Build Coastguard Worker }
3523*7c568831SAndroid Build Coastguard Worker return (def);
3524*7c568831SAndroid Build Coastguard Worker }
3525*7c568831SAndroid Build Coastguard Worker
3526*7c568831SAndroid Build Coastguard Worker /**
3527*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParseData:
3528*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
3529*7c568831SAndroid Build Coastguard Worker * @node: the data node.
3530*7c568831SAndroid Build Coastguard Worker *
3531*7c568831SAndroid Build Coastguard Worker * parse the content of a RelaxNG data node.
3532*7c568831SAndroid Build Coastguard Worker *
3533*7c568831SAndroid Build Coastguard Worker * Returns the definition pointer or NULL in case of error
3534*7c568831SAndroid Build Coastguard Worker */
3535*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr
xmlRelaxNGParseData(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr node)3536*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseData(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
3537*7c568831SAndroid Build Coastguard Worker {
3538*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def = NULL, except;
3539*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr param, lastparam = NULL;
3540*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTypeLibraryPtr lib;
3541*7c568831SAndroid Build Coastguard Worker xmlChar *type;
3542*7c568831SAndroid Build Coastguard Worker xmlChar *library;
3543*7c568831SAndroid Build Coastguard Worker xmlNodePtr content;
3544*7c568831SAndroid Build Coastguard Worker int tmp;
3545*7c568831SAndroid Build Coastguard Worker
3546*7c568831SAndroid Build Coastguard Worker type = xmlGetProp(node, BAD_CAST "type");
3547*7c568831SAndroid Build Coastguard Worker if (type == NULL) {
3548*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_TYPE_MISSING, "data has no type\n", NULL,
3549*7c568831SAndroid Build Coastguard Worker NULL);
3550*7c568831SAndroid Build Coastguard Worker return (NULL);
3551*7c568831SAndroid Build Coastguard Worker }
3552*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNormExtSpace(type);
3553*7c568831SAndroid Build Coastguard Worker if (xmlValidateNCName(type, 0)) {
3554*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_TYPE_VALUE,
3555*7c568831SAndroid Build Coastguard Worker "data type '%s' is not an NCName\n", type, NULL);
3556*7c568831SAndroid Build Coastguard Worker }
3557*7c568831SAndroid Build Coastguard Worker library = xmlRelaxNGGetDataTypeLibrary(ctxt, node);
3558*7c568831SAndroid Build Coastguard Worker if (library == NULL)
3559*7c568831SAndroid Build Coastguard Worker library =
3560*7c568831SAndroid Build Coastguard Worker xmlStrdup(BAD_CAST "http://relaxng.org/ns/structure/1.0");
3561*7c568831SAndroid Build Coastguard Worker
3562*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, node);
3563*7c568831SAndroid Build Coastguard Worker if (def == NULL) {
3564*7c568831SAndroid Build Coastguard Worker xmlFree(library);
3565*7c568831SAndroid Build Coastguard Worker xmlFree(type);
3566*7c568831SAndroid Build Coastguard Worker return (NULL);
3567*7c568831SAndroid Build Coastguard Worker }
3568*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_DATATYPE;
3569*7c568831SAndroid Build Coastguard Worker def->name = type;
3570*7c568831SAndroid Build Coastguard Worker def->ns = library;
3571*7c568831SAndroid Build Coastguard Worker
3572*7c568831SAndroid Build Coastguard Worker lib = (xmlRelaxNGTypeLibraryPtr)
3573*7c568831SAndroid Build Coastguard Worker xmlHashLookup(xmlRelaxNGRegisteredTypes, library);
3574*7c568831SAndroid Build Coastguard Worker if (lib == NULL) {
3575*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_TYPE_LIB,
3576*7c568831SAndroid Build Coastguard Worker "Use of unregistered type library '%s'\n", library,
3577*7c568831SAndroid Build Coastguard Worker NULL);
3578*7c568831SAndroid Build Coastguard Worker def->data = NULL;
3579*7c568831SAndroid Build Coastguard Worker } else {
3580*7c568831SAndroid Build Coastguard Worker def->data = lib;
3581*7c568831SAndroid Build Coastguard Worker if (lib->have == NULL) {
3582*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_ERROR_TYPE_LIB,
3583*7c568831SAndroid Build Coastguard Worker "Internal error with type library '%s': no 'have'\n",
3584*7c568831SAndroid Build Coastguard Worker library, NULL);
3585*7c568831SAndroid Build Coastguard Worker } else {
3586*7c568831SAndroid Build Coastguard Worker tmp = lib->have(lib->data, def->name);
3587*7c568831SAndroid Build Coastguard Worker if (tmp != 1) {
3588*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_TYPE_NOT_FOUND,
3589*7c568831SAndroid Build Coastguard Worker "Error type '%s' is not exported by type library '%s'\n",
3590*7c568831SAndroid Build Coastguard Worker def->name, library);
3591*7c568831SAndroid Build Coastguard Worker } else
3592*7c568831SAndroid Build Coastguard Worker if ((xmlStrEqual
3593*7c568831SAndroid Build Coastguard Worker (library,
3594*7c568831SAndroid Build Coastguard Worker BAD_CAST
3595*7c568831SAndroid Build Coastguard Worker "http://www.w3.org/2001/XMLSchema-datatypes"))
3596*7c568831SAndroid Build Coastguard Worker && ((xmlStrEqual(def->name, BAD_CAST "IDREF"))
3597*7c568831SAndroid Build Coastguard Worker || (xmlStrEqual(def->name, BAD_CAST "IDREFS")))) {
3598*7c568831SAndroid Build Coastguard Worker ctxt->idref = 1;
3599*7c568831SAndroid Build Coastguard Worker }
3600*7c568831SAndroid Build Coastguard Worker }
3601*7c568831SAndroid Build Coastguard Worker }
3602*7c568831SAndroid Build Coastguard Worker content = node->children;
3603*7c568831SAndroid Build Coastguard Worker
3604*7c568831SAndroid Build Coastguard Worker /*
3605*7c568831SAndroid Build Coastguard Worker * Handle optional params
3606*7c568831SAndroid Build Coastguard Worker */
3607*7c568831SAndroid Build Coastguard Worker while (content != NULL) {
3608*7c568831SAndroid Build Coastguard Worker if (!xmlStrEqual(content->name, BAD_CAST "param"))
3609*7c568831SAndroid Build Coastguard Worker break;
3610*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual(library,
3611*7c568831SAndroid Build Coastguard Worker BAD_CAST "http://relaxng.org/ns/structure/1.0")) {
3612*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_PARAM_FORBIDDEN,
3613*7c568831SAndroid Build Coastguard Worker "Type library '%s' does not allow type parameters\n",
3614*7c568831SAndroid Build Coastguard Worker library, NULL);
3615*7c568831SAndroid Build Coastguard Worker content = content->next;
3616*7c568831SAndroid Build Coastguard Worker while ((content != NULL) &&
3617*7c568831SAndroid Build Coastguard Worker (xmlStrEqual(content->name, BAD_CAST "param")))
3618*7c568831SAndroid Build Coastguard Worker content = content->next;
3619*7c568831SAndroid Build Coastguard Worker } else {
3620*7c568831SAndroid Build Coastguard Worker param = xmlRelaxNGNewDefine(ctxt, node);
3621*7c568831SAndroid Build Coastguard Worker if (param != NULL) {
3622*7c568831SAndroid Build Coastguard Worker param->type = XML_RELAXNG_PARAM;
3623*7c568831SAndroid Build Coastguard Worker param->name = xmlGetProp(content, BAD_CAST "name");
3624*7c568831SAndroid Build Coastguard Worker if (param->name == NULL) {
3625*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_PARAM_NAME_MISSING,
3626*7c568831SAndroid Build Coastguard Worker "param has no name\n", NULL, NULL);
3627*7c568831SAndroid Build Coastguard Worker }
3628*7c568831SAndroid Build Coastguard Worker param->value = xmlNodeGetContent(content);
3629*7c568831SAndroid Build Coastguard Worker if (lastparam == NULL) {
3630*7c568831SAndroid Build Coastguard Worker def->attrs = lastparam = param;
3631*7c568831SAndroid Build Coastguard Worker } else {
3632*7c568831SAndroid Build Coastguard Worker lastparam->next = param;
3633*7c568831SAndroid Build Coastguard Worker lastparam = param;
3634*7c568831SAndroid Build Coastguard Worker }
3635*7c568831SAndroid Build Coastguard Worker if (lib != NULL) {
3636*7c568831SAndroid Build Coastguard Worker }
3637*7c568831SAndroid Build Coastguard Worker }
3638*7c568831SAndroid Build Coastguard Worker content = content->next;
3639*7c568831SAndroid Build Coastguard Worker }
3640*7c568831SAndroid Build Coastguard Worker }
3641*7c568831SAndroid Build Coastguard Worker /*
3642*7c568831SAndroid Build Coastguard Worker * Handle optional except
3643*7c568831SAndroid Build Coastguard Worker */
3644*7c568831SAndroid Build Coastguard Worker if ((content != NULL)
3645*7c568831SAndroid Build Coastguard Worker && (xmlStrEqual(content->name, BAD_CAST "except"))) {
3646*7c568831SAndroid Build Coastguard Worker xmlNodePtr child;
3647*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr tmp2, last = NULL;
3648*7c568831SAndroid Build Coastguard Worker
3649*7c568831SAndroid Build Coastguard Worker except = xmlRelaxNGNewDefine(ctxt, node);
3650*7c568831SAndroid Build Coastguard Worker if (except == NULL) {
3651*7c568831SAndroid Build Coastguard Worker return (def);
3652*7c568831SAndroid Build Coastguard Worker }
3653*7c568831SAndroid Build Coastguard Worker except->type = XML_RELAXNG_EXCEPT;
3654*7c568831SAndroid Build Coastguard Worker child = content->children;
3655*7c568831SAndroid Build Coastguard Worker def->content = except;
3656*7c568831SAndroid Build Coastguard Worker if (child == NULL) {
3657*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, content, XML_RNGP_EXCEPT_NO_CONTENT,
3658*7c568831SAndroid Build Coastguard Worker "except has no content\n", NULL, NULL);
3659*7c568831SAndroid Build Coastguard Worker }
3660*7c568831SAndroid Build Coastguard Worker while (child != NULL) {
3661*7c568831SAndroid Build Coastguard Worker tmp2 = xmlRelaxNGParsePattern(ctxt, child);
3662*7c568831SAndroid Build Coastguard Worker if (tmp2 != NULL) {
3663*7c568831SAndroid Build Coastguard Worker if (last == NULL) {
3664*7c568831SAndroid Build Coastguard Worker except->content = last = tmp2;
3665*7c568831SAndroid Build Coastguard Worker } else {
3666*7c568831SAndroid Build Coastguard Worker last->next = tmp2;
3667*7c568831SAndroid Build Coastguard Worker last = tmp2;
3668*7c568831SAndroid Build Coastguard Worker }
3669*7c568831SAndroid Build Coastguard Worker }
3670*7c568831SAndroid Build Coastguard Worker child = child->next;
3671*7c568831SAndroid Build Coastguard Worker }
3672*7c568831SAndroid Build Coastguard Worker content = content->next;
3673*7c568831SAndroid Build Coastguard Worker }
3674*7c568831SAndroid Build Coastguard Worker /*
3675*7c568831SAndroid Build Coastguard Worker * Check there is no unhandled data
3676*7c568831SAndroid Build Coastguard Worker */
3677*7c568831SAndroid Build Coastguard Worker if (content != NULL) {
3678*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, content, XML_RNGP_DATA_CONTENT,
3679*7c568831SAndroid Build Coastguard Worker "Element data has unexpected content %s\n",
3680*7c568831SAndroid Build Coastguard Worker content->name, NULL);
3681*7c568831SAndroid Build Coastguard Worker }
3682*7c568831SAndroid Build Coastguard Worker
3683*7c568831SAndroid Build Coastguard Worker return (def);
3684*7c568831SAndroid Build Coastguard Worker }
3685*7c568831SAndroid Build Coastguard Worker
3686*7c568831SAndroid Build Coastguard Worker static const xmlChar *invalidName = BAD_CAST "\1";
3687*7c568831SAndroid Build Coastguard Worker
3688*7c568831SAndroid Build Coastguard Worker /**
3689*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGCompareNameClasses:
3690*7c568831SAndroid Build Coastguard Worker * @defs1: the first element/attribute defs
3691*7c568831SAndroid Build Coastguard Worker * @defs2: the second element/attribute defs
3692*7c568831SAndroid Build Coastguard Worker * @name: the restriction on the name
3693*7c568831SAndroid Build Coastguard Worker * @ns: the restriction on the namespace
3694*7c568831SAndroid Build Coastguard Worker *
3695*7c568831SAndroid Build Coastguard Worker * Compare the 2 lists of element definitions. The comparison is
3696*7c568831SAndroid Build Coastguard Worker * that if both lists do not accept the same QNames, it returns 1
3697*7c568831SAndroid Build Coastguard Worker * If the 2 lists can accept the same QName the comparison returns 0
3698*7c568831SAndroid Build Coastguard Worker *
3699*7c568831SAndroid Build Coastguard Worker * Returns 1 distinct, 0 if equal
3700*7c568831SAndroid Build Coastguard Worker */
3701*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGCompareNameClasses(xmlRelaxNGDefinePtr def1,xmlRelaxNGDefinePtr def2)3702*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCompareNameClasses(xmlRelaxNGDefinePtr def1,
3703*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def2)
3704*7c568831SAndroid Build Coastguard Worker {
3705*7c568831SAndroid Build Coastguard Worker int ret = 1;
3706*7c568831SAndroid Build Coastguard Worker xmlNode node;
3707*7c568831SAndroid Build Coastguard Worker xmlNs ns;
3708*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidCtxt ctxt;
3709*7c568831SAndroid Build Coastguard Worker
3710*7c568831SAndroid Build Coastguard Worker memset(&ctxt, 0, sizeof(xmlRelaxNGValidCtxt));
3711*7c568831SAndroid Build Coastguard Worker
3712*7c568831SAndroid Build Coastguard Worker ctxt.flags = FLAGS_IGNORABLE | FLAGS_NOERROR;
3713*7c568831SAndroid Build Coastguard Worker
3714*7c568831SAndroid Build Coastguard Worker if ((def1->type == XML_RELAXNG_ELEMENT) ||
3715*7c568831SAndroid Build Coastguard Worker (def1->type == XML_RELAXNG_ATTRIBUTE)) {
3716*7c568831SAndroid Build Coastguard Worker if (def2->type == XML_RELAXNG_TEXT)
3717*7c568831SAndroid Build Coastguard Worker return (1);
3718*7c568831SAndroid Build Coastguard Worker if (def1->name != NULL) {
3719*7c568831SAndroid Build Coastguard Worker node.name = def1->name;
3720*7c568831SAndroid Build Coastguard Worker } else {
3721*7c568831SAndroid Build Coastguard Worker node.name = invalidName;
3722*7c568831SAndroid Build Coastguard Worker }
3723*7c568831SAndroid Build Coastguard Worker if (def1->ns != NULL) {
3724*7c568831SAndroid Build Coastguard Worker if (def1->ns[0] == 0) {
3725*7c568831SAndroid Build Coastguard Worker node.ns = NULL;
3726*7c568831SAndroid Build Coastguard Worker } else {
3727*7c568831SAndroid Build Coastguard Worker node.ns = &ns;
3728*7c568831SAndroid Build Coastguard Worker ns.href = def1->ns;
3729*7c568831SAndroid Build Coastguard Worker }
3730*7c568831SAndroid Build Coastguard Worker } else {
3731*7c568831SAndroid Build Coastguard Worker node.ns = NULL;
3732*7c568831SAndroid Build Coastguard Worker }
3733*7c568831SAndroid Build Coastguard Worker if (xmlRelaxNGElementMatch(&ctxt, def2, &node)) {
3734*7c568831SAndroid Build Coastguard Worker if (def1->nameClass != NULL) {
3735*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGCompareNameClasses(def1->nameClass, def2);
3736*7c568831SAndroid Build Coastguard Worker } else {
3737*7c568831SAndroid Build Coastguard Worker ret = 0;
3738*7c568831SAndroid Build Coastguard Worker }
3739*7c568831SAndroid Build Coastguard Worker } else {
3740*7c568831SAndroid Build Coastguard Worker ret = 1;
3741*7c568831SAndroid Build Coastguard Worker }
3742*7c568831SAndroid Build Coastguard Worker } else if (def1->type == XML_RELAXNG_TEXT) {
3743*7c568831SAndroid Build Coastguard Worker if (def2->type == XML_RELAXNG_TEXT)
3744*7c568831SAndroid Build Coastguard Worker return (0);
3745*7c568831SAndroid Build Coastguard Worker return (1);
3746*7c568831SAndroid Build Coastguard Worker } else if (def1->type == XML_RELAXNG_EXCEPT) {
3747*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGCompareNameClasses(def1->content, def2);
3748*7c568831SAndroid Build Coastguard Worker if (ret == 0)
3749*7c568831SAndroid Build Coastguard Worker ret = 1;
3750*7c568831SAndroid Build Coastguard Worker else if (ret == 1)
3751*7c568831SAndroid Build Coastguard Worker ret = 0;
3752*7c568831SAndroid Build Coastguard Worker } else {
3753*7c568831SAndroid Build Coastguard Worker /* TODO */
3754*7c568831SAndroid Build Coastguard Worker ret = 0;
3755*7c568831SAndroid Build Coastguard Worker }
3756*7c568831SAndroid Build Coastguard Worker if (ret == 0)
3757*7c568831SAndroid Build Coastguard Worker return (ret);
3758*7c568831SAndroid Build Coastguard Worker if ((def2->type == XML_RELAXNG_ELEMENT) ||
3759*7c568831SAndroid Build Coastguard Worker (def2->type == XML_RELAXNG_ATTRIBUTE)) {
3760*7c568831SAndroid Build Coastguard Worker if (def2->name != NULL) {
3761*7c568831SAndroid Build Coastguard Worker node.name = def2->name;
3762*7c568831SAndroid Build Coastguard Worker } else {
3763*7c568831SAndroid Build Coastguard Worker node.name = invalidName;
3764*7c568831SAndroid Build Coastguard Worker }
3765*7c568831SAndroid Build Coastguard Worker node.ns = &ns;
3766*7c568831SAndroid Build Coastguard Worker if (def2->ns != NULL) {
3767*7c568831SAndroid Build Coastguard Worker if (def2->ns[0] == 0) {
3768*7c568831SAndroid Build Coastguard Worker node.ns = NULL;
3769*7c568831SAndroid Build Coastguard Worker } else {
3770*7c568831SAndroid Build Coastguard Worker ns.href = def2->ns;
3771*7c568831SAndroid Build Coastguard Worker }
3772*7c568831SAndroid Build Coastguard Worker } else {
3773*7c568831SAndroid Build Coastguard Worker ns.href = invalidName;
3774*7c568831SAndroid Build Coastguard Worker }
3775*7c568831SAndroid Build Coastguard Worker if (xmlRelaxNGElementMatch(&ctxt, def1, &node)) {
3776*7c568831SAndroid Build Coastguard Worker if (def2->nameClass != NULL) {
3777*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGCompareNameClasses(def2->nameClass, def1);
3778*7c568831SAndroid Build Coastguard Worker } else {
3779*7c568831SAndroid Build Coastguard Worker ret = 0;
3780*7c568831SAndroid Build Coastguard Worker }
3781*7c568831SAndroid Build Coastguard Worker } else {
3782*7c568831SAndroid Build Coastguard Worker ret = 1;
3783*7c568831SAndroid Build Coastguard Worker }
3784*7c568831SAndroid Build Coastguard Worker } else {
3785*7c568831SAndroid Build Coastguard Worker /* TODO */
3786*7c568831SAndroid Build Coastguard Worker ret = 0;
3787*7c568831SAndroid Build Coastguard Worker }
3788*7c568831SAndroid Build Coastguard Worker
3789*7c568831SAndroid Build Coastguard Worker return (ret);
3790*7c568831SAndroid Build Coastguard Worker }
3791*7c568831SAndroid Build Coastguard Worker
3792*7c568831SAndroid Build Coastguard Worker /**
3793*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGCompareElemDefLists:
3794*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
3795*7c568831SAndroid Build Coastguard Worker * @defs1: the first list of element/attribute defs
3796*7c568831SAndroid Build Coastguard Worker * @defs2: the second list of element/attribute defs
3797*7c568831SAndroid Build Coastguard Worker *
3798*7c568831SAndroid Build Coastguard Worker * Compare the 2 lists of element or attribute definitions. The comparison
3799*7c568831SAndroid Build Coastguard Worker * is that if both lists do not accept the same QNames, it returns 1
3800*7c568831SAndroid Build Coastguard Worker * If the 2 lists can accept the same QName the comparison returns 0
3801*7c568831SAndroid Build Coastguard Worker *
3802*7c568831SAndroid Build Coastguard Worker * Returns 1 distinct, 0 if equal
3803*7c568831SAndroid Build Coastguard Worker */
3804*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGCompareElemDefLists(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,xmlRelaxNGDefinePtr * def1,xmlRelaxNGDefinePtr * def2)3805*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCompareElemDefLists(xmlRelaxNGParserCtxtPtr ctxt
3806*7c568831SAndroid Build Coastguard Worker ATTRIBUTE_UNUSED, xmlRelaxNGDefinePtr * def1,
3807*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr * def2)
3808*7c568831SAndroid Build Coastguard Worker {
3809*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr *basedef2 = def2;
3810*7c568831SAndroid Build Coastguard Worker
3811*7c568831SAndroid Build Coastguard Worker if ((def1 == NULL) || (def2 == NULL))
3812*7c568831SAndroid Build Coastguard Worker return (1);
3813*7c568831SAndroid Build Coastguard Worker if ((*def1 == NULL) || (*def2 == NULL))
3814*7c568831SAndroid Build Coastguard Worker return (1);
3815*7c568831SAndroid Build Coastguard Worker while (*def1 != NULL) {
3816*7c568831SAndroid Build Coastguard Worker while ((*def2) != NULL) {
3817*7c568831SAndroid Build Coastguard Worker if (xmlRelaxNGCompareNameClasses(*def1, *def2) == 0)
3818*7c568831SAndroid Build Coastguard Worker return (0);
3819*7c568831SAndroid Build Coastguard Worker def2++;
3820*7c568831SAndroid Build Coastguard Worker }
3821*7c568831SAndroid Build Coastguard Worker def2 = basedef2;
3822*7c568831SAndroid Build Coastguard Worker def1++;
3823*7c568831SAndroid Build Coastguard Worker }
3824*7c568831SAndroid Build Coastguard Worker return (1);
3825*7c568831SAndroid Build Coastguard Worker }
3826*7c568831SAndroid Build Coastguard Worker
3827*7c568831SAndroid Build Coastguard Worker /**
3828*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGGenerateAttributes:
3829*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
3830*7c568831SAndroid Build Coastguard Worker * @def: the definition definition
3831*7c568831SAndroid Build Coastguard Worker *
3832*7c568831SAndroid Build Coastguard Worker * Check if the definition can only generate attributes
3833*7c568831SAndroid Build Coastguard Worker *
3834*7c568831SAndroid Build Coastguard Worker * Returns 1 if yes, 0 if no and -1 in case of error.
3835*7c568831SAndroid Build Coastguard Worker */
3836*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGGenerateAttributes(xmlRelaxNGParserCtxtPtr ctxt,xmlRelaxNGDefinePtr def)3837*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGenerateAttributes(xmlRelaxNGParserCtxtPtr ctxt,
3838*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def)
3839*7c568831SAndroid Build Coastguard Worker {
3840*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr parent, cur, tmp;
3841*7c568831SAndroid Build Coastguard Worker
3842*7c568831SAndroid Build Coastguard Worker /*
3843*7c568831SAndroid Build Coastguard Worker * Don't run that check in case of error. Infinite recursion
3844*7c568831SAndroid Build Coastguard Worker * becomes possible.
3845*7c568831SAndroid Build Coastguard Worker */
3846*7c568831SAndroid Build Coastguard Worker if (ctxt->nbErrors != 0)
3847*7c568831SAndroid Build Coastguard Worker return (-1);
3848*7c568831SAndroid Build Coastguard Worker
3849*7c568831SAndroid Build Coastguard Worker parent = NULL;
3850*7c568831SAndroid Build Coastguard Worker cur = def;
3851*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
3852*7c568831SAndroid Build Coastguard Worker if ((cur->type == XML_RELAXNG_ELEMENT) ||
3853*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_TEXT) ||
3854*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_DATATYPE) ||
3855*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_PARAM) ||
3856*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_LIST) ||
3857*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_VALUE) ||
3858*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_EMPTY))
3859*7c568831SAndroid Build Coastguard Worker return (0);
3860*7c568831SAndroid Build Coastguard Worker if ((cur->type == XML_RELAXNG_CHOICE) ||
3861*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_INTERLEAVE) ||
3862*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_GROUP) ||
3863*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_ONEORMORE) ||
3864*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_ZEROORMORE) ||
3865*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_OPTIONAL) ||
3866*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_PARENTREF) ||
3867*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_EXTERNALREF) ||
3868*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_REF) ||
3869*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_DEF)) {
3870*7c568831SAndroid Build Coastguard Worker if (cur->content != NULL) {
3871*7c568831SAndroid Build Coastguard Worker parent = cur;
3872*7c568831SAndroid Build Coastguard Worker cur = cur->content;
3873*7c568831SAndroid Build Coastguard Worker tmp = cur;
3874*7c568831SAndroid Build Coastguard Worker while (tmp != NULL) {
3875*7c568831SAndroid Build Coastguard Worker tmp->parent = parent;
3876*7c568831SAndroid Build Coastguard Worker tmp = tmp->next;
3877*7c568831SAndroid Build Coastguard Worker }
3878*7c568831SAndroid Build Coastguard Worker continue;
3879*7c568831SAndroid Build Coastguard Worker }
3880*7c568831SAndroid Build Coastguard Worker }
3881*7c568831SAndroid Build Coastguard Worker if (cur == def)
3882*7c568831SAndroid Build Coastguard Worker break;
3883*7c568831SAndroid Build Coastguard Worker if (cur->next != NULL) {
3884*7c568831SAndroid Build Coastguard Worker cur = cur->next;
3885*7c568831SAndroid Build Coastguard Worker continue;
3886*7c568831SAndroid Build Coastguard Worker }
3887*7c568831SAndroid Build Coastguard Worker do {
3888*7c568831SAndroid Build Coastguard Worker cur = cur->parent;
3889*7c568831SAndroid Build Coastguard Worker if (cur == NULL)
3890*7c568831SAndroid Build Coastguard Worker break;
3891*7c568831SAndroid Build Coastguard Worker if (cur == def)
3892*7c568831SAndroid Build Coastguard Worker return (1);
3893*7c568831SAndroid Build Coastguard Worker if (cur->next != NULL) {
3894*7c568831SAndroid Build Coastguard Worker cur = cur->next;
3895*7c568831SAndroid Build Coastguard Worker break;
3896*7c568831SAndroid Build Coastguard Worker }
3897*7c568831SAndroid Build Coastguard Worker } while (cur != NULL);
3898*7c568831SAndroid Build Coastguard Worker }
3899*7c568831SAndroid Build Coastguard Worker return (1);
3900*7c568831SAndroid Build Coastguard Worker }
3901*7c568831SAndroid Build Coastguard Worker
3902*7c568831SAndroid Build Coastguard Worker /**
3903*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGGetElements:
3904*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
3905*7c568831SAndroid Build Coastguard Worker * @def: the definition definition
3906*7c568831SAndroid Build Coastguard Worker * @eora: gather elements (0), attributes (1) or elements and text (2)
3907*7c568831SAndroid Build Coastguard Worker *
3908*7c568831SAndroid Build Coastguard Worker * Compute the list of top elements a definition can generate
3909*7c568831SAndroid Build Coastguard Worker *
3910*7c568831SAndroid Build Coastguard Worker * Returns a list of elements or NULL if none was found.
3911*7c568831SAndroid Build Coastguard Worker */
3912*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr *
xmlRelaxNGGetElements(xmlRelaxNGParserCtxtPtr ctxt,xmlRelaxNGDefinePtr def,int eora)3913*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGetElements(xmlRelaxNGParserCtxtPtr ctxt,
3914*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def, int eora)
3915*7c568831SAndroid Build Coastguard Worker {
3916*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr *ret = NULL, parent, cur, tmp;
3917*7c568831SAndroid Build Coastguard Worker int len = 0;
3918*7c568831SAndroid Build Coastguard Worker int max = 0;
3919*7c568831SAndroid Build Coastguard Worker
3920*7c568831SAndroid Build Coastguard Worker /*
3921*7c568831SAndroid Build Coastguard Worker * Don't run that check in case of error. Infinite recursion
3922*7c568831SAndroid Build Coastguard Worker * becomes possible.
3923*7c568831SAndroid Build Coastguard Worker */
3924*7c568831SAndroid Build Coastguard Worker if (ctxt->nbErrors != 0)
3925*7c568831SAndroid Build Coastguard Worker return (NULL);
3926*7c568831SAndroid Build Coastguard Worker
3927*7c568831SAndroid Build Coastguard Worker parent = NULL;
3928*7c568831SAndroid Build Coastguard Worker cur = def;
3929*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
3930*7c568831SAndroid Build Coastguard Worker if (((eora == 0) && ((cur->type == XML_RELAXNG_ELEMENT) ||
3931*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_TEXT))) ||
3932*7c568831SAndroid Build Coastguard Worker ((eora == 1) && (cur->type == XML_RELAXNG_ATTRIBUTE)) ||
3933*7c568831SAndroid Build Coastguard Worker ((eora == 2) && ((cur->type == XML_RELAXNG_DATATYPE) ||
3934*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_ELEMENT) ||
3935*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_LIST) ||
3936*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_TEXT) ||
3937*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_VALUE)))) {
3938*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
3939*7c568831SAndroid Build Coastguard Worker max = 10;
3940*7c568831SAndroid Build Coastguard Worker ret = (xmlRelaxNGDefinePtr *)
3941*7c568831SAndroid Build Coastguard Worker xmlMalloc((max + 1) * sizeof(xmlRelaxNGDefinePtr));
3942*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
3943*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
3944*7c568831SAndroid Build Coastguard Worker return (NULL);
3945*7c568831SAndroid Build Coastguard Worker }
3946*7c568831SAndroid Build Coastguard Worker } else if (max <= len) {
3947*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr *temp;
3948*7c568831SAndroid Build Coastguard Worker
3949*7c568831SAndroid Build Coastguard Worker max *= 2;
3950*7c568831SAndroid Build Coastguard Worker temp = xmlRealloc(ret,
3951*7c568831SAndroid Build Coastguard Worker (max + 1) * sizeof(xmlRelaxNGDefinePtr));
3952*7c568831SAndroid Build Coastguard Worker if (temp == NULL) {
3953*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
3954*7c568831SAndroid Build Coastguard Worker xmlFree(ret);
3955*7c568831SAndroid Build Coastguard Worker return (NULL);
3956*7c568831SAndroid Build Coastguard Worker }
3957*7c568831SAndroid Build Coastguard Worker ret = temp;
3958*7c568831SAndroid Build Coastguard Worker }
3959*7c568831SAndroid Build Coastguard Worker ret[len++] = cur;
3960*7c568831SAndroid Build Coastguard Worker ret[len] = NULL;
3961*7c568831SAndroid Build Coastguard Worker } else if ((cur->type == XML_RELAXNG_CHOICE) ||
3962*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_INTERLEAVE) ||
3963*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_GROUP) ||
3964*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_ONEORMORE) ||
3965*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_ZEROORMORE) ||
3966*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_OPTIONAL) ||
3967*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_PARENTREF) ||
3968*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_REF) ||
3969*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_DEF) ||
3970*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_EXTERNALREF)) {
3971*7c568831SAndroid Build Coastguard Worker /*
3972*7c568831SAndroid Build Coastguard Worker * Don't go within elements or attributes or string values.
3973*7c568831SAndroid Build Coastguard Worker * Just gather the element top list
3974*7c568831SAndroid Build Coastguard Worker */
3975*7c568831SAndroid Build Coastguard Worker if (cur->content != NULL) {
3976*7c568831SAndroid Build Coastguard Worker parent = cur;
3977*7c568831SAndroid Build Coastguard Worker cur = cur->content;
3978*7c568831SAndroid Build Coastguard Worker tmp = cur;
3979*7c568831SAndroid Build Coastguard Worker while (tmp != NULL) {
3980*7c568831SAndroid Build Coastguard Worker tmp->parent = parent;
3981*7c568831SAndroid Build Coastguard Worker tmp = tmp->next;
3982*7c568831SAndroid Build Coastguard Worker }
3983*7c568831SAndroid Build Coastguard Worker continue;
3984*7c568831SAndroid Build Coastguard Worker }
3985*7c568831SAndroid Build Coastguard Worker }
3986*7c568831SAndroid Build Coastguard Worker if (cur == def)
3987*7c568831SAndroid Build Coastguard Worker break;
3988*7c568831SAndroid Build Coastguard Worker if (cur->next != NULL) {
3989*7c568831SAndroid Build Coastguard Worker cur = cur->next;
3990*7c568831SAndroid Build Coastguard Worker continue;
3991*7c568831SAndroid Build Coastguard Worker }
3992*7c568831SAndroid Build Coastguard Worker do {
3993*7c568831SAndroid Build Coastguard Worker cur = cur->parent;
3994*7c568831SAndroid Build Coastguard Worker if (cur == NULL)
3995*7c568831SAndroid Build Coastguard Worker break;
3996*7c568831SAndroid Build Coastguard Worker if (cur == def)
3997*7c568831SAndroid Build Coastguard Worker return (ret);
3998*7c568831SAndroid Build Coastguard Worker if (cur->next != NULL) {
3999*7c568831SAndroid Build Coastguard Worker cur = cur->next;
4000*7c568831SAndroid Build Coastguard Worker break;
4001*7c568831SAndroid Build Coastguard Worker }
4002*7c568831SAndroid Build Coastguard Worker } while (cur != NULL);
4003*7c568831SAndroid Build Coastguard Worker }
4004*7c568831SAndroid Build Coastguard Worker return (ret);
4005*7c568831SAndroid Build Coastguard Worker }
4006*7c568831SAndroid Build Coastguard Worker
4007*7c568831SAndroid Build Coastguard Worker /**
4008*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGCheckChoiceDeterminism:
4009*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
4010*7c568831SAndroid Build Coastguard Worker * @def: the choice definition
4011*7c568831SAndroid Build Coastguard Worker *
4012*7c568831SAndroid Build Coastguard Worker * Also used to find indeterministic pattern in choice
4013*7c568831SAndroid Build Coastguard Worker */
4014*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGCheckChoiceDeterminism(xmlRelaxNGParserCtxtPtr ctxt,xmlRelaxNGDefinePtr def)4015*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckChoiceDeterminism(xmlRelaxNGParserCtxtPtr ctxt,
4016*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def)
4017*7c568831SAndroid Build Coastguard Worker {
4018*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr **list;
4019*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr cur;
4020*7c568831SAndroid Build Coastguard Worker int nbchild = 0, i, j, ret;
4021*7c568831SAndroid Build Coastguard Worker int is_nullable = 0;
4022*7c568831SAndroid Build Coastguard Worker int is_indeterminist = 0;
4023*7c568831SAndroid Build Coastguard Worker xmlHashTablePtr triage = NULL;
4024*7c568831SAndroid Build Coastguard Worker int is_triable = 1;
4025*7c568831SAndroid Build Coastguard Worker
4026*7c568831SAndroid Build Coastguard Worker if ((def == NULL) || (def->type != XML_RELAXNG_CHOICE))
4027*7c568831SAndroid Build Coastguard Worker return;
4028*7c568831SAndroid Build Coastguard Worker
4029*7c568831SAndroid Build Coastguard Worker if (def->dflags & IS_PROCESSED)
4030*7c568831SAndroid Build Coastguard Worker return;
4031*7c568831SAndroid Build Coastguard Worker
4032*7c568831SAndroid Build Coastguard Worker /*
4033*7c568831SAndroid Build Coastguard Worker * Don't run that check in case of error. Infinite recursion
4034*7c568831SAndroid Build Coastguard Worker * becomes possible.
4035*7c568831SAndroid Build Coastguard Worker */
4036*7c568831SAndroid Build Coastguard Worker if (ctxt->nbErrors != 0)
4037*7c568831SAndroid Build Coastguard Worker return;
4038*7c568831SAndroid Build Coastguard Worker
4039*7c568831SAndroid Build Coastguard Worker is_nullable = xmlRelaxNGIsNullable(def);
4040*7c568831SAndroid Build Coastguard Worker
4041*7c568831SAndroid Build Coastguard Worker cur = def->content;
4042*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
4043*7c568831SAndroid Build Coastguard Worker nbchild++;
4044*7c568831SAndroid Build Coastguard Worker cur = cur->next;
4045*7c568831SAndroid Build Coastguard Worker }
4046*7c568831SAndroid Build Coastguard Worker
4047*7c568831SAndroid Build Coastguard Worker list = (xmlRelaxNGDefinePtr **) xmlMalloc(nbchild *
4048*7c568831SAndroid Build Coastguard Worker sizeof(xmlRelaxNGDefinePtr
4049*7c568831SAndroid Build Coastguard Worker *));
4050*7c568831SAndroid Build Coastguard Worker if (list == NULL) {
4051*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
4052*7c568831SAndroid Build Coastguard Worker return;
4053*7c568831SAndroid Build Coastguard Worker }
4054*7c568831SAndroid Build Coastguard Worker i = 0;
4055*7c568831SAndroid Build Coastguard Worker /*
4056*7c568831SAndroid Build Coastguard Worker * a bit strong but safe
4057*7c568831SAndroid Build Coastguard Worker */
4058*7c568831SAndroid Build Coastguard Worker if (is_nullable == 0) {
4059*7c568831SAndroid Build Coastguard Worker triage = xmlHashCreate(10);
4060*7c568831SAndroid Build Coastguard Worker } else {
4061*7c568831SAndroid Build Coastguard Worker is_triable = 0;
4062*7c568831SAndroid Build Coastguard Worker }
4063*7c568831SAndroid Build Coastguard Worker cur = def->content;
4064*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
4065*7c568831SAndroid Build Coastguard Worker list[i] = xmlRelaxNGGetElements(ctxt, cur, 0);
4066*7c568831SAndroid Build Coastguard Worker if ((list[i] == NULL) || (list[i][0] == NULL)) {
4067*7c568831SAndroid Build Coastguard Worker is_triable = 0;
4068*7c568831SAndroid Build Coastguard Worker } else if (is_triable == 1) {
4069*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr *tmp;
4070*7c568831SAndroid Build Coastguard Worker int res;
4071*7c568831SAndroid Build Coastguard Worker
4072*7c568831SAndroid Build Coastguard Worker tmp = list[i];
4073*7c568831SAndroid Build Coastguard Worker while ((*tmp != NULL) && (is_triable == 1)) {
4074*7c568831SAndroid Build Coastguard Worker if ((*tmp)->type == XML_RELAXNG_TEXT) {
4075*7c568831SAndroid Build Coastguard Worker res = xmlHashAddEntry2(triage,
4076*7c568831SAndroid Build Coastguard Worker BAD_CAST "#text", NULL,
4077*7c568831SAndroid Build Coastguard Worker (void *) cur);
4078*7c568831SAndroid Build Coastguard Worker if (res != 0)
4079*7c568831SAndroid Build Coastguard Worker is_triable = -1;
4080*7c568831SAndroid Build Coastguard Worker } else if (((*tmp)->type == XML_RELAXNG_ELEMENT) &&
4081*7c568831SAndroid Build Coastguard Worker ((*tmp)->name != NULL)) {
4082*7c568831SAndroid Build Coastguard Worker if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
4083*7c568831SAndroid Build Coastguard Worker res = xmlHashAddEntry2(triage,
4084*7c568831SAndroid Build Coastguard Worker (*tmp)->name, NULL,
4085*7c568831SAndroid Build Coastguard Worker (void *) cur);
4086*7c568831SAndroid Build Coastguard Worker else
4087*7c568831SAndroid Build Coastguard Worker res = xmlHashAddEntry2(triage,
4088*7c568831SAndroid Build Coastguard Worker (*tmp)->name, (*tmp)->ns,
4089*7c568831SAndroid Build Coastguard Worker (void *) cur);
4090*7c568831SAndroid Build Coastguard Worker if (res != 0)
4091*7c568831SAndroid Build Coastguard Worker is_triable = -1;
4092*7c568831SAndroid Build Coastguard Worker } else if ((*tmp)->type == XML_RELAXNG_ELEMENT) {
4093*7c568831SAndroid Build Coastguard Worker if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
4094*7c568831SAndroid Build Coastguard Worker res = xmlHashAddEntry2(triage,
4095*7c568831SAndroid Build Coastguard Worker BAD_CAST "#any", NULL,
4096*7c568831SAndroid Build Coastguard Worker (void *) cur);
4097*7c568831SAndroid Build Coastguard Worker else
4098*7c568831SAndroid Build Coastguard Worker res = xmlHashAddEntry2(triage,
4099*7c568831SAndroid Build Coastguard Worker BAD_CAST "#any", (*tmp)->ns,
4100*7c568831SAndroid Build Coastguard Worker (void *) cur);
4101*7c568831SAndroid Build Coastguard Worker if (res != 0)
4102*7c568831SAndroid Build Coastguard Worker is_triable = -1;
4103*7c568831SAndroid Build Coastguard Worker } else {
4104*7c568831SAndroid Build Coastguard Worker is_triable = -1;
4105*7c568831SAndroid Build Coastguard Worker }
4106*7c568831SAndroid Build Coastguard Worker tmp++;
4107*7c568831SAndroid Build Coastguard Worker }
4108*7c568831SAndroid Build Coastguard Worker }
4109*7c568831SAndroid Build Coastguard Worker i++;
4110*7c568831SAndroid Build Coastguard Worker cur = cur->next;
4111*7c568831SAndroid Build Coastguard Worker }
4112*7c568831SAndroid Build Coastguard Worker
4113*7c568831SAndroid Build Coastguard Worker for (i = 0; i < nbchild; i++) {
4114*7c568831SAndroid Build Coastguard Worker if (list[i] == NULL)
4115*7c568831SAndroid Build Coastguard Worker continue;
4116*7c568831SAndroid Build Coastguard Worker for (j = 0; j < i; j++) {
4117*7c568831SAndroid Build Coastguard Worker if (list[j] == NULL)
4118*7c568831SAndroid Build Coastguard Worker continue;
4119*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGCompareElemDefLists(ctxt, list[i], list[j]);
4120*7c568831SAndroid Build Coastguard Worker if (ret == 0) {
4121*7c568831SAndroid Build Coastguard Worker is_indeterminist = 1;
4122*7c568831SAndroid Build Coastguard Worker }
4123*7c568831SAndroid Build Coastguard Worker }
4124*7c568831SAndroid Build Coastguard Worker }
4125*7c568831SAndroid Build Coastguard Worker for (i = 0; i < nbchild; i++) {
4126*7c568831SAndroid Build Coastguard Worker if (list[i] != NULL)
4127*7c568831SAndroid Build Coastguard Worker xmlFree(list[i]);
4128*7c568831SAndroid Build Coastguard Worker }
4129*7c568831SAndroid Build Coastguard Worker
4130*7c568831SAndroid Build Coastguard Worker xmlFree(list);
4131*7c568831SAndroid Build Coastguard Worker if (is_indeterminist) {
4132*7c568831SAndroid Build Coastguard Worker def->dflags |= IS_INDETERMINIST;
4133*7c568831SAndroid Build Coastguard Worker }
4134*7c568831SAndroid Build Coastguard Worker if (is_triable == 1) {
4135*7c568831SAndroid Build Coastguard Worker def->dflags |= IS_TRIABLE;
4136*7c568831SAndroid Build Coastguard Worker def->data = triage;
4137*7c568831SAndroid Build Coastguard Worker } else if (triage != NULL) {
4138*7c568831SAndroid Build Coastguard Worker xmlHashFree(triage, NULL);
4139*7c568831SAndroid Build Coastguard Worker }
4140*7c568831SAndroid Build Coastguard Worker def->dflags |= IS_PROCESSED;
4141*7c568831SAndroid Build Coastguard Worker }
4142*7c568831SAndroid Build Coastguard Worker
4143*7c568831SAndroid Build Coastguard Worker /**
4144*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGCheckGroupAttrs:
4145*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
4146*7c568831SAndroid Build Coastguard Worker * @def: the group definition
4147*7c568831SAndroid Build Coastguard Worker *
4148*7c568831SAndroid Build Coastguard Worker * Detects violations of rule 7.3
4149*7c568831SAndroid Build Coastguard Worker */
4150*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGCheckGroupAttrs(xmlRelaxNGParserCtxtPtr ctxt,xmlRelaxNGDefinePtr def)4151*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckGroupAttrs(xmlRelaxNGParserCtxtPtr ctxt,
4152*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def)
4153*7c568831SAndroid Build Coastguard Worker {
4154*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr **list;
4155*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr cur;
4156*7c568831SAndroid Build Coastguard Worker int nbchild = 0, i, j, ret;
4157*7c568831SAndroid Build Coastguard Worker
4158*7c568831SAndroid Build Coastguard Worker if ((def == NULL) ||
4159*7c568831SAndroid Build Coastguard Worker ((def->type != XML_RELAXNG_GROUP) &&
4160*7c568831SAndroid Build Coastguard Worker (def->type != XML_RELAXNG_ELEMENT)))
4161*7c568831SAndroid Build Coastguard Worker return;
4162*7c568831SAndroid Build Coastguard Worker
4163*7c568831SAndroid Build Coastguard Worker if (def->dflags & IS_PROCESSED)
4164*7c568831SAndroid Build Coastguard Worker return;
4165*7c568831SAndroid Build Coastguard Worker
4166*7c568831SAndroid Build Coastguard Worker /*
4167*7c568831SAndroid Build Coastguard Worker * Don't run that check in case of error. Infinite recursion
4168*7c568831SAndroid Build Coastguard Worker * becomes possible.
4169*7c568831SAndroid Build Coastguard Worker */
4170*7c568831SAndroid Build Coastguard Worker if (ctxt->nbErrors != 0)
4171*7c568831SAndroid Build Coastguard Worker return;
4172*7c568831SAndroid Build Coastguard Worker
4173*7c568831SAndroid Build Coastguard Worker cur = def->attrs;
4174*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
4175*7c568831SAndroid Build Coastguard Worker nbchild++;
4176*7c568831SAndroid Build Coastguard Worker cur = cur->next;
4177*7c568831SAndroid Build Coastguard Worker }
4178*7c568831SAndroid Build Coastguard Worker cur = def->content;
4179*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
4180*7c568831SAndroid Build Coastguard Worker nbchild++;
4181*7c568831SAndroid Build Coastguard Worker cur = cur->next;
4182*7c568831SAndroid Build Coastguard Worker }
4183*7c568831SAndroid Build Coastguard Worker
4184*7c568831SAndroid Build Coastguard Worker list = (xmlRelaxNGDefinePtr **) xmlMalloc(nbchild *
4185*7c568831SAndroid Build Coastguard Worker sizeof(xmlRelaxNGDefinePtr
4186*7c568831SAndroid Build Coastguard Worker *));
4187*7c568831SAndroid Build Coastguard Worker if (list == NULL) {
4188*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
4189*7c568831SAndroid Build Coastguard Worker return;
4190*7c568831SAndroid Build Coastguard Worker }
4191*7c568831SAndroid Build Coastguard Worker i = 0;
4192*7c568831SAndroid Build Coastguard Worker cur = def->attrs;
4193*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
4194*7c568831SAndroid Build Coastguard Worker list[i] = xmlRelaxNGGetElements(ctxt, cur, 1);
4195*7c568831SAndroid Build Coastguard Worker i++;
4196*7c568831SAndroid Build Coastguard Worker cur = cur->next;
4197*7c568831SAndroid Build Coastguard Worker }
4198*7c568831SAndroid Build Coastguard Worker cur = def->content;
4199*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
4200*7c568831SAndroid Build Coastguard Worker list[i] = xmlRelaxNGGetElements(ctxt, cur, 1);
4201*7c568831SAndroid Build Coastguard Worker i++;
4202*7c568831SAndroid Build Coastguard Worker cur = cur->next;
4203*7c568831SAndroid Build Coastguard Worker }
4204*7c568831SAndroid Build Coastguard Worker
4205*7c568831SAndroid Build Coastguard Worker for (i = 0; i < nbchild; i++) {
4206*7c568831SAndroid Build Coastguard Worker if (list[i] == NULL)
4207*7c568831SAndroid Build Coastguard Worker continue;
4208*7c568831SAndroid Build Coastguard Worker for (j = 0; j < i; j++) {
4209*7c568831SAndroid Build Coastguard Worker if (list[j] == NULL)
4210*7c568831SAndroid Build Coastguard Worker continue;
4211*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGCompareElemDefLists(ctxt, list[i], list[j]);
4212*7c568831SAndroid Build Coastguard Worker if (ret == 0) {
4213*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, def->node, XML_RNGP_GROUP_ATTR_CONFLICT,
4214*7c568831SAndroid Build Coastguard Worker "Attributes conflicts in group\n", NULL, NULL);
4215*7c568831SAndroid Build Coastguard Worker }
4216*7c568831SAndroid Build Coastguard Worker }
4217*7c568831SAndroid Build Coastguard Worker }
4218*7c568831SAndroid Build Coastguard Worker for (i = 0; i < nbchild; i++) {
4219*7c568831SAndroid Build Coastguard Worker if (list[i] != NULL)
4220*7c568831SAndroid Build Coastguard Worker xmlFree(list[i]);
4221*7c568831SAndroid Build Coastguard Worker }
4222*7c568831SAndroid Build Coastguard Worker
4223*7c568831SAndroid Build Coastguard Worker xmlFree(list);
4224*7c568831SAndroid Build Coastguard Worker def->dflags |= IS_PROCESSED;
4225*7c568831SAndroid Build Coastguard Worker }
4226*7c568831SAndroid Build Coastguard Worker
4227*7c568831SAndroid Build Coastguard Worker /**
4228*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGComputeInterleaves:
4229*7c568831SAndroid Build Coastguard Worker * @def: the interleave definition
4230*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
4231*7c568831SAndroid Build Coastguard Worker * @name: the definition name
4232*7c568831SAndroid Build Coastguard Worker *
4233*7c568831SAndroid Build Coastguard Worker * A lot of work for preprocessing interleave definitions
4234*7c568831SAndroid Build Coastguard Worker * is potentially needed to get a decent execution speed at runtime
4235*7c568831SAndroid Build Coastguard Worker * - trying to get a total order on the element nodes generated
4236*7c568831SAndroid Build Coastguard Worker * by the interleaves, order the list of interleave definitions
4237*7c568831SAndroid Build Coastguard Worker * following that order.
4238*7c568831SAndroid Build Coastguard Worker * - if <text/> is used to handle mixed content, it is better to
4239*7c568831SAndroid Build Coastguard Worker * flag this in the define and simplify the runtime checking
4240*7c568831SAndroid Build Coastguard Worker * algorithm
4241*7c568831SAndroid Build Coastguard Worker */
4242*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGComputeInterleaves(void * payload,void * data,const xmlChar * name ATTRIBUTE_UNUSED)4243*7c568831SAndroid Build Coastguard Worker xmlRelaxNGComputeInterleaves(void *payload, void *data,
4244*7c568831SAndroid Build Coastguard Worker const xmlChar * name ATTRIBUTE_UNUSED)
4245*7c568831SAndroid Build Coastguard Worker {
4246*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def = (xmlRelaxNGDefinePtr) payload;
4247*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data;
4248*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr cur, *tmp;
4249*7c568831SAndroid Build Coastguard Worker
4250*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPartitionPtr partitions = NULL;
4251*7c568831SAndroid Build Coastguard Worker xmlRelaxNGInterleaveGroupPtr *groups = NULL;
4252*7c568831SAndroid Build Coastguard Worker xmlRelaxNGInterleaveGroupPtr group;
4253*7c568831SAndroid Build Coastguard Worker int i, j, ret, res;
4254*7c568831SAndroid Build Coastguard Worker int nbgroups = 0;
4255*7c568831SAndroid Build Coastguard Worker int nbchild = 0;
4256*7c568831SAndroid Build Coastguard Worker int is_mixed = 0;
4257*7c568831SAndroid Build Coastguard Worker int is_determinist = 1;
4258*7c568831SAndroid Build Coastguard Worker
4259*7c568831SAndroid Build Coastguard Worker /*
4260*7c568831SAndroid Build Coastguard Worker * Don't run that check in case of error. Infinite recursion
4261*7c568831SAndroid Build Coastguard Worker * becomes possible.
4262*7c568831SAndroid Build Coastguard Worker */
4263*7c568831SAndroid Build Coastguard Worker if (ctxt->nbErrors != 0)
4264*7c568831SAndroid Build Coastguard Worker return;
4265*7c568831SAndroid Build Coastguard Worker
4266*7c568831SAndroid Build Coastguard Worker cur = def->content;
4267*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
4268*7c568831SAndroid Build Coastguard Worker nbchild++;
4269*7c568831SAndroid Build Coastguard Worker cur = cur->next;
4270*7c568831SAndroid Build Coastguard Worker }
4271*7c568831SAndroid Build Coastguard Worker
4272*7c568831SAndroid Build Coastguard Worker groups = (xmlRelaxNGInterleaveGroupPtr *)
4273*7c568831SAndroid Build Coastguard Worker xmlMalloc(nbchild * sizeof(xmlRelaxNGInterleaveGroupPtr));
4274*7c568831SAndroid Build Coastguard Worker if (groups == NULL)
4275*7c568831SAndroid Build Coastguard Worker goto error;
4276*7c568831SAndroid Build Coastguard Worker cur = def->content;
4277*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
4278*7c568831SAndroid Build Coastguard Worker groups[nbgroups] = (xmlRelaxNGInterleaveGroupPtr)
4279*7c568831SAndroid Build Coastguard Worker xmlMalloc(sizeof(xmlRelaxNGInterleaveGroup));
4280*7c568831SAndroid Build Coastguard Worker if (groups[nbgroups] == NULL)
4281*7c568831SAndroid Build Coastguard Worker goto error;
4282*7c568831SAndroid Build Coastguard Worker if (cur->type == XML_RELAXNG_TEXT)
4283*7c568831SAndroid Build Coastguard Worker is_mixed++;
4284*7c568831SAndroid Build Coastguard Worker groups[nbgroups]->rule = cur;
4285*7c568831SAndroid Build Coastguard Worker groups[nbgroups]->defs = xmlRelaxNGGetElements(ctxt, cur, 2);
4286*7c568831SAndroid Build Coastguard Worker groups[nbgroups]->attrs = xmlRelaxNGGetElements(ctxt, cur, 1);
4287*7c568831SAndroid Build Coastguard Worker nbgroups++;
4288*7c568831SAndroid Build Coastguard Worker cur = cur->next;
4289*7c568831SAndroid Build Coastguard Worker }
4290*7c568831SAndroid Build Coastguard Worker
4291*7c568831SAndroid Build Coastguard Worker /*
4292*7c568831SAndroid Build Coastguard Worker * Let's check that all rules makes a partitions according to 7.4
4293*7c568831SAndroid Build Coastguard Worker */
4294*7c568831SAndroid Build Coastguard Worker partitions = (xmlRelaxNGPartitionPtr)
4295*7c568831SAndroid Build Coastguard Worker xmlMalloc(sizeof(xmlRelaxNGPartition));
4296*7c568831SAndroid Build Coastguard Worker if (partitions == NULL)
4297*7c568831SAndroid Build Coastguard Worker goto error;
4298*7c568831SAndroid Build Coastguard Worker memset(partitions, 0, sizeof(xmlRelaxNGPartition));
4299*7c568831SAndroid Build Coastguard Worker partitions->nbgroups = nbgroups;
4300*7c568831SAndroid Build Coastguard Worker partitions->triage = xmlHashCreate(nbgroups);
4301*7c568831SAndroid Build Coastguard Worker for (i = 0; i < nbgroups; i++) {
4302*7c568831SAndroid Build Coastguard Worker group = groups[i];
4303*7c568831SAndroid Build Coastguard Worker for (j = i + 1; j < nbgroups; j++) {
4304*7c568831SAndroid Build Coastguard Worker if (groups[j] == NULL)
4305*7c568831SAndroid Build Coastguard Worker continue;
4306*7c568831SAndroid Build Coastguard Worker
4307*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGCompareElemDefLists(ctxt, group->defs,
4308*7c568831SAndroid Build Coastguard Worker groups[j]->defs);
4309*7c568831SAndroid Build Coastguard Worker if (ret == 0) {
4310*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, def->node, XML_RNGP_ELEM_TEXT_CONFLICT,
4311*7c568831SAndroid Build Coastguard Worker "Element or text conflicts in interleave\n",
4312*7c568831SAndroid Build Coastguard Worker NULL, NULL);
4313*7c568831SAndroid Build Coastguard Worker }
4314*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGCompareElemDefLists(ctxt, group->attrs,
4315*7c568831SAndroid Build Coastguard Worker groups[j]->attrs);
4316*7c568831SAndroid Build Coastguard Worker if (ret == 0) {
4317*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, def->node, XML_RNGP_ATTR_CONFLICT,
4318*7c568831SAndroid Build Coastguard Worker "Attributes conflicts in interleave\n", NULL,
4319*7c568831SAndroid Build Coastguard Worker NULL);
4320*7c568831SAndroid Build Coastguard Worker }
4321*7c568831SAndroid Build Coastguard Worker }
4322*7c568831SAndroid Build Coastguard Worker tmp = group->defs;
4323*7c568831SAndroid Build Coastguard Worker if ((tmp != NULL) && (*tmp != NULL)) {
4324*7c568831SAndroid Build Coastguard Worker while (*tmp != NULL) {
4325*7c568831SAndroid Build Coastguard Worker if ((*tmp)->type == XML_RELAXNG_TEXT) {
4326*7c568831SAndroid Build Coastguard Worker res = xmlHashAddEntry2(partitions->triage,
4327*7c568831SAndroid Build Coastguard Worker BAD_CAST "#text", NULL,
4328*7c568831SAndroid Build Coastguard Worker (void *) (ptrdiff_t) (i + 1));
4329*7c568831SAndroid Build Coastguard Worker if (res != 0)
4330*7c568831SAndroid Build Coastguard Worker is_determinist = -1;
4331*7c568831SAndroid Build Coastguard Worker } else if (((*tmp)->type == XML_RELAXNG_ELEMENT) &&
4332*7c568831SAndroid Build Coastguard Worker ((*tmp)->name != NULL)) {
4333*7c568831SAndroid Build Coastguard Worker if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
4334*7c568831SAndroid Build Coastguard Worker res = xmlHashAddEntry2(partitions->triage,
4335*7c568831SAndroid Build Coastguard Worker (*tmp)->name, NULL,
4336*7c568831SAndroid Build Coastguard Worker (void *) (ptrdiff_t) (i + 1));
4337*7c568831SAndroid Build Coastguard Worker else
4338*7c568831SAndroid Build Coastguard Worker res = xmlHashAddEntry2(partitions->triage,
4339*7c568831SAndroid Build Coastguard Worker (*tmp)->name, (*tmp)->ns,
4340*7c568831SAndroid Build Coastguard Worker (void *) (ptrdiff_t) (i + 1));
4341*7c568831SAndroid Build Coastguard Worker if (res != 0)
4342*7c568831SAndroid Build Coastguard Worker is_determinist = -1;
4343*7c568831SAndroid Build Coastguard Worker } else if ((*tmp)->type == XML_RELAXNG_ELEMENT) {
4344*7c568831SAndroid Build Coastguard Worker if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
4345*7c568831SAndroid Build Coastguard Worker res = xmlHashAddEntry2(partitions->triage,
4346*7c568831SAndroid Build Coastguard Worker BAD_CAST "#any", NULL,
4347*7c568831SAndroid Build Coastguard Worker (void *) (ptrdiff_t) (i + 1));
4348*7c568831SAndroid Build Coastguard Worker else
4349*7c568831SAndroid Build Coastguard Worker res = xmlHashAddEntry2(partitions->triage,
4350*7c568831SAndroid Build Coastguard Worker BAD_CAST "#any", (*tmp)->ns,
4351*7c568831SAndroid Build Coastguard Worker (void *) (ptrdiff_t) (i + 1));
4352*7c568831SAndroid Build Coastguard Worker if ((*tmp)->nameClass != NULL)
4353*7c568831SAndroid Build Coastguard Worker is_determinist = 2;
4354*7c568831SAndroid Build Coastguard Worker if (res != 0)
4355*7c568831SAndroid Build Coastguard Worker is_determinist = -1;
4356*7c568831SAndroid Build Coastguard Worker } else {
4357*7c568831SAndroid Build Coastguard Worker is_determinist = -1;
4358*7c568831SAndroid Build Coastguard Worker }
4359*7c568831SAndroid Build Coastguard Worker tmp++;
4360*7c568831SAndroid Build Coastguard Worker }
4361*7c568831SAndroid Build Coastguard Worker } else {
4362*7c568831SAndroid Build Coastguard Worker is_determinist = 0;
4363*7c568831SAndroid Build Coastguard Worker }
4364*7c568831SAndroid Build Coastguard Worker }
4365*7c568831SAndroid Build Coastguard Worker partitions->groups = groups;
4366*7c568831SAndroid Build Coastguard Worker
4367*7c568831SAndroid Build Coastguard Worker /*
4368*7c568831SAndroid Build Coastguard Worker * and save the partition list back in the def
4369*7c568831SAndroid Build Coastguard Worker */
4370*7c568831SAndroid Build Coastguard Worker def->data = partitions;
4371*7c568831SAndroid Build Coastguard Worker if (is_mixed != 0)
4372*7c568831SAndroid Build Coastguard Worker def->dflags |= IS_MIXED;
4373*7c568831SAndroid Build Coastguard Worker if (is_determinist == 1)
4374*7c568831SAndroid Build Coastguard Worker partitions->flags = IS_DETERMINIST;
4375*7c568831SAndroid Build Coastguard Worker if (is_determinist == 2)
4376*7c568831SAndroid Build Coastguard Worker partitions->flags = IS_DETERMINIST | IS_NEEDCHECK;
4377*7c568831SAndroid Build Coastguard Worker return;
4378*7c568831SAndroid Build Coastguard Worker
4379*7c568831SAndroid Build Coastguard Worker error:
4380*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
4381*7c568831SAndroid Build Coastguard Worker if (groups != NULL) {
4382*7c568831SAndroid Build Coastguard Worker for (i = 0; i < nbgroups; i++)
4383*7c568831SAndroid Build Coastguard Worker if (groups[i] != NULL) {
4384*7c568831SAndroid Build Coastguard Worker if (groups[i]->defs != NULL)
4385*7c568831SAndroid Build Coastguard Worker xmlFree(groups[i]->defs);
4386*7c568831SAndroid Build Coastguard Worker xmlFree(groups[i]);
4387*7c568831SAndroid Build Coastguard Worker }
4388*7c568831SAndroid Build Coastguard Worker xmlFree(groups);
4389*7c568831SAndroid Build Coastguard Worker }
4390*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreePartition(partitions);
4391*7c568831SAndroid Build Coastguard Worker }
4392*7c568831SAndroid Build Coastguard Worker
4393*7c568831SAndroid Build Coastguard Worker /**
4394*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParseInterleave:
4395*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
4396*7c568831SAndroid Build Coastguard Worker * @node: the data node.
4397*7c568831SAndroid Build Coastguard Worker *
4398*7c568831SAndroid Build Coastguard Worker * parse the content of a RelaxNG interleave node.
4399*7c568831SAndroid Build Coastguard Worker *
4400*7c568831SAndroid Build Coastguard Worker * Returns the definition pointer or NULL in case of error
4401*7c568831SAndroid Build Coastguard Worker */
4402*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr
xmlRelaxNGParseInterleave(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr node)4403*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseInterleave(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
4404*7c568831SAndroid Build Coastguard Worker {
4405*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def = NULL;
4406*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr last = NULL, cur;
4407*7c568831SAndroid Build Coastguard Worker xmlNodePtr child;
4408*7c568831SAndroid Build Coastguard Worker
4409*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, node);
4410*7c568831SAndroid Build Coastguard Worker if (def == NULL) {
4411*7c568831SAndroid Build Coastguard Worker return (NULL);
4412*7c568831SAndroid Build Coastguard Worker }
4413*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_INTERLEAVE;
4414*7c568831SAndroid Build Coastguard Worker
4415*7c568831SAndroid Build Coastguard Worker if (ctxt->interleaves == NULL)
4416*7c568831SAndroid Build Coastguard Worker ctxt->interleaves = xmlHashCreate(10);
4417*7c568831SAndroid Build Coastguard Worker if (ctxt->interleaves == NULL) {
4418*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(ctxt);
4419*7c568831SAndroid Build Coastguard Worker } else {
4420*7c568831SAndroid Build Coastguard Worker char name[32];
4421*7c568831SAndroid Build Coastguard Worker
4422*7c568831SAndroid Build Coastguard Worker snprintf(name, 32, "interleave%d", ctxt->nbInterleaves++);
4423*7c568831SAndroid Build Coastguard Worker if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST name, def) < 0) {
4424*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_INTERLEAVE_ADD,
4425*7c568831SAndroid Build Coastguard Worker "Failed to add %s to hash table\n",
4426*7c568831SAndroid Build Coastguard Worker (const xmlChar *) name, NULL);
4427*7c568831SAndroid Build Coastguard Worker }
4428*7c568831SAndroid Build Coastguard Worker }
4429*7c568831SAndroid Build Coastguard Worker child = node->children;
4430*7c568831SAndroid Build Coastguard Worker if (child == NULL) {
4431*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_INTERLEAVE_NO_CONTENT,
4432*7c568831SAndroid Build Coastguard Worker "Element interleave is empty\n", NULL, NULL);
4433*7c568831SAndroid Build Coastguard Worker }
4434*7c568831SAndroid Build Coastguard Worker while (child != NULL) {
4435*7c568831SAndroid Build Coastguard Worker if (IS_RELAXNG(child, "element")) {
4436*7c568831SAndroid Build Coastguard Worker cur = xmlRelaxNGParseElement(ctxt, child);
4437*7c568831SAndroid Build Coastguard Worker } else {
4438*7c568831SAndroid Build Coastguard Worker cur = xmlRelaxNGParsePattern(ctxt, child);
4439*7c568831SAndroid Build Coastguard Worker }
4440*7c568831SAndroid Build Coastguard Worker if (cur != NULL) {
4441*7c568831SAndroid Build Coastguard Worker cur->parent = def;
4442*7c568831SAndroid Build Coastguard Worker if (last == NULL) {
4443*7c568831SAndroid Build Coastguard Worker def->content = last = cur;
4444*7c568831SAndroid Build Coastguard Worker } else {
4445*7c568831SAndroid Build Coastguard Worker last->next = cur;
4446*7c568831SAndroid Build Coastguard Worker last = cur;
4447*7c568831SAndroid Build Coastguard Worker }
4448*7c568831SAndroid Build Coastguard Worker }
4449*7c568831SAndroid Build Coastguard Worker child = child->next;
4450*7c568831SAndroid Build Coastguard Worker }
4451*7c568831SAndroid Build Coastguard Worker
4452*7c568831SAndroid Build Coastguard Worker return (def);
4453*7c568831SAndroid Build Coastguard Worker }
4454*7c568831SAndroid Build Coastguard Worker
4455*7c568831SAndroid Build Coastguard Worker /**
4456*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParseInclude:
4457*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
4458*7c568831SAndroid Build Coastguard Worker * @node: the include node
4459*7c568831SAndroid Build Coastguard Worker *
4460*7c568831SAndroid Build Coastguard Worker * Integrate the content of an include node in the current grammar
4461*7c568831SAndroid Build Coastguard Worker *
4462*7c568831SAndroid Build Coastguard Worker * Returns 0 in case of success or -1 in case of error
4463*7c568831SAndroid Build Coastguard Worker */
4464*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGParseInclude(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr node)4465*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseInclude(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
4466*7c568831SAndroid Build Coastguard Worker {
4467*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIncludePtr incl;
4468*7c568831SAndroid Build Coastguard Worker xmlNodePtr root;
4469*7c568831SAndroid Build Coastguard Worker int ret = 0, tmp;
4470*7c568831SAndroid Build Coastguard Worker
4471*7c568831SAndroid Build Coastguard Worker incl = node->psvi;
4472*7c568831SAndroid Build Coastguard Worker if (incl == NULL) {
4473*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_INCLUDE_EMPTY,
4474*7c568831SAndroid Build Coastguard Worker "Include node has no data\n", NULL, NULL);
4475*7c568831SAndroid Build Coastguard Worker return (-1);
4476*7c568831SAndroid Build Coastguard Worker }
4477*7c568831SAndroid Build Coastguard Worker root = xmlDocGetRootElement(incl->doc);
4478*7c568831SAndroid Build Coastguard Worker if (root == NULL) {
4479*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_EMPTY, "Include document is empty\n",
4480*7c568831SAndroid Build Coastguard Worker NULL, NULL);
4481*7c568831SAndroid Build Coastguard Worker return (-1);
4482*7c568831SAndroid Build Coastguard Worker }
4483*7c568831SAndroid Build Coastguard Worker if (!xmlStrEqual(root->name, BAD_CAST "grammar")) {
4484*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_GRAMMAR_MISSING,
4485*7c568831SAndroid Build Coastguard Worker "Include document root is not a grammar\n", NULL, NULL);
4486*7c568831SAndroid Build Coastguard Worker return (-1);
4487*7c568831SAndroid Build Coastguard Worker }
4488*7c568831SAndroid Build Coastguard Worker
4489*7c568831SAndroid Build Coastguard Worker /*
4490*7c568831SAndroid Build Coastguard Worker * Merge the definition from both the include and the internal list
4491*7c568831SAndroid Build Coastguard Worker */
4492*7c568831SAndroid Build Coastguard Worker if (root->children != NULL) {
4493*7c568831SAndroid Build Coastguard Worker tmp = xmlRelaxNGParseGrammarContent(ctxt, root->children);
4494*7c568831SAndroid Build Coastguard Worker if (tmp != 0)
4495*7c568831SAndroid Build Coastguard Worker ret = -1;
4496*7c568831SAndroid Build Coastguard Worker }
4497*7c568831SAndroid Build Coastguard Worker if (node->children != NULL) {
4498*7c568831SAndroid Build Coastguard Worker tmp = xmlRelaxNGParseGrammarContent(ctxt, node->children);
4499*7c568831SAndroid Build Coastguard Worker if (tmp != 0)
4500*7c568831SAndroid Build Coastguard Worker ret = -1;
4501*7c568831SAndroid Build Coastguard Worker }
4502*7c568831SAndroid Build Coastguard Worker return (ret);
4503*7c568831SAndroid Build Coastguard Worker }
4504*7c568831SAndroid Build Coastguard Worker
4505*7c568831SAndroid Build Coastguard Worker /**
4506*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParseDefine:
4507*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
4508*7c568831SAndroid Build Coastguard Worker * @node: the define node
4509*7c568831SAndroid Build Coastguard Worker *
4510*7c568831SAndroid Build Coastguard Worker * parse the content of a RelaxNG define element node.
4511*7c568831SAndroid Build Coastguard Worker *
4512*7c568831SAndroid Build Coastguard Worker * Returns 0 in case of success or -1 in case of error
4513*7c568831SAndroid Build Coastguard Worker */
4514*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGParseDefine(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr node)4515*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseDefine(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
4516*7c568831SAndroid Build Coastguard Worker {
4517*7c568831SAndroid Build Coastguard Worker xmlChar *name;
4518*7c568831SAndroid Build Coastguard Worker int ret = 0, tmp;
4519*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def;
4520*7c568831SAndroid Build Coastguard Worker const xmlChar *olddefine;
4521*7c568831SAndroid Build Coastguard Worker
4522*7c568831SAndroid Build Coastguard Worker name = xmlGetProp(node, BAD_CAST "name");
4523*7c568831SAndroid Build Coastguard Worker if (name == NULL) {
4524*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_NAME_MISSING,
4525*7c568831SAndroid Build Coastguard Worker "define has no name\n", NULL, NULL);
4526*7c568831SAndroid Build Coastguard Worker } else {
4527*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNormExtSpace(name);
4528*7c568831SAndroid Build Coastguard Worker if (xmlValidateNCName(name, 0)) {
4529*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_INVALID_DEFINE_NAME,
4530*7c568831SAndroid Build Coastguard Worker "define name '%s' is not an NCName\n", name, NULL);
4531*7c568831SAndroid Build Coastguard Worker }
4532*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, node);
4533*7c568831SAndroid Build Coastguard Worker if (def == NULL) {
4534*7c568831SAndroid Build Coastguard Worker xmlFree(name);
4535*7c568831SAndroid Build Coastguard Worker return (-1);
4536*7c568831SAndroid Build Coastguard Worker }
4537*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_DEF;
4538*7c568831SAndroid Build Coastguard Worker def->name = name;
4539*7c568831SAndroid Build Coastguard Worker if (node->children == NULL) {
4540*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_EMPTY,
4541*7c568831SAndroid Build Coastguard Worker "define has no children\n", NULL, NULL);
4542*7c568831SAndroid Build Coastguard Worker } else {
4543*7c568831SAndroid Build Coastguard Worker olddefine = ctxt->define;
4544*7c568831SAndroid Build Coastguard Worker ctxt->define = name;
4545*7c568831SAndroid Build Coastguard Worker def->content =
4546*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParsePatterns(ctxt, node->children, 0);
4547*7c568831SAndroid Build Coastguard Worker ctxt->define = olddefine;
4548*7c568831SAndroid Build Coastguard Worker }
4549*7c568831SAndroid Build Coastguard Worker if (ctxt->grammar->defs == NULL)
4550*7c568831SAndroid Build Coastguard Worker ctxt->grammar->defs = xmlHashCreate(10);
4551*7c568831SAndroid Build Coastguard Worker if (ctxt->grammar->defs == NULL) {
4552*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_CREATE_FAILED,
4553*7c568831SAndroid Build Coastguard Worker "Could not create definition hash\n", NULL, NULL);
4554*7c568831SAndroid Build Coastguard Worker ret = -1;
4555*7c568831SAndroid Build Coastguard Worker } else {
4556*7c568831SAndroid Build Coastguard Worker tmp = xmlHashAddEntry(ctxt->grammar->defs, name, def);
4557*7c568831SAndroid Build Coastguard Worker if (tmp < 0) {
4558*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr prev;
4559*7c568831SAndroid Build Coastguard Worker
4560*7c568831SAndroid Build Coastguard Worker prev = xmlHashLookup(ctxt->grammar->defs, name);
4561*7c568831SAndroid Build Coastguard Worker if (prev == NULL) {
4562*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_CREATE_FAILED,
4563*7c568831SAndroid Build Coastguard Worker "Internal error on define aggregation of %s\n",
4564*7c568831SAndroid Build Coastguard Worker name, NULL);
4565*7c568831SAndroid Build Coastguard Worker ret = -1;
4566*7c568831SAndroid Build Coastguard Worker } else {
4567*7c568831SAndroid Build Coastguard Worker while (prev->nextHash != NULL)
4568*7c568831SAndroid Build Coastguard Worker prev = prev->nextHash;
4569*7c568831SAndroid Build Coastguard Worker prev->nextHash = def;
4570*7c568831SAndroid Build Coastguard Worker }
4571*7c568831SAndroid Build Coastguard Worker }
4572*7c568831SAndroid Build Coastguard Worker }
4573*7c568831SAndroid Build Coastguard Worker }
4574*7c568831SAndroid Build Coastguard Worker return (ret);
4575*7c568831SAndroid Build Coastguard Worker }
4576*7c568831SAndroid Build Coastguard Worker
4577*7c568831SAndroid Build Coastguard Worker /**
4578*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParseImportRef:
4579*7c568831SAndroid Build Coastguard Worker * @payload: the parser context
4580*7c568831SAndroid Build Coastguard Worker * @data: the current grammar
4581*7c568831SAndroid Build Coastguard Worker * @name: the reference name
4582*7c568831SAndroid Build Coastguard Worker *
4583*7c568831SAndroid Build Coastguard Worker * Import import one references into the current grammar
4584*7c568831SAndroid Build Coastguard Worker */
4585*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGParseImportRef(void * payload,void * data,const xmlChar * name)4586*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseImportRef(void *payload, void *data, const xmlChar *name) {
4587*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data;
4588*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def = (xmlRelaxNGDefinePtr) payload;
4589*7c568831SAndroid Build Coastguard Worker int tmp;
4590*7c568831SAndroid Build Coastguard Worker
4591*7c568831SAndroid Build Coastguard Worker def->dflags |= IS_EXTERNAL_REF;
4592*7c568831SAndroid Build Coastguard Worker
4593*7c568831SAndroid Build Coastguard Worker tmp = xmlHashAddEntry(ctxt->grammar->refs, name, def);
4594*7c568831SAndroid Build Coastguard Worker if (tmp < 0) {
4595*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr prev;
4596*7c568831SAndroid Build Coastguard Worker
4597*7c568831SAndroid Build Coastguard Worker prev = (xmlRelaxNGDefinePtr)
4598*7c568831SAndroid Build Coastguard Worker xmlHashLookup(ctxt->grammar->refs, def->name);
4599*7c568831SAndroid Build Coastguard Worker if (prev == NULL) {
4600*7c568831SAndroid Build Coastguard Worker if (def->name != NULL) {
4601*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
4602*7c568831SAndroid Build Coastguard Worker "Error refs definitions '%s'\n",
4603*7c568831SAndroid Build Coastguard Worker def->name, NULL);
4604*7c568831SAndroid Build Coastguard Worker } else {
4605*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
4606*7c568831SAndroid Build Coastguard Worker "Error refs definitions\n",
4607*7c568831SAndroid Build Coastguard Worker NULL, NULL);
4608*7c568831SAndroid Build Coastguard Worker }
4609*7c568831SAndroid Build Coastguard Worker } else {
4610*7c568831SAndroid Build Coastguard Worker def->nextHash = prev->nextHash;
4611*7c568831SAndroid Build Coastguard Worker prev->nextHash = def;
4612*7c568831SAndroid Build Coastguard Worker }
4613*7c568831SAndroid Build Coastguard Worker }
4614*7c568831SAndroid Build Coastguard Worker }
4615*7c568831SAndroid Build Coastguard Worker
4616*7c568831SAndroid Build Coastguard Worker /**
4617*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParseImportRefs:
4618*7c568831SAndroid Build Coastguard Worker * @ctxt: the parser context
4619*7c568831SAndroid Build Coastguard Worker * @grammar: the sub grammar
4620*7c568831SAndroid Build Coastguard Worker *
4621*7c568831SAndroid Build Coastguard Worker * Import references from the subgrammar into the current grammar
4622*7c568831SAndroid Build Coastguard Worker *
4623*7c568831SAndroid Build Coastguard Worker * Returns 0 in case of success, -1 in case of failure
4624*7c568831SAndroid Build Coastguard Worker */
4625*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGParseImportRefs(xmlRelaxNGParserCtxtPtr ctxt,xmlRelaxNGGrammarPtr grammar)4626*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseImportRefs(xmlRelaxNGParserCtxtPtr ctxt,
4627*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGrammarPtr grammar) {
4628*7c568831SAndroid Build Coastguard Worker if ((ctxt == NULL) || (grammar == NULL) || (ctxt->grammar == NULL))
4629*7c568831SAndroid Build Coastguard Worker return(-1);
4630*7c568831SAndroid Build Coastguard Worker if (grammar->refs == NULL)
4631*7c568831SAndroid Build Coastguard Worker return(0);
4632*7c568831SAndroid Build Coastguard Worker if (ctxt->grammar->refs == NULL)
4633*7c568831SAndroid Build Coastguard Worker ctxt->grammar->refs = xmlHashCreate(10);
4634*7c568831SAndroid Build Coastguard Worker if (ctxt->grammar->refs == NULL) {
4635*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
4636*7c568831SAndroid Build Coastguard Worker "Could not create references hash\n", NULL, NULL);
4637*7c568831SAndroid Build Coastguard Worker return(-1);
4638*7c568831SAndroid Build Coastguard Worker }
4639*7c568831SAndroid Build Coastguard Worker xmlHashScan(grammar->refs, xmlRelaxNGParseImportRef, ctxt);
4640*7c568831SAndroid Build Coastguard Worker return(0);
4641*7c568831SAndroid Build Coastguard Worker }
4642*7c568831SAndroid Build Coastguard Worker
4643*7c568831SAndroid Build Coastguard Worker /**
4644*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGProcessExternalRef:
4645*7c568831SAndroid Build Coastguard Worker * @ctxt: the parser context
4646*7c568831SAndroid Build Coastguard Worker * @node: the externalRef node
4647*7c568831SAndroid Build Coastguard Worker *
4648*7c568831SAndroid Build Coastguard Worker * Process and compile an externalRef node
4649*7c568831SAndroid Build Coastguard Worker *
4650*7c568831SAndroid Build Coastguard Worker * Returns the xmlRelaxNGDefinePtr or NULL in case of error
4651*7c568831SAndroid Build Coastguard Worker */
4652*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr
xmlRelaxNGProcessExternalRef(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr node)4653*7c568831SAndroid Build Coastguard Worker xmlRelaxNGProcessExternalRef(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
4654*7c568831SAndroid Build Coastguard Worker {
4655*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDocumentPtr docu;
4656*7c568831SAndroid Build Coastguard Worker xmlNodePtr root, tmp;
4657*7c568831SAndroid Build Coastguard Worker xmlChar *ns;
4658*7c568831SAndroid Build Coastguard Worker int newNs = 0, oldflags;
4659*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def;
4660*7c568831SAndroid Build Coastguard Worker
4661*7c568831SAndroid Build Coastguard Worker docu = node->psvi;
4662*7c568831SAndroid Build Coastguard Worker if (docu != NULL) {
4663*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, node);
4664*7c568831SAndroid Build Coastguard Worker if (def == NULL)
4665*7c568831SAndroid Build Coastguard Worker return (NULL);
4666*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_EXTERNALREF;
4667*7c568831SAndroid Build Coastguard Worker
4668*7c568831SAndroid Build Coastguard Worker if (docu->content == NULL) {
4669*7c568831SAndroid Build Coastguard Worker /*
4670*7c568831SAndroid Build Coastguard Worker * Then do the parsing for good
4671*7c568831SAndroid Build Coastguard Worker */
4672*7c568831SAndroid Build Coastguard Worker root = xmlDocGetRootElement(docu->doc);
4673*7c568831SAndroid Build Coastguard Worker if (root == NULL) {
4674*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_EXTERNALREF_EMTPY,
4675*7c568831SAndroid Build Coastguard Worker "xmlRelaxNGParse: %s is empty\n", ctxt->URL,
4676*7c568831SAndroid Build Coastguard Worker NULL);
4677*7c568831SAndroid Build Coastguard Worker return (NULL);
4678*7c568831SAndroid Build Coastguard Worker }
4679*7c568831SAndroid Build Coastguard Worker /*
4680*7c568831SAndroid Build Coastguard Worker * ns transmission rules
4681*7c568831SAndroid Build Coastguard Worker */
4682*7c568831SAndroid Build Coastguard Worker ns = xmlGetProp(root, BAD_CAST "ns");
4683*7c568831SAndroid Build Coastguard Worker if (ns == NULL) {
4684*7c568831SAndroid Build Coastguard Worker tmp = node;
4685*7c568831SAndroid Build Coastguard Worker while ((tmp != NULL) && (tmp->type == XML_ELEMENT_NODE)) {
4686*7c568831SAndroid Build Coastguard Worker ns = xmlGetProp(tmp, BAD_CAST "ns");
4687*7c568831SAndroid Build Coastguard Worker if (ns != NULL) {
4688*7c568831SAndroid Build Coastguard Worker break;
4689*7c568831SAndroid Build Coastguard Worker }
4690*7c568831SAndroid Build Coastguard Worker tmp = tmp->parent;
4691*7c568831SAndroid Build Coastguard Worker }
4692*7c568831SAndroid Build Coastguard Worker if (ns != NULL) {
4693*7c568831SAndroid Build Coastguard Worker xmlSetProp(root, BAD_CAST "ns", ns);
4694*7c568831SAndroid Build Coastguard Worker newNs = 1;
4695*7c568831SAndroid Build Coastguard Worker xmlFree(ns);
4696*7c568831SAndroid Build Coastguard Worker }
4697*7c568831SAndroid Build Coastguard Worker } else {
4698*7c568831SAndroid Build Coastguard Worker xmlFree(ns);
4699*7c568831SAndroid Build Coastguard Worker }
4700*7c568831SAndroid Build Coastguard Worker
4701*7c568831SAndroid Build Coastguard Worker /*
4702*7c568831SAndroid Build Coastguard Worker * Parsing to get a precompiled schemas.
4703*7c568831SAndroid Build Coastguard Worker */
4704*7c568831SAndroid Build Coastguard Worker oldflags = ctxt->flags;
4705*7c568831SAndroid Build Coastguard Worker ctxt->flags |= XML_RELAXNG_IN_EXTERNALREF;
4706*7c568831SAndroid Build Coastguard Worker docu->schema = xmlRelaxNGParseDocument(ctxt, root);
4707*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
4708*7c568831SAndroid Build Coastguard Worker if ((docu->schema != NULL) &&
4709*7c568831SAndroid Build Coastguard Worker (docu->schema->topgrammar != NULL)) {
4710*7c568831SAndroid Build Coastguard Worker docu->content = docu->schema->topgrammar->start;
4711*7c568831SAndroid Build Coastguard Worker if (docu->schema->topgrammar->refs)
4712*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseImportRefs(ctxt, docu->schema->topgrammar);
4713*7c568831SAndroid Build Coastguard Worker }
4714*7c568831SAndroid Build Coastguard Worker
4715*7c568831SAndroid Build Coastguard Worker /*
4716*7c568831SAndroid Build Coastguard Worker * the externalRef may be reused in a different ns context
4717*7c568831SAndroid Build Coastguard Worker */
4718*7c568831SAndroid Build Coastguard Worker if (newNs == 1) {
4719*7c568831SAndroid Build Coastguard Worker xmlUnsetProp(root, BAD_CAST "ns");
4720*7c568831SAndroid Build Coastguard Worker }
4721*7c568831SAndroid Build Coastguard Worker }
4722*7c568831SAndroid Build Coastguard Worker def->content = docu->content;
4723*7c568831SAndroid Build Coastguard Worker } else {
4724*7c568831SAndroid Build Coastguard Worker def = NULL;
4725*7c568831SAndroid Build Coastguard Worker }
4726*7c568831SAndroid Build Coastguard Worker return (def);
4727*7c568831SAndroid Build Coastguard Worker }
4728*7c568831SAndroid Build Coastguard Worker
4729*7c568831SAndroid Build Coastguard Worker /**
4730*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParsePattern:
4731*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
4732*7c568831SAndroid Build Coastguard Worker * @node: the pattern node.
4733*7c568831SAndroid Build Coastguard Worker *
4734*7c568831SAndroid Build Coastguard Worker * parse the content of a RelaxNG pattern node.
4735*7c568831SAndroid Build Coastguard Worker *
4736*7c568831SAndroid Build Coastguard Worker * Returns the definition pointer or NULL in case of error or if no
4737*7c568831SAndroid Build Coastguard Worker * pattern is generated.
4738*7c568831SAndroid Build Coastguard Worker */
4739*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr
xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr node)4740*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
4741*7c568831SAndroid Build Coastguard Worker {
4742*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def = NULL;
4743*7c568831SAndroid Build Coastguard Worker
4744*7c568831SAndroid Build Coastguard Worker if (node == NULL) {
4745*7c568831SAndroid Build Coastguard Worker return (NULL);
4746*7c568831SAndroid Build Coastguard Worker }
4747*7c568831SAndroid Build Coastguard Worker if (IS_RELAXNG(node, "element")) {
4748*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGParseElement(ctxt, node);
4749*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "attribute")) {
4750*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGParseAttribute(ctxt, node);
4751*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "empty")) {
4752*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, node);
4753*7c568831SAndroid Build Coastguard Worker if (def == NULL)
4754*7c568831SAndroid Build Coastguard Worker return (NULL);
4755*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_EMPTY;
4756*7c568831SAndroid Build Coastguard Worker if (node->children != NULL) {
4757*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_NOT_EMPTY,
4758*7c568831SAndroid Build Coastguard Worker "empty: had a child node\n", NULL, NULL);
4759*7c568831SAndroid Build Coastguard Worker }
4760*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "text")) {
4761*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, node);
4762*7c568831SAndroid Build Coastguard Worker if (def == NULL)
4763*7c568831SAndroid Build Coastguard Worker return (NULL);
4764*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_TEXT;
4765*7c568831SAndroid Build Coastguard Worker if (node->children != NULL) {
4766*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_TEXT_HAS_CHILD,
4767*7c568831SAndroid Build Coastguard Worker "text: had a child node\n", NULL, NULL);
4768*7c568831SAndroid Build Coastguard Worker }
4769*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "zeroOrMore")) {
4770*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, node);
4771*7c568831SAndroid Build Coastguard Worker if (def == NULL)
4772*7c568831SAndroid Build Coastguard Worker return (NULL);
4773*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_ZEROORMORE;
4774*7c568831SAndroid Build Coastguard Worker if (node->children == NULL) {
4775*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
4776*7c568831SAndroid Build Coastguard Worker "Element %s is empty\n", node->name, NULL);
4777*7c568831SAndroid Build Coastguard Worker } else {
4778*7c568831SAndroid Build Coastguard Worker def->content =
4779*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParsePatterns(ctxt, node->children, 1);
4780*7c568831SAndroid Build Coastguard Worker }
4781*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "oneOrMore")) {
4782*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, node);
4783*7c568831SAndroid Build Coastguard Worker if (def == NULL)
4784*7c568831SAndroid Build Coastguard Worker return (NULL);
4785*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_ONEORMORE;
4786*7c568831SAndroid Build Coastguard Worker if (node->children == NULL) {
4787*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
4788*7c568831SAndroid Build Coastguard Worker "Element %s is empty\n", node->name, NULL);
4789*7c568831SAndroid Build Coastguard Worker } else {
4790*7c568831SAndroid Build Coastguard Worker def->content =
4791*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParsePatterns(ctxt, node->children, 1);
4792*7c568831SAndroid Build Coastguard Worker }
4793*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "optional")) {
4794*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, node);
4795*7c568831SAndroid Build Coastguard Worker if (def == NULL)
4796*7c568831SAndroid Build Coastguard Worker return (NULL);
4797*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_OPTIONAL;
4798*7c568831SAndroid Build Coastguard Worker if (node->children == NULL) {
4799*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
4800*7c568831SAndroid Build Coastguard Worker "Element %s is empty\n", node->name, NULL);
4801*7c568831SAndroid Build Coastguard Worker } else {
4802*7c568831SAndroid Build Coastguard Worker def->content =
4803*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParsePatterns(ctxt, node->children, 1);
4804*7c568831SAndroid Build Coastguard Worker }
4805*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "choice")) {
4806*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, node);
4807*7c568831SAndroid Build Coastguard Worker if (def == NULL)
4808*7c568831SAndroid Build Coastguard Worker return (NULL);
4809*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_CHOICE;
4810*7c568831SAndroid Build Coastguard Worker if (node->children == NULL) {
4811*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
4812*7c568831SAndroid Build Coastguard Worker "Element %s is empty\n", node->name, NULL);
4813*7c568831SAndroid Build Coastguard Worker } else {
4814*7c568831SAndroid Build Coastguard Worker def->content =
4815*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParsePatterns(ctxt, node->children, 0);
4816*7c568831SAndroid Build Coastguard Worker }
4817*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "group")) {
4818*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, node);
4819*7c568831SAndroid Build Coastguard Worker if (def == NULL)
4820*7c568831SAndroid Build Coastguard Worker return (NULL);
4821*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_GROUP;
4822*7c568831SAndroid Build Coastguard Worker if (node->children == NULL) {
4823*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
4824*7c568831SAndroid Build Coastguard Worker "Element %s is empty\n", node->name, NULL);
4825*7c568831SAndroid Build Coastguard Worker } else {
4826*7c568831SAndroid Build Coastguard Worker def->content =
4827*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParsePatterns(ctxt, node->children, 0);
4828*7c568831SAndroid Build Coastguard Worker }
4829*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "ref")) {
4830*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, node);
4831*7c568831SAndroid Build Coastguard Worker if (def == NULL)
4832*7c568831SAndroid Build Coastguard Worker return (NULL);
4833*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_REF;
4834*7c568831SAndroid Build Coastguard Worker def->name = xmlGetProp(node, BAD_CAST "name");
4835*7c568831SAndroid Build Coastguard Worker if (def->name == NULL) {
4836*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_REF_NO_NAME, "ref has no name\n",
4837*7c568831SAndroid Build Coastguard Worker NULL, NULL);
4838*7c568831SAndroid Build Coastguard Worker } else {
4839*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNormExtSpace(def->name);
4840*7c568831SAndroid Build Coastguard Worker if (xmlValidateNCName(def->name, 0)) {
4841*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_REF_NAME_INVALID,
4842*7c568831SAndroid Build Coastguard Worker "ref name '%s' is not an NCName\n", def->name,
4843*7c568831SAndroid Build Coastguard Worker NULL);
4844*7c568831SAndroid Build Coastguard Worker }
4845*7c568831SAndroid Build Coastguard Worker }
4846*7c568831SAndroid Build Coastguard Worker if (node->children != NULL) {
4847*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_REF_NOT_EMPTY, "ref is not empty\n",
4848*7c568831SAndroid Build Coastguard Worker NULL, NULL);
4849*7c568831SAndroid Build Coastguard Worker }
4850*7c568831SAndroid Build Coastguard Worker if (ctxt->grammar->refs == NULL)
4851*7c568831SAndroid Build Coastguard Worker ctxt->grammar->refs = xmlHashCreate(10);
4852*7c568831SAndroid Build Coastguard Worker if (ctxt->grammar->refs == NULL) {
4853*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_REF_CREATE_FAILED,
4854*7c568831SAndroid Build Coastguard Worker "Could not create references hash\n", NULL, NULL);
4855*7c568831SAndroid Build Coastguard Worker def = NULL;
4856*7c568831SAndroid Build Coastguard Worker } else {
4857*7c568831SAndroid Build Coastguard Worker int tmp;
4858*7c568831SAndroid Build Coastguard Worker
4859*7c568831SAndroid Build Coastguard Worker tmp = xmlHashAddEntry(ctxt->grammar->refs, def->name, def);
4860*7c568831SAndroid Build Coastguard Worker if (tmp < 0) {
4861*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr prev;
4862*7c568831SAndroid Build Coastguard Worker
4863*7c568831SAndroid Build Coastguard Worker prev = (xmlRelaxNGDefinePtr)
4864*7c568831SAndroid Build Coastguard Worker xmlHashLookup(ctxt->grammar->refs, def->name);
4865*7c568831SAndroid Build Coastguard Worker if (prev == NULL) {
4866*7c568831SAndroid Build Coastguard Worker if (def->name != NULL) {
4867*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_REF_CREATE_FAILED,
4868*7c568831SAndroid Build Coastguard Worker "Error refs definitions '%s'\n",
4869*7c568831SAndroid Build Coastguard Worker def->name, NULL);
4870*7c568831SAndroid Build Coastguard Worker } else {
4871*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_REF_CREATE_FAILED,
4872*7c568831SAndroid Build Coastguard Worker "Error refs definitions\n",
4873*7c568831SAndroid Build Coastguard Worker NULL, NULL);
4874*7c568831SAndroid Build Coastguard Worker }
4875*7c568831SAndroid Build Coastguard Worker def = NULL;
4876*7c568831SAndroid Build Coastguard Worker } else {
4877*7c568831SAndroid Build Coastguard Worker def->nextHash = prev->nextHash;
4878*7c568831SAndroid Build Coastguard Worker prev->nextHash = def;
4879*7c568831SAndroid Build Coastguard Worker }
4880*7c568831SAndroid Build Coastguard Worker }
4881*7c568831SAndroid Build Coastguard Worker }
4882*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "data")) {
4883*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGParseData(ctxt, node);
4884*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "value")) {
4885*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGParseValue(ctxt, node);
4886*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "list")) {
4887*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, node);
4888*7c568831SAndroid Build Coastguard Worker if (def == NULL)
4889*7c568831SAndroid Build Coastguard Worker return (NULL);
4890*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_LIST;
4891*7c568831SAndroid Build Coastguard Worker if (node->children == NULL) {
4892*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
4893*7c568831SAndroid Build Coastguard Worker "Element %s is empty\n", node->name, NULL);
4894*7c568831SAndroid Build Coastguard Worker } else {
4895*7c568831SAndroid Build Coastguard Worker def->content =
4896*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParsePatterns(ctxt, node->children, 0);
4897*7c568831SAndroid Build Coastguard Worker }
4898*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "interleave")) {
4899*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGParseInterleave(ctxt, node);
4900*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "externalRef")) {
4901*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGProcessExternalRef(ctxt, node);
4902*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "notAllowed")) {
4903*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, node);
4904*7c568831SAndroid Build Coastguard Worker if (def == NULL)
4905*7c568831SAndroid Build Coastguard Worker return (NULL);
4906*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_NOT_ALLOWED;
4907*7c568831SAndroid Build Coastguard Worker if (node->children != NULL) {
4908*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_NOTALLOWED_NOT_EMPTY,
4909*7c568831SAndroid Build Coastguard Worker "xmlRelaxNGParse: notAllowed element is not empty\n",
4910*7c568831SAndroid Build Coastguard Worker NULL, NULL);
4911*7c568831SAndroid Build Coastguard Worker }
4912*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "grammar")) {
4913*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGrammarPtr grammar, old;
4914*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGrammarPtr oldparent;
4915*7c568831SAndroid Build Coastguard Worker
4916*7c568831SAndroid Build Coastguard Worker oldparent = ctxt->parentgrammar;
4917*7c568831SAndroid Build Coastguard Worker old = ctxt->grammar;
4918*7c568831SAndroid Build Coastguard Worker ctxt->parentgrammar = old;
4919*7c568831SAndroid Build Coastguard Worker grammar = xmlRelaxNGParseGrammar(ctxt, node->children);
4920*7c568831SAndroid Build Coastguard Worker if (old != NULL) {
4921*7c568831SAndroid Build Coastguard Worker ctxt->grammar = old;
4922*7c568831SAndroid Build Coastguard Worker ctxt->parentgrammar = oldparent;
4923*7c568831SAndroid Build Coastguard Worker #if 0
4924*7c568831SAndroid Build Coastguard Worker if (grammar != NULL) {
4925*7c568831SAndroid Build Coastguard Worker grammar->next = old->next;
4926*7c568831SAndroid Build Coastguard Worker old->next = grammar;
4927*7c568831SAndroid Build Coastguard Worker }
4928*7c568831SAndroid Build Coastguard Worker #endif
4929*7c568831SAndroid Build Coastguard Worker }
4930*7c568831SAndroid Build Coastguard Worker if (grammar != NULL)
4931*7c568831SAndroid Build Coastguard Worker def = grammar->start;
4932*7c568831SAndroid Build Coastguard Worker else
4933*7c568831SAndroid Build Coastguard Worker def = NULL;
4934*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "parentRef")) {
4935*7c568831SAndroid Build Coastguard Worker if (ctxt->parentgrammar == NULL) {
4936*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NO_PARENT,
4937*7c568831SAndroid Build Coastguard Worker "Use of parentRef without a parent grammar\n", NULL,
4938*7c568831SAndroid Build Coastguard Worker NULL);
4939*7c568831SAndroid Build Coastguard Worker return (NULL);
4940*7c568831SAndroid Build Coastguard Worker }
4941*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, node);
4942*7c568831SAndroid Build Coastguard Worker if (def == NULL)
4943*7c568831SAndroid Build Coastguard Worker return (NULL);
4944*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_PARENTREF;
4945*7c568831SAndroid Build Coastguard Worker def->name = xmlGetProp(node, BAD_CAST "name");
4946*7c568831SAndroid Build Coastguard Worker if (def->name == NULL) {
4947*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NO_NAME,
4948*7c568831SAndroid Build Coastguard Worker "parentRef has no name\n", NULL, NULL);
4949*7c568831SAndroid Build Coastguard Worker } else {
4950*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNormExtSpace(def->name);
4951*7c568831SAndroid Build Coastguard Worker if (xmlValidateNCName(def->name, 0)) {
4952*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NAME_INVALID,
4953*7c568831SAndroid Build Coastguard Worker "parentRef name '%s' is not an NCName\n",
4954*7c568831SAndroid Build Coastguard Worker def->name, NULL);
4955*7c568831SAndroid Build Coastguard Worker }
4956*7c568831SAndroid Build Coastguard Worker }
4957*7c568831SAndroid Build Coastguard Worker if (node->children != NULL) {
4958*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NOT_EMPTY,
4959*7c568831SAndroid Build Coastguard Worker "parentRef is not empty\n", NULL, NULL);
4960*7c568831SAndroid Build Coastguard Worker }
4961*7c568831SAndroid Build Coastguard Worker if (ctxt->parentgrammar->refs == NULL)
4962*7c568831SAndroid Build Coastguard Worker ctxt->parentgrammar->refs = xmlHashCreate(10);
4963*7c568831SAndroid Build Coastguard Worker if (ctxt->parentgrammar->refs == NULL) {
4964*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_CREATE_FAILED,
4965*7c568831SAndroid Build Coastguard Worker "Could not create references hash\n", NULL, NULL);
4966*7c568831SAndroid Build Coastguard Worker def = NULL;
4967*7c568831SAndroid Build Coastguard Worker } else if (def->name != NULL) {
4968*7c568831SAndroid Build Coastguard Worker int tmp;
4969*7c568831SAndroid Build Coastguard Worker
4970*7c568831SAndroid Build Coastguard Worker tmp =
4971*7c568831SAndroid Build Coastguard Worker xmlHashAddEntry(ctxt->parentgrammar->refs, def->name, def);
4972*7c568831SAndroid Build Coastguard Worker if (tmp < 0) {
4973*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr prev;
4974*7c568831SAndroid Build Coastguard Worker
4975*7c568831SAndroid Build Coastguard Worker prev = (xmlRelaxNGDefinePtr)
4976*7c568831SAndroid Build Coastguard Worker xmlHashLookup(ctxt->parentgrammar->refs, def->name);
4977*7c568831SAndroid Build Coastguard Worker if (prev == NULL) {
4978*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_CREATE_FAILED,
4979*7c568831SAndroid Build Coastguard Worker "Internal error parentRef definitions '%s'\n",
4980*7c568831SAndroid Build Coastguard Worker def->name, NULL);
4981*7c568831SAndroid Build Coastguard Worker def = NULL;
4982*7c568831SAndroid Build Coastguard Worker } else {
4983*7c568831SAndroid Build Coastguard Worker def->nextHash = prev->nextHash;
4984*7c568831SAndroid Build Coastguard Worker prev->nextHash = def;
4985*7c568831SAndroid Build Coastguard Worker }
4986*7c568831SAndroid Build Coastguard Worker }
4987*7c568831SAndroid Build Coastguard Worker }
4988*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "mixed")) {
4989*7c568831SAndroid Build Coastguard Worker if (node->children == NULL) {
4990*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT, "Mixed is empty\n",
4991*7c568831SAndroid Build Coastguard Worker NULL, NULL);
4992*7c568831SAndroid Build Coastguard Worker def = NULL;
4993*7c568831SAndroid Build Coastguard Worker } else {
4994*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGParseInterleave(ctxt, node);
4995*7c568831SAndroid Build Coastguard Worker if (def != NULL) {
4996*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr tmp;
4997*7c568831SAndroid Build Coastguard Worker
4998*7c568831SAndroid Build Coastguard Worker if ((def->content != NULL) && (def->content->next != NULL)) {
4999*7c568831SAndroid Build Coastguard Worker tmp = xmlRelaxNGNewDefine(ctxt, node);
5000*7c568831SAndroid Build Coastguard Worker if (tmp != NULL) {
5001*7c568831SAndroid Build Coastguard Worker tmp->type = XML_RELAXNG_GROUP;
5002*7c568831SAndroid Build Coastguard Worker tmp->content = def->content;
5003*7c568831SAndroid Build Coastguard Worker def->content = tmp;
5004*7c568831SAndroid Build Coastguard Worker }
5005*7c568831SAndroid Build Coastguard Worker }
5006*7c568831SAndroid Build Coastguard Worker
5007*7c568831SAndroid Build Coastguard Worker tmp = xmlRelaxNGNewDefine(ctxt, node);
5008*7c568831SAndroid Build Coastguard Worker if (tmp == NULL)
5009*7c568831SAndroid Build Coastguard Worker return (def);
5010*7c568831SAndroid Build Coastguard Worker tmp->type = XML_RELAXNG_TEXT;
5011*7c568831SAndroid Build Coastguard Worker tmp->next = def->content;
5012*7c568831SAndroid Build Coastguard Worker def->content = tmp;
5013*7c568831SAndroid Build Coastguard Worker }
5014*7c568831SAndroid Build Coastguard Worker }
5015*7c568831SAndroid Build Coastguard Worker } else {
5016*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_CONSTRUCT,
5017*7c568831SAndroid Build Coastguard Worker "Unexpected node %s is not a pattern\n", node->name,
5018*7c568831SAndroid Build Coastguard Worker NULL);
5019*7c568831SAndroid Build Coastguard Worker def = NULL;
5020*7c568831SAndroid Build Coastguard Worker }
5021*7c568831SAndroid Build Coastguard Worker return (def);
5022*7c568831SAndroid Build Coastguard Worker }
5023*7c568831SAndroid Build Coastguard Worker
5024*7c568831SAndroid Build Coastguard Worker /**
5025*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParseAttribute:
5026*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
5027*7c568831SAndroid Build Coastguard Worker * @node: the element node
5028*7c568831SAndroid Build Coastguard Worker *
5029*7c568831SAndroid Build Coastguard Worker * parse the content of a RelaxNG attribute node.
5030*7c568831SAndroid Build Coastguard Worker *
5031*7c568831SAndroid Build Coastguard Worker * Returns the definition pointer or NULL in case of error.
5032*7c568831SAndroid Build Coastguard Worker */
5033*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr
xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr node)5034*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
5035*7c568831SAndroid Build Coastguard Worker {
5036*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr ret, cur;
5037*7c568831SAndroid Build Coastguard Worker xmlNodePtr child;
5038*7c568831SAndroid Build Coastguard Worker int old_flags;
5039*7c568831SAndroid Build Coastguard Worker
5040*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGNewDefine(ctxt, node);
5041*7c568831SAndroid Build Coastguard Worker if (ret == NULL)
5042*7c568831SAndroid Build Coastguard Worker return (NULL);
5043*7c568831SAndroid Build Coastguard Worker ret->type = XML_RELAXNG_ATTRIBUTE;
5044*7c568831SAndroid Build Coastguard Worker ret->parent = ctxt->def;
5045*7c568831SAndroid Build Coastguard Worker child = node->children;
5046*7c568831SAndroid Build Coastguard Worker if (child == NULL) {
5047*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_EMPTY,
5048*7c568831SAndroid Build Coastguard Worker "xmlRelaxNGParseattribute: attribute has no children\n",
5049*7c568831SAndroid Build Coastguard Worker NULL, NULL);
5050*7c568831SAndroid Build Coastguard Worker return (ret);
5051*7c568831SAndroid Build Coastguard Worker }
5052*7c568831SAndroid Build Coastguard Worker old_flags = ctxt->flags;
5053*7c568831SAndroid Build Coastguard Worker ctxt->flags |= XML_RELAXNG_IN_ATTRIBUTE;
5054*7c568831SAndroid Build Coastguard Worker cur = xmlRelaxNGParseNameClass(ctxt, child, ret);
5055*7c568831SAndroid Build Coastguard Worker if (cur != NULL)
5056*7c568831SAndroid Build Coastguard Worker child = child->next;
5057*7c568831SAndroid Build Coastguard Worker
5058*7c568831SAndroid Build Coastguard Worker if (child != NULL) {
5059*7c568831SAndroid Build Coastguard Worker cur = xmlRelaxNGParsePattern(ctxt, child);
5060*7c568831SAndroid Build Coastguard Worker if (cur != NULL) {
5061*7c568831SAndroid Build Coastguard Worker switch (cur->type) {
5062*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EMPTY:
5063*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOT_ALLOWED:
5064*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_TEXT:
5065*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ELEMENT:
5066*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DATATYPE:
5067*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_VALUE:
5068*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_LIST:
5069*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_REF:
5070*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARENTREF:
5071*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXTERNALREF:
5072*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DEF:
5073*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ONEORMORE:
5074*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ZEROORMORE:
5075*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_OPTIONAL:
5076*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_CHOICE:
5077*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_GROUP:
5078*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_INTERLEAVE:
5079*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ATTRIBUTE:
5080*7c568831SAndroid Build Coastguard Worker ret->content = cur;
5081*7c568831SAndroid Build Coastguard Worker cur->parent = ret;
5082*7c568831SAndroid Build Coastguard Worker break;
5083*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_START:
5084*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARAM:
5085*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXCEPT:
5086*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_CONTENT,
5087*7c568831SAndroid Build Coastguard Worker "attribute has invalid content\n", NULL,
5088*7c568831SAndroid Build Coastguard Worker NULL);
5089*7c568831SAndroid Build Coastguard Worker break;
5090*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOOP:
5091*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_NOOP,
5092*7c568831SAndroid Build Coastguard Worker "RNG Internal error, noop found in attribute\n",
5093*7c568831SAndroid Build Coastguard Worker NULL, NULL);
5094*7c568831SAndroid Build Coastguard Worker break;
5095*7c568831SAndroid Build Coastguard Worker }
5096*7c568831SAndroid Build Coastguard Worker }
5097*7c568831SAndroid Build Coastguard Worker child = child->next;
5098*7c568831SAndroid Build Coastguard Worker }
5099*7c568831SAndroid Build Coastguard Worker if (child != NULL) {
5100*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_CHILDREN,
5101*7c568831SAndroid Build Coastguard Worker "attribute has multiple children\n", NULL, NULL);
5102*7c568831SAndroid Build Coastguard Worker }
5103*7c568831SAndroid Build Coastguard Worker ctxt->flags = old_flags;
5104*7c568831SAndroid Build Coastguard Worker return (ret);
5105*7c568831SAndroid Build Coastguard Worker }
5106*7c568831SAndroid Build Coastguard Worker
5107*7c568831SAndroid Build Coastguard Worker /**
5108*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParseExceptNameClass:
5109*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
5110*7c568831SAndroid Build Coastguard Worker * @node: the except node
5111*7c568831SAndroid Build Coastguard Worker * @attr: 1 if within an attribute, 0 if within an element
5112*7c568831SAndroid Build Coastguard Worker *
5113*7c568831SAndroid Build Coastguard Worker * parse the content of a RelaxNG nameClass node.
5114*7c568831SAndroid Build Coastguard Worker *
5115*7c568831SAndroid Build Coastguard Worker * Returns the definition pointer or NULL in case of error.
5116*7c568831SAndroid Build Coastguard Worker */
5117*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr
xmlRelaxNGParseExceptNameClass(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr node,int attr)5118*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseExceptNameClass(xmlRelaxNGParserCtxtPtr ctxt,
5119*7c568831SAndroid Build Coastguard Worker xmlNodePtr node, int attr)
5120*7c568831SAndroid Build Coastguard Worker {
5121*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr ret, cur, last = NULL;
5122*7c568831SAndroid Build Coastguard Worker xmlNodePtr child;
5123*7c568831SAndroid Build Coastguard Worker
5124*7c568831SAndroid Build Coastguard Worker if (!IS_RELAXNG(node, "except")) {
5125*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_EXCEPT_MISSING,
5126*7c568831SAndroid Build Coastguard Worker "Expecting an except node\n", NULL, NULL);
5127*7c568831SAndroid Build Coastguard Worker return (NULL);
5128*7c568831SAndroid Build Coastguard Worker }
5129*7c568831SAndroid Build Coastguard Worker if (node->next != NULL) {
5130*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_EXCEPT_MULTIPLE,
5131*7c568831SAndroid Build Coastguard Worker "exceptNameClass allows only a single except node\n",
5132*7c568831SAndroid Build Coastguard Worker NULL, NULL);
5133*7c568831SAndroid Build Coastguard Worker }
5134*7c568831SAndroid Build Coastguard Worker if (node->children == NULL) {
5135*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_EXCEPT_EMPTY, "except has no content\n",
5136*7c568831SAndroid Build Coastguard Worker NULL, NULL);
5137*7c568831SAndroid Build Coastguard Worker return (NULL);
5138*7c568831SAndroid Build Coastguard Worker }
5139*7c568831SAndroid Build Coastguard Worker
5140*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGNewDefine(ctxt, node);
5141*7c568831SAndroid Build Coastguard Worker if (ret == NULL)
5142*7c568831SAndroid Build Coastguard Worker return (NULL);
5143*7c568831SAndroid Build Coastguard Worker ret->type = XML_RELAXNG_EXCEPT;
5144*7c568831SAndroid Build Coastguard Worker child = node->children;
5145*7c568831SAndroid Build Coastguard Worker while (child != NULL) {
5146*7c568831SAndroid Build Coastguard Worker cur = xmlRelaxNGNewDefine(ctxt, child);
5147*7c568831SAndroid Build Coastguard Worker if (cur == NULL)
5148*7c568831SAndroid Build Coastguard Worker break;
5149*7c568831SAndroid Build Coastguard Worker if (attr)
5150*7c568831SAndroid Build Coastguard Worker cur->type = XML_RELAXNG_ATTRIBUTE;
5151*7c568831SAndroid Build Coastguard Worker else
5152*7c568831SAndroid Build Coastguard Worker cur->type = XML_RELAXNG_ELEMENT;
5153*7c568831SAndroid Build Coastguard Worker
5154*7c568831SAndroid Build Coastguard Worker if (xmlRelaxNGParseNameClass(ctxt, child, cur) != NULL) {
5155*7c568831SAndroid Build Coastguard Worker if (last == NULL) {
5156*7c568831SAndroid Build Coastguard Worker ret->content = cur;
5157*7c568831SAndroid Build Coastguard Worker } else {
5158*7c568831SAndroid Build Coastguard Worker last->next = cur;
5159*7c568831SAndroid Build Coastguard Worker }
5160*7c568831SAndroid Build Coastguard Worker last = cur;
5161*7c568831SAndroid Build Coastguard Worker }
5162*7c568831SAndroid Build Coastguard Worker child = child->next;
5163*7c568831SAndroid Build Coastguard Worker }
5164*7c568831SAndroid Build Coastguard Worker
5165*7c568831SAndroid Build Coastguard Worker return (ret);
5166*7c568831SAndroid Build Coastguard Worker }
5167*7c568831SAndroid Build Coastguard Worker
5168*7c568831SAndroid Build Coastguard Worker /**
5169*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParseNameClass:
5170*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
5171*7c568831SAndroid Build Coastguard Worker * @node: the nameClass node
5172*7c568831SAndroid Build Coastguard Worker * @def: the current definition
5173*7c568831SAndroid Build Coastguard Worker *
5174*7c568831SAndroid Build Coastguard Worker * parse the content of a RelaxNG nameClass node.
5175*7c568831SAndroid Build Coastguard Worker *
5176*7c568831SAndroid Build Coastguard Worker * Returns the definition pointer or NULL in case of error.
5177*7c568831SAndroid Build Coastguard Worker */
5178*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr
xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr node,xmlRelaxNGDefinePtr def)5179*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node,
5180*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def)
5181*7c568831SAndroid Build Coastguard Worker {
5182*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr ret, tmp;
5183*7c568831SAndroid Build Coastguard Worker xmlChar *val;
5184*7c568831SAndroid Build Coastguard Worker
5185*7c568831SAndroid Build Coastguard Worker ret = def;
5186*7c568831SAndroid Build Coastguard Worker if ((IS_RELAXNG(node, "name")) || (IS_RELAXNG(node, "anyName")) ||
5187*7c568831SAndroid Build Coastguard Worker (IS_RELAXNG(node, "nsName"))) {
5188*7c568831SAndroid Build Coastguard Worker if ((def->type != XML_RELAXNG_ELEMENT) &&
5189*7c568831SAndroid Build Coastguard Worker (def->type != XML_RELAXNG_ATTRIBUTE)) {
5190*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGNewDefine(ctxt, node);
5191*7c568831SAndroid Build Coastguard Worker if (ret == NULL)
5192*7c568831SAndroid Build Coastguard Worker return (NULL);
5193*7c568831SAndroid Build Coastguard Worker ret->parent = def;
5194*7c568831SAndroid Build Coastguard Worker if (ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE)
5195*7c568831SAndroid Build Coastguard Worker ret->type = XML_RELAXNG_ATTRIBUTE;
5196*7c568831SAndroid Build Coastguard Worker else
5197*7c568831SAndroid Build Coastguard Worker ret->type = XML_RELAXNG_ELEMENT;
5198*7c568831SAndroid Build Coastguard Worker }
5199*7c568831SAndroid Build Coastguard Worker }
5200*7c568831SAndroid Build Coastguard Worker if (IS_RELAXNG(node, "name")) {
5201*7c568831SAndroid Build Coastguard Worker val = xmlNodeGetContent(node);
5202*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNormExtSpace(val);
5203*7c568831SAndroid Build Coastguard Worker if (xmlValidateNCName(val, 0)) {
5204*7c568831SAndroid Build Coastguard Worker if (node->parent != NULL)
5205*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_NAME,
5206*7c568831SAndroid Build Coastguard Worker "Element %s name '%s' is not an NCName\n",
5207*7c568831SAndroid Build Coastguard Worker node->parent->name, val);
5208*7c568831SAndroid Build Coastguard Worker else
5209*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_NAME,
5210*7c568831SAndroid Build Coastguard Worker "name '%s' is not an NCName\n",
5211*7c568831SAndroid Build Coastguard Worker val, NULL);
5212*7c568831SAndroid Build Coastguard Worker }
5213*7c568831SAndroid Build Coastguard Worker ret->name = val;
5214*7c568831SAndroid Build Coastguard Worker val = xmlGetProp(node, BAD_CAST "ns");
5215*7c568831SAndroid Build Coastguard Worker ret->ns = val;
5216*7c568831SAndroid Build Coastguard Worker if ((ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE) &&
5217*7c568831SAndroid Build Coastguard Worker (val != NULL) &&
5218*7c568831SAndroid Build Coastguard Worker (xmlStrEqual(val, BAD_CAST "http://www.w3.org/2000/xmlns"))) {
5219*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_XML_NS,
5220*7c568831SAndroid Build Coastguard Worker "Attribute with namespace '%s' is not allowed\n",
5221*7c568831SAndroid Build Coastguard Worker val, NULL);
5222*7c568831SAndroid Build Coastguard Worker }
5223*7c568831SAndroid Build Coastguard Worker if ((ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE) &&
5224*7c568831SAndroid Build Coastguard Worker (val != NULL) &&
5225*7c568831SAndroid Build Coastguard Worker (val[0] == 0) && (xmlStrEqual(ret->name, BAD_CAST "xmlns"))) {
5226*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_XMLNS_NAME,
5227*7c568831SAndroid Build Coastguard Worker "Attribute with QName 'xmlns' is not allowed\n",
5228*7c568831SAndroid Build Coastguard Worker val, NULL);
5229*7c568831SAndroid Build Coastguard Worker }
5230*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "anyName")) {
5231*7c568831SAndroid Build Coastguard Worker ret->name = NULL;
5232*7c568831SAndroid Build Coastguard Worker ret->ns = NULL;
5233*7c568831SAndroid Build Coastguard Worker if (node->children != NULL) {
5234*7c568831SAndroid Build Coastguard Worker ret->nameClass =
5235*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseExceptNameClass(ctxt, node->children,
5236*7c568831SAndroid Build Coastguard Worker (def->type ==
5237*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_ATTRIBUTE));
5238*7c568831SAndroid Build Coastguard Worker }
5239*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "nsName")) {
5240*7c568831SAndroid Build Coastguard Worker ret->name = NULL;
5241*7c568831SAndroid Build Coastguard Worker ret->ns = xmlGetProp(node, BAD_CAST "ns");
5242*7c568831SAndroid Build Coastguard Worker if (ret->ns == NULL) {
5243*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_NSNAME_NO_NS,
5244*7c568831SAndroid Build Coastguard Worker "nsName has no ns attribute\n", NULL, NULL);
5245*7c568831SAndroid Build Coastguard Worker }
5246*7c568831SAndroid Build Coastguard Worker if ((ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE) &&
5247*7c568831SAndroid Build Coastguard Worker (ret->ns != NULL) &&
5248*7c568831SAndroid Build Coastguard Worker (xmlStrEqual
5249*7c568831SAndroid Build Coastguard Worker (ret->ns, BAD_CAST "http://www.w3.org/2000/xmlns"))) {
5250*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_XML_NS,
5251*7c568831SAndroid Build Coastguard Worker "Attribute with namespace '%s' is not allowed\n",
5252*7c568831SAndroid Build Coastguard Worker ret->ns, NULL);
5253*7c568831SAndroid Build Coastguard Worker }
5254*7c568831SAndroid Build Coastguard Worker if (node->children != NULL) {
5255*7c568831SAndroid Build Coastguard Worker ret->nameClass =
5256*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseExceptNameClass(ctxt, node->children,
5257*7c568831SAndroid Build Coastguard Worker (def->type ==
5258*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_ATTRIBUTE));
5259*7c568831SAndroid Build Coastguard Worker }
5260*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(node, "choice")) {
5261*7c568831SAndroid Build Coastguard Worker xmlNodePtr child;
5262*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr last = NULL;
5263*7c568831SAndroid Build Coastguard Worker
5264*7c568831SAndroid Build Coastguard Worker if (def->type == XML_RELAXNG_CHOICE) {
5265*7c568831SAndroid Build Coastguard Worker ret = def;
5266*7c568831SAndroid Build Coastguard Worker } else {
5267*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGNewDefine(ctxt, node);
5268*7c568831SAndroid Build Coastguard Worker if (ret == NULL)
5269*7c568831SAndroid Build Coastguard Worker return (NULL);
5270*7c568831SAndroid Build Coastguard Worker ret->parent = def;
5271*7c568831SAndroid Build Coastguard Worker ret->type = XML_RELAXNG_CHOICE;
5272*7c568831SAndroid Build Coastguard Worker }
5273*7c568831SAndroid Build Coastguard Worker
5274*7c568831SAndroid Build Coastguard Worker if (node->children == NULL) {
5275*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_CHOICE_EMPTY,
5276*7c568831SAndroid Build Coastguard Worker "Element choice is empty\n", NULL, NULL);
5277*7c568831SAndroid Build Coastguard Worker } else {
5278*7c568831SAndroid Build Coastguard Worker
5279*7c568831SAndroid Build Coastguard Worker child = node->children;
5280*7c568831SAndroid Build Coastguard Worker while (child != NULL) {
5281*7c568831SAndroid Build Coastguard Worker tmp = xmlRelaxNGParseNameClass(ctxt, child, ret);
5282*7c568831SAndroid Build Coastguard Worker if (tmp != NULL) {
5283*7c568831SAndroid Build Coastguard Worker if (last == NULL) {
5284*7c568831SAndroid Build Coastguard Worker last = tmp;
5285*7c568831SAndroid Build Coastguard Worker } else if (tmp != ret) {
5286*7c568831SAndroid Build Coastguard Worker last->next = tmp;
5287*7c568831SAndroid Build Coastguard Worker last = tmp;
5288*7c568831SAndroid Build Coastguard Worker }
5289*7c568831SAndroid Build Coastguard Worker }
5290*7c568831SAndroid Build Coastguard Worker child = child->next;
5291*7c568831SAndroid Build Coastguard Worker }
5292*7c568831SAndroid Build Coastguard Worker }
5293*7c568831SAndroid Build Coastguard Worker } else {
5294*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_CHOICE_CONTENT,
5295*7c568831SAndroid Build Coastguard Worker "expecting name, anyName, nsName or choice : got %s\n",
5296*7c568831SAndroid Build Coastguard Worker (node == NULL ? (const xmlChar *) "nothing" : node->name),
5297*7c568831SAndroid Build Coastguard Worker NULL);
5298*7c568831SAndroid Build Coastguard Worker return (NULL);
5299*7c568831SAndroid Build Coastguard Worker }
5300*7c568831SAndroid Build Coastguard Worker if (ret != def) {
5301*7c568831SAndroid Build Coastguard Worker if (def->nameClass == NULL) {
5302*7c568831SAndroid Build Coastguard Worker def->nameClass = ret;
5303*7c568831SAndroid Build Coastguard Worker } else {
5304*7c568831SAndroid Build Coastguard Worker tmp = def->nameClass;
5305*7c568831SAndroid Build Coastguard Worker while (tmp->next != NULL) {
5306*7c568831SAndroid Build Coastguard Worker tmp = tmp->next;
5307*7c568831SAndroid Build Coastguard Worker }
5308*7c568831SAndroid Build Coastguard Worker tmp->next = ret;
5309*7c568831SAndroid Build Coastguard Worker }
5310*7c568831SAndroid Build Coastguard Worker }
5311*7c568831SAndroid Build Coastguard Worker return (ret);
5312*7c568831SAndroid Build Coastguard Worker }
5313*7c568831SAndroid Build Coastguard Worker
5314*7c568831SAndroid Build Coastguard Worker /**
5315*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParseElement:
5316*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
5317*7c568831SAndroid Build Coastguard Worker * @node: the element node
5318*7c568831SAndroid Build Coastguard Worker *
5319*7c568831SAndroid Build Coastguard Worker * parse the content of a RelaxNG element node.
5320*7c568831SAndroid Build Coastguard Worker *
5321*7c568831SAndroid Build Coastguard Worker * Returns the definition pointer or NULL in case of error.
5322*7c568831SAndroid Build Coastguard Worker */
5323*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr
xmlRelaxNGParseElement(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr node)5324*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseElement(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
5325*7c568831SAndroid Build Coastguard Worker {
5326*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr ret, cur, last;
5327*7c568831SAndroid Build Coastguard Worker xmlNodePtr child;
5328*7c568831SAndroid Build Coastguard Worker const xmlChar *olddefine;
5329*7c568831SAndroid Build Coastguard Worker
5330*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGNewDefine(ctxt, node);
5331*7c568831SAndroid Build Coastguard Worker if (ret == NULL)
5332*7c568831SAndroid Build Coastguard Worker return (NULL);
5333*7c568831SAndroid Build Coastguard Worker ret->type = XML_RELAXNG_ELEMENT;
5334*7c568831SAndroid Build Coastguard Worker ret->parent = ctxt->def;
5335*7c568831SAndroid Build Coastguard Worker child = node->children;
5336*7c568831SAndroid Build Coastguard Worker if (child == NULL) {
5337*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_EMPTY,
5338*7c568831SAndroid Build Coastguard Worker "xmlRelaxNGParseElement: element has no children\n",
5339*7c568831SAndroid Build Coastguard Worker NULL, NULL);
5340*7c568831SAndroid Build Coastguard Worker return (ret);
5341*7c568831SAndroid Build Coastguard Worker }
5342*7c568831SAndroid Build Coastguard Worker cur = xmlRelaxNGParseNameClass(ctxt, child, ret);
5343*7c568831SAndroid Build Coastguard Worker if (cur != NULL)
5344*7c568831SAndroid Build Coastguard Worker child = child->next;
5345*7c568831SAndroid Build Coastguard Worker
5346*7c568831SAndroid Build Coastguard Worker if (child == NULL) {
5347*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_NO_CONTENT,
5348*7c568831SAndroid Build Coastguard Worker "xmlRelaxNGParseElement: element has no content\n",
5349*7c568831SAndroid Build Coastguard Worker NULL, NULL);
5350*7c568831SAndroid Build Coastguard Worker return (ret);
5351*7c568831SAndroid Build Coastguard Worker }
5352*7c568831SAndroid Build Coastguard Worker olddefine = ctxt->define;
5353*7c568831SAndroid Build Coastguard Worker ctxt->define = NULL;
5354*7c568831SAndroid Build Coastguard Worker last = NULL;
5355*7c568831SAndroid Build Coastguard Worker while (child != NULL) {
5356*7c568831SAndroid Build Coastguard Worker cur = xmlRelaxNGParsePattern(ctxt, child);
5357*7c568831SAndroid Build Coastguard Worker if (cur != NULL) {
5358*7c568831SAndroid Build Coastguard Worker cur->parent = ret;
5359*7c568831SAndroid Build Coastguard Worker switch (cur->type) {
5360*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EMPTY:
5361*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOT_ALLOWED:
5362*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_TEXT:
5363*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ELEMENT:
5364*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DATATYPE:
5365*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_VALUE:
5366*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_LIST:
5367*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_REF:
5368*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARENTREF:
5369*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXTERNALREF:
5370*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DEF:
5371*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ZEROORMORE:
5372*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ONEORMORE:
5373*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_OPTIONAL:
5374*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_CHOICE:
5375*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_GROUP:
5376*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_INTERLEAVE:
5377*7c568831SAndroid Build Coastguard Worker if (last == NULL) {
5378*7c568831SAndroid Build Coastguard Worker ret->content = last = cur;
5379*7c568831SAndroid Build Coastguard Worker } else {
5380*7c568831SAndroid Build Coastguard Worker if ((last->type == XML_RELAXNG_ELEMENT) &&
5381*7c568831SAndroid Build Coastguard Worker (ret->content == last)) {
5382*7c568831SAndroid Build Coastguard Worker ret->content = xmlRelaxNGNewDefine(ctxt, node);
5383*7c568831SAndroid Build Coastguard Worker if (ret->content != NULL) {
5384*7c568831SAndroid Build Coastguard Worker ret->content->type = XML_RELAXNG_GROUP;
5385*7c568831SAndroid Build Coastguard Worker ret->content->content = last;
5386*7c568831SAndroid Build Coastguard Worker } else {
5387*7c568831SAndroid Build Coastguard Worker ret->content = last;
5388*7c568831SAndroid Build Coastguard Worker }
5389*7c568831SAndroid Build Coastguard Worker }
5390*7c568831SAndroid Build Coastguard Worker last->next = cur;
5391*7c568831SAndroid Build Coastguard Worker last = cur;
5392*7c568831SAndroid Build Coastguard Worker }
5393*7c568831SAndroid Build Coastguard Worker break;
5394*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ATTRIBUTE:
5395*7c568831SAndroid Build Coastguard Worker cur->next = ret->attrs;
5396*7c568831SAndroid Build Coastguard Worker ret->attrs = cur;
5397*7c568831SAndroid Build Coastguard Worker break;
5398*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_START:
5399*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
5400*7c568831SAndroid Build Coastguard Worker "RNG Internal error, start found in element\n",
5401*7c568831SAndroid Build Coastguard Worker NULL, NULL);
5402*7c568831SAndroid Build Coastguard Worker break;
5403*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARAM:
5404*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
5405*7c568831SAndroid Build Coastguard Worker "RNG Internal error, param found in element\n",
5406*7c568831SAndroid Build Coastguard Worker NULL, NULL);
5407*7c568831SAndroid Build Coastguard Worker break;
5408*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXCEPT:
5409*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
5410*7c568831SAndroid Build Coastguard Worker "RNG Internal error, except found in element\n",
5411*7c568831SAndroid Build Coastguard Worker NULL, NULL);
5412*7c568831SAndroid Build Coastguard Worker break;
5413*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOOP:
5414*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
5415*7c568831SAndroid Build Coastguard Worker "RNG Internal error, noop found in element\n",
5416*7c568831SAndroid Build Coastguard Worker NULL, NULL);
5417*7c568831SAndroid Build Coastguard Worker break;
5418*7c568831SAndroid Build Coastguard Worker }
5419*7c568831SAndroid Build Coastguard Worker }
5420*7c568831SAndroid Build Coastguard Worker child = child->next;
5421*7c568831SAndroid Build Coastguard Worker }
5422*7c568831SAndroid Build Coastguard Worker ctxt->define = olddefine;
5423*7c568831SAndroid Build Coastguard Worker return (ret);
5424*7c568831SAndroid Build Coastguard Worker }
5425*7c568831SAndroid Build Coastguard Worker
5426*7c568831SAndroid Build Coastguard Worker /**
5427*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParsePatterns:
5428*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
5429*7c568831SAndroid Build Coastguard Worker * @nodes: list of nodes
5430*7c568831SAndroid Build Coastguard Worker * @group: use an implicit <group> for elements
5431*7c568831SAndroid Build Coastguard Worker *
5432*7c568831SAndroid Build Coastguard Worker * parse the content of a RelaxNG start node.
5433*7c568831SAndroid Build Coastguard Worker *
5434*7c568831SAndroid Build Coastguard Worker * Returns the definition pointer or NULL in case of error.
5435*7c568831SAndroid Build Coastguard Worker */
5436*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr
xmlRelaxNGParsePatterns(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr nodes,int group)5437*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParsePatterns(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes,
5438*7c568831SAndroid Build Coastguard Worker int group)
5439*7c568831SAndroid Build Coastguard Worker {
5440*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def = NULL, last = NULL, cur, parent;
5441*7c568831SAndroid Build Coastguard Worker
5442*7c568831SAndroid Build Coastguard Worker parent = ctxt->def;
5443*7c568831SAndroid Build Coastguard Worker while (nodes != NULL) {
5444*7c568831SAndroid Build Coastguard Worker if (IS_RELAXNG(nodes, "element")) {
5445*7c568831SAndroid Build Coastguard Worker cur = xmlRelaxNGParseElement(ctxt, nodes);
5446*7c568831SAndroid Build Coastguard Worker if (cur == NULL)
5447*7c568831SAndroid Build Coastguard Worker return (NULL);
5448*7c568831SAndroid Build Coastguard Worker if (def == NULL) {
5449*7c568831SAndroid Build Coastguard Worker def = last = cur;
5450*7c568831SAndroid Build Coastguard Worker } else {
5451*7c568831SAndroid Build Coastguard Worker if ((group == 1) && (def->type == XML_RELAXNG_ELEMENT) &&
5452*7c568831SAndroid Build Coastguard Worker (def == last)) {
5453*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, nodes);
5454*7c568831SAndroid Build Coastguard Worker if (def == NULL)
5455*7c568831SAndroid Build Coastguard Worker return (NULL);
5456*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_GROUP;
5457*7c568831SAndroid Build Coastguard Worker def->content = last;
5458*7c568831SAndroid Build Coastguard Worker }
5459*7c568831SAndroid Build Coastguard Worker last->next = cur;
5460*7c568831SAndroid Build Coastguard Worker last = cur;
5461*7c568831SAndroid Build Coastguard Worker }
5462*7c568831SAndroid Build Coastguard Worker cur->parent = parent;
5463*7c568831SAndroid Build Coastguard Worker } else {
5464*7c568831SAndroid Build Coastguard Worker cur = xmlRelaxNGParsePattern(ctxt, nodes);
5465*7c568831SAndroid Build Coastguard Worker if (cur != NULL) {
5466*7c568831SAndroid Build Coastguard Worker if (def == NULL) {
5467*7c568831SAndroid Build Coastguard Worker def = last = cur;
5468*7c568831SAndroid Build Coastguard Worker } else {
5469*7c568831SAndroid Build Coastguard Worker last->next = cur;
5470*7c568831SAndroid Build Coastguard Worker last = cur;
5471*7c568831SAndroid Build Coastguard Worker }
5472*7c568831SAndroid Build Coastguard Worker }
5473*7c568831SAndroid Build Coastguard Worker }
5474*7c568831SAndroid Build Coastguard Worker nodes = nodes->next;
5475*7c568831SAndroid Build Coastguard Worker }
5476*7c568831SAndroid Build Coastguard Worker return (def);
5477*7c568831SAndroid Build Coastguard Worker }
5478*7c568831SAndroid Build Coastguard Worker
5479*7c568831SAndroid Build Coastguard Worker /**
5480*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParseStart:
5481*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
5482*7c568831SAndroid Build Coastguard Worker * @nodes: start children nodes
5483*7c568831SAndroid Build Coastguard Worker *
5484*7c568831SAndroid Build Coastguard Worker * parse the content of a RelaxNG start node.
5485*7c568831SAndroid Build Coastguard Worker *
5486*7c568831SAndroid Build Coastguard Worker * Returns 0 in case of success, -1 in case of error
5487*7c568831SAndroid Build Coastguard Worker */
5488*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGParseStart(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr nodes)5489*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseStart(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes)
5490*7c568831SAndroid Build Coastguard Worker {
5491*7c568831SAndroid Build Coastguard Worker int ret = 0;
5492*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def = NULL, last;
5493*7c568831SAndroid Build Coastguard Worker
5494*7c568831SAndroid Build Coastguard Worker if (nodes == NULL) {
5495*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, nodes, XML_RNGP_START_EMPTY, "start has no children\n",
5496*7c568831SAndroid Build Coastguard Worker NULL, NULL);
5497*7c568831SAndroid Build Coastguard Worker return (-1);
5498*7c568831SAndroid Build Coastguard Worker }
5499*7c568831SAndroid Build Coastguard Worker if (IS_RELAXNG(nodes, "empty")) {
5500*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, nodes);
5501*7c568831SAndroid Build Coastguard Worker if (def == NULL)
5502*7c568831SAndroid Build Coastguard Worker return (-1);
5503*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_EMPTY;
5504*7c568831SAndroid Build Coastguard Worker if (nodes->children != NULL) {
5505*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, nodes, XML_RNGP_EMPTY_CONTENT,
5506*7c568831SAndroid Build Coastguard Worker "element empty is not empty\n", NULL, NULL);
5507*7c568831SAndroid Build Coastguard Worker }
5508*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(nodes, "notAllowed")) {
5509*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, nodes);
5510*7c568831SAndroid Build Coastguard Worker if (def == NULL)
5511*7c568831SAndroid Build Coastguard Worker return (-1);
5512*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_NOT_ALLOWED;
5513*7c568831SAndroid Build Coastguard Worker if (nodes->children != NULL) {
5514*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, nodes, XML_RNGP_NOTALLOWED_NOT_EMPTY,
5515*7c568831SAndroid Build Coastguard Worker "element notAllowed is not empty\n", NULL, NULL);
5516*7c568831SAndroid Build Coastguard Worker }
5517*7c568831SAndroid Build Coastguard Worker } else {
5518*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGParsePatterns(ctxt, nodes, 1);
5519*7c568831SAndroid Build Coastguard Worker }
5520*7c568831SAndroid Build Coastguard Worker if (ctxt->grammar->start != NULL) {
5521*7c568831SAndroid Build Coastguard Worker last = ctxt->grammar->start;
5522*7c568831SAndroid Build Coastguard Worker while (last->next != NULL)
5523*7c568831SAndroid Build Coastguard Worker last = last->next;
5524*7c568831SAndroid Build Coastguard Worker last->next = def;
5525*7c568831SAndroid Build Coastguard Worker } else {
5526*7c568831SAndroid Build Coastguard Worker ctxt->grammar->start = def;
5527*7c568831SAndroid Build Coastguard Worker }
5528*7c568831SAndroid Build Coastguard Worker nodes = nodes->next;
5529*7c568831SAndroid Build Coastguard Worker if (nodes != NULL) {
5530*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, nodes, XML_RNGP_START_CONTENT,
5531*7c568831SAndroid Build Coastguard Worker "start more than one children\n", NULL, NULL);
5532*7c568831SAndroid Build Coastguard Worker return (-1);
5533*7c568831SAndroid Build Coastguard Worker }
5534*7c568831SAndroid Build Coastguard Worker return (ret);
5535*7c568831SAndroid Build Coastguard Worker }
5536*7c568831SAndroid Build Coastguard Worker
5537*7c568831SAndroid Build Coastguard Worker /**
5538*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParseGrammarContent:
5539*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
5540*7c568831SAndroid Build Coastguard Worker * @nodes: grammar children nodes
5541*7c568831SAndroid Build Coastguard Worker *
5542*7c568831SAndroid Build Coastguard Worker * parse the content of a RelaxNG grammar node.
5543*7c568831SAndroid Build Coastguard Worker *
5544*7c568831SAndroid Build Coastguard Worker * Returns 0 in case of success, -1 in case of error
5545*7c568831SAndroid Build Coastguard Worker */
5546*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGParseGrammarContent(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr nodes)5547*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseGrammarContent(xmlRelaxNGParserCtxtPtr ctxt,
5548*7c568831SAndroid Build Coastguard Worker xmlNodePtr nodes)
5549*7c568831SAndroid Build Coastguard Worker {
5550*7c568831SAndroid Build Coastguard Worker int ret = 0, tmp;
5551*7c568831SAndroid Build Coastguard Worker
5552*7c568831SAndroid Build Coastguard Worker if (nodes == NULL) {
5553*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_EMPTY,
5554*7c568831SAndroid Build Coastguard Worker "grammar has no children\n", NULL, NULL);
5555*7c568831SAndroid Build Coastguard Worker return (-1);
5556*7c568831SAndroid Build Coastguard Worker }
5557*7c568831SAndroid Build Coastguard Worker while (nodes != NULL) {
5558*7c568831SAndroid Build Coastguard Worker if (IS_RELAXNG(nodes, "start")) {
5559*7c568831SAndroid Build Coastguard Worker if (nodes->children == NULL) {
5560*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, nodes, XML_RNGP_START_EMPTY,
5561*7c568831SAndroid Build Coastguard Worker "start has no children\n", NULL, NULL);
5562*7c568831SAndroid Build Coastguard Worker } else {
5563*7c568831SAndroid Build Coastguard Worker tmp = xmlRelaxNGParseStart(ctxt, nodes->children);
5564*7c568831SAndroid Build Coastguard Worker if (tmp != 0)
5565*7c568831SAndroid Build Coastguard Worker ret = -1;
5566*7c568831SAndroid Build Coastguard Worker }
5567*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(nodes, "define")) {
5568*7c568831SAndroid Build Coastguard Worker tmp = xmlRelaxNGParseDefine(ctxt, nodes);
5569*7c568831SAndroid Build Coastguard Worker if (tmp != 0)
5570*7c568831SAndroid Build Coastguard Worker ret = -1;
5571*7c568831SAndroid Build Coastguard Worker } else if (IS_RELAXNG(nodes, "include")) {
5572*7c568831SAndroid Build Coastguard Worker tmp = xmlRelaxNGParseInclude(ctxt, nodes);
5573*7c568831SAndroid Build Coastguard Worker if (tmp != 0)
5574*7c568831SAndroid Build Coastguard Worker ret = -1;
5575*7c568831SAndroid Build Coastguard Worker } else {
5576*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_CONTENT,
5577*7c568831SAndroid Build Coastguard Worker "grammar has unexpected child %s\n", nodes->name,
5578*7c568831SAndroid Build Coastguard Worker NULL);
5579*7c568831SAndroid Build Coastguard Worker ret = -1;
5580*7c568831SAndroid Build Coastguard Worker }
5581*7c568831SAndroid Build Coastguard Worker nodes = nodes->next;
5582*7c568831SAndroid Build Coastguard Worker }
5583*7c568831SAndroid Build Coastguard Worker return (ret);
5584*7c568831SAndroid Build Coastguard Worker }
5585*7c568831SAndroid Build Coastguard Worker
5586*7c568831SAndroid Build Coastguard Worker /**
5587*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGCheckReference:
5588*7c568831SAndroid Build Coastguard Worker * @ref: the ref
5589*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
5590*7c568831SAndroid Build Coastguard Worker * @name: the name associated to the defines
5591*7c568831SAndroid Build Coastguard Worker *
5592*7c568831SAndroid Build Coastguard Worker * Applies the 4.17. combine attribute rule for all the define
5593*7c568831SAndroid Build Coastguard Worker * element of a given grammar using the same name.
5594*7c568831SAndroid Build Coastguard Worker */
5595*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGCheckReference(void * payload,void * data,const xmlChar * name)5596*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckReference(void *payload, void *data, const xmlChar * name)
5597*7c568831SAndroid Build Coastguard Worker {
5598*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr ref = (xmlRelaxNGDefinePtr) payload;
5599*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data;
5600*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGrammarPtr grammar;
5601*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def, cur;
5602*7c568831SAndroid Build Coastguard Worker
5603*7c568831SAndroid Build Coastguard Worker /*
5604*7c568831SAndroid Build Coastguard Worker * Those rules don't apply to imported ref from xmlRelaxNGParseImportRef
5605*7c568831SAndroid Build Coastguard Worker */
5606*7c568831SAndroid Build Coastguard Worker if (ref->dflags & IS_EXTERNAL_REF)
5607*7c568831SAndroid Build Coastguard Worker return;
5608*7c568831SAndroid Build Coastguard Worker
5609*7c568831SAndroid Build Coastguard Worker grammar = ctxt->grammar;
5610*7c568831SAndroid Build Coastguard Worker if (grammar == NULL) {
5611*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, ref->node, XML_ERR_INTERNAL_ERROR,
5612*7c568831SAndroid Build Coastguard Worker "Internal error: no grammar in CheckReference %s\n",
5613*7c568831SAndroid Build Coastguard Worker name, NULL);
5614*7c568831SAndroid Build Coastguard Worker return;
5615*7c568831SAndroid Build Coastguard Worker }
5616*7c568831SAndroid Build Coastguard Worker if (ref->content != NULL) {
5617*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, ref->node, XML_ERR_INTERNAL_ERROR,
5618*7c568831SAndroid Build Coastguard Worker "Internal error: reference has content in CheckReference %s\n",
5619*7c568831SAndroid Build Coastguard Worker name, NULL);
5620*7c568831SAndroid Build Coastguard Worker return;
5621*7c568831SAndroid Build Coastguard Worker }
5622*7c568831SAndroid Build Coastguard Worker if (grammar->defs != NULL) {
5623*7c568831SAndroid Build Coastguard Worker def = xmlHashLookup(grammar->defs, name);
5624*7c568831SAndroid Build Coastguard Worker if (def != NULL) {
5625*7c568831SAndroid Build Coastguard Worker cur = ref;
5626*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
5627*7c568831SAndroid Build Coastguard Worker cur->content = def;
5628*7c568831SAndroid Build Coastguard Worker cur = cur->nextHash;
5629*7c568831SAndroid Build Coastguard Worker }
5630*7c568831SAndroid Build Coastguard Worker } else {
5631*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, ref->node, XML_RNGP_REF_NO_DEF,
5632*7c568831SAndroid Build Coastguard Worker "Reference %s has no matching definition\n", name,
5633*7c568831SAndroid Build Coastguard Worker NULL);
5634*7c568831SAndroid Build Coastguard Worker }
5635*7c568831SAndroid Build Coastguard Worker } else {
5636*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, ref->node, XML_RNGP_REF_NO_DEF,
5637*7c568831SAndroid Build Coastguard Worker "Reference %s has no matching definition\n", name,
5638*7c568831SAndroid Build Coastguard Worker NULL);
5639*7c568831SAndroid Build Coastguard Worker }
5640*7c568831SAndroid Build Coastguard Worker }
5641*7c568831SAndroid Build Coastguard Worker
5642*7c568831SAndroid Build Coastguard Worker /**
5643*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGCheckCombine:
5644*7c568831SAndroid Build Coastguard Worker * @define: the define(s) list
5645*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
5646*7c568831SAndroid Build Coastguard Worker * @name: the name associated to the defines
5647*7c568831SAndroid Build Coastguard Worker *
5648*7c568831SAndroid Build Coastguard Worker * Applies the 4.17. combine attribute rule for all the define
5649*7c568831SAndroid Build Coastguard Worker * element of a given grammar using the same name.
5650*7c568831SAndroid Build Coastguard Worker */
5651*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGCheckCombine(void * payload,void * data,const xmlChar * name)5652*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckCombine(void *payload, void *data, const xmlChar * name)
5653*7c568831SAndroid Build Coastguard Worker {
5654*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr define = (xmlRelaxNGDefinePtr) payload;
5655*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data;
5656*7c568831SAndroid Build Coastguard Worker xmlChar *combine;
5657*7c568831SAndroid Build Coastguard Worker int choiceOrInterleave = -1;
5658*7c568831SAndroid Build Coastguard Worker int missing = 0;
5659*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr cur, last, tmp, tmp2;
5660*7c568831SAndroid Build Coastguard Worker
5661*7c568831SAndroid Build Coastguard Worker if (define->nextHash == NULL)
5662*7c568831SAndroid Build Coastguard Worker return;
5663*7c568831SAndroid Build Coastguard Worker cur = define;
5664*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
5665*7c568831SAndroid Build Coastguard Worker combine = xmlGetProp(cur->node, BAD_CAST "combine");
5666*7c568831SAndroid Build Coastguard Worker if (combine != NULL) {
5667*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual(combine, BAD_CAST "choice")) {
5668*7c568831SAndroid Build Coastguard Worker if (choiceOrInterleave == -1)
5669*7c568831SAndroid Build Coastguard Worker choiceOrInterleave = 1;
5670*7c568831SAndroid Build Coastguard Worker else if (choiceOrInterleave == 0) {
5671*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, define->node, XML_RNGP_DEF_CHOICE_AND_INTERLEAVE,
5672*7c568831SAndroid Build Coastguard Worker "Defines for %s use both 'choice' and 'interleave'\n",
5673*7c568831SAndroid Build Coastguard Worker name, NULL);
5674*7c568831SAndroid Build Coastguard Worker }
5675*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(combine, BAD_CAST "interleave")) {
5676*7c568831SAndroid Build Coastguard Worker if (choiceOrInterleave == -1)
5677*7c568831SAndroid Build Coastguard Worker choiceOrInterleave = 0;
5678*7c568831SAndroid Build Coastguard Worker else if (choiceOrInterleave == 1) {
5679*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, define->node, XML_RNGP_DEF_CHOICE_AND_INTERLEAVE,
5680*7c568831SAndroid Build Coastguard Worker "Defines for %s use both 'choice' and 'interleave'\n",
5681*7c568831SAndroid Build Coastguard Worker name, NULL);
5682*7c568831SAndroid Build Coastguard Worker }
5683*7c568831SAndroid Build Coastguard Worker } else {
5684*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, define->node, XML_RNGP_UNKNOWN_COMBINE,
5685*7c568831SAndroid Build Coastguard Worker "Defines for %s use unknown combine value '%s''\n",
5686*7c568831SAndroid Build Coastguard Worker name, combine);
5687*7c568831SAndroid Build Coastguard Worker }
5688*7c568831SAndroid Build Coastguard Worker xmlFree(combine);
5689*7c568831SAndroid Build Coastguard Worker } else {
5690*7c568831SAndroid Build Coastguard Worker if (missing == 0)
5691*7c568831SAndroid Build Coastguard Worker missing = 1;
5692*7c568831SAndroid Build Coastguard Worker else {
5693*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, define->node, XML_RNGP_NEED_COMBINE,
5694*7c568831SAndroid Build Coastguard Worker "Some defines for %s needs the combine attribute\n",
5695*7c568831SAndroid Build Coastguard Worker name, NULL);
5696*7c568831SAndroid Build Coastguard Worker }
5697*7c568831SAndroid Build Coastguard Worker }
5698*7c568831SAndroid Build Coastguard Worker
5699*7c568831SAndroid Build Coastguard Worker cur = cur->nextHash;
5700*7c568831SAndroid Build Coastguard Worker }
5701*7c568831SAndroid Build Coastguard Worker if (choiceOrInterleave == -1)
5702*7c568831SAndroid Build Coastguard Worker choiceOrInterleave = 0;
5703*7c568831SAndroid Build Coastguard Worker cur = xmlRelaxNGNewDefine(ctxt, define->node);
5704*7c568831SAndroid Build Coastguard Worker if (cur == NULL)
5705*7c568831SAndroid Build Coastguard Worker return;
5706*7c568831SAndroid Build Coastguard Worker if (choiceOrInterleave == 0)
5707*7c568831SAndroid Build Coastguard Worker cur->type = XML_RELAXNG_INTERLEAVE;
5708*7c568831SAndroid Build Coastguard Worker else
5709*7c568831SAndroid Build Coastguard Worker cur->type = XML_RELAXNG_CHOICE;
5710*7c568831SAndroid Build Coastguard Worker tmp = define;
5711*7c568831SAndroid Build Coastguard Worker last = NULL;
5712*7c568831SAndroid Build Coastguard Worker while (tmp != NULL) {
5713*7c568831SAndroid Build Coastguard Worker if (tmp->content != NULL) {
5714*7c568831SAndroid Build Coastguard Worker if (tmp->content->next != NULL) {
5715*7c568831SAndroid Build Coastguard Worker /*
5716*7c568831SAndroid Build Coastguard Worker * we need first to create a wrapper.
5717*7c568831SAndroid Build Coastguard Worker */
5718*7c568831SAndroid Build Coastguard Worker tmp2 = xmlRelaxNGNewDefine(ctxt, tmp->content->node);
5719*7c568831SAndroid Build Coastguard Worker if (tmp2 == NULL)
5720*7c568831SAndroid Build Coastguard Worker break;
5721*7c568831SAndroid Build Coastguard Worker tmp2->type = XML_RELAXNG_GROUP;
5722*7c568831SAndroid Build Coastguard Worker tmp2->content = tmp->content;
5723*7c568831SAndroid Build Coastguard Worker } else {
5724*7c568831SAndroid Build Coastguard Worker tmp2 = tmp->content;
5725*7c568831SAndroid Build Coastguard Worker }
5726*7c568831SAndroid Build Coastguard Worker if (last == NULL) {
5727*7c568831SAndroid Build Coastguard Worker cur->content = tmp2;
5728*7c568831SAndroid Build Coastguard Worker } else {
5729*7c568831SAndroid Build Coastguard Worker last->next = tmp2;
5730*7c568831SAndroid Build Coastguard Worker }
5731*7c568831SAndroid Build Coastguard Worker last = tmp2;
5732*7c568831SAndroid Build Coastguard Worker }
5733*7c568831SAndroid Build Coastguard Worker tmp->content = cur;
5734*7c568831SAndroid Build Coastguard Worker tmp = tmp->nextHash;
5735*7c568831SAndroid Build Coastguard Worker }
5736*7c568831SAndroid Build Coastguard Worker define->content = cur;
5737*7c568831SAndroid Build Coastguard Worker if (choiceOrInterleave == 0) {
5738*7c568831SAndroid Build Coastguard Worker if (ctxt->interleaves == NULL)
5739*7c568831SAndroid Build Coastguard Worker ctxt->interleaves = xmlHashCreate(10);
5740*7c568831SAndroid Build Coastguard Worker if (ctxt->interleaves == NULL) {
5741*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, define->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
5742*7c568831SAndroid Build Coastguard Worker "Failed to create interleaves hash table\n", NULL,
5743*7c568831SAndroid Build Coastguard Worker NULL);
5744*7c568831SAndroid Build Coastguard Worker } else {
5745*7c568831SAndroid Build Coastguard Worker char tmpname[32];
5746*7c568831SAndroid Build Coastguard Worker
5747*7c568831SAndroid Build Coastguard Worker snprintf(tmpname, 32, "interleave%d", ctxt->nbInterleaves++);
5748*7c568831SAndroid Build Coastguard Worker if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST tmpname, cur) <
5749*7c568831SAndroid Build Coastguard Worker 0) {
5750*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, define->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
5751*7c568831SAndroid Build Coastguard Worker "Failed to add %s to hash table\n",
5752*7c568831SAndroid Build Coastguard Worker (const xmlChar *) tmpname, NULL);
5753*7c568831SAndroid Build Coastguard Worker }
5754*7c568831SAndroid Build Coastguard Worker }
5755*7c568831SAndroid Build Coastguard Worker }
5756*7c568831SAndroid Build Coastguard Worker }
5757*7c568831SAndroid Build Coastguard Worker
5758*7c568831SAndroid Build Coastguard Worker /**
5759*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGCombineStart:
5760*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
5761*7c568831SAndroid Build Coastguard Worker * @grammar: the grammar
5762*7c568831SAndroid Build Coastguard Worker *
5763*7c568831SAndroid Build Coastguard Worker * Applies the 4.17. combine rule for all the start
5764*7c568831SAndroid Build Coastguard Worker * element of a given grammar.
5765*7c568831SAndroid Build Coastguard Worker */
5766*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGCombineStart(xmlRelaxNGParserCtxtPtr ctxt,xmlRelaxNGGrammarPtr grammar)5767*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCombineStart(xmlRelaxNGParserCtxtPtr ctxt,
5768*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGrammarPtr grammar)
5769*7c568831SAndroid Build Coastguard Worker {
5770*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr starts;
5771*7c568831SAndroid Build Coastguard Worker xmlChar *combine;
5772*7c568831SAndroid Build Coastguard Worker int choiceOrInterleave = -1;
5773*7c568831SAndroid Build Coastguard Worker int missing = 0;
5774*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr cur;
5775*7c568831SAndroid Build Coastguard Worker
5776*7c568831SAndroid Build Coastguard Worker starts = grammar->start;
5777*7c568831SAndroid Build Coastguard Worker if ((starts == NULL) || (starts->next == NULL))
5778*7c568831SAndroid Build Coastguard Worker return;
5779*7c568831SAndroid Build Coastguard Worker cur = starts;
5780*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
5781*7c568831SAndroid Build Coastguard Worker if ((cur->node == NULL) || (cur->node->parent == NULL) ||
5782*7c568831SAndroid Build Coastguard Worker (!xmlStrEqual(cur->node->parent->name, BAD_CAST "start"))) {
5783*7c568831SAndroid Build Coastguard Worker combine = NULL;
5784*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_START_MISSING,
5785*7c568831SAndroid Build Coastguard Worker "Internal error: start element not found\n", NULL,
5786*7c568831SAndroid Build Coastguard Worker NULL);
5787*7c568831SAndroid Build Coastguard Worker } else {
5788*7c568831SAndroid Build Coastguard Worker combine = xmlGetProp(cur->node->parent, BAD_CAST "combine");
5789*7c568831SAndroid Build Coastguard Worker }
5790*7c568831SAndroid Build Coastguard Worker
5791*7c568831SAndroid Build Coastguard Worker if (combine != NULL) {
5792*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual(combine, BAD_CAST "choice")) {
5793*7c568831SAndroid Build Coastguard Worker if (choiceOrInterleave == -1)
5794*7c568831SAndroid Build Coastguard Worker choiceOrInterleave = 1;
5795*7c568831SAndroid Build Coastguard Worker else if (choiceOrInterleave == 0) {
5796*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_START_CHOICE_AND_INTERLEAVE,
5797*7c568831SAndroid Build Coastguard Worker "<start> use both 'choice' and 'interleave'\n",
5798*7c568831SAndroid Build Coastguard Worker NULL, NULL);
5799*7c568831SAndroid Build Coastguard Worker }
5800*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(combine, BAD_CAST "interleave")) {
5801*7c568831SAndroid Build Coastguard Worker if (choiceOrInterleave == -1)
5802*7c568831SAndroid Build Coastguard Worker choiceOrInterleave = 0;
5803*7c568831SAndroid Build Coastguard Worker else if (choiceOrInterleave == 1) {
5804*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_START_CHOICE_AND_INTERLEAVE,
5805*7c568831SAndroid Build Coastguard Worker "<start> use both 'choice' and 'interleave'\n",
5806*7c568831SAndroid Build Coastguard Worker NULL, NULL);
5807*7c568831SAndroid Build Coastguard Worker }
5808*7c568831SAndroid Build Coastguard Worker } else {
5809*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_UNKNOWN_COMBINE,
5810*7c568831SAndroid Build Coastguard Worker "<start> uses unknown combine value '%s''\n",
5811*7c568831SAndroid Build Coastguard Worker combine, NULL);
5812*7c568831SAndroid Build Coastguard Worker }
5813*7c568831SAndroid Build Coastguard Worker xmlFree(combine);
5814*7c568831SAndroid Build Coastguard Worker } else {
5815*7c568831SAndroid Build Coastguard Worker if (missing == 0)
5816*7c568831SAndroid Build Coastguard Worker missing = 1;
5817*7c568831SAndroid Build Coastguard Worker else {
5818*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_NEED_COMBINE,
5819*7c568831SAndroid Build Coastguard Worker "Some <start> element miss the combine attribute\n",
5820*7c568831SAndroid Build Coastguard Worker NULL, NULL);
5821*7c568831SAndroid Build Coastguard Worker }
5822*7c568831SAndroid Build Coastguard Worker }
5823*7c568831SAndroid Build Coastguard Worker
5824*7c568831SAndroid Build Coastguard Worker cur = cur->next;
5825*7c568831SAndroid Build Coastguard Worker }
5826*7c568831SAndroid Build Coastguard Worker if (choiceOrInterleave == -1)
5827*7c568831SAndroid Build Coastguard Worker choiceOrInterleave = 0;
5828*7c568831SAndroid Build Coastguard Worker cur = xmlRelaxNGNewDefine(ctxt, starts->node);
5829*7c568831SAndroid Build Coastguard Worker if (cur == NULL)
5830*7c568831SAndroid Build Coastguard Worker return;
5831*7c568831SAndroid Build Coastguard Worker if (choiceOrInterleave == 0)
5832*7c568831SAndroid Build Coastguard Worker cur->type = XML_RELAXNG_INTERLEAVE;
5833*7c568831SAndroid Build Coastguard Worker else
5834*7c568831SAndroid Build Coastguard Worker cur->type = XML_RELAXNG_CHOICE;
5835*7c568831SAndroid Build Coastguard Worker cur->content = grammar->start;
5836*7c568831SAndroid Build Coastguard Worker grammar->start = cur;
5837*7c568831SAndroid Build Coastguard Worker if (choiceOrInterleave == 0) {
5838*7c568831SAndroid Build Coastguard Worker if (ctxt->interleaves == NULL)
5839*7c568831SAndroid Build Coastguard Worker ctxt->interleaves = xmlHashCreate(10);
5840*7c568831SAndroid Build Coastguard Worker if (ctxt->interleaves == NULL) {
5841*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
5842*7c568831SAndroid Build Coastguard Worker "Failed to create interleaves hash table\n", NULL,
5843*7c568831SAndroid Build Coastguard Worker NULL);
5844*7c568831SAndroid Build Coastguard Worker } else {
5845*7c568831SAndroid Build Coastguard Worker char tmpname[32];
5846*7c568831SAndroid Build Coastguard Worker
5847*7c568831SAndroid Build Coastguard Worker snprintf(tmpname, 32, "interleave%d", ctxt->nbInterleaves++);
5848*7c568831SAndroid Build Coastguard Worker if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST tmpname, cur) <
5849*7c568831SAndroid Build Coastguard Worker 0) {
5850*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
5851*7c568831SAndroid Build Coastguard Worker "Failed to add %s to hash table\n",
5852*7c568831SAndroid Build Coastguard Worker (const xmlChar *) tmpname, NULL);
5853*7c568831SAndroid Build Coastguard Worker }
5854*7c568831SAndroid Build Coastguard Worker }
5855*7c568831SAndroid Build Coastguard Worker }
5856*7c568831SAndroid Build Coastguard Worker }
5857*7c568831SAndroid Build Coastguard Worker
5858*7c568831SAndroid Build Coastguard Worker /**
5859*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGCheckCycles:
5860*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
5861*7c568831SAndroid Build Coastguard Worker * @nodes: grammar children nodes
5862*7c568831SAndroid Build Coastguard Worker * @depth: the counter
5863*7c568831SAndroid Build Coastguard Worker *
5864*7c568831SAndroid Build Coastguard Worker * Check for cycles.
5865*7c568831SAndroid Build Coastguard Worker *
5866*7c568831SAndroid Build Coastguard Worker * Returns 0 if check passed, and -1 in case of error
5867*7c568831SAndroid Build Coastguard Worker */
5868*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGCheckCycles(xmlRelaxNGParserCtxtPtr ctxt,xmlRelaxNGDefinePtr cur,int depth)5869*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckCycles(xmlRelaxNGParserCtxtPtr ctxt,
5870*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr cur, int depth)
5871*7c568831SAndroid Build Coastguard Worker {
5872*7c568831SAndroid Build Coastguard Worker int ret = 0;
5873*7c568831SAndroid Build Coastguard Worker
5874*7c568831SAndroid Build Coastguard Worker while ((ret == 0) && (cur != NULL)) {
5875*7c568831SAndroid Build Coastguard Worker if ((cur->type == XML_RELAXNG_REF) ||
5876*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_PARENTREF)) {
5877*7c568831SAndroid Build Coastguard Worker if (cur->depth == -1) {
5878*7c568831SAndroid Build Coastguard Worker cur->depth = depth;
5879*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth);
5880*7c568831SAndroid Build Coastguard Worker cur->depth = -2;
5881*7c568831SAndroid Build Coastguard Worker } else if (depth == cur->depth) {
5882*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_CYCLE,
5883*7c568831SAndroid Build Coastguard Worker "Detected a cycle in %s references\n",
5884*7c568831SAndroid Build Coastguard Worker cur->name, NULL);
5885*7c568831SAndroid Build Coastguard Worker return (-1);
5886*7c568831SAndroid Build Coastguard Worker }
5887*7c568831SAndroid Build Coastguard Worker } else if (cur->type == XML_RELAXNG_ELEMENT) {
5888*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth + 1);
5889*7c568831SAndroid Build Coastguard Worker } else {
5890*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth);
5891*7c568831SAndroid Build Coastguard Worker }
5892*7c568831SAndroid Build Coastguard Worker cur = cur->next;
5893*7c568831SAndroid Build Coastguard Worker }
5894*7c568831SAndroid Build Coastguard Worker return (ret);
5895*7c568831SAndroid Build Coastguard Worker }
5896*7c568831SAndroid Build Coastguard Worker
5897*7c568831SAndroid Build Coastguard Worker /**
5898*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGTryUnlink:
5899*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
5900*7c568831SAndroid Build Coastguard Worker * @cur: the definition to unlink
5901*7c568831SAndroid Build Coastguard Worker * @parent: the parent definition
5902*7c568831SAndroid Build Coastguard Worker * @prev: the previous sibling definition
5903*7c568831SAndroid Build Coastguard Worker *
5904*7c568831SAndroid Build Coastguard Worker * Try to unlink a definition. If not possible make it a NOOP
5905*7c568831SAndroid Build Coastguard Worker *
5906*7c568831SAndroid Build Coastguard Worker * Returns the new prev definition
5907*7c568831SAndroid Build Coastguard Worker */
5908*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGDefinePtr
xmlRelaxNGTryUnlink(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,xmlRelaxNGDefinePtr cur,xmlRelaxNGDefinePtr parent,xmlRelaxNGDefinePtr prev)5909*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTryUnlink(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
5910*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr cur,
5911*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr parent, xmlRelaxNGDefinePtr prev)
5912*7c568831SAndroid Build Coastguard Worker {
5913*7c568831SAndroid Build Coastguard Worker if (prev != NULL) {
5914*7c568831SAndroid Build Coastguard Worker prev->next = cur->next;
5915*7c568831SAndroid Build Coastguard Worker } else {
5916*7c568831SAndroid Build Coastguard Worker if (parent != NULL) {
5917*7c568831SAndroid Build Coastguard Worker if (parent->content == cur)
5918*7c568831SAndroid Build Coastguard Worker parent->content = cur->next;
5919*7c568831SAndroid Build Coastguard Worker else if (parent->attrs == cur)
5920*7c568831SAndroid Build Coastguard Worker parent->attrs = cur->next;
5921*7c568831SAndroid Build Coastguard Worker else if (parent->nameClass == cur)
5922*7c568831SAndroid Build Coastguard Worker parent->nameClass = cur->next;
5923*7c568831SAndroid Build Coastguard Worker } else {
5924*7c568831SAndroid Build Coastguard Worker cur->type = XML_RELAXNG_NOOP;
5925*7c568831SAndroid Build Coastguard Worker prev = cur;
5926*7c568831SAndroid Build Coastguard Worker }
5927*7c568831SAndroid Build Coastguard Worker }
5928*7c568831SAndroid Build Coastguard Worker return (prev);
5929*7c568831SAndroid Build Coastguard Worker }
5930*7c568831SAndroid Build Coastguard Worker
5931*7c568831SAndroid Build Coastguard Worker /**
5932*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGSimplify:
5933*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
5934*7c568831SAndroid Build Coastguard Worker * @nodes: grammar children nodes
5935*7c568831SAndroid Build Coastguard Worker *
5936*7c568831SAndroid Build Coastguard Worker * Check for simplification of empty and notAllowed
5937*7c568831SAndroid Build Coastguard Worker */
5938*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGSimplify(xmlRelaxNGParserCtxtPtr ctxt,xmlRelaxNGDefinePtr cur,xmlRelaxNGDefinePtr parent)5939*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSimplify(xmlRelaxNGParserCtxtPtr ctxt,
5940*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr cur, xmlRelaxNGDefinePtr parent)
5941*7c568831SAndroid Build Coastguard Worker {
5942*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr prev = NULL;
5943*7c568831SAndroid Build Coastguard Worker
5944*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
5945*7c568831SAndroid Build Coastguard Worker if ((cur->type == XML_RELAXNG_REF) ||
5946*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_PARENTREF)) {
5947*7c568831SAndroid Build Coastguard Worker if (cur->depth != -3) {
5948*7c568831SAndroid Build Coastguard Worker cur->depth = -3;
5949*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSimplify(ctxt, cur->content, cur);
5950*7c568831SAndroid Build Coastguard Worker }
5951*7c568831SAndroid Build Coastguard Worker } else if (cur->type == XML_RELAXNG_NOT_ALLOWED) {
5952*7c568831SAndroid Build Coastguard Worker cur->parent = parent;
5953*7c568831SAndroid Build Coastguard Worker if ((parent != NULL) &&
5954*7c568831SAndroid Build Coastguard Worker ((parent->type == XML_RELAXNG_ATTRIBUTE) ||
5955*7c568831SAndroid Build Coastguard Worker (parent->type == XML_RELAXNG_LIST) ||
5956*7c568831SAndroid Build Coastguard Worker (parent->type == XML_RELAXNG_GROUP) ||
5957*7c568831SAndroid Build Coastguard Worker (parent->type == XML_RELAXNG_INTERLEAVE) ||
5958*7c568831SAndroid Build Coastguard Worker (parent->type == XML_RELAXNG_ONEORMORE) ||
5959*7c568831SAndroid Build Coastguard Worker (parent->type == XML_RELAXNG_ZEROORMORE))) {
5960*7c568831SAndroid Build Coastguard Worker parent->type = XML_RELAXNG_NOT_ALLOWED;
5961*7c568831SAndroid Build Coastguard Worker break;
5962*7c568831SAndroid Build Coastguard Worker }
5963*7c568831SAndroid Build Coastguard Worker if ((parent != NULL) && (parent->type == XML_RELAXNG_CHOICE)) {
5964*7c568831SAndroid Build Coastguard Worker prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
5965*7c568831SAndroid Build Coastguard Worker } else
5966*7c568831SAndroid Build Coastguard Worker prev = cur;
5967*7c568831SAndroid Build Coastguard Worker } else if (cur->type == XML_RELAXNG_EMPTY) {
5968*7c568831SAndroid Build Coastguard Worker cur->parent = parent;
5969*7c568831SAndroid Build Coastguard Worker if ((parent != NULL) &&
5970*7c568831SAndroid Build Coastguard Worker ((parent->type == XML_RELAXNG_ONEORMORE) ||
5971*7c568831SAndroid Build Coastguard Worker (parent->type == XML_RELAXNG_ZEROORMORE))) {
5972*7c568831SAndroid Build Coastguard Worker parent->type = XML_RELAXNG_EMPTY;
5973*7c568831SAndroid Build Coastguard Worker break;
5974*7c568831SAndroid Build Coastguard Worker }
5975*7c568831SAndroid Build Coastguard Worker if ((parent != NULL) &&
5976*7c568831SAndroid Build Coastguard Worker ((parent->type == XML_RELAXNG_GROUP) ||
5977*7c568831SAndroid Build Coastguard Worker (parent->type == XML_RELAXNG_INTERLEAVE))) {
5978*7c568831SAndroid Build Coastguard Worker prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
5979*7c568831SAndroid Build Coastguard Worker } else
5980*7c568831SAndroid Build Coastguard Worker prev = cur;
5981*7c568831SAndroid Build Coastguard Worker } else {
5982*7c568831SAndroid Build Coastguard Worker cur->parent = parent;
5983*7c568831SAndroid Build Coastguard Worker if (cur->content != NULL)
5984*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSimplify(ctxt, cur->content, cur);
5985*7c568831SAndroid Build Coastguard Worker if ((cur->type != XML_RELAXNG_VALUE) && (cur->attrs != NULL))
5986*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSimplify(ctxt, cur->attrs, cur);
5987*7c568831SAndroid Build Coastguard Worker if (cur->nameClass != NULL)
5988*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSimplify(ctxt, cur->nameClass, cur);
5989*7c568831SAndroid Build Coastguard Worker /*
5990*7c568831SAndroid Build Coastguard Worker * On Elements, try to move attribute only generating rules on
5991*7c568831SAndroid Build Coastguard Worker * the attrs rules.
5992*7c568831SAndroid Build Coastguard Worker */
5993*7c568831SAndroid Build Coastguard Worker if (cur->type == XML_RELAXNG_ELEMENT) {
5994*7c568831SAndroid Build Coastguard Worker int attronly;
5995*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr tmp, pre;
5996*7c568831SAndroid Build Coastguard Worker
5997*7c568831SAndroid Build Coastguard Worker while (cur->content != NULL) {
5998*7c568831SAndroid Build Coastguard Worker attronly =
5999*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGenerateAttributes(ctxt, cur->content);
6000*7c568831SAndroid Build Coastguard Worker if (attronly == 1) {
6001*7c568831SAndroid Build Coastguard Worker /*
6002*7c568831SAndroid Build Coastguard Worker * migrate cur->content to attrs
6003*7c568831SAndroid Build Coastguard Worker */
6004*7c568831SAndroid Build Coastguard Worker tmp = cur->content;
6005*7c568831SAndroid Build Coastguard Worker cur->content = tmp->next;
6006*7c568831SAndroid Build Coastguard Worker tmp->next = cur->attrs;
6007*7c568831SAndroid Build Coastguard Worker cur->attrs = tmp;
6008*7c568831SAndroid Build Coastguard Worker } else {
6009*7c568831SAndroid Build Coastguard Worker /*
6010*7c568831SAndroid Build Coastguard Worker * cur->content can generate elements or text
6011*7c568831SAndroid Build Coastguard Worker */
6012*7c568831SAndroid Build Coastguard Worker break;
6013*7c568831SAndroid Build Coastguard Worker }
6014*7c568831SAndroid Build Coastguard Worker }
6015*7c568831SAndroid Build Coastguard Worker pre = cur->content;
6016*7c568831SAndroid Build Coastguard Worker while ((pre != NULL) && (pre->next != NULL)) {
6017*7c568831SAndroid Build Coastguard Worker tmp = pre->next;
6018*7c568831SAndroid Build Coastguard Worker attronly = xmlRelaxNGGenerateAttributes(ctxt, tmp);
6019*7c568831SAndroid Build Coastguard Worker if (attronly == 1) {
6020*7c568831SAndroid Build Coastguard Worker /*
6021*7c568831SAndroid Build Coastguard Worker * migrate tmp to attrs
6022*7c568831SAndroid Build Coastguard Worker */
6023*7c568831SAndroid Build Coastguard Worker pre->next = tmp->next;
6024*7c568831SAndroid Build Coastguard Worker tmp->next = cur->attrs;
6025*7c568831SAndroid Build Coastguard Worker cur->attrs = tmp;
6026*7c568831SAndroid Build Coastguard Worker } else {
6027*7c568831SAndroid Build Coastguard Worker pre = tmp;
6028*7c568831SAndroid Build Coastguard Worker }
6029*7c568831SAndroid Build Coastguard Worker }
6030*7c568831SAndroid Build Coastguard Worker }
6031*7c568831SAndroid Build Coastguard Worker /*
6032*7c568831SAndroid Build Coastguard Worker * This may result in a simplification
6033*7c568831SAndroid Build Coastguard Worker */
6034*7c568831SAndroid Build Coastguard Worker if ((cur->type == XML_RELAXNG_GROUP) ||
6035*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_INTERLEAVE)) {
6036*7c568831SAndroid Build Coastguard Worker if (cur->content == NULL)
6037*7c568831SAndroid Build Coastguard Worker cur->type = XML_RELAXNG_EMPTY;
6038*7c568831SAndroid Build Coastguard Worker else if (cur->content->next == NULL) {
6039*7c568831SAndroid Build Coastguard Worker if ((parent == NULL) && (prev == NULL)) {
6040*7c568831SAndroid Build Coastguard Worker cur->type = XML_RELAXNG_NOOP;
6041*7c568831SAndroid Build Coastguard Worker } else if (prev == NULL) {
6042*7c568831SAndroid Build Coastguard Worker parent->content = cur->content;
6043*7c568831SAndroid Build Coastguard Worker cur->content->next = cur->next;
6044*7c568831SAndroid Build Coastguard Worker cur = cur->content;
6045*7c568831SAndroid Build Coastguard Worker } else {
6046*7c568831SAndroid Build Coastguard Worker cur->content->next = cur->next;
6047*7c568831SAndroid Build Coastguard Worker prev->next = cur->content;
6048*7c568831SAndroid Build Coastguard Worker cur = cur->content;
6049*7c568831SAndroid Build Coastguard Worker }
6050*7c568831SAndroid Build Coastguard Worker }
6051*7c568831SAndroid Build Coastguard Worker }
6052*7c568831SAndroid Build Coastguard Worker /*
6053*7c568831SAndroid Build Coastguard Worker * the current node may have been transformed back
6054*7c568831SAndroid Build Coastguard Worker */
6055*7c568831SAndroid Build Coastguard Worker if ((cur->type == XML_RELAXNG_EXCEPT) &&
6056*7c568831SAndroid Build Coastguard Worker (cur->content != NULL) &&
6057*7c568831SAndroid Build Coastguard Worker (cur->content->type == XML_RELAXNG_NOT_ALLOWED)) {
6058*7c568831SAndroid Build Coastguard Worker prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
6059*7c568831SAndroid Build Coastguard Worker } else if (cur->type == XML_RELAXNG_NOT_ALLOWED) {
6060*7c568831SAndroid Build Coastguard Worker if ((parent != NULL) &&
6061*7c568831SAndroid Build Coastguard Worker ((parent->type == XML_RELAXNG_ATTRIBUTE) ||
6062*7c568831SAndroid Build Coastguard Worker (parent->type == XML_RELAXNG_LIST) ||
6063*7c568831SAndroid Build Coastguard Worker (parent->type == XML_RELAXNG_GROUP) ||
6064*7c568831SAndroid Build Coastguard Worker (parent->type == XML_RELAXNG_INTERLEAVE) ||
6065*7c568831SAndroid Build Coastguard Worker (parent->type == XML_RELAXNG_ONEORMORE) ||
6066*7c568831SAndroid Build Coastguard Worker (parent->type == XML_RELAXNG_ZEROORMORE))) {
6067*7c568831SAndroid Build Coastguard Worker parent->type = XML_RELAXNG_NOT_ALLOWED;
6068*7c568831SAndroid Build Coastguard Worker break;
6069*7c568831SAndroid Build Coastguard Worker }
6070*7c568831SAndroid Build Coastguard Worker if ((parent != NULL) &&
6071*7c568831SAndroid Build Coastguard Worker (parent->type == XML_RELAXNG_CHOICE)) {
6072*7c568831SAndroid Build Coastguard Worker prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
6073*7c568831SAndroid Build Coastguard Worker } else
6074*7c568831SAndroid Build Coastguard Worker prev = cur;
6075*7c568831SAndroid Build Coastguard Worker } else if (cur->type == XML_RELAXNG_EMPTY) {
6076*7c568831SAndroid Build Coastguard Worker if ((parent != NULL) &&
6077*7c568831SAndroid Build Coastguard Worker ((parent->type == XML_RELAXNG_ONEORMORE) ||
6078*7c568831SAndroid Build Coastguard Worker (parent->type == XML_RELAXNG_ZEROORMORE))) {
6079*7c568831SAndroid Build Coastguard Worker parent->type = XML_RELAXNG_EMPTY;
6080*7c568831SAndroid Build Coastguard Worker break;
6081*7c568831SAndroid Build Coastguard Worker }
6082*7c568831SAndroid Build Coastguard Worker if ((parent != NULL) &&
6083*7c568831SAndroid Build Coastguard Worker ((parent->type == XML_RELAXNG_GROUP) ||
6084*7c568831SAndroid Build Coastguard Worker (parent->type == XML_RELAXNG_INTERLEAVE) ||
6085*7c568831SAndroid Build Coastguard Worker (parent->type == XML_RELAXNG_CHOICE))) {
6086*7c568831SAndroid Build Coastguard Worker prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
6087*7c568831SAndroid Build Coastguard Worker } else
6088*7c568831SAndroid Build Coastguard Worker prev = cur;
6089*7c568831SAndroid Build Coastguard Worker } else {
6090*7c568831SAndroid Build Coastguard Worker prev = cur;
6091*7c568831SAndroid Build Coastguard Worker }
6092*7c568831SAndroid Build Coastguard Worker }
6093*7c568831SAndroid Build Coastguard Worker cur = cur->next;
6094*7c568831SAndroid Build Coastguard Worker }
6095*7c568831SAndroid Build Coastguard Worker }
6096*7c568831SAndroid Build Coastguard Worker
6097*7c568831SAndroid Build Coastguard Worker /**
6098*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGGroupContentType:
6099*7c568831SAndroid Build Coastguard Worker * @ct1: the first content type
6100*7c568831SAndroid Build Coastguard Worker * @ct2: the second content type
6101*7c568831SAndroid Build Coastguard Worker *
6102*7c568831SAndroid Build Coastguard Worker * Try to group 2 content types
6103*7c568831SAndroid Build Coastguard Worker *
6104*7c568831SAndroid Build Coastguard Worker * Returns the content type
6105*7c568831SAndroid Build Coastguard Worker */
6106*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGContentType
xmlRelaxNGGroupContentType(xmlRelaxNGContentType ct1,xmlRelaxNGContentType ct2)6107*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGroupContentType(xmlRelaxNGContentType ct1,
6108*7c568831SAndroid Build Coastguard Worker xmlRelaxNGContentType ct2)
6109*7c568831SAndroid Build Coastguard Worker {
6110*7c568831SAndroid Build Coastguard Worker if ((ct1 == XML_RELAXNG_CONTENT_ERROR) ||
6111*7c568831SAndroid Build Coastguard Worker (ct2 == XML_RELAXNG_CONTENT_ERROR))
6112*7c568831SAndroid Build Coastguard Worker return (XML_RELAXNG_CONTENT_ERROR);
6113*7c568831SAndroid Build Coastguard Worker if (ct1 == XML_RELAXNG_CONTENT_EMPTY)
6114*7c568831SAndroid Build Coastguard Worker return (ct2);
6115*7c568831SAndroid Build Coastguard Worker if (ct2 == XML_RELAXNG_CONTENT_EMPTY)
6116*7c568831SAndroid Build Coastguard Worker return (ct1);
6117*7c568831SAndroid Build Coastguard Worker if ((ct1 == XML_RELAXNG_CONTENT_COMPLEX) &&
6118*7c568831SAndroid Build Coastguard Worker (ct2 == XML_RELAXNG_CONTENT_COMPLEX))
6119*7c568831SAndroid Build Coastguard Worker return (XML_RELAXNG_CONTENT_COMPLEX);
6120*7c568831SAndroid Build Coastguard Worker return (XML_RELAXNG_CONTENT_ERROR);
6121*7c568831SAndroid Build Coastguard Worker }
6122*7c568831SAndroid Build Coastguard Worker
6123*7c568831SAndroid Build Coastguard Worker /**
6124*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGMaxContentType:
6125*7c568831SAndroid Build Coastguard Worker * @ct1: the first content type
6126*7c568831SAndroid Build Coastguard Worker * @ct2: the second content type
6127*7c568831SAndroid Build Coastguard Worker *
6128*7c568831SAndroid Build Coastguard Worker * Compute the max content-type
6129*7c568831SAndroid Build Coastguard Worker *
6130*7c568831SAndroid Build Coastguard Worker * Returns the content type
6131*7c568831SAndroid Build Coastguard Worker */
6132*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGContentType
xmlRelaxNGMaxContentType(xmlRelaxNGContentType ct1,xmlRelaxNGContentType ct2)6133*7c568831SAndroid Build Coastguard Worker xmlRelaxNGMaxContentType(xmlRelaxNGContentType ct1,
6134*7c568831SAndroid Build Coastguard Worker xmlRelaxNGContentType ct2)
6135*7c568831SAndroid Build Coastguard Worker {
6136*7c568831SAndroid Build Coastguard Worker if ((ct1 == XML_RELAXNG_CONTENT_ERROR) ||
6137*7c568831SAndroid Build Coastguard Worker (ct2 == XML_RELAXNG_CONTENT_ERROR))
6138*7c568831SAndroid Build Coastguard Worker return (XML_RELAXNG_CONTENT_ERROR);
6139*7c568831SAndroid Build Coastguard Worker if ((ct1 == XML_RELAXNG_CONTENT_SIMPLE) ||
6140*7c568831SAndroid Build Coastguard Worker (ct2 == XML_RELAXNG_CONTENT_SIMPLE))
6141*7c568831SAndroid Build Coastguard Worker return (XML_RELAXNG_CONTENT_SIMPLE);
6142*7c568831SAndroid Build Coastguard Worker if ((ct1 == XML_RELAXNG_CONTENT_COMPLEX) ||
6143*7c568831SAndroid Build Coastguard Worker (ct2 == XML_RELAXNG_CONTENT_COMPLEX))
6144*7c568831SAndroid Build Coastguard Worker return (XML_RELAXNG_CONTENT_COMPLEX);
6145*7c568831SAndroid Build Coastguard Worker return (XML_RELAXNG_CONTENT_EMPTY);
6146*7c568831SAndroid Build Coastguard Worker }
6147*7c568831SAndroid Build Coastguard Worker
6148*7c568831SAndroid Build Coastguard Worker /**
6149*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGCheckRules:
6150*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
6151*7c568831SAndroid Build Coastguard Worker * @cur: the current definition
6152*7c568831SAndroid Build Coastguard Worker * @flags: some accumulated flags
6153*7c568831SAndroid Build Coastguard Worker * @ptype: the parent type
6154*7c568831SAndroid Build Coastguard Worker *
6155*7c568831SAndroid Build Coastguard Worker * Check for rules in section 7.1 and 7.2
6156*7c568831SAndroid Build Coastguard Worker *
6157*7c568831SAndroid Build Coastguard Worker * Returns the content type of @cur
6158*7c568831SAndroid Build Coastguard Worker */
6159*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGContentType
xmlRelaxNGCheckRules(xmlRelaxNGParserCtxtPtr ctxt,xmlRelaxNGDefinePtr cur,int flags,xmlRelaxNGType ptype)6160*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckRules(xmlRelaxNGParserCtxtPtr ctxt,
6161*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr cur, int flags,
6162*7c568831SAndroid Build Coastguard Worker xmlRelaxNGType ptype)
6163*7c568831SAndroid Build Coastguard Worker {
6164*7c568831SAndroid Build Coastguard Worker int nflags;
6165*7c568831SAndroid Build Coastguard Worker xmlRelaxNGContentType ret, tmp, val = XML_RELAXNG_CONTENT_EMPTY;
6166*7c568831SAndroid Build Coastguard Worker
6167*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
6168*7c568831SAndroid Build Coastguard Worker ret = XML_RELAXNG_CONTENT_EMPTY;
6169*7c568831SAndroid Build Coastguard Worker if ((cur->type == XML_RELAXNG_REF) ||
6170*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_PARENTREF)) {
6171*7c568831SAndroid Build Coastguard Worker /*
6172*7c568831SAndroid Build Coastguard Worker * This should actually be caught by list//element(ref) at the
6173*7c568831SAndroid Build Coastguard Worker * element boundaries, c.f. Bug #159968 local refs are dropped
6174*7c568831SAndroid Build Coastguard Worker * in step 4.19.
6175*7c568831SAndroid Build Coastguard Worker */
6176*7c568831SAndroid Build Coastguard Worker #if 0
6177*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_LIST) {
6178*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_REF,
6179*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern list//ref\n", NULL,
6180*7c568831SAndroid Build Coastguard Worker NULL);
6181*7c568831SAndroid Build Coastguard Worker }
6182*7c568831SAndroid Build Coastguard Worker #endif
6183*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
6184*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_REF,
6185*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern data/except//ref\n",
6186*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6187*7c568831SAndroid Build Coastguard Worker }
6188*7c568831SAndroid Build Coastguard Worker if (cur->content == NULL) {
6189*7c568831SAndroid Build Coastguard Worker if (cur->type == XML_RELAXNG_PARENTREF)
6190*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF,
6191*7c568831SAndroid Build Coastguard Worker "Internal found no define for parent refs\n",
6192*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6193*7c568831SAndroid Build Coastguard Worker else
6194*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF,
6195*7c568831SAndroid Build Coastguard Worker "Internal found no define for ref %s\n",
6196*7c568831SAndroid Build Coastguard Worker (cur->name ? cur->name: BAD_CAST "null"), NULL);
6197*7c568831SAndroid Build Coastguard Worker }
6198*7c568831SAndroid Build Coastguard Worker if (cur->depth > -4) {
6199*7c568831SAndroid Build Coastguard Worker cur->depth = -4;
6200*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGCheckRules(ctxt, cur->content,
6201*7c568831SAndroid Build Coastguard Worker flags, cur->type);
6202*7c568831SAndroid Build Coastguard Worker cur->depth = ret - 15;
6203*7c568831SAndroid Build Coastguard Worker } else if (cur->depth == -4) {
6204*7c568831SAndroid Build Coastguard Worker ret = XML_RELAXNG_CONTENT_COMPLEX;
6205*7c568831SAndroid Build Coastguard Worker } else {
6206*7c568831SAndroid Build Coastguard Worker ret = (xmlRelaxNGContentType) (cur->depth + 15);
6207*7c568831SAndroid Build Coastguard Worker }
6208*7c568831SAndroid Build Coastguard Worker } else if (cur->type == XML_RELAXNG_ELEMENT) {
6209*7c568831SAndroid Build Coastguard Worker /*
6210*7c568831SAndroid Build Coastguard Worker * The 7.3 Attribute derivation rule for groups is plugged there
6211*7c568831SAndroid Build Coastguard Worker */
6212*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckGroupAttrs(ctxt, cur);
6213*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
6214*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_ELEM,
6215*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern data/except//element(ref)\n",
6216*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6217*7c568831SAndroid Build Coastguard Worker }
6218*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_LIST) {
6219*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_ELEM,
6220*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern list//element(ref)\n",
6221*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6222*7c568831SAndroid Build Coastguard Worker }
6223*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
6224*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ATTR_ELEM,
6225*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern attribute//element(ref)\n",
6226*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6227*7c568831SAndroid Build Coastguard Worker }
6228*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
6229*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ATTR_ELEM,
6230*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern attribute//element(ref)\n",
6231*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6232*7c568831SAndroid Build Coastguard Worker }
6233*7c568831SAndroid Build Coastguard Worker /*
6234*7c568831SAndroid Build Coastguard Worker * reset since in the simple form elements are only child
6235*7c568831SAndroid Build Coastguard Worker * of grammar/define
6236*7c568831SAndroid Build Coastguard Worker */
6237*7c568831SAndroid Build Coastguard Worker nflags = 0;
6238*7c568831SAndroid Build Coastguard Worker ret =
6239*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckRules(ctxt, cur->attrs, nflags, cur->type);
6240*7c568831SAndroid Build Coastguard Worker if (ret != XML_RELAXNG_CONTENT_EMPTY) {
6241*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_ELEM_CONTENT_EMPTY,
6242*7c568831SAndroid Build Coastguard Worker "Element %s attributes have a content type error\n",
6243*7c568831SAndroid Build Coastguard Worker cur->name, NULL);
6244*7c568831SAndroid Build Coastguard Worker }
6245*7c568831SAndroid Build Coastguard Worker ret =
6246*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
6247*7c568831SAndroid Build Coastguard Worker cur->type);
6248*7c568831SAndroid Build Coastguard Worker if (ret == XML_RELAXNG_CONTENT_ERROR) {
6249*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_ELEM_CONTENT_ERROR,
6250*7c568831SAndroid Build Coastguard Worker "Element %s has a content type error\n",
6251*7c568831SAndroid Build Coastguard Worker cur->name, NULL);
6252*7c568831SAndroid Build Coastguard Worker } else {
6253*7c568831SAndroid Build Coastguard Worker ret = XML_RELAXNG_CONTENT_COMPLEX;
6254*7c568831SAndroid Build Coastguard Worker }
6255*7c568831SAndroid Build Coastguard Worker } else if (cur->type == XML_RELAXNG_ATTRIBUTE) {
6256*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
6257*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ATTR_ATTR,
6258*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern attribute//attribute\n",
6259*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6260*7c568831SAndroid Build Coastguard Worker }
6261*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_LIST) {
6262*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_ATTR,
6263*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern list//attribute\n",
6264*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6265*7c568831SAndroid Build Coastguard Worker }
6266*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_OOMGROUP) {
6267*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ONEMORE_GROUP_ATTR,
6268*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern oneOrMore//group//attribute\n",
6269*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6270*7c568831SAndroid Build Coastguard Worker }
6271*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_OOMINTERLEAVE) {
6272*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ONEMORE_INTERLEAVE_ATTR,
6273*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern oneOrMore//interleave//attribute\n",
6274*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6275*7c568831SAndroid Build Coastguard Worker }
6276*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
6277*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_ATTR,
6278*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern data/except//attribute\n",
6279*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6280*7c568831SAndroid Build Coastguard Worker }
6281*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_START) {
6282*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_ATTR,
6283*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern start//attribute\n",
6284*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6285*7c568831SAndroid Build Coastguard Worker }
6286*7c568831SAndroid Build Coastguard Worker if ((!(flags & XML_RELAXNG_IN_ONEORMORE))
6287*7c568831SAndroid Build Coastguard Worker && cur->name == NULL
6288*7c568831SAndroid Build Coastguard Worker /* following is checking alternative name class readiness
6289*7c568831SAndroid Build Coastguard Worker in case it went the "choice" route */
6290*7c568831SAndroid Build Coastguard Worker && cur->nameClass == NULL) {
6291*7c568831SAndroid Build Coastguard Worker if (cur->ns == NULL) {
6292*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_ANYNAME_ATTR_ANCESTOR,
6293*7c568831SAndroid Build Coastguard Worker "Found anyName attribute without oneOrMore ancestor\n",
6294*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6295*7c568831SAndroid Build Coastguard Worker } else {
6296*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_NSNAME_ATTR_ANCESTOR,
6297*7c568831SAndroid Build Coastguard Worker "Found nsName attribute without oneOrMore ancestor\n",
6298*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6299*7c568831SAndroid Build Coastguard Worker }
6300*7c568831SAndroid Build Coastguard Worker }
6301*7c568831SAndroid Build Coastguard Worker nflags = flags | XML_RELAXNG_IN_ATTRIBUTE;
6302*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckRules(ctxt, cur->content, nflags, cur->type);
6303*7c568831SAndroid Build Coastguard Worker ret = XML_RELAXNG_CONTENT_EMPTY;
6304*7c568831SAndroid Build Coastguard Worker } else if ((cur->type == XML_RELAXNG_ONEORMORE) ||
6305*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_ZEROORMORE)) {
6306*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
6307*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_ONEMORE,
6308*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern data/except//oneOrMore\n",
6309*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6310*7c568831SAndroid Build Coastguard Worker }
6311*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_START) {
6312*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_ONEMORE,
6313*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern start//oneOrMore\n",
6314*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6315*7c568831SAndroid Build Coastguard Worker }
6316*7c568831SAndroid Build Coastguard Worker nflags = flags | XML_RELAXNG_IN_ONEORMORE;
6317*7c568831SAndroid Build Coastguard Worker ret =
6318*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
6319*7c568831SAndroid Build Coastguard Worker cur->type);
6320*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGGroupContentType(ret, ret);
6321*7c568831SAndroid Build Coastguard Worker } else if (cur->type == XML_RELAXNG_LIST) {
6322*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_LIST) {
6323*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_LIST,
6324*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern list//list\n", NULL,
6325*7c568831SAndroid Build Coastguard Worker NULL);
6326*7c568831SAndroid Build Coastguard Worker }
6327*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
6328*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_LIST,
6329*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern data/except//list\n",
6330*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6331*7c568831SAndroid Build Coastguard Worker }
6332*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_START) {
6333*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_LIST,
6334*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern start//list\n", NULL,
6335*7c568831SAndroid Build Coastguard Worker NULL);
6336*7c568831SAndroid Build Coastguard Worker }
6337*7c568831SAndroid Build Coastguard Worker nflags = flags | XML_RELAXNG_IN_LIST;
6338*7c568831SAndroid Build Coastguard Worker ret =
6339*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
6340*7c568831SAndroid Build Coastguard Worker cur->type);
6341*7c568831SAndroid Build Coastguard Worker } else if (cur->type == XML_RELAXNG_GROUP) {
6342*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
6343*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_GROUP,
6344*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern data/except//group\n",
6345*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6346*7c568831SAndroid Build Coastguard Worker }
6347*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_START) {
6348*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_GROUP,
6349*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern start//group\n", NULL,
6350*7c568831SAndroid Build Coastguard Worker NULL);
6351*7c568831SAndroid Build Coastguard Worker }
6352*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_ONEORMORE)
6353*7c568831SAndroid Build Coastguard Worker nflags = flags | XML_RELAXNG_IN_OOMGROUP;
6354*7c568831SAndroid Build Coastguard Worker else
6355*7c568831SAndroid Build Coastguard Worker nflags = flags;
6356*7c568831SAndroid Build Coastguard Worker ret =
6357*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
6358*7c568831SAndroid Build Coastguard Worker cur->type);
6359*7c568831SAndroid Build Coastguard Worker /*
6360*7c568831SAndroid Build Coastguard Worker * The 7.3 Attribute derivation rule for groups is plugged there
6361*7c568831SAndroid Build Coastguard Worker */
6362*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckGroupAttrs(ctxt, cur);
6363*7c568831SAndroid Build Coastguard Worker } else if (cur->type == XML_RELAXNG_INTERLEAVE) {
6364*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_LIST) {
6365*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_INTERLEAVE,
6366*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern list//interleave\n",
6367*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6368*7c568831SAndroid Build Coastguard Worker }
6369*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
6370*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE,
6371*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern data/except//interleave\n",
6372*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6373*7c568831SAndroid Build Coastguard Worker }
6374*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_START) {
6375*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE,
6376*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern start//interleave\n",
6377*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6378*7c568831SAndroid Build Coastguard Worker }
6379*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_ONEORMORE)
6380*7c568831SAndroid Build Coastguard Worker nflags = flags | XML_RELAXNG_IN_OOMINTERLEAVE;
6381*7c568831SAndroid Build Coastguard Worker else
6382*7c568831SAndroid Build Coastguard Worker nflags = flags;
6383*7c568831SAndroid Build Coastguard Worker ret =
6384*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
6385*7c568831SAndroid Build Coastguard Worker cur->type);
6386*7c568831SAndroid Build Coastguard Worker } else if (cur->type == XML_RELAXNG_EXCEPT) {
6387*7c568831SAndroid Build Coastguard Worker if ((cur->parent != NULL) &&
6388*7c568831SAndroid Build Coastguard Worker (cur->parent->type == XML_RELAXNG_DATATYPE))
6389*7c568831SAndroid Build Coastguard Worker nflags = flags | XML_RELAXNG_IN_DATAEXCEPT;
6390*7c568831SAndroid Build Coastguard Worker else
6391*7c568831SAndroid Build Coastguard Worker nflags = flags;
6392*7c568831SAndroid Build Coastguard Worker ret =
6393*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
6394*7c568831SAndroid Build Coastguard Worker cur->type);
6395*7c568831SAndroid Build Coastguard Worker } else if (cur->type == XML_RELAXNG_DATATYPE) {
6396*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_START) {
6397*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_DATA,
6398*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern start//data\n", NULL,
6399*7c568831SAndroid Build Coastguard Worker NULL);
6400*7c568831SAndroid Build Coastguard Worker }
6401*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
6402*7c568831SAndroid Build Coastguard Worker ret = XML_RELAXNG_CONTENT_SIMPLE;
6403*7c568831SAndroid Build Coastguard Worker } else if (cur->type == XML_RELAXNG_VALUE) {
6404*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_START) {
6405*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_VALUE,
6406*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern start//value\n", NULL,
6407*7c568831SAndroid Build Coastguard Worker NULL);
6408*7c568831SAndroid Build Coastguard Worker }
6409*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
6410*7c568831SAndroid Build Coastguard Worker ret = XML_RELAXNG_CONTENT_SIMPLE;
6411*7c568831SAndroid Build Coastguard Worker } else if (cur->type == XML_RELAXNG_TEXT) {
6412*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_LIST) {
6413*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_TEXT,
6414*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern list//text\n", NULL,
6415*7c568831SAndroid Build Coastguard Worker NULL);
6416*7c568831SAndroid Build Coastguard Worker }
6417*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
6418*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_TEXT,
6419*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern data/except//text\n",
6420*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6421*7c568831SAndroid Build Coastguard Worker }
6422*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_START) {
6423*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_TEXT,
6424*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern start//text\n", NULL,
6425*7c568831SAndroid Build Coastguard Worker NULL);
6426*7c568831SAndroid Build Coastguard Worker }
6427*7c568831SAndroid Build Coastguard Worker ret = XML_RELAXNG_CONTENT_COMPLEX;
6428*7c568831SAndroid Build Coastguard Worker } else if (cur->type == XML_RELAXNG_EMPTY) {
6429*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
6430*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_EMPTY,
6431*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern data/except//empty\n",
6432*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6433*7c568831SAndroid Build Coastguard Worker }
6434*7c568831SAndroid Build Coastguard Worker if (flags & XML_RELAXNG_IN_START) {
6435*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_EMPTY,
6436*7c568831SAndroid Build Coastguard Worker "Found forbidden pattern start//empty\n", NULL,
6437*7c568831SAndroid Build Coastguard Worker NULL);
6438*7c568831SAndroid Build Coastguard Worker }
6439*7c568831SAndroid Build Coastguard Worker ret = XML_RELAXNG_CONTENT_EMPTY;
6440*7c568831SAndroid Build Coastguard Worker } else if (cur->type == XML_RELAXNG_CHOICE) {
6441*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckChoiceDeterminism(ctxt, cur);
6442*7c568831SAndroid Build Coastguard Worker ret =
6443*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
6444*7c568831SAndroid Build Coastguard Worker } else {
6445*7c568831SAndroid Build Coastguard Worker ret =
6446*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
6447*7c568831SAndroid Build Coastguard Worker }
6448*7c568831SAndroid Build Coastguard Worker cur = cur->next;
6449*7c568831SAndroid Build Coastguard Worker if (ptype == XML_RELAXNG_GROUP) {
6450*7c568831SAndroid Build Coastguard Worker val = xmlRelaxNGGroupContentType(val, ret);
6451*7c568831SAndroid Build Coastguard Worker } else if (ptype == XML_RELAXNG_INTERLEAVE) {
6452*7c568831SAndroid Build Coastguard Worker /*
6453*7c568831SAndroid Build Coastguard Worker * TODO: scan complain that tmp is never used, seems on purpose
6454*7c568831SAndroid Build Coastguard Worker * need double-checking
6455*7c568831SAndroid Build Coastguard Worker */
6456*7c568831SAndroid Build Coastguard Worker tmp = xmlRelaxNGGroupContentType(val, ret);
6457*7c568831SAndroid Build Coastguard Worker if (tmp != XML_RELAXNG_CONTENT_ERROR)
6458*7c568831SAndroid Build Coastguard Worker tmp = xmlRelaxNGMaxContentType(val, ret);
6459*7c568831SAndroid Build Coastguard Worker } else if (ptype == XML_RELAXNG_CHOICE) {
6460*7c568831SAndroid Build Coastguard Worker val = xmlRelaxNGMaxContentType(val, ret);
6461*7c568831SAndroid Build Coastguard Worker } else if (ptype == XML_RELAXNG_LIST) {
6462*7c568831SAndroid Build Coastguard Worker val = XML_RELAXNG_CONTENT_SIMPLE;
6463*7c568831SAndroid Build Coastguard Worker } else if (ptype == XML_RELAXNG_EXCEPT) {
6464*7c568831SAndroid Build Coastguard Worker if (ret == XML_RELAXNG_CONTENT_ERROR)
6465*7c568831SAndroid Build Coastguard Worker val = XML_RELAXNG_CONTENT_ERROR;
6466*7c568831SAndroid Build Coastguard Worker else
6467*7c568831SAndroid Build Coastguard Worker val = XML_RELAXNG_CONTENT_SIMPLE;
6468*7c568831SAndroid Build Coastguard Worker } else {
6469*7c568831SAndroid Build Coastguard Worker val = xmlRelaxNGGroupContentType(val, ret);
6470*7c568831SAndroid Build Coastguard Worker }
6471*7c568831SAndroid Build Coastguard Worker
6472*7c568831SAndroid Build Coastguard Worker }
6473*7c568831SAndroid Build Coastguard Worker return (val);
6474*7c568831SAndroid Build Coastguard Worker }
6475*7c568831SAndroid Build Coastguard Worker
6476*7c568831SAndroid Build Coastguard Worker /**
6477*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParseGrammar:
6478*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
6479*7c568831SAndroid Build Coastguard Worker * @nodes: grammar children nodes
6480*7c568831SAndroid Build Coastguard Worker *
6481*7c568831SAndroid Build Coastguard Worker * parse a Relax-NG <grammar> node
6482*7c568831SAndroid Build Coastguard Worker *
6483*7c568831SAndroid Build Coastguard Worker * Returns the internal xmlRelaxNGGrammarPtr built or
6484*7c568831SAndroid Build Coastguard Worker * NULL in case of error
6485*7c568831SAndroid Build Coastguard Worker */
6486*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGGrammarPtr
xmlRelaxNGParseGrammar(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr nodes)6487*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseGrammar(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes)
6488*7c568831SAndroid Build Coastguard Worker {
6489*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGrammarPtr ret, tmp, old;
6490*7c568831SAndroid Build Coastguard Worker
6491*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGNewGrammar(ctxt);
6492*7c568831SAndroid Build Coastguard Worker if (ret == NULL)
6493*7c568831SAndroid Build Coastguard Worker return (NULL);
6494*7c568831SAndroid Build Coastguard Worker
6495*7c568831SAndroid Build Coastguard Worker /*
6496*7c568831SAndroid Build Coastguard Worker * Link the new grammar in the tree
6497*7c568831SAndroid Build Coastguard Worker */
6498*7c568831SAndroid Build Coastguard Worker ret->parent = ctxt->grammar;
6499*7c568831SAndroid Build Coastguard Worker if (ctxt->grammar != NULL) {
6500*7c568831SAndroid Build Coastguard Worker tmp = ctxt->grammar->children;
6501*7c568831SAndroid Build Coastguard Worker if (tmp == NULL) {
6502*7c568831SAndroid Build Coastguard Worker ctxt->grammar->children = ret;
6503*7c568831SAndroid Build Coastguard Worker } else {
6504*7c568831SAndroid Build Coastguard Worker while (tmp->next != NULL)
6505*7c568831SAndroid Build Coastguard Worker tmp = tmp->next;
6506*7c568831SAndroid Build Coastguard Worker tmp->next = ret;
6507*7c568831SAndroid Build Coastguard Worker }
6508*7c568831SAndroid Build Coastguard Worker }
6509*7c568831SAndroid Build Coastguard Worker
6510*7c568831SAndroid Build Coastguard Worker old = ctxt->grammar;
6511*7c568831SAndroid Build Coastguard Worker ctxt->grammar = ret;
6512*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseGrammarContent(ctxt, nodes);
6513*7c568831SAndroid Build Coastguard Worker ctxt->grammar = ret;
6514*7c568831SAndroid Build Coastguard Worker if (ctxt->grammar == NULL) {
6515*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_CONTENT,
6516*7c568831SAndroid Build Coastguard Worker "Failed to parse <grammar> content\n", NULL, NULL);
6517*7c568831SAndroid Build Coastguard Worker } else if (ctxt->grammar->start == NULL) {
6518*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_NO_START,
6519*7c568831SAndroid Build Coastguard Worker "Element <grammar> has no <start>\n", NULL, NULL);
6520*7c568831SAndroid Build Coastguard Worker }
6521*7c568831SAndroid Build Coastguard Worker
6522*7c568831SAndroid Build Coastguard Worker /*
6523*7c568831SAndroid Build Coastguard Worker * Apply 4.17 merging rules to defines and starts
6524*7c568831SAndroid Build Coastguard Worker */
6525*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCombineStart(ctxt, ret);
6526*7c568831SAndroid Build Coastguard Worker if (ret->defs != NULL) {
6527*7c568831SAndroid Build Coastguard Worker xmlHashScan(ret->defs, xmlRelaxNGCheckCombine, ctxt);
6528*7c568831SAndroid Build Coastguard Worker }
6529*7c568831SAndroid Build Coastguard Worker
6530*7c568831SAndroid Build Coastguard Worker /*
6531*7c568831SAndroid Build Coastguard Worker * link together defines and refs in this grammar
6532*7c568831SAndroid Build Coastguard Worker */
6533*7c568831SAndroid Build Coastguard Worker if (ret->refs != NULL) {
6534*7c568831SAndroid Build Coastguard Worker xmlHashScan(ret->refs, xmlRelaxNGCheckReference, ctxt);
6535*7c568831SAndroid Build Coastguard Worker }
6536*7c568831SAndroid Build Coastguard Worker
6537*7c568831SAndroid Build Coastguard Worker
6538*7c568831SAndroid Build Coastguard Worker /* @@@@ */
6539*7c568831SAndroid Build Coastguard Worker
6540*7c568831SAndroid Build Coastguard Worker ctxt->grammar = old;
6541*7c568831SAndroid Build Coastguard Worker return (ret);
6542*7c568831SAndroid Build Coastguard Worker }
6543*7c568831SAndroid Build Coastguard Worker
6544*7c568831SAndroid Build Coastguard Worker /**
6545*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParseDocument:
6546*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
6547*7c568831SAndroid Build Coastguard Worker * @node: the root node of the RelaxNG schema
6548*7c568831SAndroid Build Coastguard Worker *
6549*7c568831SAndroid Build Coastguard Worker * parse a Relax-NG definition resource and build an internal
6550*7c568831SAndroid Build Coastguard Worker * xmlRelaxNG structure which can be used to validate instances.
6551*7c568831SAndroid Build Coastguard Worker *
6552*7c568831SAndroid Build Coastguard Worker * Returns the internal XML RelaxNG structure built or
6553*7c568831SAndroid Build Coastguard Worker * NULL in case of error
6554*7c568831SAndroid Build Coastguard Worker */
6555*7c568831SAndroid Build Coastguard Worker static xmlRelaxNGPtr
xmlRelaxNGParseDocument(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr node)6556*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseDocument(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
6557*7c568831SAndroid Build Coastguard Worker {
6558*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPtr schema = NULL;
6559*7c568831SAndroid Build Coastguard Worker const xmlChar *olddefine;
6560*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGrammarPtr old;
6561*7c568831SAndroid Build Coastguard Worker
6562*7c568831SAndroid Build Coastguard Worker if ((ctxt == NULL) || (node == NULL))
6563*7c568831SAndroid Build Coastguard Worker return (NULL);
6564*7c568831SAndroid Build Coastguard Worker
6565*7c568831SAndroid Build Coastguard Worker schema = xmlRelaxNGNewRelaxNG(ctxt);
6566*7c568831SAndroid Build Coastguard Worker if (schema == NULL)
6567*7c568831SAndroid Build Coastguard Worker return (NULL);
6568*7c568831SAndroid Build Coastguard Worker
6569*7c568831SAndroid Build Coastguard Worker olddefine = ctxt->define;
6570*7c568831SAndroid Build Coastguard Worker ctxt->define = NULL;
6571*7c568831SAndroid Build Coastguard Worker if (IS_RELAXNG(node, "grammar")) {
6572*7c568831SAndroid Build Coastguard Worker schema->topgrammar = xmlRelaxNGParseGrammar(ctxt, node->children);
6573*7c568831SAndroid Build Coastguard Worker if (schema->topgrammar == NULL) {
6574*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFree(schema);
6575*7c568831SAndroid Build Coastguard Worker return (NULL);
6576*7c568831SAndroid Build Coastguard Worker }
6577*7c568831SAndroid Build Coastguard Worker } else {
6578*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGrammarPtr tmp, ret;
6579*7c568831SAndroid Build Coastguard Worker
6580*7c568831SAndroid Build Coastguard Worker schema->topgrammar = ret = xmlRelaxNGNewGrammar(ctxt);
6581*7c568831SAndroid Build Coastguard Worker if (schema->topgrammar == NULL) {
6582*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFree(schema);
6583*7c568831SAndroid Build Coastguard Worker return (NULL);
6584*7c568831SAndroid Build Coastguard Worker }
6585*7c568831SAndroid Build Coastguard Worker /*
6586*7c568831SAndroid Build Coastguard Worker * Link the new grammar in the tree
6587*7c568831SAndroid Build Coastguard Worker */
6588*7c568831SAndroid Build Coastguard Worker ret->parent = ctxt->grammar;
6589*7c568831SAndroid Build Coastguard Worker if (ctxt->grammar != NULL) {
6590*7c568831SAndroid Build Coastguard Worker tmp = ctxt->grammar->children;
6591*7c568831SAndroid Build Coastguard Worker if (tmp == NULL) {
6592*7c568831SAndroid Build Coastguard Worker ctxt->grammar->children = ret;
6593*7c568831SAndroid Build Coastguard Worker } else {
6594*7c568831SAndroid Build Coastguard Worker while (tmp->next != NULL)
6595*7c568831SAndroid Build Coastguard Worker tmp = tmp->next;
6596*7c568831SAndroid Build Coastguard Worker tmp->next = ret;
6597*7c568831SAndroid Build Coastguard Worker }
6598*7c568831SAndroid Build Coastguard Worker }
6599*7c568831SAndroid Build Coastguard Worker old = ctxt->grammar;
6600*7c568831SAndroid Build Coastguard Worker ctxt->grammar = ret;
6601*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParseStart(ctxt, node);
6602*7c568831SAndroid Build Coastguard Worker if (old != NULL)
6603*7c568831SAndroid Build Coastguard Worker ctxt->grammar = old;
6604*7c568831SAndroid Build Coastguard Worker }
6605*7c568831SAndroid Build Coastguard Worker ctxt->define = olddefine;
6606*7c568831SAndroid Build Coastguard Worker if (schema->topgrammar->start != NULL) {
6607*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckCycles(ctxt, schema->topgrammar->start, 0);
6608*7c568831SAndroid Build Coastguard Worker if ((ctxt->flags & XML_RELAXNG_IN_EXTERNALREF) == 0) {
6609*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSimplify(ctxt, schema->topgrammar->start, NULL);
6610*7c568831SAndroid Build Coastguard Worker while ((schema->topgrammar->start != NULL) &&
6611*7c568831SAndroid Build Coastguard Worker (schema->topgrammar->start->type == XML_RELAXNG_NOOP) &&
6612*7c568831SAndroid Build Coastguard Worker (schema->topgrammar->start->next != NULL))
6613*7c568831SAndroid Build Coastguard Worker schema->topgrammar->start =
6614*7c568831SAndroid Build Coastguard Worker schema->topgrammar->start->content;
6615*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCheckRules(ctxt, schema->topgrammar->start,
6616*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_IN_START, XML_RELAXNG_NOOP);
6617*7c568831SAndroid Build Coastguard Worker }
6618*7c568831SAndroid Build Coastguard Worker }
6619*7c568831SAndroid Build Coastguard Worker
6620*7c568831SAndroid Build Coastguard Worker return (schema);
6621*7c568831SAndroid Build Coastguard Worker }
6622*7c568831SAndroid Build Coastguard Worker
6623*7c568831SAndroid Build Coastguard Worker /************************************************************************
6624*7c568831SAndroid Build Coastguard Worker * *
6625*7c568831SAndroid Build Coastguard Worker * Reading RelaxNGs *
6626*7c568831SAndroid Build Coastguard Worker * *
6627*7c568831SAndroid Build Coastguard Worker ************************************************************************/
6628*7c568831SAndroid Build Coastguard Worker
6629*7c568831SAndroid Build Coastguard Worker /**
6630*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGNewParserCtxt:
6631*7c568831SAndroid Build Coastguard Worker * @URL: the location of the schema
6632*7c568831SAndroid Build Coastguard Worker *
6633*7c568831SAndroid Build Coastguard Worker * Create an XML RelaxNGs parse context for that file/resource expected
6634*7c568831SAndroid Build Coastguard Worker * to contain an XML RelaxNGs file.
6635*7c568831SAndroid Build Coastguard Worker *
6636*7c568831SAndroid Build Coastguard Worker * Returns the parser context or NULL in case of error
6637*7c568831SAndroid Build Coastguard Worker */
6638*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParserCtxtPtr
xmlRelaxNGNewParserCtxt(const char * URL)6639*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNewParserCtxt(const char *URL)
6640*7c568831SAndroid Build Coastguard Worker {
6641*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParserCtxtPtr ret;
6642*7c568831SAndroid Build Coastguard Worker
6643*7c568831SAndroid Build Coastguard Worker if (URL == NULL)
6644*7c568831SAndroid Build Coastguard Worker return (NULL);
6645*7c568831SAndroid Build Coastguard Worker
6646*7c568831SAndroid Build Coastguard Worker ret =
6647*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
6648*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
6649*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(NULL);
6650*7c568831SAndroid Build Coastguard Worker return (NULL);
6651*7c568831SAndroid Build Coastguard Worker }
6652*7c568831SAndroid Build Coastguard Worker memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
6653*7c568831SAndroid Build Coastguard Worker ret->URL = xmlStrdup((const xmlChar *) URL);
6654*7c568831SAndroid Build Coastguard Worker return (ret);
6655*7c568831SAndroid Build Coastguard Worker }
6656*7c568831SAndroid Build Coastguard Worker
6657*7c568831SAndroid Build Coastguard Worker /**
6658*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGNewMemParserCtxt:
6659*7c568831SAndroid Build Coastguard Worker * @buffer: a pointer to a char array containing the schemas
6660*7c568831SAndroid Build Coastguard Worker * @size: the size of the array
6661*7c568831SAndroid Build Coastguard Worker *
6662*7c568831SAndroid Build Coastguard Worker * Create an XML RelaxNGs parse context for that memory buffer expected
6663*7c568831SAndroid Build Coastguard Worker * to contain an XML RelaxNGs file.
6664*7c568831SAndroid Build Coastguard Worker *
6665*7c568831SAndroid Build Coastguard Worker * Returns the parser context or NULL in case of error
6666*7c568831SAndroid Build Coastguard Worker */
6667*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParserCtxtPtr
xmlRelaxNGNewMemParserCtxt(const char * buffer,int size)6668*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNewMemParserCtxt(const char *buffer, int size)
6669*7c568831SAndroid Build Coastguard Worker {
6670*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParserCtxtPtr ret;
6671*7c568831SAndroid Build Coastguard Worker
6672*7c568831SAndroid Build Coastguard Worker if ((buffer == NULL) || (size <= 0))
6673*7c568831SAndroid Build Coastguard Worker return (NULL);
6674*7c568831SAndroid Build Coastguard Worker
6675*7c568831SAndroid Build Coastguard Worker ret =
6676*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
6677*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
6678*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(NULL);
6679*7c568831SAndroid Build Coastguard Worker return (NULL);
6680*7c568831SAndroid Build Coastguard Worker }
6681*7c568831SAndroid Build Coastguard Worker memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
6682*7c568831SAndroid Build Coastguard Worker ret->buffer = buffer;
6683*7c568831SAndroid Build Coastguard Worker ret->size = size;
6684*7c568831SAndroid Build Coastguard Worker return (ret);
6685*7c568831SAndroid Build Coastguard Worker }
6686*7c568831SAndroid Build Coastguard Worker
6687*7c568831SAndroid Build Coastguard Worker /**
6688*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGNewDocParserCtxt:
6689*7c568831SAndroid Build Coastguard Worker * @doc: a preparsed document tree
6690*7c568831SAndroid Build Coastguard Worker *
6691*7c568831SAndroid Build Coastguard Worker * Create an XML RelaxNGs parser context for that document.
6692*7c568831SAndroid Build Coastguard Worker * Note: since the process of compiling a RelaxNG schemas modifies the
6693*7c568831SAndroid Build Coastguard Worker * document, the @doc parameter is duplicated internally.
6694*7c568831SAndroid Build Coastguard Worker *
6695*7c568831SAndroid Build Coastguard Worker * Returns the parser context or NULL in case of error
6696*7c568831SAndroid Build Coastguard Worker */
6697*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParserCtxtPtr
xmlRelaxNGNewDocParserCtxt(xmlDocPtr doc)6698*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNewDocParserCtxt(xmlDocPtr doc)
6699*7c568831SAndroid Build Coastguard Worker {
6700*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParserCtxtPtr ret;
6701*7c568831SAndroid Build Coastguard Worker xmlDocPtr copy;
6702*7c568831SAndroid Build Coastguard Worker
6703*7c568831SAndroid Build Coastguard Worker if (doc == NULL)
6704*7c568831SAndroid Build Coastguard Worker return (NULL);
6705*7c568831SAndroid Build Coastguard Worker copy = xmlCopyDoc(doc, 1);
6706*7c568831SAndroid Build Coastguard Worker if (copy == NULL)
6707*7c568831SAndroid Build Coastguard Worker return (NULL);
6708*7c568831SAndroid Build Coastguard Worker
6709*7c568831SAndroid Build Coastguard Worker ret =
6710*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
6711*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
6712*7c568831SAndroid Build Coastguard Worker xmlRngPErrMemory(NULL);
6713*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(copy);
6714*7c568831SAndroid Build Coastguard Worker return (NULL);
6715*7c568831SAndroid Build Coastguard Worker }
6716*7c568831SAndroid Build Coastguard Worker memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
6717*7c568831SAndroid Build Coastguard Worker ret->document = copy;
6718*7c568831SAndroid Build Coastguard Worker ret->freedoc = 1;
6719*7c568831SAndroid Build Coastguard Worker ret->userData = xmlGenericErrorContext;
6720*7c568831SAndroid Build Coastguard Worker return (ret);
6721*7c568831SAndroid Build Coastguard Worker }
6722*7c568831SAndroid Build Coastguard Worker
6723*7c568831SAndroid Build Coastguard Worker /**
6724*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGFreeParserCtxt:
6725*7c568831SAndroid Build Coastguard Worker * @ctxt: the schema parser context
6726*7c568831SAndroid Build Coastguard Worker *
6727*7c568831SAndroid Build Coastguard Worker * Free the resources associated to the schema parser context
6728*7c568831SAndroid Build Coastguard Worker */
6729*7c568831SAndroid Build Coastguard Worker void
xmlRelaxNGFreeParserCtxt(xmlRelaxNGParserCtxtPtr ctxt)6730*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeParserCtxt(xmlRelaxNGParserCtxtPtr ctxt)
6731*7c568831SAndroid Build Coastguard Worker {
6732*7c568831SAndroid Build Coastguard Worker if (ctxt == NULL)
6733*7c568831SAndroid Build Coastguard Worker return;
6734*7c568831SAndroid Build Coastguard Worker if (ctxt->URL != NULL)
6735*7c568831SAndroid Build Coastguard Worker xmlFree(ctxt->URL);
6736*7c568831SAndroid Build Coastguard Worker if (ctxt->doc != NULL)
6737*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeDocument(ctxt->doc);
6738*7c568831SAndroid Build Coastguard Worker if (ctxt->interleaves != NULL)
6739*7c568831SAndroid Build Coastguard Worker xmlHashFree(ctxt->interleaves, NULL);
6740*7c568831SAndroid Build Coastguard Worker if (ctxt->documents != NULL)
6741*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeDocumentList(ctxt->documents);
6742*7c568831SAndroid Build Coastguard Worker if (ctxt->includes != NULL)
6743*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeIncludeList(ctxt->includes);
6744*7c568831SAndroid Build Coastguard Worker if (ctxt->docTab != NULL)
6745*7c568831SAndroid Build Coastguard Worker xmlFree(ctxt->docTab);
6746*7c568831SAndroid Build Coastguard Worker if (ctxt->incTab != NULL)
6747*7c568831SAndroid Build Coastguard Worker xmlFree(ctxt->incTab);
6748*7c568831SAndroid Build Coastguard Worker if (ctxt->defTab != NULL) {
6749*7c568831SAndroid Build Coastguard Worker int i;
6750*7c568831SAndroid Build Coastguard Worker
6751*7c568831SAndroid Build Coastguard Worker for (i = 0; i < ctxt->defNr; i++)
6752*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeDefine(ctxt->defTab[i]);
6753*7c568831SAndroid Build Coastguard Worker xmlFree(ctxt->defTab);
6754*7c568831SAndroid Build Coastguard Worker }
6755*7c568831SAndroid Build Coastguard Worker if ((ctxt->document != NULL) && (ctxt->freedoc))
6756*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(ctxt->document);
6757*7c568831SAndroid Build Coastguard Worker xmlFree(ctxt);
6758*7c568831SAndroid Build Coastguard Worker }
6759*7c568831SAndroid Build Coastguard Worker
6760*7c568831SAndroid Build Coastguard Worker /**
6761*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGNormExtSpace:
6762*7c568831SAndroid Build Coastguard Worker * @value: a value
6763*7c568831SAndroid Build Coastguard Worker *
6764*7c568831SAndroid Build Coastguard Worker * Removes the leading and ending spaces of the value
6765*7c568831SAndroid Build Coastguard Worker * The string is modified "in situ"
6766*7c568831SAndroid Build Coastguard Worker */
6767*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGNormExtSpace(xmlChar * value)6768*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNormExtSpace(xmlChar * value)
6769*7c568831SAndroid Build Coastguard Worker {
6770*7c568831SAndroid Build Coastguard Worker xmlChar *start = value;
6771*7c568831SAndroid Build Coastguard Worker xmlChar *cur = value;
6772*7c568831SAndroid Build Coastguard Worker
6773*7c568831SAndroid Build Coastguard Worker if (value == NULL)
6774*7c568831SAndroid Build Coastguard Worker return;
6775*7c568831SAndroid Build Coastguard Worker
6776*7c568831SAndroid Build Coastguard Worker while (IS_BLANK_CH(*cur))
6777*7c568831SAndroid Build Coastguard Worker cur++;
6778*7c568831SAndroid Build Coastguard Worker if (cur == start) {
6779*7c568831SAndroid Build Coastguard Worker do {
6780*7c568831SAndroid Build Coastguard Worker while ((*cur != 0) && (!IS_BLANK_CH(*cur)))
6781*7c568831SAndroid Build Coastguard Worker cur++;
6782*7c568831SAndroid Build Coastguard Worker if (*cur == 0)
6783*7c568831SAndroid Build Coastguard Worker return;
6784*7c568831SAndroid Build Coastguard Worker start = cur;
6785*7c568831SAndroid Build Coastguard Worker while (IS_BLANK_CH(*cur))
6786*7c568831SAndroid Build Coastguard Worker cur++;
6787*7c568831SAndroid Build Coastguard Worker if (*cur == 0) {
6788*7c568831SAndroid Build Coastguard Worker *start = 0;
6789*7c568831SAndroid Build Coastguard Worker return;
6790*7c568831SAndroid Build Coastguard Worker }
6791*7c568831SAndroid Build Coastguard Worker } while (1);
6792*7c568831SAndroid Build Coastguard Worker } else {
6793*7c568831SAndroid Build Coastguard Worker do {
6794*7c568831SAndroid Build Coastguard Worker while ((*cur != 0) && (!IS_BLANK_CH(*cur)))
6795*7c568831SAndroid Build Coastguard Worker *start++ = *cur++;
6796*7c568831SAndroid Build Coastguard Worker if (*cur == 0) {
6797*7c568831SAndroid Build Coastguard Worker *start = 0;
6798*7c568831SAndroid Build Coastguard Worker return;
6799*7c568831SAndroid Build Coastguard Worker }
6800*7c568831SAndroid Build Coastguard Worker /* don't try to normalize the inner spaces */
6801*7c568831SAndroid Build Coastguard Worker while (IS_BLANK_CH(*cur))
6802*7c568831SAndroid Build Coastguard Worker cur++;
6803*7c568831SAndroid Build Coastguard Worker if (*cur == 0) {
6804*7c568831SAndroid Build Coastguard Worker *start = 0;
6805*7c568831SAndroid Build Coastguard Worker return;
6806*7c568831SAndroid Build Coastguard Worker }
6807*7c568831SAndroid Build Coastguard Worker *start++ = *cur++;
6808*7c568831SAndroid Build Coastguard Worker } while (1);
6809*7c568831SAndroid Build Coastguard Worker }
6810*7c568831SAndroid Build Coastguard Worker }
6811*7c568831SAndroid Build Coastguard Worker
6812*7c568831SAndroid Build Coastguard Worker /**
6813*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGCleanupAttributes:
6814*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
6815*7c568831SAndroid Build Coastguard Worker * @node: a Relax-NG node
6816*7c568831SAndroid Build Coastguard Worker *
6817*7c568831SAndroid Build Coastguard Worker * Check all the attributes on the given node
6818*7c568831SAndroid Build Coastguard Worker */
6819*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGCleanupAttributes(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr node)6820*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCleanupAttributes(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
6821*7c568831SAndroid Build Coastguard Worker {
6822*7c568831SAndroid Build Coastguard Worker xmlAttrPtr cur, next;
6823*7c568831SAndroid Build Coastguard Worker
6824*7c568831SAndroid Build Coastguard Worker cur = node->properties;
6825*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
6826*7c568831SAndroid Build Coastguard Worker next = cur->next;
6827*7c568831SAndroid Build Coastguard Worker if ((cur->ns == NULL) ||
6828*7c568831SAndroid Build Coastguard Worker (xmlStrEqual(cur->ns->href, xmlRelaxNGNs))) {
6829*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual(cur->name, BAD_CAST "name")) {
6830*7c568831SAndroid Build Coastguard Worker if ((!xmlStrEqual(node->name, BAD_CAST "element")) &&
6831*7c568831SAndroid Build Coastguard Worker (!xmlStrEqual(node->name, BAD_CAST "attribute")) &&
6832*7c568831SAndroid Build Coastguard Worker (!xmlStrEqual(node->name, BAD_CAST "ref")) &&
6833*7c568831SAndroid Build Coastguard Worker (!xmlStrEqual(node->name, BAD_CAST "parentRef")) &&
6834*7c568831SAndroid Build Coastguard Worker (!xmlStrEqual(node->name, BAD_CAST "param")) &&
6835*7c568831SAndroid Build Coastguard Worker (!xmlStrEqual(node->name, BAD_CAST "define"))) {
6836*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
6837*7c568831SAndroid Build Coastguard Worker "Attribute %s is not allowed on %s\n",
6838*7c568831SAndroid Build Coastguard Worker cur->name, node->name);
6839*7c568831SAndroid Build Coastguard Worker }
6840*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(cur->name, BAD_CAST "type")) {
6841*7c568831SAndroid Build Coastguard Worker if ((!xmlStrEqual(node->name, BAD_CAST "value")) &&
6842*7c568831SAndroid Build Coastguard Worker (!xmlStrEqual(node->name, BAD_CAST "data"))) {
6843*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
6844*7c568831SAndroid Build Coastguard Worker "Attribute %s is not allowed on %s\n",
6845*7c568831SAndroid Build Coastguard Worker cur->name, node->name);
6846*7c568831SAndroid Build Coastguard Worker }
6847*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(cur->name, BAD_CAST "href")) {
6848*7c568831SAndroid Build Coastguard Worker if ((!xmlStrEqual(node->name, BAD_CAST "externalRef")) &&
6849*7c568831SAndroid Build Coastguard Worker (!xmlStrEqual(node->name, BAD_CAST "include"))) {
6850*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
6851*7c568831SAndroid Build Coastguard Worker "Attribute %s is not allowed on %s\n",
6852*7c568831SAndroid Build Coastguard Worker cur->name, node->name);
6853*7c568831SAndroid Build Coastguard Worker }
6854*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(cur->name, BAD_CAST "combine")) {
6855*7c568831SAndroid Build Coastguard Worker if ((!xmlStrEqual(node->name, BAD_CAST "start")) &&
6856*7c568831SAndroid Build Coastguard Worker (!xmlStrEqual(node->name, BAD_CAST "define"))) {
6857*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
6858*7c568831SAndroid Build Coastguard Worker "Attribute %s is not allowed on %s\n",
6859*7c568831SAndroid Build Coastguard Worker cur->name, node->name);
6860*7c568831SAndroid Build Coastguard Worker }
6861*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(cur->name, BAD_CAST "datatypeLibrary")) {
6862*7c568831SAndroid Build Coastguard Worker xmlChar *val;
6863*7c568831SAndroid Build Coastguard Worker xmlURIPtr uri;
6864*7c568831SAndroid Build Coastguard Worker
6865*7c568831SAndroid Build Coastguard Worker val = xmlNodeListGetString(node->doc, cur->children, 1);
6866*7c568831SAndroid Build Coastguard Worker if (val != NULL) {
6867*7c568831SAndroid Build Coastguard Worker if (val[0] != 0) {
6868*7c568831SAndroid Build Coastguard Worker uri = xmlParseURI((const char *) val);
6869*7c568831SAndroid Build Coastguard Worker if (uri == NULL) {
6870*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_INVALID_URI,
6871*7c568831SAndroid Build Coastguard Worker "Attribute %s contains invalid URI %s\n",
6872*7c568831SAndroid Build Coastguard Worker cur->name, val);
6873*7c568831SAndroid Build Coastguard Worker } else {
6874*7c568831SAndroid Build Coastguard Worker if (uri->scheme == NULL) {
6875*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_URI_NOT_ABSOLUTE,
6876*7c568831SAndroid Build Coastguard Worker "Attribute %s URI %s is not absolute\n",
6877*7c568831SAndroid Build Coastguard Worker cur->name, val);
6878*7c568831SAndroid Build Coastguard Worker }
6879*7c568831SAndroid Build Coastguard Worker if (uri->fragment != NULL) {
6880*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_URI_FRAGMENT,
6881*7c568831SAndroid Build Coastguard Worker "Attribute %s URI %s has a fragment ID\n",
6882*7c568831SAndroid Build Coastguard Worker cur->name, val);
6883*7c568831SAndroid Build Coastguard Worker }
6884*7c568831SAndroid Build Coastguard Worker xmlFreeURI(uri);
6885*7c568831SAndroid Build Coastguard Worker }
6886*7c568831SAndroid Build Coastguard Worker }
6887*7c568831SAndroid Build Coastguard Worker xmlFree(val);
6888*7c568831SAndroid Build Coastguard Worker }
6889*7c568831SAndroid Build Coastguard Worker } else if (!xmlStrEqual(cur->name, BAD_CAST "ns")) {
6890*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_ATTRIBUTE,
6891*7c568831SAndroid Build Coastguard Worker "Unknown attribute %s on %s\n", cur->name,
6892*7c568831SAndroid Build Coastguard Worker node->name);
6893*7c568831SAndroid Build Coastguard Worker }
6894*7c568831SAndroid Build Coastguard Worker }
6895*7c568831SAndroid Build Coastguard Worker cur = next;
6896*7c568831SAndroid Build Coastguard Worker }
6897*7c568831SAndroid Build Coastguard Worker }
6898*7c568831SAndroid Build Coastguard Worker
6899*7c568831SAndroid Build Coastguard Worker /**
6900*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGCleanupTree:
6901*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
6902*7c568831SAndroid Build Coastguard Worker * @root: an xmlNodePtr subtree
6903*7c568831SAndroid Build Coastguard Worker *
6904*7c568831SAndroid Build Coastguard Worker * Cleanup the subtree from unwanted nodes for parsing, resolve
6905*7c568831SAndroid Build Coastguard Worker * Include and externalRef lookups.
6906*7c568831SAndroid Build Coastguard Worker */
6907*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGCleanupTree(xmlRelaxNGParserCtxtPtr ctxt,xmlNodePtr root)6908*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCleanupTree(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr root)
6909*7c568831SAndroid Build Coastguard Worker {
6910*7c568831SAndroid Build Coastguard Worker xmlNodePtr cur, delete;
6911*7c568831SAndroid Build Coastguard Worker
6912*7c568831SAndroid Build Coastguard Worker delete = NULL;
6913*7c568831SAndroid Build Coastguard Worker cur = root;
6914*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
6915*7c568831SAndroid Build Coastguard Worker if (delete != NULL) {
6916*7c568831SAndroid Build Coastguard Worker xmlUnlinkNode(delete);
6917*7c568831SAndroid Build Coastguard Worker xmlFreeNode(delete);
6918*7c568831SAndroid Build Coastguard Worker delete = NULL;
6919*7c568831SAndroid Build Coastguard Worker }
6920*7c568831SAndroid Build Coastguard Worker if (cur->type == XML_ELEMENT_NODE) {
6921*7c568831SAndroid Build Coastguard Worker /*
6922*7c568831SAndroid Build Coastguard Worker * Simplification 4.1. Annotations
6923*7c568831SAndroid Build Coastguard Worker */
6924*7c568831SAndroid Build Coastguard Worker if ((cur->ns == NULL) ||
6925*7c568831SAndroid Build Coastguard Worker (!xmlStrEqual(cur->ns->href, xmlRelaxNGNs))) {
6926*7c568831SAndroid Build Coastguard Worker if ((cur->parent != NULL) &&
6927*7c568831SAndroid Build Coastguard Worker (cur->parent->type == XML_ELEMENT_NODE) &&
6928*7c568831SAndroid Build Coastguard Worker ((xmlStrEqual(cur->parent->name, BAD_CAST "name")) ||
6929*7c568831SAndroid Build Coastguard Worker (xmlStrEqual(cur->parent->name, BAD_CAST "value")) ||
6930*7c568831SAndroid Build Coastguard Worker (xmlStrEqual(cur->parent->name, BAD_CAST "param")))) {
6931*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur, XML_RNGP_FOREIGN_ELEMENT,
6932*7c568831SAndroid Build Coastguard Worker "element %s doesn't allow foreign elements\n",
6933*7c568831SAndroid Build Coastguard Worker cur->parent->name, NULL);
6934*7c568831SAndroid Build Coastguard Worker }
6935*7c568831SAndroid Build Coastguard Worker delete = cur;
6936*7c568831SAndroid Build Coastguard Worker goto skip_children;
6937*7c568831SAndroid Build Coastguard Worker } else {
6938*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCleanupAttributes(ctxt, cur);
6939*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual(cur->name, BAD_CAST "externalRef")) {
6940*7c568831SAndroid Build Coastguard Worker xmlChar *href, *ns, *base, *URL;
6941*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDocumentPtr docu;
6942*7c568831SAndroid Build Coastguard Worker xmlNodePtr tmp;
6943*7c568831SAndroid Build Coastguard Worker xmlURIPtr uri;
6944*7c568831SAndroid Build Coastguard Worker
6945*7c568831SAndroid Build Coastguard Worker ns = xmlGetProp(cur, BAD_CAST "ns");
6946*7c568831SAndroid Build Coastguard Worker if (ns == NULL) {
6947*7c568831SAndroid Build Coastguard Worker tmp = cur->parent;
6948*7c568831SAndroid Build Coastguard Worker while ((tmp != NULL) &&
6949*7c568831SAndroid Build Coastguard Worker (tmp->type == XML_ELEMENT_NODE)) {
6950*7c568831SAndroid Build Coastguard Worker ns = xmlGetProp(tmp, BAD_CAST "ns");
6951*7c568831SAndroid Build Coastguard Worker if (ns != NULL)
6952*7c568831SAndroid Build Coastguard Worker break;
6953*7c568831SAndroid Build Coastguard Worker tmp = tmp->parent;
6954*7c568831SAndroid Build Coastguard Worker }
6955*7c568831SAndroid Build Coastguard Worker }
6956*7c568831SAndroid Build Coastguard Worker href = xmlGetProp(cur, BAD_CAST "href");
6957*7c568831SAndroid Build Coastguard Worker if (href == NULL) {
6958*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur, XML_RNGP_MISSING_HREF,
6959*7c568831SAndroid Build Coastguard Worker "xmlRelaxNGParse: externalRef has no href attribute\n",
6960*7c568831SAndroid Build Coastguard Worker NULL, NULL);
6961*7c568831SAndroid Build Coastguard Worker if (ns != NULL)
6962*7c568831SAndroid Build Coastguard Worker xmlFree(ns);
6963*7c568831SAndroid Build Coastguard Worker delete = cur;
6964*7c568831SAndroid Build Coastguard Worker goto skip_children;
6965*7c568831SAndroid Build Coastguard Worker }
6966*7c568831SAndroid Build Coastguard Worker uri = xmlParseURI((const char *) href);
6967*7c568831SAndroid Build Coastguard Worker if (uri == NULL) {
6968*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
6969*7c568831SAndroid Build Coastguard Worker "Incorrect URI for externalRef %s\n",
6970*7c568831SAndroid Build Coastguard Worker href, NULL);
6971*7c568831SAndroid Build Coastguard Worker if (ns != NULL)
6972*7c568831SAndroid Build Coastguard Worker xmlFree(ns);
6973*7c568831SAndroid Build Coastguard Worker if (href != NULL)
6974*7c568831SAndroid Build Coastguard Worker xmlFree(href);
6975*7c568831SAndroid Build Coastguard Worker delete = cur;
6976*7c568831SAndroid Build Coastguard Worker goto skip_children;
6977*7c568831SAndroid Build Coastguard Worker }
6978*7c568831SAndroid Build Coastguard Worker if (uri->fragment != NULL) {
6979*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
6980*7c568831SAndroid Build Coastguard Worker "Fragment forbidden in URI for externalRef %s\n",
6981*7c568831SAndroid Build Coastguard Worker href, NULL);
6982*7c568831SAndroid Build Coastguard Worker if (ns != NULL)
6983*7c568831SAndroid Build Coastguard Worker xmlFree(ns);
6984*7c568831SAndroid Build Coastguard Worker xmlFreeURI(uri);
6985*7c568831SAndroid Build Coastguard Worker if (href != NULL)
6986*7c568831SAndroid Build Coastguard Worker xmlFree(href);
6987*7c568831SAndroid Build Coastguard Worker delete = cur;
6988*7c568831SAndroid Build Coastguard Worker goto skip_children;
6989*7c568831SAndroid Build Coastguard Worker }
6990*7c568831SAndroid Build Coastguard Worker xmlFreeURI(uri);
6991*7c568831SAndroid Build Coastguard Worker base = xmlNodeGetBase(cur->doc, cur);
6992*7c568831SAndroid Build Coastguard Worker URL = xmlBuildURI(href, base);
6993*7c568831SAndroid Build Coastguard Worker if (URL == NULL) {
6994*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
6995*7c568831SAndroid Build Coastguard Worker "Failed to compute URL for externalRef %s\n",
6996*7c568831SAndroid Build Coastguard Worker href, NULL);
6997*7c568831SAndroid Build Coastguard Worker if (ns != NULL)
6998*7c568831SAndroid Build Coastguard Worker xmlFree(ns);
6999*7c568831SAndroid Build Coastguard Worker if (href != NULL)
7000*7c568831SAndroid Build Coastguard Worker xmlFree(href);
7001*7c568831SAndroid Build Coastguard Worker if (base != NULL)
7002*7c568831SAndroid Build Coastguard Worker xmlFree(base);
7003*7c568831SAndroid Build Coastguard Worker delete = cur;
7004*7c568831SAndroid Build Coastguard Worker goto skip_children;
7005*7c568831SAndroid Build Coastguard Worker }
7006*7c568831SAndroid Build Coastguard Worker if (href != NULL)
7007*7c568831SAndroid Build Coastguard Worker xmlFree(href);
7008*7c568831SAndroid Build Coastguard Worker if (base != NULL)
7009*7c568831SAndroid Build Coastguard Worker xmlFree(base);
7010*7c568831SAndroid Build Coastguard Worker docu = xmlRelaxNGLoadExternalRef(ctxt, URL, ns);
7011*7c568831SAndroid Build Coastguard Worker if (docu == NULL) {
7012*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur, XML_RNGP_EXTERNAL_REF_FAILURE,
7013*7c568831SAndroid Build Coastguard Worker "Failed to load externalRef %s\n", URL,
7014*7c568831SAndroid Build Coastguard Worker NULL);
7015*7c568831SAndroid Build Coastguard Worker if (ns != NULL)
7016*7c568831SAndroid Build Coastguard Worker xmlFree(ns);
7017*7c568831SAndroid Build Coastguard Worker xmlFree(URL);
7018*7c568831SAndroid Build Coastguard Worker delete = cur;
7019*7c568831SAndroid Build Coastguard Worker goto skip_children;
7020*7c568831SAndroid Build Coastguard Worker }
7021*7c568831SAndroid Build Coastguard Worker if (ns != NULL)
7022*7c568831SAndroid Build Coastguard Worker xmlFree(ns);
7023*7c568831SAndroid Build Coastguard Worker xmlFree(URL);
7024*7c568831SAndroid Build Coastguard Worker cur->psvi = docu;
7025*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(cur->name, BAD_CAST "include")) {
7026*7c568831SAndroid Build Coastguard Worker xmlChar *href, *ns, *base, *URL;
7027*7c568831SAndroid Build Coastguard Worker xmlRelaxNGIncludePtr incl;
7028*7c568831SAndroid Build Coastguard Worker xmlNodePtr tmp;
7029*7c568831SAndroid Build Coastguard Worker
7030*7c568831SAndroid Build Coastguard Worker href = xmlGetProp(cur, BAD_CAST "href");
7031*7c568831SAndroid Build Coastguard Worker if (href == NULL) {
7032*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur, XML_RNGP_MISSING_HREF,
7033*7c568831SAndroid Build Coastguard Worker "xmlRelaxNGParse: include has no href attribute\n",
7034*7c568831SAndroid Build Coastguard Worker NULL, NULL);
7035*7c568831SAndroid Build Coastguard Worker delete = cur;
7036*7c568831SAndroid Build Coastguard Worker goto skip_children;
7037*7c568831SAndroid Build Coastguard Worker }
7038*7c568831SAndroid Build Coastguard Worker base = xmlNodeGetBase(cur->doc, cur);
7039*7c568831SAndroid Build Coastguard Worker URL = xmlBuildURI(href, base);
7040*7c568831SAndroid Build Coastguard Worker if (URL == NULL) {
7041*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
7042*7c568831SAndroid Build Coastguard Worker "Failed to compute URL for include %s\n",
7043*7c568831SAndroid Build Coastguard Worker href, NULL);
7044*7c568831SAndroid Build Coastguard Worker if (href != NULL)
7045*7c568831SAndroid Build Coastguard Worker xmlFree(href);
7046*7c568831SAndroid Build Coastguard Worker if (base != NULL)
7047*7c568831SAndroid Build Coastguard Worker xmlFree(base);
7048*7c568831SAndroid Build Coastguard Worker delete = cur;
7049*7c568831SAndroid Build Coastguard Worker goto skip_children;
7050*7c568831SAndroid Build Coastguard Worker }
7051*7c568831SAndroid Build Coastguard Worker if (href != NULL)
7052*7c568831SAndroid Build Coastguard Worker xmlFree(href);
7053*7c568831SAndroid Build Coastguard Worker if (base != NULL)
7054*7c568831SAndroid Build Coastguard Worker xmlFree(base);
7055*7c568831SAndroid Build Coastguard Worker ns = xmlGetProp(cur, BAD_CAST "ns");
7056*7c568831SAndroid Build Coastguard Worker if (ns == NULL) {
7057*7c568831SAndroid Build Coastguard Worker tmp = cur->parent;
7058*7c568831SAndroid Build Coastguard Worker while ((tmp != NULL) &&
7059*7c568831SAndroid Build Coastguard Worker (tmp->type == XML_ELEMENT_NODE)) {
7060*7c568831SAndroid Build Coastguard Worker ns = xmlGetProp(tmp, BAD_CAST "ns");
7061*7c568831SAndroid Build Coastguard Worker if (ns != NULL)
7062*7c568831SAndroid Build Coastguard Worker break;
7063*7c568831SAndroid Build Coastguard Worker tmp = tmp->parent;
7064*7c568831SAndroid Build Coastguard Worker }
7065*7c568831SAndroid Build Coastguard Worker }
7066*7c568831SAndroid Build Coastguard Worker incl = xmlRelaxNGLoadInclude(ctxt, URL, cur, ns);
7067*7c568831SAndroid Build Coastguard Worker if (ns != NULL)
7068*7c568831SAndroid Build Coastguard Worker xmlFree(ns);
7069*7c568831SAndroid Build Coastguard Worker if (incl == NULL) {
7070*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur, XML_RNGP_INCLUDE_FAILURE,
7071*7c568831SAndroid Build Coastguard Worker "Failed to load include %s\n", URL,
7072*7c568831SAndroid Build Coastguard Worker NULL);
7073*7c568831SAndroid Build Coastguard Worker xmlFree(URL);
7074*7c568831SAndroid Build Coastguard Worker delete = cur;
7075*7c568831SAndroid Build Coastguard Worker goto skip_children;
7076*7c568831SAndroid Build Coastguard Worker }
7077*7c568831SAndroid Build Coastguard Worker xmlFree(URL);
7078*7c568831SAndroid Build Coastguard Worker cur->psvi = incl;
7079*7c568831SAndroid Build Coastguard Worker } else if ((xmlStrEqual(cur->name, BAD_CAST "element")) ||
7080*7c568831SAndroid Build Coastguard Worker (xmlStrEqual(cur->name, BAD_CAST "attribute")))
7081*7c568831SAndroid Build Coastguard Worker {
7082*7c568831SAndroid Build Coastguard Worker xmlChar *name, *ns;
7083*7c568831SAndroid Build Coastguard Worker xmlNodePtr text = NULL;
7084*7c568831SAndroid Build Coastguard Worker
7085*7c568831SAndroid Build Coastguard Worker /*
7086*7c568831SAndroid Build Coastguard Worker * Simplification 4.8. name attribute of element
7087*7c568831SAndroid Build Coastguard Worker * and attribute elements
7088*7c568831SAndroid Build Coastguard Worker */
7089*7c568831SAndroid Build Coastguard Worker name = xmlGetProp(cur, BAD_CAST "name");
7090*7c568831SAndroid Build Coastguard Worker if (name != NULL) {
7091*7c568831SAndroid Build Coastguard Worker if (cur->children == NULL) {
7092*7c568831SAndroid Build Coastguard Worker text =
7093*7c568831SAndroid Build Coastguard Worker xmlNewChild(cur, cur->ns, BAD_CAST "name",
7094*7c568831SAndroid Build Coastguard Worker name);
7095*7c568831SAndroid Build Coastguard Worker } else {
7096*7c568831SAndroid Build Coastguard Worker xmlNodePtr node;
7097*7c568831SAndroid Build Coastguard Worker
7098*7c568831SAndroid Build Coastguard Worker node = xmlNewDocNode(cur->doc, cur->ns,
7099*7c568831SAndroid Build Coastguard Worker BAD_CAST "name", NULL);
7100*7c568831SAndroid Build Coastguard Worker if (node != NULL) {
7101*7c568831SAndroid Build Coastguard Worker xmlAddPrevSibling(cur->children, node);
7102*7c568831SAndroid Build Coastguard Worker text = xmlNewDocText(node->doc, name);
7103*7c568831SAndroid Build Coastguard Worker xmlAddChild(node, text);
7104*7c568831SAndroid Build Coastguard Worker text = node;
7105*7c568831SAndroid Build Coastguard Worker }
7106*7c568831SAndroid Build Coastguard Worker }
7107*7c568831SAndroid Build Coastguard Worker if (text == NULL) {
7108*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur, XML_RNGP_CREATE_FAILURE,
7109*7c568831SAndroid Build Coastguard Worker "Failed to create a name %s element\n",
7110*7c568831SAndroid Build Coastguard Worker name, NULL);
7111*7c568831SAndroid Build Coastguard Worker }
7112*7c568831SAndroid Build Coastguard Worker xmlUnsetProp(cur, BAD_CAST "name");
7113*7c568831SAndroid Build Coastguard Worker xmlFree(name);
7114*7c568831SAndroid Build Coastguard Worker ns = xmlGetProp(cur, BAD_CAST "ns");
7115*7c568831SAndroid Build Coastguard Worker if (ns != NULL) {
7116*7c568831SAndroid Build Coastguard Worker if (text != NULL) {
7117*7c568831SAndroid Build Coastguard Worker xmlSetProp(text, BAD_CAST "ns", ns);
7118*7c568831SAndroid Build Coastguard Worker /* xmlUnsetProp(cur, BAD_CAST "ns"); */
7119*7c568831SAndroid Build Coastguard Worker }
7120*7c568831SAndroid Build Coastguard Worker xmlFree(ns);
7121*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(cur->name,
7122*7c568831SAndroid Build Coastguard Worker BAD_CAST "attribute")) {
7123*7c568831SAndroid Build Coastguard Worker xmlSetProp(text, BAD_CAST "ns", BAD_CAST "");
7124*7c568831SAndroid Build Coastguard Worker }
7125*7c568831SAndroid Build Coastguard Worker }
7126*7c568831SAndroid Build Coastguard Worker } else if ((xmlStrEqual(cur->name, BAD_CAST "name")) ||
7127*7c568831SAndroid Build Coastguard Worker (xmlStrEqual(cur->name, BAD_CAST "nsName")) ||
7128*7c568831SAndroid Build Coastguard Worker (xmlStrEqual(cur->name, BAD_CAST "value"))) {
7129*7c568831SAndroid Build Coastguard Worker /*
7130*7c568831SAndroid Build Coastguard Worker * Simplification 4.8. name attribute of element
7131*7c568831SAndroid Build Coastguard Worker * and attribute elements
7132*7c568831SAndroid Build Coastguard Worker */
7133*7c568831SAndroid Build Coastguard Worker if (xmlHasProp(cur, BAD_CAST "ns") == NULL) {
7134*7c568831SAndroid Build Coastguard Worker xmlNodePtr node;
7135*7c568831SAndroid Build Coastguard Worker xmlChar *ns = NULL;
7136*7c568831SAndroid Build Coastguard Worker
7137*7c568831SAndroid Build Coastguard Worker node = cur->parent;
7138*7c568831SAndroid Build Coastguard Worker while ((node != NULL) &&
7139*7c568831SAndroid Build Coastguard Worker (node->type == XML_ELEMENT_NODE)) {
7140*7c568831SAndroid Build Coastguard Worker ns = xmlGetProp(node, BAD_CAST "ns");
7141*7c568831SAndroid Build Coastguard Worker if (ns != NULL) {
7142*7c568831SAndroid Build Coastguard Worker break;
7143*7c568831SAndroid Build Coastguard Worker }
7144*7c568831SAndroid Build Coastguard Worker node = node->parent;
7145*7c568831SAndroid Build Coastguard Worker }
7146*7c568831SAndroid Build Coastguard Worker if (ns == NULL) {
7147*7c568831SAndroid Build Coastguard Worker xmlSetProp(cur, BAD_CAST "ns", BAD_CAST "");
7148*7c568831SAndroid Build Coastguard Worker } else {
7149*7c568831SAndroid Build Coastguard Worker xmlSetProp(cur, BAD_CAST "ns", ns);
7150*7c568831SAndroid Build Coastguard Worker xmlFree(ns);
7151*7c568831SAndroid Build Coastguard Worker }
7152*7c568831SAndroid Build Coastguard Worker }
7153*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual(cur->name, BAD_CAST "name")) {
7154*7c568831SAndroid Build Coastguard Worker xmlChar *name, *local, *prefix;
7155*7c568831SAndroid Build Coastguard Worker
7156*7c568831SAndroid Build Coastguard Worker /*
7157*7c568831SAndroid Build Coastguard Worker * Simplification: 4.10. QNames
7158*7c568831SAndroid Build Coastguard Worker */
7159*7c568831SAndroid Build Coastguard Worker name = xmlNodeGetContent(cur);
7160*7c568831SAndroid Build Coastguard Worker if (name != NULL) {
7161*7c568831SAndroid Build Coastguard Worker local = xmlSplitQName2(name, &prefix);
7162*7c568831SAndroid Build Coastguard Worker if (local != NULL) {
7163*7c568831SAndroid Build Coastguard Worker xmlNsPtr ns;
7164*7c568831SAndroid Build Coastguard Worker
7165*7c568831SAndroid Build Coastguard Worker ns = xmlSearchNs(cur->doc, cur, prefix);
7166*7c568831SAndroid Build Coastguard Worker if (ns == NULL) {
7167*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur,
7168*7c568831SAndroid Build Coastguard Worker XML_RNGP_PREFIX_UNDEFINED,
7169*7c568831SAndroid Build Coastguard Worker "xmlRelaxNGParse: no namespace for prefix %s\n",
7170*7c568831SAndroid Build Coastguard Worker prefix, NULL);
7171*7c568831SAndroid Build Coastguard Worker } else {
7172*7c568831SAndroid Build Coastguard Worker xmlSetProp(cur, BAD_CAST "ns",
7173*7c568831SAndroid Build Coastguard Worker ns->href);
7174*7c568831SAndroid Build Coastguard Worker xmlNodeSetContent(cur, local);
7175*7c568831SAndroid Build Coastguard Worker }
7176*7c568831SAndroid Build Coastguard Worker xmlFree(local);
7177*7c568831SAndroid Build Coastguard Worker xmlFree(prefix);
7178*7c568831SAndroid Build Coastguard Worker }
7179*7c568831SAndroid Build Coastguard Worker xmlFree(name);
7180*7c568831SAndroid Build Coastguard Worker }
7181*7c568831SAndroid Build Coastguard Worker }
7182*7c568831SAndroid Build Coastguard Worker /*
7183*7c568831SAndroid Build Coastguard Worker * 4.16
7184*7c568831SAndroid Build Coastguard Worker */
7185*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual(cur->name, BAD_CAST "nsName")) {
7186*7c568831SAndroid Build Coastguard Worker if (ctxt->flags & XML_RELAXNG_IN_NSEXCEPT) {
7187*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur,
7188*7c568831SAndroid Build Coastguard Worker XML_RNGP_PAT_NSNAME_EXCEPT_NSNAME,
7189*7c568831SAndroid Build Coastguard Worker "Found nsName/except//nsName forbidden construct\n",
7190*7c568831SAndroid Build Coastguard Worker NULL, NULL);
7191*7c568831SAndroid Build Coastguard Worker }
7192*7c568831SAndroid Build Coastguard Worker }
7193*7c568831SAndroid Build Coastguard Worker } else if ((xmlStrEqual(cur->name, BAD_CAST "except")) &&
7194*7c568831SAndroid Build Coastguard Worker (cur != root)) {
7195*7c568831SAndroid Build Coastguard Worker int oldflags = ctxt->flags;
7196*7c568831SAndroid Build Coastguard Worker
7197*7c568831SAndroid Build Coastguard Worker /*
7198*7c568831SAndroid Build Coastguard Worker * 4.16
7199*7c568831SAndroid Build Coastguard Worker */
7200*7c568831SAndroid Build Coastguard Worker if ((cur->parent != NULL) &&
7201*7c568831SAndroid Build Coastguard Worker (xmlStrEqual
7202*7c568831SAndroid Build Coastguard Worker (cur->parent->name, BAD_CAST "anyName"))) {
7203*7c568831SAndroid Build Coastguard Worker ctxt->flags |= XML_RELAXNG_IN_ANYEXCEPT;
7204*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCleanupTree(ctxt, cur);
7205*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
7206*7c568831SAndroid Build Coastguard Worker goto skip_children;
7207*7c568831SAndroid Build Coastguard Worker } else if ((cur->parent != NULL) &&
7208*7c568831SAndroid Build Coastguard Worker (xmlStrEqual
7209*7c568831SAndroid Build Coastguard Worker (cur->parent->name, BAD_CAST "nsName"))) {
7210*7c568831SAndroid Build Coastguard Worker ctxt->flags |= XML_RELAXNG_IN_NSEXCEPT;
7211*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCleanupTree(ctxt, cur);
7212*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
7213*7c568831SAndroid Build Coastguard Worker goto skip_children;
7214*7c568831SAndroid Build Coastguard Worker }
7215*7c568831SAndroid Build Coastguard Worker } else if (xmlStrEqual(cur->name, BAD_CAST "anyName")) {
7216*7c568831SAndroid Build Coastguard Worker /*
7217*7c568831SAndroid Build Coastguard Worker * 4.16
7218*7c568831SAndroid Build Coastguard Worker */
7219*7c568831SAndroid Build Coastguard Worker if (ctxt->flags & XML_RELAXNG_IN_ANYEXCEPT) {
7220*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur,
7221*7c568831SAndroid Build Coastguard Worker XML_RNGP_PAT_ANYNAME_EXCEPT_ANYNAME,
7222*7c568831SAndroid Build Coastguard Worker "Found anyName/except//anyName forbidden construct\n",
7223*7c568831SAndroid Build Coastguard Worker NULL, NULL);
7224*7c568831SAndroid Build Coastguard Worker } else if (ctxt->flags & XML_RELAXNG_IN_NSEXCEPT) {
7225*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, cur,
7226*7c568831SAndroid Build Coastguard Worker XML_RNGP_PAT_NSNAME_EXCEPT_ANYNAME,
7227*7c568831SAndroid Build Coastguard Worker "Found nsName/except//anyName forbidden construct\n",
7228*7c568831SAndroid Build Coastguard Worker NULL, NULL);
7229*7c568831SAndroid Build Coastguard Worker }
7230*7c568831SAndroid Build Coastguard Worker }
7231*7c568831SAndroid Build Coastguard Worker /*
7232*7c568831SAndroid Build Coastguard Worker * This is not an else since "include" is transformed
7233*7c568831SAndroid Build Coastguard Worker * into a div
7234*7c568831SAndroid Build Coastguard Worker */
7235*7c568831SAndroid Build Coastguard Worker if (xmlStrEqual(cur->name, BAD_CAST "div")) {
7236*7c568831SAndroid Build Coastguard Worker xmlChar *ns;
7237*7c568831SAndroid Build Coastguard Worker xmlNodePtr child, ins, tmp;
7238*7c568831SAndroid Build Coastguard Worker
7239*7c568831SAndroid Build Coastguard Worker /*
7240*7c568831SAndroid Build Coastguard Worker * implements rule 4.11
7241*7c568831SAndroid Build Coastguard Worker */
7242*7c568831SAndroid Build Coastguard Worker
7243*7c568831SAndroid Build Coastguard Worker ns = xmlGetProp(cur, BAD_CAST "ns");
7244*7c568831SAndroid Build Coastguard Worker
7245*7c568831SAndroid Build Coastguard Worker child = cur->children;
7246*7c568831SAndroid Build Coastguard Worker ins = cur;
7247*7c568831SAndroid Build Coastguard Worker while (child != NULL) {
7248*7c568831SAndroid Build Coastguard Worker if (ns != NULL) {
7249*7c568831SAndroid Build Coastguard Worker if (!xmlHasProp(child, BAD_CAST "ns")) {
7250*7c568831SAndroid Build Coastguard Worker xmlSetProp(child, BAD_CAST "ns", ns);
7251*7c568831SAndroid Build Coastguard Worker }
7252*7c568831SAndroid Build Coastguard Worker }
7253*7c568831SAndroid Build Coastguard Worker tmp = child->next;
7254*7c568831SAndroid Build Coastguard Worker xmlUnlinkNode(child);
7255*7c568831SAndroid Build Coastguard Worker ins = xmlAddNextSibling(ins, child);
7256*7c568831SAndroid Build Coastguard Worker child = tmp;
7257*7c568831SAndroid Build Coastguard Worker }
7258*7c568831SAndroid Build Coastguard Worker if (ns != NULL)
7259*7c568831SAndroid Build Coastguard Worker xmlFree(ns);
7260*7c568831SAndroid Build Coastguard Worker /*
7261*7c568831SAndroid Build Coastguard Worker * Since we are about to delete cur, if its nsDef is non-NULL we
7262*7c568831SAndroid Build Coastguard Worker * need to preserve it (it contains the ns definitions for the
7263*7c568831SAndroid Build Coastguard Worker * children we just moved). We'll just stick it on to the end
7264*7c568831SAndroid Build Coastguard Worker * of cur->parent's list, since it's never going to be re-serialized
7265*7c568831SAndroid Build Coastguard Worker * (bug 143738).
7266*7c568831SAndroid Build Coastguard Worker */
7267*7c568831SAndroid Build Coastguard Worker if ((cur->nsDef != NULL) && (cur->parent != NULL)) {
7268*7c568831SAndroid Build Coastguard Worker xmlNsPtr parDef = (xmlNsPtr)&cur->parent->nsDef;
7269*7c568831SAndroid Build Coastguard Worker while (parDef->next != NULL)
7270*7c568831SAndroid Build Coastguard Worker parDef = parDef->next;
7271*7c568831SAndroid Build Coastguard Worker parDef->next = cur->nsDef;
7272*7c568831SAndroid Build Coastguard Worker cur->nsDef = NULL;
7273*7c568831SAndroid Build Coastguard Worker }
7274*7c568831SAndroid Build Coastguard Worker delete = cur;
7275*7c568831SAndroid Build Coastguard Worker goto skip_children;
7276*7c568831SAndroid Build Coastguard Worker }
7277*7c568831SAndroid Build Coastguard Worker }
7278*7c568831SAndroid Build Coastguard Worker }
7279*7c568831SAndroid Build Coastguard Worker /*
7280*7c568831SAndroid Build Coastguard Worker * Simplification 4.2 whitespaces
7281*7c568831SAndroid Build Coastguard Worker */
7282*7c568831SAndroid Build Coastguard Worker else if ((cur->type == XML_TEXT_NODE) ||
7283*7c568831SAndroid Build Coastguard Worker (cur->type == XML_CDATA_SECTION_NODE)) {
7284*7c568831SAndroid Build Coastguard Worker if (IS_BLANK_NODE(cur)) {
7285*7c568831SAndroid Build Coastguard Worker if ((cur->parent != NULL) &&
7286*7c568831SAndroid Build Coastguard Worker (cur->parent->type == XML_ELEMENT_NODE)) {
7287*7c568831SAndroid Build Coastguard Worker if ((!xmlStrEqual(cur->parent->name, BAD_CAST "value"))
7288*7c568831SAndroid Build Coastguard Worker &&
7289*7c568831SAndroid Build Coastguard Worker (!xmlStrEqual
7290*7c568831SAndroid Build Coastguard Worker (cur->parent->name, BAD_CAST "param")))
7291*7c568831SAndroid Build Coastguard Worker delete = cur;
7292*7c568831SAndroid Build Coastguard Worker } else {
7293*7c568831SAndroid Build Coastguard Worker delete = cur;
7294*7c568831SAndroid Build Coastguard Worker goto skip_children;
7295*7c568831SAndroid Build Coastguard Worker }
7296*7c568831SAndroid Build Coastguard Worker }
7297*7c568831SAndroid Build Coastguard Worker } else {
7298*7c568831SAndroid Build Coastguard Worker delete = cur;
7299*7c568831SAndroid Build Coastguard Worker goto skip_children;
7300*7c568831SAndroid Build Coastguard Worker }
7301*7c568831SAndroid Build Coastguard Worker
7302*7c568831SAndroid Build Coastguard Worker /*
7303*7c568831SAndroid Build Coastguard Worker * Skip to next node
7304*7c568831SAndroid Build Coastguard Worker */
7305*7c568831SAndroid Build Coastguard Worker if (cur->children != NULL) {
7306*7c568831SAndroid Build Coastguard Worker if ((cur->children->type != XML_ENTITY_DECL) &&
7307*7c568831SAndroid Build Coastguard Worker (cur->children->type != XML_ENTITY_REF_NODE) &&
7308*7c568831SAndroid Build Coastguard Worker (cur->children->type != XML_ENTITY_NODE)) {
7309*7c568831SAndroid Build Coastguard Worker cur = cur->children;
7310*7c568831SAndroid Build Coastguard Worker continue;
7311*7c568831SAndroid Build Coastguard Worker }
7312*7c568831SAndroid Build Coastguard Worker }
7313*7c568831SAndroid Build Coastguard Worker skip_children:
7314*7c568831SAndroid Build Coastguard Worker if (cur->next != NULL) {
7315*7c568831SAndroid Build Coastguard Worker cur = cur->next;
7316*7c568831SAndroid Build Coastguard Worker continue;
7317*7c568831SAndroid Build Coastguard Worker }
7318*7c568831SAndroid Build Coastguard Worker
7319*7c568831SAndroid Build Coastguard Worker do {
7320*7c568831SAndroid Build Coastguard Worker cur = cur->parent;
7321*7c568831SAndroid Build Coastguard Worker if (cur == NULL)
7322*7c568831SAndroid Build Coastguard Worker break;
7323*7c568831SAndroid Build Coastguard Worker if (cur == root) {
7324*7c568831SAndroid Build Coastguard Worker cur = NULL;
7325*7c568831SAndroid Build Coastguard Worker break;
7326*7c568831SAndroid Build Coastguard Worker }
7327*7c568831SAndroid Build Coastguard Worker if (cur->next != NULL) {
7328*7c568831SAndroid Build Coastguard Worker cur = cur->next;
7329*7c568831SAndroid Build Coastguard Worker break;
7330*7c568831SAndroid Build Coastguard Worker }
7331*7c568831SAndroid Build Coastguard Worker } while (cur != NULL);
7332*7c568831SAndroid Build Coastguard Worker }
7333*7c568831SAndroid Build Coastguard Worker if (delete != NULL) {
7334*7c568831SAndroid Build Coastguard Worker xmlUnlinkNode(delete);
7335*7c568831SAndroid Build Coastguard Worker xmlFreeNode(delete);
7336*7c568831SAndroid Build Coastguard Worker delete = NULL;
7337*7c568831SAndroid Build Coastguard Worker }
7338*7c568831SAndroid Build Coastguard Worker }
7339*7c568831SAndroid Build Coastguard Worker
7340*7c568831SAndroid Build Coastguard Worker /**
7341*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGCleanupDoc:
7342*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
7343*7c568831SAndroid Build Coastguard Worker * @doc: an xmldocPtr document pointer
7344*7c568831SAndroid Build Coastguard Worker *
7345*7c568831SAndroid Build Coastguard Worker * Cleanup the document from unwanted nodes for parsing, resolve
7346*7c568831SAndroid Build Coastguard Worker * Include and externalRef lookups.
7347*7c568831SAndroid Build Coastguard Worker *
7348*7c568831SAndroid Build Coastguard Worker * Returns the cleaned up document or NULL in case of error
7349*7c568831SAndroid Build Coastguard Worker */
7350*7c568831SAndroid Build Coastguard Worker static xmlDocPtr
xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt,xmlDocPtr doc)7351*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt, xmlDocPtr doc)
7352*7c568831SAndroid Build Coastguard Worker {
7353*7c568831SAndroid Build Coastguard Worker xmlNodePtr root;
7354*7c568831SAndroid Build Coastguard Worker
7355*7c568831SAndroid Build Coastguard Worker /*
7356*7c568831SAndroid Build Coastguard Worker * Extract the root
7357*7c568831SAndroid Build Coastguard Worker */
7358*7c568831SAndroid Build Coastguard Worker root = xmlDocGetRootElement(doc);
7359*7c568831SAndroid Build Coastguard Worker if (root == NULL) {
7360*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, (xmlNodePtr) doc, XML_RNGP_EMPTY, "xmlRelaxNGParse: %s is empty\n",
7361*7c568831SAndroid Build Coastguard Worker ctxt->URL, NULL);
7362*7c568831SAndroid Build Coastguard Worker return (NULL);
7363*7c568831SAndroid Build Coastguard Worker }
7364*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCleanupTree(ctxt, root);
7365*7c568831SAndroid Build Coastguard Worker return (doc);
7366*7c568831SAndroid Build Coastguard Worker }
7367*7c568831SAndroid Build Coastguard Worker
7368*7c568831SAndroid Build Coastguard Worker /**
7369*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGParse:
7370*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
7371*7c568831SAndroid Build Coastguard Worker *
7372*7c568831SAndroid Build Coastguard Worker * parse a schema definition resource and build an internal
7373*7c568831SAndroid Build Coastguard Worker * XML Schema structure which can be used to validate instances.
7374*7c568831SAndroid Build Coastguard Worker *
7375*7c568831SAndroid Build Coastguard Worker * Returns the internal XML RelaxNG structure built from the resource or
7376*7c568831SAndroid Build Coastguard Worker * NULL in case of error
7377*7c568831SAndroid Build Coastguard Worker */
7378*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPtr
xmlRelaxNGParse(xmlRelaxNGParserCtxtPtr ctxt)7379*7c568831SAndroid Build Coastguard Worker xmlRelaxNGParse(xmlRelaxNGParserCtxtPtr ctxt)
7380*7c568831SAndroid Build Coastguard Worker {
7381*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPtr ret = NULL;
7382*7c568831SAndroid Build Coastguard Worker xmlDocPtr doc;
7383*7c568831SAndroid Build Coastguard Worker xmlNodePtr root;
7384*7c568831SAndroid Build Coastguard Worker
7385*7c568831SAndroid Build Coastguard Worker xmlRelaxNGInitTypes();
7386*7c568831SAndroid Build Coastguard Worker
7387*7c568831SAndroid Build Coastguard Worker if (ctxt == NULL)
7388*7c568831SAndroid Build Coastguard Worker return (NULL);
7389*7c568831SAndroid Build Coastguard Worker
7390*7c568831SAndroid Build Coastguard Worker /*
7391*7c568831SAndroid Build Coastguard Worker * First step is to parse the input document into an DOM/Infoset
7392*7c568831SAndroid Build Coastguard Worker */
7393*7c568831SAndroid Build Coastguard Worker if (ctxt->URL != NULL) {
7394*7c568831SAndroid Build Coastguard Worker doc = xmlRelaxReadFile(ctxt, (const char *) ctxt->URL);
7395*7c568831SAndroid Build Coastguard Worker if (doc == NULL) {
7396*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
7397*7c568831SAndroid Build Coastguard Worker "xmlRelaxNGParse: could not load %s\n", ctxt->URL,
7398*7c568831SAndroid Build Coastguard Worker NULL);
7399*7c568831SAndroid Build Coastguard Worker return (NULL);
7400*7c568831SAndroid Build Coastguard Worker }
7401*7c568831SAndroid Build Coastguard Worker } else if (ctxt->buffer != NULL) {
7402*7c568831SAndroid Build Coastguard Worker doc = xmlRelaxReadMemory(ctxt, ctxt->buffer, ctxt->size);
7403*7c568831SAndroid Build Coastguard Worker if (doc == NULL) {
7404*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
7405*7c568831SAndroid Build Coastguard Worker "xmlRelaxNGParse: could not parse schemas\n", NULL,
7406*7c568831SAndroid Build Coastguard Worker NULL);
7407*7c568831SAndroid Build Coastguard Worker return (NULL);
7408*7c568831SAndroid Build Coastguard Worker }
7409*7c568831SAndroid Build Coastguard Worker doc->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
7410*7c568831SAndroid Build Coastguard Worker ctxt->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
7411*7c568831SAndroid Build Coastguard Worker } else if (ctxt->document != NULL) {
7412*7c568831SAndroid Build Coastguard Worker doc = ctxt->document;
7413*7c568831SAndroid Build Coastguard Worker } else {
7414*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, NULL, XML_RNGP_EMPTY,
7415*7c568831SAndroid Build Coastguard Worker "xmlRelaxNGParse: nothing to parse\n", NULL, NULL);
7416*7c568831SAndroid Build Coastguard Worker return (NULL);
7417*7c568831SAndroid Build Coastguard Worker }
7418*7c568831SAndroid Build Coastguard Worker ctxt->document = doc;
7419*7c568831SAndroid Build Coastguard Worker
7420*7c568831SAndroid Build Coastguard Worker /*
7421*7c568831SAndroid Build Coastguard Worker * Some preprocessing of the document content
7422*7c568831SAndroid Build Coastguard Worker */
7423*7c568831SAndroid Build Coastguard Worker doc = xmlRelaxNGCleanupDoc(ctxt, doc);
7424*7c568831SAndroid Build Coastguard Worker if (doc == NULL) {
7425*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(ctxt->document);
7426*7c568831SAndroid Build Coastguard Worker ctxt->document = NULL;
7427*7c568831SAndroid Build Coastguard Worker return (NULL);
7428*7c568831SAndroid Build Coastguard Worker }
7429*7c568831SAndroid Build Coastguard Worker
7430*7c568831SAndroid Build Coastguard Worker /*
7431*7c568831SAndroid Build Coastguard Worker * Then do the parsing for good
7432*7c568831SAndroid Build Coastguard Worker */
7433*7c568831SAndroid Build Coastguard Worker root = xmlDocGetRootElement(doc);
7434*7c568831SAndroid Build Coastguard Worker if (root == NULL) {
7435*7c568831SAndroid Build Coastguard Worker xmlRngPErr(ctxt, (xmlNodePtr) doc,
7436*7c568831SAndroid Build Coastguard Worker XML_RNGP_EMPTY, "xmlRelaxNGParse: %s is empty\n",
7437*7c568831SAndroid Build Coastguard Worker (ctxt->URL ? ctxt->URL : BAD_CAST "schemas"), NULL);
7438*7c568831SAndroid Build Coastguard Worker
7439*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(ctxt->document);
7440*7c568831SAndroid Build Coastguard Worker ctxt->document = NULL;
7441*7c568831SAndroid Build Coastguard Worker return (NULL);
7442*7c568831SAndroid Build Coastguard Worker }
7443*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGParseDocument(ctxt, root);
7444*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
7445*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(ctxt->document);
7446*7c568831SAndroid Build Coastguard Worker ctxt->document = NULL;
7447*7c568831SAndroid Build Coastguard Worker return (NULL);
7448*7c568831SAndroid Build Coastguard Worker }
7449*7c568831SAndroid Build Coastguard Worker
7450*7c568831SAndroid Build Coastguard Worker /*
7451*7c568831SAndroid Build Coastguard Worker * Check the ref/defines links
7452*7c568831SAndroid Build Coastguard Worker */
7453*7c568831SAndroid Build Coastguard Worker /*
7454*7c568831SAndroid Build Coastguard Worker * try to preprocess interleaves
7455*7c568831SAndroid Build Coastguard Worker */
7456*7c568831SAndroid Build Coastguard Worker if (ctxt->interleaves != NULL) {
7457*7c568831SAndroid Build Coastguard Worker xmlHashScan(ctxt->interleaves, xmlRelaxNGComputeInterleaves, ctxt);
7458*7c568831SAndroid Build Coastguard Worker }
7459*7c568831SAndroid Build Coastguard Worker
7460*7c568831SAndroid Build Coastguard Worker /*
7461*7c568831SAndroid Build Coastguard Worker * if there was a parsing error return NULL
7462*7c568831SAndroid Build Coastguard Worker */
7463*7c568831SAndroid Build Coastguard Worker if (ctxt->nbErrors > 0) {
7464*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFree(ret);
7465*7c568831SAndroid Build Coastguard Worker ctxt->document = NULL;
7466*7c568831SAndroid Build Coastguard Worker xmlFreeDoc(doc);
7467*7c568831SAndroid Build Coastguard Worker return (NULL);
7468*7c568831SAndroid Build Coastguard Worker }
7469*7c568831SAndroid Build Coastguard Worker
7470*7c568831SAndroid Build Coastguard Worker /*
7471*7c568831SAndroid Build Coastguard Worker * try to compile (parts of) the schemas
7472*7c568831SAndroid Build Coastguard Worker */
7473*7c568831SAndroid Build Coastguard Worker if ((ret->topgrammar != NULL) && (ret->topgrammar->start != NULL)) {
7474*7c568831SAndroid Build Coastguard Worker if (ret->topgrammar->start->type != XML_RELAXNG_START) {
7475*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr def;
7476*7c568831SAndroid Build Coastguard Worker
7477*7c568831SAndroid Build Coastguard Worker def = xmlRelaxNGNewDefine(ctxt, NULL);
7478*7c568831SAndroid Build Coastguard Worker if (def != NULL) {
7479*7c568831SAndroid Build Coastguard Worker def->type = XML_RELAXNG_START;
7480*7c568831SAndroid Build Coastguard Worker def->content = ret->topgrammar->start;
7481*7c568831SAndroid Build Coastguard Worker ret->topgrammar->start = def;
7482*7c568831SAndroid Build Coastguard Worker }
7483*7c568831SAndroid Build Coastguard Worker }
7484*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTryCompile(ctxt, ret->topgrammar->start);
7485*7c568831SAndroid Build Coastguard Worker }
7486*7c568831SAndroid Build Coastguard Worker
7487*7c568831SAndroid Build Coastguard Worker /*
7488*7c568831SAndroid Build Coastguard Worker * Transfer the pointer for cleanup at the schema level.
7489*7c568831SAndroid Build Coastguard Worker */
7490*7c568831SAndroid Build Coastguard Worker ret->doc = doc;
7491*7c568831SAndroid Build Coastguard Worker ctxt->document = NULL;
7492*7c568831SAndroid Build Coastguard Worker ret->documents = ctxt->documents;
7493*7c568831SAndroid Build Coastguard Worker ctxt->documents = NULL;
7494*7c568831SAndroid Build Coastguard Worker
7495*7c568831SAndroid Build Coastguard Worker ret->includes = ctxt->includes;
7496*7c568831SAndroid Build Coastguard Worker ctxt->includes = NULL;
7497*7c568831SAndroid Build Coastguard Worker ret->defNr = ctxt->defNr;
7498*7c568831SAndroid Build Coastguard Worker ret->defTab = ctxt->defTab;
7499*7c568831SAndroid Build Coastguard Worker ctxt->defTab = NULL;
7500*7c568831SAndroid Build Coastguard Worker if (ctxt->idref == 1)
7501*7c568831SAndroid Build Coastguard Worker ret->idref = 1;
7502*7c568831SAndroid Build Coastguard Worker
7503*7c568831SAndroid Build Coastguard Worker return (ret);
7504*7c568831SAndroid Build Coastguard Worker }
7505*7c568831SAndroid Build Coastguard Worker
7506*7c568831SAndroid Build Coastguard Worker /**
7507*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGSetParserErrors:
7508*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
7509*7c568831SAndroid Build Coastguard Worker * @err: the error callback
7510*7c568831SAndroid Build Coastguard Worker * @warn: the warning callback
7511*7c568831SAndroid Build Coastguard Worker * @ctx: contextual data for the callbacks
7512*7c568831SAndroid Build Coastguard Worker *
7513*7c568831SAndroid Build Coastguard Worker * DEPRECATED: Use xmlRelaxNGSetParserStructuredErrors.
7514*7c568831SAndroid Build Coastguard Worker *
7515*7c568831SAndroid Build Coastguard Worker * Set the callback functions used to handle errors for a validation context
7516*7c568831SAndroid Build Coastguard Worker */
7517*7c568831SAndroid Build Coastguard Worker void
xmlRelaxNGSetParserErrors(xmlRelaxNGParserCtxtPtr ctxt,xmlRelaxNGValidityErrorFunc err,xmlRelaxNGValidityWarningFunc warn,void * ctx)7518*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSetParserErrors(xmlRelaxNGParserCtxtPtr ctxt,
7519*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidityErrorFunc err,
7520*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidityWarningFunc warn, void *ctx)
7521*7c568831SAndroid Build Coastguard Worker {
7522*7c568831SAndroid Build Coastguard Worker if (ctxt == NULL)
7523*7c568831SAndroid Build Coastguard Worker return;
7524*7c568831SAndroid Build Coastguard Worker ctxt->error = err;
7525*7c568831SAndroid Build Coastguard Worker ctxt->warning = warn;
7526*7c568831SAndroid Build Coastguard Worker ctxt->serror = NULL;
7527*7c568831SAndroid Build Coastguard Worker ctxt->userData = ctx;
7528*7c568831SAndroid Build Coastguard Worker }
7529*7c568831SAndroid Build Coastguard Worker
7530*7c568831SAndroid Build Coastguard Worker /**
7531*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGGetParserErrors:
7532*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
7533*7c568831SAndroid Build Coastguard Worker * @err: the error callback result
7534*7c568831SAndroid Build Coastguard Worker * @warn: the warning callback result
7535*7c568831SAndroid Build Coastguard Worker * @ctx: contextual data for the callbacks result
7536*7c568831SAndroid Build Coastguard Worker *
7537*7c568831SAndroid Build Coastguard Worker * Get the callback information used to handle errors for a validation context
7538*7c568831SAndroid Build Coastguard Worker *
7539*7c568831SAndroid Build Coastguard Worker * Returns -1 in case of failure, 0 otherwise.
7540*7c568831SAndroid Build Coastguard Worker */
7541*7c568831SAndroid Build Coastguard Worker int
xmlRelaxNGGetParserErrors(xmlRelaxNGParserCtxtPtr ctxt,xmlRelaxNGValidityErrorFunc * err,xmlRelaxNGValidityWarningFunc * warn,void ** ctx)7542*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGetParserErrors(xmlRelaxNGParserCtxtPtr ctxt,
7543*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidityErrorFunc * err,
7544*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidityWarningFunc * warn, void **ctx)
7545*7c568831SAndroid Build Coastguard Worker {
7546*7c568831SAndroid Build Coastguard Worker if (ctxt == NULL)
7547*7c568831SAndroid Build Coastguard Worker return (-1);
7548*7c568831SAndroid Build Coastguard Worker if (err != NULL)
7549*7c568831SAndroid Build Coastguard Worker *err = ctxt->error;
7550*7c568831SAndroid Build Coastguard Worker if (warn != NULL)
7551*7c568831SAndroid Build Coastguard Worker *warn = ctxt->warning;
7552*7c568831SAndroid Build Coastguard Worker if (ctx != NULL)
7553*7c568831SAndroid Build Coastguard Worker *ctx = ctxt->userData;
7554*7c568831SAndroid Build Coastguard Worker return (0);
7555*7c568831SAndroid Build Coastguard Worker }
7556*7c568831SAndroid Build Coastguard Worker
7557*7c568831SAndroid Build Coastguard Worker /**
7558*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGSetParserStructuredErrors:
7559*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
7560*7c568831SAndroid Build Coastguard Worker * @serror: the error callback
7561*7c568831SAndroid Build Coastguard Worker * @ctx: contextual data for the callbacks
7562*7c568831SAndroid Build Coastguard Worker *
7563*7c568831SAndroid Build Coastguard Worker * Set the callback functions used to handle errors for a parsing context
7564*7c568831SAndroid Build Coastguard Worker */
7565*7c568831SAndroid Build Coastguard Worker void
xmlRelaxNGSetParserStructuredErrors(xmlRelaxNGParserCtxtPtr ctxt,xmlStructuredErrorFunc serror,void * ctx)7566*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSetParserStructuredErrors(xmlRelaxNGParserCtxtPtr ctxt,
7567*7c568831SAndroid Build Coastguard Worker xmlStructuredErrorFunc serror,
7568*7c568831SAndroid Build Coastguard Worker void *ctx)
7569*7c568831SAndroid Build Coastguard Worker {
7570*7c568831SAndroid Build Coastguard Worker if (ctxt == NULL)
7571*7c568831SAndroid Build Coastguard Worker return;
7572*7c568831SAndroid Build Coastguard Worker ctxt->serror = serror;
7573*7c568831SAndroid Build Coastguard Worker ctxt->error = NULL;
7574*7c568831SAndroid Build Coastguard Worker ctxt->warning = NULL;
7575*7c568831SAndroid Build Coastguard Worker ctxt->userData = ctx;
7576*7c568831SAndroid Build Coastguard Worker }
7577*7c568831SAndroid Build Coastguard Worker
7578*7c568831SAndroid Build Coastguard Worker /**
7579*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGSetResourceLoader:
7580*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG parser context
7581*7c568831SAndroid Build Coastguard Worker * @loader: the callback
7582*7c568831SAndroid Build Coastguard Worker * @vctxt: contextual data for the callbacks
7583*7c568831SAndroid Build Coastguard Worker *
7584*7c568831SAndroid Build Coastguard Worker * Set the callback function used to load external resources.
7585*7c568831SAndroid Build Coastguard Worker */
7586*7c568831SAndroid Build Coastguard Worker void
xmlRelaxNGSetResourceLoader(xmlRelaxNGParserCtxtPtr ctxt,xmlResourceLoader loader,void * vctxt)7587*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSetResourceLoader(xmlRelaxNGParserCtxtPtr ctxt,
7588*7c568831SAndroid Build Coastguard Worker xmlResourceLoader loader, void *vctxt) {
7589*7c568831SAndroid Build Coastguard Worker if (ctxt == NULL)
7590*7c568831SAndroid Build Coastguard Worker return;
7591*7c568831SAndroid Build Coastguard Worker ctxt->resourceLoader = loader;
7592*7c568831SAndroid Build Coastguard Worker ctxt->resourceCtxt = vctxt;
7593*7c568831SAndroid Build Coastguard Worker }
7594*7c568831SAndroid Build Coastguard Worker
7595*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_OUTPUT_ENABLED
7596*7c568831SAndroid Build Coastguard Worker
7597*7c568831SAndroid Build Coastguard Worker /************************************************************************
7598*7c568831SAndroid Build Coastguard Worker * *
7599*7c568831SAndroid Build Coastguard Worker * Dump back a compiled form *
7600*7c568831SAndroid Build Coastguard Worker * *
7601*7c568831SAndroid Build Coastguard Worker ************************************************************************/
7602*7c568831SAndroid Build Coastguard Worker static void xmlRelaxNGDumpDefine(FILE * output,
7603*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr define);
7604*7c568831SAndroid Build Coastguard Worker
7605*7c568831SAndroid Build Coastguard Worker /**
7606*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGDumpDefines:
7607*7c568831SAndroid Build Coastguard Worker * @output: the file output
7608*7c568831SAndroid Build Coastguard Worker * @defines: a list of define structures
7609*7c568831SAndroid Build Coastguard Worker *
7610*7c568831SAndroid Build Coastguard Worker * Dump a RelaxNG structure back
7611*7c568831SAndroid Build Coastguard Worker */
7612*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGDumpDefines(FILE * output,xmlRelaxNGDefinePtr defines)7613*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefines(FILE * output, xmlRelaxNGDefinePtr defines)
7614*7c568831SAndroid Build Coastguard Worker {
7615*7c568831SAndroid Build Coastguard Worker while (defines != NULL) {
7616*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefine(output, defines);
7617*7c568831SAndroid Build Coastguard Worker defines = defines->next;
7618*7c568831SAndroid Build Coastguard Worker }
7619*7c568831SAndroid Build Coastguard Worker }
7620*7c568831SAndroid Build Coastguard Worker
7621*7c568831SAndroid Build Coastguard Worker /**
7622*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGDumpDefine:
7623*7c568831SAndroid Build Coastguard Worker * @output: the file output
7624*7c568831SAndroid Build Coastguard Worker * @define: a define structure
7625*7c568831SAndroid Build Coastguard Worker *
7626*7c568831SAndroid Build Coastguard Worker * Dump a RelaxNG structure back
7627*7c568831SAndroid Build Coastguard Worker */
7628*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGDumpDefine(FILE * output,xmlRelaxNGDefinePtr define)7629*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefine(FILE * output, xmlRelaxNGDefinePtr define)
7630*7c568831SAndroid Build Coastguard Worker {
7631*7c568831SAndroid Build Coastguard Worker if (define == NULL)
7632*7c568831SAndroid Build Coastguard Worker return;
7633*7c568831SAndroid Build Coastguard Worker switch (define->type) {
7634*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EMPTY:
7635*7c568831SAndroid Build Coastguard Worker fprintf(output, "<empty/>\n");
7636*7c568831SAndroid Build Coastguard Worker break;
7637*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOT_ALLOWED:
7638*7c568831SAndroid Build Coastguard Worker fprintf(output, "<notAllowed/>\n");
7639*7c568831SAndroid Build Coastguard Worker break;
7640*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_TEXT:
7641*7c568831SAndroid Build Coastguard Worker fprintf(output, "<text/>\n");
7642*7c568831SAndroid Build Coastguard Worker break;
7643*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ELEMENT:
7644*7c568831SAndroid Build Coastguard Worker fprintf(output, "<element>\n");
7645*7c568831SAndroid Build Coastguard Worker if (define->name != NULL) {
7646*7c568831SAndroid Build Coastguard Worker fprintf(output, "<name");
7647*7c568831SAndroid Build Coastguard Worker if (define->ns != NULL)
7648*7c568831SAndroid Build Coastguard Worker fprintf(output, " ns=\"%s\"", define->ns);
7649*7c568831SAndroid Build Coastguard Worker fprintf(output, ">%s</name>\n", define->name);
7650*7c568831SAndroid Build Coastguard Worker }
7651*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefines(output, define->attrs);
7652*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefines(output, define->content);
7653*7c568831SAndroid Build Coastguard Worker fprintf(output, "</element>\n");
7654*7c568831SAndroid Build Coastguard Worker break;
7655*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_LIST:
7656*7c568831SAndroid Build Coastguard Worker fprintf(output, "<list>\n");
7657*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefines(output, define->content);
7658*7c568831SAndroid Build Coastguard Worker fprintf(output, "</list>\n");
7659*7c568831SAndroid Build Coastguard Worker break;
7660*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ONEORMORE:
7661*7c568831SAndroid Build Coastguard Worker fprintf(output, "<oneOrMore>\n");
7662*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefines(output, define->content);
7663*7c568831SAndroid Build Coastguard Worker fprintf(output, "</oneOrMore>\n");
7664*7c568831SAndroid Build Coastguard Worker break;
7665*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ZEROORMORE:
7666*7c568831SAndroid Build Coastguard Worker fprintf(output, "<zeroOrMore>\n");
7667*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefines(output, define->content);
7668*7c568831SAndroid Build Coastguard Worker fprintf(output, "</zeroOrMore>\n");
7669*7c568831SAndroid Build Coastguard Worker break;
7670*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_CHOICE:
7671*7c568831SAndroid Build Coastguard Worker fprintf(output, "<choice>\n");
7672*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefines(output, define->content);
7673*7c568831SAndroid Build Coastguard Worker fprintf(output, "</choice>\n");
7674*7c568831SAndroid Build Coastguard Worker break;
7675*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_GROUP:
7676*7c568831SAndroid Build Coastguard Worker fprintf(output, "<group>\n");
7677*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefines(output, define->content);
7678*7c568831SAndroid Build Coastguard Worker fprintf(output, "</group>\n");
7679*7c568831SAndroid Build Coastguard Worker break;
7680*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_INTERLEAVE:
7681*7c568831SAndroid Build Coastguard Worker fprintf(output, "<interleave>\n");
7682*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefines(output, define->content);
7683*7c568831SAndroid Build Coastguard Worker fprintf(output, "</interleave>\n");
7684*7c568831SAndroid Build Coastguard Worker break;
7685*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_OPTIONAL:
7686*7c568831SAndroid Build Coastguard Worker fprintf(output, "<optional>\n");
7687*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefines(output, define->content);
7688*7c568831SAndroid Build Coastguard Worker fprintf(output, "</optional>\n");
7689*7c568831SAndroid Build Coastguard Worker break;
7690*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ATTRIBUTE:
7691*7c568831SAndroid Build Coastguard Worker fprintf(output, "<attribute>\n");
7692*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefines(output, define->content);
7693*7c568831SAndroid Build Coastguard Worker fprintf(output, "</attribute>\n");
7694*7c568831SAndroid Build Coastguard Worker break;
7695*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DEF:
7696*7c568831SAndroid Build Coastguard Worker fprintf(output, "<define");
7697*7c568831SAndroid Build Coastguard Worker if (define->name != NULL)
7698*7c568831SAndroid Build Coastguard Worker fprintf(output, " name=\"%s\"", define->name);
7699*7c568831SAndroid Build Coastguard Worker fprintf(output, ">\n");
7700*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefines(output, define->content);
7701*7c568831SAndroid Build Coastguard Worker fprintf(output, "</define>\n");
7702*7c568831SAndroid Build Coastguard Worker break;
7703*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_REF:
7704*7c568831SAndroid Build Coastguard Worker fprintf(output, "<ref");
7705*7c568831SAndroid Build Coastguard Worker if (define->name != NULL)
7706*7c568831SAndroid Build Coastguard Worker fprintf(output, " name=\"%s\"", define->name);
7707*7c568831SAndroid Build Coastguard Worker fprintf(output, ">\n");
7708*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefines(output, define->content);
7709*7c568831SAndroid Build Coastguard Worker fprintf(output, "</ref>\n");
7710*7c568831SAndroid Build Coastguard Worker break;
7711*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARENTREF:
7712*7c568831SAndroid Build Coastguard Worker fprintf(output, "<parentRef");
7713*7c568831SAndroid Build Coastguard Worker if (define->name != NULL)
7714*7c568831SAndroid Build Coastguard Worker fprintf(output, " name=\"%s\"", define->name);
7715*7c568831SAndroid Build Coastguard Worker fprintf(output, ">\n");
7716*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefines(output, define->content);
7717*7c568831SAndroid Build Coastguard Worker fprintf(output, "</parentRef>\n");
7718*7c568831SAndroid Build Coastguard Worker break;
7719*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXTERNALREF:
7720*7c568831SAndroid Build Coastguard Worker fprintf(output, "<externalRef>");
7721*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefines(output, define->content);
7722*7c568831SAndroid Build Coastguard Worker fprintf(output, "</externalRef>\n");
7723*7c568831SAndroid Build Coastguard Worker break;
7724*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DATATYPE:
7725*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_VALUE:
7726*7c568831SAndroid Build Coastguard Worker /* TODO */
7727*7c568831SAndroid Build Coastguard Worker break;
7728*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_START:
7729*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXCEPT:
7730*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARAM:
7731*7c568831SAndroid Build Coastguard Worker /* TODO */
7732*7c568831SAndroid Build Coastguard Worker break;
7733*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOOP:
7734*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefines(output, define->content);
7735*7c568831SAndroid Build Coastguard Worker break;
7736*7c568831SAndroid Build Coastguard Worker }
7737*7c568831SAndroid Build Coastguard Worker }
7738*7c568831SAndroid Build Coastguard Worker
7739*7c568831SAndroid Build Coastguard Worker /**
7740*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGDumpGrammar:
7741*7c568831SAndroid Build Coastguard Worker * @output: the file output
7742*7c568831SAndroid Build Coastguard Worker * @grammar: a grammar structure
7743*7c568831SAndroid Build Coastguard Worker * @top: is this a top grammar
7744*7c568831SAndroid Build Coastguard Worker *
7745*7c568831SAndroid Build Coastguard Worker * Dump a RelaxNG structure back
7746*7c568831SAndroid Build Coastguard Worker */
7747*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGDumpGrammar(FILE * output,xmlRelaxNGGrammarPtr grammar,int top)7748*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpGrammar(FILE * output, xmlRelaxNGGrammarPtr grammar, int top)
7749*7c568831SAndroid Build Coastguard Worker {
7750*7c568831SAndroid Build Coastguard Worker if (grammar == NULL)
7751*7c568831SAndroid Build Coastguard Worker return;
7752*7c568831SAndroid Build Coastguard Worker
7753*7c568831SAndroid Build Coastguard Worker fprintf(output, "<grammar");
7754*7c568831SAndroid Build Coastguard Worker if (top)
7755*7c568831SAndroid Build Coastguard Worker fprintf(output, " xmlns=\"http://relaxng.org/ns/structure/1.0\"");
7756*7c568831SAndroid Build Coastguard Worker switch (grammar->combine) {
7757*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_COMBINE_UNDEFINED:
7758*7c568831SAndroid Build Coastguard Worker break;
7759*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_COMBINE_CHOICE:
7760*7c568831SAndroid Build Coastguard Worker fprintf(output, " combine=\"choice\"");
7761*7c568831SAndroid Build Coastguard Worker break;
7762*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_COMBINE_INTERLEAVE:
7763*7c568831SAndroid Build Coastguard Worker fprintf(output, " combine=\"interleave\"");
7764*7c568831SAndroid Build Coastguard Worker break;
7765*7c568831SAndroid Build Coastguard Worker default:
7766*7c568831SAndroid Build Coastguard Worker fprintf(output, " <!-- invalid combine value -->");
7767*7c568831SAndroid Build Coastguard Worker }
7768*7c568831SAndroid Build Coastguard Worker fprintf(output, ">\n");
7769*7c568831SAndroid Build Coastguard Worker if (grammar->start == NULL) {
7770*7c568831SAndroid Build Coastguard Worker fprintf(output, " <!-- grammar had no start -->");
7771*7c568831SAndroid Build Coastguard Worker } else {
7772*7c568831SAndroid Build Coastguard Worker fprintf(output, "<start>\n");
7773*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpDefine(output, grammar->start);
7774*7c568831SAndroid Build Coastguard Worker fprintf(output, "</start>\n");
7775*7c568831SAndroid Build Coastguard Worker }
7776*7c568831SAndroid Build Coastguard Worker /* TODO ? Dump the defines ? */
7777*7c568831SAndroid Build Coastguard Worker fprintf(output, "</grammar>\n");
7778*7c568831SAndroid Build Coastguard Worker }
7779*7c568831SAndroid Build Coastguard Worker
7780*7c568831SAndroid Build Coastguard Worker /**
7781*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGDump:
7782*7c568831SAndroid Build Coastguard Worker * @output: the file output
7783*7c568831SAndroid Build Coastguard Worker * @schema: a schema structure
7784*7c568831SAndroid Build Coastguard Worker *
7785*7c568831SAndroid Build Coastguard Worker * Dump a RelaxNG structure back
7786*7c568831SAndroid Build Coastguard Worker */
7787*7c568831SAndroid Build Coastguard Worker void
xmlRelaxNGDump(FILE * output,xmlRelaxNGPtr schema)7788*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDump(FILE * output, xmlRelaxNGPtr schema)
7789*7c568831SAndroid Build Coastguard Worker {
7790*7c568831SAndroid Build Coastguard Worker if (output == NULL)
7791*7c568831SAndroid Build Coastguard Worker return;
7792*7c568831SAndroid Build Coastguard Worker if (schema == NULL) {
7793*7c568831SAndroid Build Coastguard Worker fprintf(output, "RelaxNG empty or failed to compile\n");
7794*7c568831SAndroid Build Coastguard Worker return;
7795*7c568831SAndroid Build Coastguard Worker }
7796*7c568831SAndroid Build Coastguard Worker fprintf(output, "RelaxNG: ");
7797*7c568831SAndroid Build Coastguard Worker if (schema->doc == NULL) {
7798*7c568831SAndroid Build Coastguard Worker fprintf(output, "no document\n");
7799*7c568831SAndroid Build Coastguard Worker } else if (schema->doc->URL != NULL) {
7800*7c568831SAndroid Build Coastguard Worker fprintf(output, "%s\n", schema->doc->URL);
7801*7c568831SAndroid Build Coastguard Worker } else {
7802*7c568831SAndroid Build Coastguard Worker fprintf(output, "\n");
7803*7c568831SAndroid Build Coastguard Worker }
7804*7c568831SAndroid Build Coastguard Worker if (schema->topgrammar == NULL) {
7805*7c568831SAndroid Build Coastguard Worker fprintf(output, "RelaxNG has no top grammar\n");
7806*7c568831SAndroid Build Coastguard Worker return;
7807*7c568831SAndroid Build Coastguard Worker }
7808*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpGrammar(output, schema->topgrammar, 1);
7809*7c568831SAndroid Build Coastguard Worker }
7810*7c568831SAndroid Build Coastguard Worker
7811*7c568831SAndroid Build Coastguard Worker /**
7812*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGDumpTree:
7813*7c568831SAndroid Build Coastguard Worker * @output: the file output
7814*7c568831SAndroid Build Coastguard Worker * @schema: a schema structure
7815*7c568831SAndroid Build Coastguard Worker *
7816*7c568831SAndroid Build Coastguard Worker * Dump the transformed RelaxNG tree.
7817*7c568831SAndroid Build Coastguard Worker */
7818*7c568831SAndroid Build Coastguard Worker void
xmlRelaxNGDumpTree(FILE * output,xmlRelaxNGPtr schema)7819*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpTree(FILE * output, xmlRelaxNGPtr schema)
7820*7c568831SAndroid Build Coastguard Worker {
7821*7c568831SAndroid Build Coastguard Worker if (output == NULL)
7822*7c568831SAndroid Build Coastguard Worker return;
7823*7c568831SAndroid Build Coastguard Worker if (schema == NULL) {
7824*7c568831SAndroid Build Coastguard Worker fprintf(output, "RelaxNG empty or failed to compile\n");
7825*7c568831SAndroid Build Coastguard Worker return;
7826*7c568831SAndroid Build Coastguard Worker }
7827*7c568831SAndroid Build Coastguard Worker if (schema->doc == NULL) {
7828*7c568831SAndroid Build Coastguard Worker fprintf(output, "no document\n");
7829*7c568831SAndroid Build Coastguard Worker } else {
7830*7c568831SAndroid Build Coastguard Worker xmlDocDump(output, schema->doc);
7831*7c568831SAndroid Build Coastguard Worker }
7832*7c568831SAndroid Build Coastguard Worker }
7833*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_OUTPUT_ENABLED */
7834*7c568831SAndroid Build Coastguard Worker
7835*7c568831SAndroid Build Coastguard Worker /************************************************************************
7836*7c568831SAndroid Build Coastguard Worker * *
7837*7c568831SAndroid Build Coastguard Worker * Validation of compiled content *
7838*7c568831SAndroid Build Coastguard Worker * *
7839*7c568831SAndroid Build Coastguard Worker ************************************************************************/
7840*7c568831SAndroid Build Coastguard Worker static int xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,
7841*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr define);
7842*7c568831SAndroid Build Coastguard Worker
7843*7c568831SAndroid Build Coastguard Worker /**
7844*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidateCompiledCallback:
7845*7c568831SAndroid Build Coastguard Worker * @exec: the regular expression instance
7846*7c568831SAndroid Build Coastguard Worker * @token: the token which matched
7847*7c568831SAndroid Build Coastguard Worker * @transdata: callback data, the define for the subelement if available
7848*7c568831SAndroid Build Coastguard Worker @ @inputdata: callback data, the Relax NG validation context
7849*7c568831SAndroid Build Coastguard Worker *
7850*7c568831SAndroid Build Coastguard Worker * Handle the callback and if needed validate the element children.
7851*7c568831SAndroid Build Coastguard Worker */
7852*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGValidateCompiledCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,const xmlChar * token,void * transdata,void * inputdata)7853*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateCompiledCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
7854*7c568831SAndroid Build Coastguard Worker const xmlChar * token,
7855*7c568831SAndroid Build Coastguard Worker void *transdata, void *inputdata)
7856*7c568831SAndroid Build Coastguard Worker {
7857*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidCtxtPtr ctxt = (xmlRelaxNGValidCtxtPtr) inputdata;
7858*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr define = (xmlRelaxNGDefinePtr) transdata;
7859*7c568831SAndroid Build Coastguard Worker int ret;
7860*7c568831SAndroid Build Coastguard Worker
7861*7c568831SAndroid Build Coastguard Worker if (ctxt == NULL) {
7862*7c568831SAndroid Build Coastguard Worker xmlRngVErr(ctxt, NULL, XML_ERR_INTERNAL_ERROR,
7863*7c568831SAndroid Build Coastguard Worker "callback on %s missing context\n", token, NULL);
7864*7c568831SAndroid Build Coastguard Worker return;
7865*7c568831SAndroid Build Coastguard Worker }
7866*7c568831SAndroid Build Coastguard Worker if (define == NULL) {
7867*7c568831SAndroid Build Coastguard Worker if (token[0] == '#')
7868*7c568831SAndroid Build Coastguard Worker return;
7869*7c568831SAndroid Build Coastguard Worker xmlRngVErr(ctxt, NULL, XML_ERR_INTERNAL_ERROR,
7870*7c568831SAndroid Build Coastguard Worker "callback on %s missing define\n", token, NULL);
7871*7c568831SAndroid Build Coastguard Worker if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
7872*7c568831SAndroid Build Coastguard Worker ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
7873*7c568831SAndroid Build Coastguard Worker return;
7874*7c568831SAndroid Build Coastguard Worker }
7875*7c568831SAndroid Build Coastguard Worker if (define->type != XML_RELAXNG_ELEMENT) {
7876*7c568831SAndroid Build Coastguard Worker xmlRngVErr(ctxt, NULL, XML_ERR_INTERNAL_ERROR,
7877*7c568831SAndroid Build Coastguard Worker "callback on %s define is not element\n", token, NULL);
7878*7c568831SAndroid Build Coastguard Worker if (ctxt->errNo == XML_RELAXNG_OK)
7879*7c568831SAndroid Build Coastguard Worker ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
7880*7c568831SAndroid Build Coastguard Worker return;
7881*7c568831SAndroid Build Coastguard Worker }
7882*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateDefinition(ctxt, define);
7883*7c568831SAndroid Build Coastguard Worker if (ret != 0)
7884*7c568831SAndroid Build Coastguard Worker ctxt->perr = ret;
7885*7c568831SAndroid Build Coastguard Worker }
7886*7c568831SAndroid Build Coastguard Worker
7887*7c568831SAndroid Build Coastguard Worker /**
7888*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidateCompiledContent:
7889*7c568831SAndroid Build Coastguard Worker * @ctxt: the RelaxNG validation context
7890*7c568831SAndroid Build Coastguard Worker * @regexp: the regular expression as compiled
7891*7c568831SAndroid Build Coastguard Worker * @content: list of children to test against the regexp
7892*7c568831SAndroid Build Coastguard Worker *
7893*7c568831SAndroid Build Coastguard Worker * Validate the content model of an element or start using the regexp
7894*7c568831SAndroid Build Coastguard Worker *
7895*7c568831SAndroid Build Coastguard Worker * Returns 0 in case of success, -1 in case of error.
7896*7c568831SAndroid Build Coastguard Worker */
7897*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGValidateCompiledContent(xmlRelaxNGValidCtxtPtr ctxt,xmlRegexpPtr regexp,xmlNodePtr content)7898*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateCompiledContent(xmlRelaxNGValidCtxtPtr ctxt,
7899*7c568831SAndroid Build Coastguard Worker xmlRegexpPtr regexp, xmlNodePtr content)
7900*7c568831SAndroid Build Coastguard Worker {
7901*7c568831SAndroid Build Coastguard Worker xmlRegExecCtxtPtr exec;
7902*7c568831SAndroid Build Coastguard Worker xmlNodePtr cur;
7903*7c568831SAndroid Build Coastguard Worker int ret = 0;
7904*7c568831SAndroid Build Coastguard Worker int oldperr;
7905*7c568831SAndroid Build Coastguard Worker
7906*7c568831SAndroid Build Coastguard Worker if ((ctxt == NULL) || (regexp == NULL))
7907*7c568831SAndroid Build Coastguard Worker return (-1);
7908*7c568831SAndroid Build Coastguard Worker oldperr = ctxt->perr;
7909*7c568831SAndroid Build Coastguard Worker exec = xmlRegNewExecCtxt(regexp,
7910*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateCompiledCallback, ctxt);
7911*7c568831SAndroid Build Coastguard Worker ctxt->perr = 0;
7912*7c568831SAndroid Build Coastguard Worker cur = content;
7913*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
7914*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = cur;
7915*7c568831SAndroid Build Coastguard Worker switch (cur->type) {
7916*7c568831SAndroid Build Coastguard Worker case XML_TEXT_NODE:
7917*7c568831SAndroid Build Coastguard Worker case XML_CDATA_SECTION_NODE:
7918*7c568831SAndroid Build Coastguard Worker if (xmlIsBlankNode(cur))
7919*7c568831SAndroid Build Coastguard Worker break;
7920*7c568831SAndroid Build Coastguard Worker ret = xmlRegExecPushString(exec, BAD_CAST "#text", ctxt);
7921*7c568831SAndroid Build Coastguard Worker if (ret < 0) {
7922*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_TEXTWRONG,
7923*7c568831SAndroid Build Coastguard Worker cur->parent->name);
7924*7c568831SAndroid Build Coastguard Worker }
7925*7c568831SAndroid Build Coastguard Worker break;
7926*7c568831SAndroid Build Coastguard Worker case XML_ELEMENT_NODE:
7927*7c568831SAndroid Build Coastguard Worker if (cur->ns != NULL) {
7928*7c568831SAndroid Build Coastguard Worker ret = xmlRegExecPushString2(exec, cur->name,
7929*7c568831SAndroid Build Coastguard Worker cur->ns->href, ctxt);
7930*7c568831SAndroid Build Coastguard Worker } else {
7931*7c568831SAndroid Build Coastguard Worker ret = xmlRegExecPushString(exec, cur->name, ctxt);
7932*7c568831SAndroid Build Coastguard Worker }
7933*7c568831SAndroid Build Coastguard Worker if (ret < 0) {
7934*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_ELEMWRONG, cur->name);
7935*7c568831SAndroid Build Coastguard Worker }
7936*7c568831SAndroid Build Coastguard Worker break;
7937*7c568831SAndroid Build Coastguard Worker default:
7938*7c568831SAndroid Build Coastguard Worker break;
7939*7c568831SAndroid Build Coastguard Worker }
7940*7c568831SAndroid Build Coastguard Worker if (ret < 0)
7941*7c568831SAndroid Build Coastguard Worker break;
7942*7c568831SAndroid Build Coastguard Worker /*
7943*7c568831SAndroid Build Coastguard Worker * Switch to next element
7944*7c568831SAndroid Build Coastguard Worker */
7945*7c568831SAndroid Build Coastguard Worker cur = cur->next;
7946*7c568831SAndroid Build Coastguard Worker }
7947*7c568831SAndroid Build Coastguard Worker ret = xmlRegExecPushString(exec, NULL, NULL);
7948*7c568831SAndroid Build Coastguard Worker if (ret == 1) {
7949*7c568831SAndroid Build Coastguard Worker ret = 0;
7950*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = NULL;
7951*7c568831SAndroid Build Coastguard Worker } else if (ret == 0) {
7952*7c568831SAndroid Build Coastguard Worker /*
7953*7c568831SAndroid Build Coastguard Worker * TODO: get some of the names needed to exit the current state of exec
7954*7c568831SAndroid Build Coastguard Worker */
7955*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_NOELEM, BAD_CAST "");
7956*7c568831SAndroid Build Coastguard Worker ret = -1;
7957*7c568831SAndroid Build Coastguard Worker if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
7958*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpValidError(ctxt);
7959*7c568831SAndroid Build Coastguard Worker } else {
7960*7c568831SAndroid Build Coastguard Worker ret = -1;
7961*7c568831SAndroid Build Coastguard Worker }
7962*7c568831SAndroid Build Coastguard Worker xmlRegFreeExecCtxt(exec);
7963*7c568831SAndroid Build Coastguard Worker /*
7964*7c568831SAndroid Build Coastguard Worker * There might be content model errors outside of the pure
7965*7c568831SAndroid Build Coastguard Worker * regexp validation, e.g. for attribute values.
7966*7c568831SAndroid Build Coastguard Worker */
7967*7c568831SAndroid Build Coastguard Worker if ((ret == 0) && (ctxt->perr != 0)) {
7968*7c568831SAndroid Build Coastguard Worker ret = ctxt->perr;
7969*7c568831SAndroid Build Coastguard Worker }
7970*7c568831SAndroid Build Coastguard Worker ctxt->perr = oldperr;
7971*7c568831SAndroid Build Coastguard Worker return (ret);
7972*7c568831SAndroid Build Coastguard Worker }
7973*7c568831SAndroid Build Coastguard Worker
7974*7c568831SAndroid Build Coastguard Worker /************************************************************************
7975*7c568831SAndroid Build Coastguard Worker * *
7976*7c568831SAndroid Build Coastguard Worker * Progressive validation of when possible *
7977*7c568831SAndroid Build Coastguard Worker * *
7978*7c568831SAndroid Build Coastguard Worker ************************************************************************/
7979*7c568831SAndroid Build Coastguard Worker static int xmlRelaxNGValidateAttributeList(xmlRelaxNGValidCtxtPtr ctxt,
7980*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr defines);
7981*7c568831SAndroid Build Coastguard Worker static int xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt,
7982*7c568831SAndroid Build Coastguard Worker int dolog);
7983*7c568831SAndroid Build Coastguard Worker static void xmlRelaxNGLogBestError(xmlRelaxNGValidCtxtPtr ctxt);
7984*7c568831SAndroid Build Coastguard Worker
7985*7c568831SAndroid Build Coastguard Worker /**
7986*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGElemPush:
7987*7c568831SAndroid Build Coastguard Worker * @ctxt: the validation context
7988*7c568831SAndroid Build Coastguard Worker * @exec: the regexp runtime for the new content model
7989*7c568831SAndroid Build Coastguard Worker *
7990*7c568831SAndroid Build Coastguard Worker * Push a new regexp for the current node content model on the stack
7991*7c568831SAndroid Build Coastguard Worker *
7992*7c568831SAndroid Build Coastguard Worker * Returns 0 in case of success and -1 in case of error.
7993*7c568831SAndroid Build Coastguard Worker */
7994*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGElemPush(xmlRelaxNGValidCtxtPtr ctxt,xmlRegExecCtxtPtr exec)7995*7c568831SAndroid Build Coastguard Worker xmlRelaxNGElemPush(xmlRelaxNGValidCtxtPtr ctxt, xmlRegExecCtxtPtr exec)
7996*7c568831SAndroid Build Coastguard Worker {
7997*7c568831SAndroid Build Coastguard Worker if (ctxt->elemTab == NULL) {
7998*7c568831SAndroid Build Coastguard Worker ctxt->elemMax = 10;
7999*7c568831SAndroid Build Coastguard Worker ctxt->elemTab = (xmlRegExecCtxtPtr *) xmlMalloc(ctxt->elemMax *
8000*7c568831SAndroid Build Coastguard Worker sizeof
8001*7c568831SAndroid Build Coastguard Worker (xmlRegExecCtxtPtr));
8002*7c568831SAndroid Build Coastguard Worker if (ctxt->elemTab == NULL) {
8003*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
8004*7c568831SAndroid Build Coastguard Worker return (-1);
8005*7c568831SAndroid Build Coastguard Worker }
8006*7c568831SAndroid Build Coastguard Worker }
8007*7c568831SAndroid Build Coastguard Worker if (ctxt->elemNr >= ctxt->elemMax) {
8008*7c568831SAndroid Build Coastguard Worker ctxt->elemMax *= 2;
8009*7c568831SAndroid Build Coastguard Worker ctxt->elemTab = (xmlRegExecCtxtPtr *) xmlRealloc(ctxt->elemTab,
8010*7c568831SAndroid Build Coastguard Worker ctxt->elemMax *
8011*7c568831SAndroid Build Coastguard Worker sizeof
8012*7c568831SAndroid Build Coastguard Worker (xmlRegExecCtxtPtr));
8013*7c568831SAndroid Build Coastguard Worker if (ctxt->elemTab == NULL) {
8014*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
8015*7c568831SAndroid Build Coastguard Worker return (-1);
8016*7c568831SAndroid Build Coastguard Worker }
8017*7c568831SAndroid Build Coastguard Worker }
8018*7c568831SAndroid Build Coastguard Worker ctxt->elemTab[ctxt->elemNr++] = exec;
8019*7c568831SAndroid Build Coastguard Worker ctxt->elem = exec;
8020*7c568831SAndroid Build Coastguard Worker return (0);
8021*7c568831SAndroid Build Coastguard Worker }
8022*7c568831SAndroid Build Coastguard Worker
8023*7c568831SAndroid Build Coastguard Worker /**
8024*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGElemPop:
8025*7c568831SAndroid Build Coastguard Worker * @ctxt: the validation context
8026*7c568831SAndroid Build Coastguard Worker *
8027*7c568831SAndroid Build Coastguard Worker * Pop the regexp of the current node content model from the stack
8028*7c568831SAndroid Build Coastguard Worker *
8029*7c568831SAndroid Build Coastguard Worker * Returns the exec or NULL if empty
8030*7c568831SAndroid Build Coastguard Worker */
8031*7c568831SAndroid Build Coastguard Worker static xmlRegExecCtxtPtr
xmlRelaxNGElemPop(xmlRelaxNGValidCtxtPtr ctxt)8032*7c568831SAndroid Build Coastguard Worker xmlRelaxNGElemPop(xmlRelaxNGValidCtxtPtr ctxt)
8033*7c568831SAndroid Build Coastguard Worker {
8034*7c568831SAndroid Build Coastguard Worker xmlRegExecCtxtPtr ret;
8035*7c568831SAndroid Build Coastguard Worker
8036*7c568831SAndroid Build Coastguard Worker if (ctxt->elemNr <= 0)
8037*7c568831SAndroid Build Coastguard Worker return (NULL);
8038*7c568831SAndroid Build Coastguard Worker ctxt->elemNr--;
8039*7c568831SAndroid Build Coastguard Worker ret = ctxt->elemTab[ctxt->elemNr];
8040*7c568831SAndroid Build Coastguard Worker ctxt->elemTab[ctxt->elemNr] = NULL;
8041*7c568831SAndroid Build Coastguard Worker if (ctxt->elemNr > 0)
8042*7c568831SAndroid Build Coastguard Worker ctxt->elem = ctxt->elemTab[ctxt->elemNr - 1];
8043*7c568831SAndroid Build Coastguard Worker else
8044*7c568831SAndroid Build Coastguard Worker ctxt->elem = NULL;
8045*7c568831SAndroid Build Coastguard Worker return (ret);
8046*7c568831SAndroid Build Coastguard Worker }
8047*7c568831SAndroid Build Coastguard Worker
8048*7c568831SAndroid Build Coastguard Worker /**
8049*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidateProgressiveCallback:
8050*7c568831SAndroid Build Coastguard Worker * @exec: the regular expression instance
8051*7c568831SAndroid Build Coastguard Worker * @token: the token which matched
8052*7c568831SAndroid Build Coastguard Worker * @transdata: callback data, the define for the subelement if available
8053*7c568831SAndroid Build Coastguard Worker @ @inputdata: callback data, the Relax NG validation context
8054*7c568831SAndroid Build Coastguard Worker *
8055*7c568831SAndroid Build Coastguard Worker * Handle the callback and if needed validate the element children.
8056*7c568831SAndroid Build Coastguard Worker * some of the in/out information are passed via the context in @inputdata.
8057*7c568831SAndroid Build Coastguard Worker */
8058*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGValidateProgressiveCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,const xmlChar * token,void * transdata,void * inputdata)8059*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateProgressiveCallback(xmlRegExecCtxtPtr exec
8060*7c568831SAndroid Build Coastguard Worker ATTRIBUTE_UNUSED,
8061*7c568831SAndroid Build Coastguard Worker const xmlChar * token,
8062*7c568831SAndroid Build Coastguard Worker void *transdata, void *inputdata)
8063*7c568831SAndroid Build Coastguard Worker {
8064*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidCtxtPtr ctxt = (xmlRelaxNGValidCtxtPtr) inputdata;
8065*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr define = (xmlRelaxNGDefinePtr) transdata;
8066*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr state, oldstate;
8067*7c568831SAndroid Build Coastguard Worker xmlNodePtr node;
8068*7c568831SAndroid Build Coastguard Worker int ret = 0, oldflags;
8069*7c568831SAndroid Build Coastguard Worker
8070*7c568831SAndroid Build Coastguard Worker if (ctxt == NULL) {
8071*7c568831SAndroid Build Coastguard Worker xmlRngVErr(ctxt, NULL, XML_ERR_INTERNAL_ERROR,
8072*7c568831SAndroid Build Coastguard Worker "callback on %s missing context\n", token, NULL);
8073*7c568831SAndroid Build Coastguard Worker return;
8074*7c568831SAndroid Build Coastguard Worker }
8075*7c568831SAndroid Build Coastguard Worker node = ctxt->pnode;
8076*7c568831SAndroid Build Coastguard Worker ctxt->pstate = 1;
8077*7c568831SAndroid Build Coastguard Worker if (define == NULL) {
8078*7c568831SAndroid Build Coastguard Worker if (token[0] == '#')
8079*7c568831SAndroid Build Coastguard Worker return;
8080*7c568831SAndroid Build Coastguard Worker xmlRngVErr(ctxt, NULL, XML_ERR_INTERNAL_ERROR,
8081*7c568831SAndroid Build Coastguard Worker "callback on %s missing define\n", token, NULL);
8082*7c568831SAndroid Build Coastguard Worker if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
8083*7c568831SAndroid Build Coastguard Worker ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
8084*7c568831SAndroid Build Coastguard Worker ctxt->pstate = -1;
8085*7c568831SAndroid Build Coastguard Worker return;
8086*7c568831SAndroid Build Coastguard Worker }
8087*7c568831SAndroid Build Coastguard Worker if (define->type != XML_RELAXNG_ELEMENT) {
8088*7c568831SAndroid Build Coastguard Worker xmlRngVErr(ctxt, NULL, XML_ERR_INTERNAL_ERROR,
8089*7c568831SAndroid Build Coastguard Worker "callback on %s define is not element\n", token, NULL);
8090*7c568831SAndroid Build Coastguard Worker if (ctxt->errNo == XML_RELAXNG_OK)
8091*7c568831SAndroid Build Coastguard Worker ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
8092*7c568831SAndroid Build Coastguard Worker ctxt->pstate = -1;
8093*7c568831SAndroid Build Coastguard Worker return;
8094*7c568831SAndroid Build Coastguard Worker }
8095*7c568831SAndroid Build Coastguard Worker if (node->type != XML_ELEMENT_NODE) {
8096*7c568831SAndroid Build Coastguard Worker VALID_ERR(XML_RELAXNG_ERR_NOTELEM);
8097*7c568831SAndroid Build Coastguard Worker if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
8098*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpValidError(ctxt);
8099*7c568831SAndroid Build Coastguard Worker ctxt->pstate = -1;
8100*7c568831SAndroid Build Coastguard Worker return;
8101*7c568831SAndroid Build Coastguard Worker }
8102*7c568831SAndroid Build Coastguard Worker if (define->contModel == NULL) {
8103*7c568831SAndroid Build Coastguard Worker /*
8104*7c568831SAndroid Build Coastguard Worker * this node cannot be validated in a streamable fashion
8105*7c568831SAndroid Build Coastguard Worker */
8106*7c568831SAndroid Build Coastguard Worker ctxt->pstate = 0;
8107*7c568831SAndroid Build Coastguard Worker ctxt->pdef = define;
8108*7c568831SAndroid Build Coastguard Worker return;
8109*7c568831SAndroid Build Coastguard Worker }
8110*7c568831SAndroid Build Coastguard Worker exec = xmlRegNewExecCtxt(define->contModel,
8111*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateProgressiveCallback, ctxt);
8112*7c568831SAndroid Build Coastguard Worker if (exec == NULL) {
8113*7c568831SAndroid Build Coastguard Worker ctxt->pstate = -1;
8114*7c568831SAndroid Build Coastguard Worker return;
8115*7c568831SAndroid Build Coastguard Worker }
8116*7c568831SAndroid Build Coastguard Worker xmlRelaxNGElemPush(ctxt, exec);
8117*7c568831SAndroid Build Coastguard Worker
8118*7c568831SAndroid Build Coastguard Worker /*
8119*7c568831SAndroid Build Coastguard Worker * Validate the attributes part of the content.
8120*7c568831SAndroid Build Coastguard Worker */
8121*7c568831SAndroid Build Coastguard Worker state = xmlRelaxNGNewValidState(ctxt, node);
8122*7c568831SAndroid Build Coastguard Worker if (state == NULL) {
8123*7c568831SAndroid Build Coastguard Worker ctxt->pstate = -1;
8124*7c568831SAndroid Build Coastguard Worker return;
8125*7c568831SAndroid Build Coastguard Worker }
8126*7c568831SAndroid Build Coastguard Worker oldstate = ctxt->state;
8127*7c568831SAndroid Build Coastguard Worker ctxt->state = state;
8128*7c568831SAndroid Build Coastguard Worker if (define->attrs != NULL) {
8129*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateAttributeList(ctxt, define->attrs);
8130*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
8131*7c568831SAndroid Build Coastguard Worker ctxt->pstate = -1;
8132*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_ATTRVALID, node->name);
8133*7c568831SAndroid Build Coastguard Worker }
8134*7c568831SAndroid Build Coastguard Worker }
8135*7c568831SAndroid Build Coastguard Worker if (ctxt->state != NULL) {
8136*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = NULL;
8137*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
8138*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
8139*7c568831SAndroid Build Coastguard Worker ctxt->pstate = -1;
8140*7c568831SAndroid Build Coastguard Worker }
8141*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, ctxt->state);
8142*7c568831SAndroid Build Coastguard Worker } else if (ctxt->states != NULL) {
8143*7c568831SAndroid Build Coastguard Worker int tmp = -1, i;
8144*7c568831SAndroid Build Coastguard Worker
8145*7c568831SAndroid Build Coastguard Worker oldflags = ctxt->flags;
8146*7c568831SAndroid Build Coastguard Worker
8147*7c568831SAndroid Build Coastguard Worker for (i = 0; i < ctxt->states->nbState; i++) {
8148*7c568831SAndroid Build Coastguard Worker state = ctxt->states->tabState[i];
8149*7c568831SAndroid Build Coastguard Worker ctxt->state = state;
8150*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = NULL;
8151*7c568831SAndroid Build Coastguard Worker
8152*7c568831SAndroid Build Coastguard Worker if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
8153*7c568831SAndroid Build Coastguard Worker tmp = 0;
8154*7c568831SAndroid Build Coastguard Worker break;
8155*7c568831SAndroid Build Coastguard Worker }
8156*7c568831SAndroid Build Coastguard Worker }
8157*7c568831SAndroid Build Coastguard Worker if (tmp != 0) {
8158*7c568831SAndroid Build Coastguard Worker /*
8159*7c568831SAndroid Build Coastguard Worker * validation error, log the message for the "best" one
8160*7c568831SAndroid Build Coastguard Worker */
8161*7c568831SAndroid Build Coastguard Worker ctxt->flags |= FLAGS_IGNORABLE;
8162*7c568831SAndroid Build Coastguard Worker xmlRelaxNGLogBestError(ctxt);
8163*7c568831SAndroid Build Coastguard Worker }
8164*7c568831SAndroid Build Coastguard Worker for (i = 0; i < ctxt->states->nbState; i++) {
8165*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, ctxt->states->tabState[i]);
8166*7c568831SAndroid Build Coastguard Worker }
8167*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(ctxt, ctxt->states);
8168*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
8169*7c568831SAndroid Build Coastguard Worker if ((ret == 0) && (tmp == -1))
8170*7c568831SAndroid Build Coastguard Worker ctxt->pstate = -1;
8171*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
8172*7c568831SAndroid Build Coastguard Worker }
8173*7c568831SAndroid Build Coastguard Worker if (ctxt->pstate == -1) {
8174*7c568831SAndroid Build Coastguard Worker if ((ctxt->flags & FLAGS_IGNORABLE) == 0) {
8175*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpValidError(ctxt);
8176*7c568831SAndroid Build Coastguard Worker }
8177*7c568831SAndroid Build Coastguard Worker }
8178*7c568831SAndroid Build Coastguard Worker ctxt->state = oldstate;
8179*7c568831SAndroid Build Coastguard Worker }
8180*7c568831SAndroid Build Coastguard Worker
8181*7c568831SAndroid Build Coastguard Worker /**
8182*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidatePushElement:
8183*7c568831SAndroid Build Coastguard Worker * @ctxt: the validation context
8184*7c568831SAndroid Build Coastguard Worker * @doc: a document instance
8185*7c568831SAndroid Build Coastguard Worker * @elem: an element instance
8186*7c568831SAndroid Build Coastguard Worker *
8187*7c568831SAndroid Build Coastguard Worker * Push a new element start on the RelaxNG validation stack.
8188*7c568831SAndroid Build Coastguard Worker *
8189*7c568831SAndroid Build Coastguard Worker * returns 1 if no validation problem was found or 0 if validating the
8190*7c568831SAndroid Build Coastguard Worker * element requires a full node, and -1 in case of error.
8191*7c568831SAndroid Build Coastguard Worker */
8192*7c568831SAndroid Build Coastguard Worker int
xmlRelaxNGValidatePushElement(xmlRelaxNGValidCtxtPtr ctxt,xmlDocPtr doc ATTRIBUTE_UNUSED,xmlNodePtr elem)8193*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidatePushElement(xmlRelaxNGValidCtxtPtr ctxt,
8194*7c568831SAndroid Build Coastguard Worker xmlDocPtr doc ATTRIBUTE_UNUSED,
8195*7c568831SAndroid Build Coastguard Worker xmlNodePtr elem)
8196*7c568831SAndroid Build Coastguard Worker {
8197*7c568831SAndroid Build Coastguard Worker int ret = 1;
8198*7c568831SAndroid Build Coastguard Worker
8199*7c568831SAndroid Build Coastguard Worker if ((ctxt == NULL) || (elem == NULL))
8200*7c568831SAndroid Build Coastguard Worker return (-1);
8201*7c568831SAndroid Build Coastguard Worker
8202*7c568831SAndroid Build Coastguard Worker if (ctxt->elem == 0) {
8203*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPtr schema;
8204*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGrammarPtr grammar;
8205*7c568831SAndroid Build Coastguard Worker xmlRegExecCtxtPtr exec;
8206*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr define;
8207*7c568831SAndroid Build Coastguard Worker
8208*7c568831SAndroid Build Coastguard Worker schema = ctxt->schema;
8209*7c568831SAndroid Build Coastguard Worker if (schema == NULL) {
8210*7c568831SAndroid Build Coastguard Worker VALID_ERR(XML_RELAXNG_ERR_NOGRAMMAR);
8211*7c568831SAndroid Build Coastguard Worker return (-1);
8212*7c568831SAndroid Build Coastguard Worker }
8213*7c568831SAndroid Build Coastguard Worker grammar = schema->topgrammar;
8214*7c568831SAndroid Build Coastguard Worker if ((grammar == NULL) || (grammar->start == NULL)) {
8215*7c568831SAndroid Build Coastguard Worker VALID_ERR(XML_RELAXNG_ERR_NOGRAMMAR);
8216*7c568831SAndroid Build Coastguard Worker return (-1);
8217*7c568831SAndroid Build Coastguard Worker }
8218*7c568831SAndroid Build Coastguard Worker define = grammar->start;
8219*7c568831SAndroid Build Coastguard Worker if (define->contModel == NULL) {
8220*7c568831SAndroid Build Coastguard Worker ctxt->pdef = define;
8221*7c568831SAndroid Build Coastguard Worker return (0);
8222*7c568831SAndroid Build Coastguard Worker }
8223*7c568831SAndroid Build Coastguard Worker exec = xmlRegNewExecCtxt(define->contModel,
8224*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateProgressiveCallback,
8225*7c568831SAndroid Build Coastguard Worker ctxt);
8226*7c568831SAndroid Build Coastguard Worker if (exec == NULL) {
8227*7c568831SAndroid Build Coastguard Worker return (-1);
8228*7c568831SAndroid Build Coastguard Worker }
8229*7c568831SAndroid Build Coastguard Worker xmlRelaxNGElemPush(ctxt, exec);
8230*7c568831SAndroid Build Coastguard Worker }
8231*7c568831SAndroid Build Coastguard Worker ctxt->pnode = elem;
8232*7c568831SAndroid Build Coastguard Worker ctxt->pstate = 0;
8233*7c568831SAndroid Build Coastguard Worker if (elem->ns != NULL) {
8234*7c568831SAndroid Build Coastguard Worker ret =
8235*7c568831SAndroid Build Coastguard Worker xmlRegExecPushString2(ctxt->elem, elem->name, elem->ns->href,
8236*7c568831SAndroid Build Coastguard Worker ctxt);
8237*7c568831SAndroid Build Coastguard Worker } else {
8238*7c568831SAndroid Build Coastguard Worker ret = xmlRegExecPushString(ctxt->elem, elem->name, ctxt);
8239*7c568831SAndroid Build Coastguard Worker }
8240*7c568831SAndroid Build Coastguard Worker if (ret < 0) {
8241*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_ELEMWRONG, elem->name);
8242*7c568831SAndroid Build Coastguard Worker } else {
8243*7c568831SAndroid Build Coastguard Worker if (ctxt->pstate == 0)
8244*7c568831SAndroid Build Coastguard Worker ret = 0;
8245*7c568831SAndroid Build Coastguard Worker else if (ctxt->pstate < 0)
8246*7c568831SAndroid Build Coastguard Worker ret = -1;
8247*7c568831SAndroid Build Coastguard Worker else
8248*7c568831SAndroid Build Coastguard Worker ret = 1;
8249*7c568831SAndroid Build Coastguard Worker }
8250*7c568831SAndroid Build Coastguard Worker return (ret);
8251*7c568831SAndroid Build Coastguard Worker }
8252*7c568831SAndroid Build Coastguard Worker
8253*7c568831SAndroid Build Coastguard Worker /**
8254*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidatePushCData:
8255*7c568831SAndroid Build Coastguard Worker * @ctxt: the RelaxNG validation context
8256*7c568831SAndroid Build Coastguard Worker * @data: some character data read
8257*7c568831SAndroid Build Coastguard Worker * @len: the length of the data
8258*7c568831SAndroid Build Coastguard Worker *
8259*7c568831SAndroid Build Coastguard Worker * check the CData parsed for validation in the current stack
8260*7c568831SAndroid Build Coastguard Worker *
8261*7c568831SAndroid Build Coastguard Worker * returns 1 if no validation problem was found or -1 otherwise
8262*7c568831SAndroid Build Coastguard Worker */
8263*7c568831SAndroid Build Coastguard Worker int
xmlRelaxNGValidatePushCData(xmlRelaxNGValidCtxtPtr ctxt,const xmlChar * data,int len ATTRIBUTE_UNUSED)8264*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidatePushCData(xmlRelaxNGValidCtxtPtr ctxt,
8265*7c568831SAndroid Build Coastguard Worker const xmlChar * data, int len ATTRIBUTE_UNUSED)
8266*7c568831SAndroid Build Coastguard Worker {
8267*7c568831SAndroid Build Coastguard Worker int ret = 1;
8268*7c568831SAndroid Build Coastguard Worker
8269*7c568831SAndroid Build Coastguard Worker if ((ctxt == NULL) || (ctxt->elem == NULL) || (data == NULL))
8270*7c568831SAndroid Build Coastguard Worker return (-1);
8271*7c568831SAndroid Build Coastguard Worker
8272*7c568831SAndroid Build Coastguard Worker while (*data != 0) {
8273*7c568831SAndroid Build Coastguard Worker if (!IS_BLANK_CH(*data))
8274*7c568831SAndroid Build Coastguard Worker break;
8275*7c568831SAndroid Build Coastguard Worker data++;
8276*7c568831SAndroid Build Coastguard Worker }
8277*7c568831SAndroid Build Coastguard Worker if (*data == 0)
8278*7c568831SAndroid Build Coastguard Worker return (1);
8279*7c568831SAndroid Build Coastguard Worker
8280*7c568831SAndroid Build Coastguard Worker ret = xmlRegExecPushString(ctxt->elem, BAD_CAST "#text", ctxt);
8281*7c568831SAndroid Build Coastguard Worker if (ret < 0) {
8282*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_TEXTWRONG, BAD_CAST " TODO ");
8283*7c568831SAndroid Build Coastguard Worker
8284*7c568831SAndroid Build Coastguard Worker return (-1);
8285*7c568831SAndroid Build Coastguard Worker }
8286*7c568831SAndroid Build Coastguard Worker return (1);
8287*7c568831SAndroid Build Coastguard Worker }
8288*7c568831SAndroid Build Coastguard Worker
8289*7c568831SAndroid Build Coastguard Worker /**
8290*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidatePopElement:
8291*7c568831SAndroid Build Coastguard Worker * @ctxt: the RelaxNG validation context
8292*7c568831SAndroid Build Coastguard Worker * @doc: a document instance
8293*7c568831SAndroid Build Coastguard Worker * @elem: an element instance
8294*7c568831SAndroid Build Coastguard Worker *
8295*7c568831SAndroid Build Coastguard Worker * Pop the element end from the RelaxNG validation stack.
8296*7c568831SAndroid Build Coastguard Worker *
8297*7c568831SAndroid Build Coastguard Worker * returns 1 if no validation problem was found or 0 otherwise
8298*7c568831SAndroid Build Coastguard Worker */
8299*7c568831SAndroid Build Coastguard Worker int
xmlRelaxNGValidatePopElement(xmlRelaxNGValidCtxtPtr ctxt,xmlDocPtr doc ATTRIBUTE_UNUSED,xmlNodePtr elem)8300*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidatePopElement(xmlRelaxNGValidCtxtPtr ctxt,
8301*7c568831SAndroid Build Coastguard Worker xmlDocPtr doc ATTRIBUTE_UNUSED,
8302*7c568831SAndroid Build Coastguard Worker xmlNodePtr elem)
8303*7c568831SAndroid Build Coastguard Worker {
8304*7c568831SAndroid Build Coastguard Worker int ret;
8305*7c568831SAndroid Build Coastguard Worker xmlRegExecCtxtPtr exec;
8306*7c568831SAndroid Build Coastguard Worker
8307*7c568831SAndroid Build Coastguard Worker if ((ctxt == NULL) || (ctxt->elem == NULL) || (elem == NULL))
8308*7c568831SAndroid Build Coastguard Worker return (-1);
8309*7c568831SAndroid Build Coastguard Worker /*
8310*7c568831SAndroid Build Coastguard Worker * verify that we reached a terminal state of the content model.
8311*7c568831SAndroid Build Coastguard Worker */
8312*7c568831SAndroid Build Coastguard Worker exec = xmlRelaxNGElemPop(ctxt);
8313*7c568831SAndroid Build Coastguard Worker ret = xmlRegExecPushString(exec, NULL, NULL);
8314*7c568831SAndroid Build Coastguard Worker if (ret == 0) {
8315*7c568831SAndroid Build Coastguard Worker /*
8316*7c568831SAndroid Build Coastguard Worker * TODO: get some of the names needed to exit the current state of exec
8317*7c568831SAndroid Build Coastguard Worker */
8318*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_NOELEM, BAD_CAST "");
8319*7c568831SAndroid Build Coastguard Worker ret = -1;
8320*7c568831SAndroid Build Coastguard Worker } else if (ret < 0) {
8321*7c568831SAndroid Build Coastguard Worker ret = -1;
8322*7c568831SAndroid Build Coastguard Worker } else {
8323*7c568831SAndroid Build Coastguard Worker ret = 1;
8324*7c568831SAndroid Build Coastguard Worker }
8325*7c568831SAndroid Build Coastguard Worker xmlRegFreeExecCtxt(exec);
8326*7c568831SAndroid Build Coastguard Worker return (ret);
8327*7c568831SAndroid Build Coastguard Worker }
8328*7c568831SAndroid Build Coastguard Worker
8329*7c568831SAndroid Build Coastguard Worker /**
8330*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidateFullElement:
8331*7c568831SAndroid Build Coastguard Worker * @ctxt: the validation context
8332*7c568831SAndroid Build Coastguard Worker * @doc: a document instance
8333*7c568831SAndroid Build Coastguard Worker * @elem: an element instance
8334*7c568831SAndroid Build Coastguard Worker *
8335*7c568831SAndroid Build Coastguard Worker * Validate a full subtree when xmlRelaxNGValidatePushElement() returned
8336*7c568831SAndroid Build Coastguard Worker * 0 and the content of the node has been expanded.
8337*7c568831SAndroid Build Coastguard Worker *
8338*7c568831SAndroid Build Coastguard Worker * returns 1 if no validation problem was found or -1 in case of error.
8339*7c568831SAndroid Build Coastguard Worker */
8340*7c568831SAndroid Build Coastguard Worker int
xmlRelaxNGValidateFullElement(xmlRelaxNGValidCtxtPtr ctxt,xmlDocPtr doc ATTRIBUTE_UNUSED,xmlNodePtr elem)8341*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateFullElement(xmlRelaxNGValidCtxtPtr ctxt,
8342*7c568831SAndroid Build Coastguard Worker xmlDocPtr doc ATTRIBUTE_UNUSED,
8343*7c568831SAndroid Build Coastguard Worker xmlNodePtr elem)
8344*7c568831SAndroid Build Coastguard Worker {
8345*7c568831SAndroid Build Coastguard Worker int ret;
8346*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr state;
8347*7c568831SAndroid Build Coastguard Worker
8348*7c568831SAndroid Build Coastguard Worker if ((ctxt == NULL) || (ctxt->pdef == NULL) || (elem == NULL))
8349*7c568831SAndroid Build Coastguard Worker return (-1);
8350*7c568831SAndroid Build Coastguard Worker state = xmlRelaxNGNewValidState(ctxt, elem->parent);
8351*7c568831SAndroid Build Coastguard Worker if (state == NULL) {
8352*7c568831SAndroid Build Coastguard Worker return (-1);
8353*7c568831SAndroid Build Coastguard Worker }
8354*7c568831SAndroid Build Coastguard Worker state->seq = elem;
8355*7c568831SAndroid Build Coastguard Worker ctxt->state = state;
8356*7c568831SAndroid Build Coastguard Worker ctxt->errNo = XML_RELAXNG_OK;
8357*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateDefinition(ctxt, ctxt->pdef);
8358*7c568831SAndroid Build Coastguard Worker if ((ret != 0) || (ctxt->errNo != XML_RELAXNG_OK))
8359*7c568831SAndroid Build Coastguard Worker ret = -1;
8360*7c568831SAndroid Build Coastguard Worker else
8361*7c568831SAndroid Build Coastguard Worker ret = 1;
8362*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, ctxt->state);
8363*7c568831SAndroid Build Coastguard Worker ctxt->state = NULL;
8364*7c568831SAndroid Build Coastguard Worker return (ret);
8365*7c568831SAndroid Build Coastguard Worker }
8366*7c568831SAndroid Build Coastguard Worker
8367*7c568831SAndroid Build Coastguard Worker /************************************************************************
8368*7c568831SAndroid Build Coastguard Worker * *
8369*7c568831SAndroid Build Coastguard Worker * Generic interpreted validation implementation *
8370*7c568831SAndroid Build Coastguard Worker * *
8371*7c568831SAndroid Build Coastguard Worker ************************************************************************/
8372*7c568831SAndroid Build Coastguard Worker static int xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
8373*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr define);
8374*7c568831SAndroid Build Coastguard Worker
8375*7c568831SAndroid Build Coastguard Worker /**
8376*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGSkipIgnored:
8377*7c568831SAndroid Build Coastguard Worker * @ctxt: a schema validation context
8378*7c568831SAndroid Build Coastguard Worker * @node: the top node.
8379*7c568831SAndroid Build Coastguard Worker *
8380*7c568831SAndroid Build Coastguard Worker * Skip ignorable nodes in that context
8381*7c568831SAndroid Build Coastguard Worker *
8382*7c568831SAndroid Build Coastguard Worker * Returns the new sibling or NULL in case of error.
8383*7c568831SAndroid Build Coastguard Worker */
8384*7c568831SAndroid Build Coastguard Worker static xmlNodePtr
xmlRelaxNGSkipIgnored(xmlRelaxNGValidCtxtPtr ctxt ATTRIBUTE_UNUSED,xmlNodePtr node)8385*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSkipIgnored(xmlRelaxNGValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
8386*7c568831SAndroid Build Coastguard Worker xmlNodePtr node)
8387*7c568831SAndroid Build Coastguard Worker {
8388*7c568831SAndroid Build Coastguard Worker /*
8389*7c568831SAndroid Build Coastguard Worker * TODO complete and handle entities
8390*7c568831SAndroid Build Coastguard Worker */
8391*7c568831SAndroid Build Coastguard Worker while ((node != NULL) &&
8392*7c568831SAndroid Build Coastguard Worker ((node->type == XML_COMMENT_NODE) ||
8393*7c568831SAndroid Build Coastguard Worker (node->type == XML_PI_NODE) ||
8394*7c568831SAndroid Build Coastguard Worker (node->type == XML_XINCLUDE_START) ||
8395*7c568831SAndroid Build Coastguard Worker (node->type == XML_XINCLUDE_END) ||
8396*7c568831SAndroid Build Coastguard Worker (((node->type == XML_TEXT_NODE) ||
8397*7c568831SAndroid Build Coastguard Worker (node->type == XML_CDATA_SECTION_NODE)) &&
8398*7c568831SAndroid Build Coastguard Worker ((ctxt->flags & FLAGS_MIXED_CONTENT) ||
8399*7c568831SAndroid Build Coastguard Worker (IS_BLANK_NODE(node)))))) {
8400*7c568831SAndroid Build Coastguard Worker node = node->next;
8401*7c568831SAndroid Build Coastguard Worker }
8402*7c568831SAndroid Build Coastguard Worker return (node);
8403*7c568831SAndroid Build Coastguard Worker }
8404*7c568831SAndroid Build Coastguard Worker
8405*7c568831SAndroid Build Coastguard Worker /**
8406*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGNormalize:
8407*7c568831SAndroid Build Coastguard Worker * @ctxt: a schema validation context
8408*7c568831SAndroid Build Coastguard Worker * @str: the string to normalize
8409*7c568831SAndroid Build Coastguard Worker *
8410*7c568831SAndroid Build Coastguard Worker * Implements the normalizeWhiteSpace( s ) function from
8411*7c568831SAndroid Build Coastguard Worker * section 6.2.9 of the spec
8412*7c568831SAndroid Build Coastguard Worker *
8413*7c568831SAndroid Build Coastguard Worker * Returns the new string or NULL in case of error.
8414*7c568831SAndroid Build Coastguard Worker */
8415*7c568831SAndroid Build Coastguard Worker static xmlChar *
xmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt,const xmlChar * str)8416*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt, const xmlChar * str)
8417*7c568831SAndroid Build Coastguard Worker {
8418*7c568831SAndroid Build Coastguard Worker xmlChar *ret, *p;
8419*7c568831SAndroid Build Coastguard Worker const xmlChar *tmp;
8420*7c568831SAndroid Build Coastguard Worker int len;
8421*7c568831SAndroid Build Coastguard Worker
8422*7c568831SAndroid Build Coastguard Worker if (str == NULL)
8423*7c568831SAndroid Build Coastguard Worker return (NULL);
8424*7c568831SAndroid Build Coastguard Worker tmp = str;
8425*7c568831SAndroid Build Coastguard Worker while (*tmp != 0)
8426*7c568831SAndroid Build Coastguard Worker tmp++;
8427*7c568831SAndroid Build Coastguard Worker len = tmp - str;
8428*7c568831SAndroid Build Coastguard Worker
8429*7c568831SAndroid Build Coastguard Worker ret = xmlMalloc(len + 1);
8430*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
8431*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
8432*7c568831SAndroid Build Coastguard Worker return (NULL);
8433*7c568831SAndroid Build Coastguard Worker }
8434*7c568831SAndroid Build Coastguard Worker p = ret;
8435*7c568831SAndroid Build Coastguard Worker while (IS_BLANK_CH(*str))
8436*7c568831SAndroid Build Coastguard Worker str++;
8437*7c568831SAndroid Build Coastguard Worker while (*str != 0) {
8438*7c568831SAndroid Build Coastguard Worker if (IS_BLANK_CH(*str)) {
8439*7c568831SAndroid Build Coastguard Worker while (IS_BLANK_CH(*str))
8440*7c568831SAndroid Build Coastguard Worker str++;
8441*7c568831SAndroid Build Coastguard Worker if (*str == 0)
8442*7c568831SAndroid Build Coastguard Worker break;
8443*7c568831SAndroid Build Coastguard Worker *p++ = ' ';
8444*7c568831SAndroid Build Coastguard Worker } else
8445*7c568831SAndroid Build Coastguard Worker *p++ = *str++;
8446*7c568831SAndroid Build Coastguard Worker }
8447*7c568831SAndroid Build Coastguard Worker *p = 0;
8448*7c568831SAndroid Build Coastguard Worker return (ret);
8449*7c568831SAndroid Build Coastguard Worker }
8450*7c568831SAndroid Build Coastguard Worker
8451*7c568831SAndroid Build Coastguard Worker /**
8452*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidateDatatype:
8453*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
8454*7c568831SAndroid Build Coastguard Worker * @value: the string value
8455*7c568831SAndroid Build Coastguard Worker * @type: the datatype definition
8456*7c568831SAndroid Build Coastguard Worker * @node: the node
8457*7c568831SAndroid Build Coastguard Worker *
8458*7c568831SAndroid Build Coastguard Worker * Validate the given value against the datatype
8459*7c568831SAndroid Build Coastguard Worker *
8460*7c568831SAndroid Build Coastguard Worker * Returns 0 if the validation succeeded or an error code.
8461*7c568831SAndroid Build Coastguard Worker */
8462*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGValidateDatatype(xmlRelaxNGValidCtxtPtr ctxt,const xmlChar * value,xmlRelaxNGDefinePtr define,xmlNodePtr node)8463*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateDatatype(xmlRelaxNGValidCtxtPtr ctxt,
8464*7c568831SAndroid Build Coastguard Worker const xmlChar * value,
8465*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr define, xmlNodePtr node)
8466*7c568831SAndroid Build Coastguard Worker {
8467*7c568831SAndroid Build Coastguard Worker int ret, tmp;
8468*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTypeLibraryPtr lib;
8469*7c568831SAndroid Build Coastguard Worker void *result = NULL;
8470*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr cur;
8471*7c568831SAndroid Build Coastguard Worker
8472*7c568831SAndroid Build Coastguard Worker if ((define == NULL) || (define->data == NULL)) {
8473*7c568831SAndroid Build Coastguard Worker return (-1);
8474*7c568831SAndroid Build Coastguard Worker }
8475*7c568831SAndroid Build Coastguard Worker lib = (xmlRelaxNGTypeLibraryPtr) define->data;
8476*7c568831SAndroid Build Coastguard Worker if (lib->check != NULL) {
8477*7c568831SAndroid Build Coastguard Worker if ((define->attrs != NULL) &&
8478*7c568831SAndroid Build Coastguard Worker (define->attrs->type == XML_RELAXNG_PARAM)) {
8479*7c568831SAndroid Build Coastguard Worker ret =
8480*7c568831SAndroid Build Coastguard Worker lib->check(lib->data, define->name, value, &result, node);
8481*7c568831SAndroid Build Coastguard Worker } else {
8482*7c568831SAndroid Build Coastguard Worker ret = lib->check(lib->data, define->name, value, NULL, node);
8483*7c568831SAndroid Build Coastguard Worker }
8484*7c568831SAndroid Build Coastguard Worker } else
8485*7c568831SAndroid Build Coastguard Worker ret = -1;
8486*7c568831SAndroid Build Coastguard Worker if (ret < 0) {
8487*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_TYPE, define->name);
8488*7c568831SAndroid Build Coastguard Worker if ((result != NULL) && (lib != NULL) && (lib->freef != NULL))
8489*7c568831SAndroid Build Coastguard Worker lib->freef(lib->data, result);
8490*7c568831SAndroid Build Coastguard Worker return (-1);
8491*7c568831SAndroid Build Coastguard Worker } else if (ret == 1) {
8492*7c568831SAndroid Build Coastguard Worker ret = 0;
8493*7c568831SAndroid Build Coastguard Worker } else if (ret == 2) {
8494*7c568831SAndroid Build Coastguard Worker VALID_ERR2P(XML_RELAXNG_ERR_DUPID, value);
8495*7c568831SAndroid Build Coastguard Worker } else {
8496*7c568831SAndroid Build Coastguard Worker VALID_ERR3P(XML_RELAXNG_ERR_TYPEVAL, define->name, value);
8497*7c568831SAndroid Build Coastguard Worker ret = -1;
8498*7c568831SAndroid Build Coastguard Worker }
8499*7c568831SAndroid Build Coastguard Worker cur = define->attrs;
8500*7c568831SAndroid Build Coastguard Worker while ((ret == 0) && (cur != NULL) && (cur->type == XML_RELAXNG_PARAM)) {
8501*7c568831SAndroid Build Coastguard Worker if (lib->facet != NULL) {
8502*7c568831SAndroid Build Coastguard Worker tmp = lib->facet(lib->data, define->name, cur->name,
8503*7c568831SAndroid Build Coastguard Worker cur->value, value, result);
8504*7c568831SAndroid Build Coastguard Worker if (tmp != 0)
8505*7c568831SAndroid Build Coastguard Worker ret = -1;
8506*7c568831SAndroid Build Coastguard Worker }
8507*7c568831SAndroid Build Coastguard Worker cur = cur->next;
8508*7c568831SAndroid Build Coastguard Worker }
8509*7c568831SAndroid Build Coastguard Worker if ((ret == 0) && (define->content != NULL)) {
8510*7c568831SAndroid Build Coastguard Worker const xmlChar *oldvalue, *oldendvalue;
8511*7c568831SAndroid Build Coastguard Worker
8512*7c568831SAndroid Build Coastguard Worker oldvalue = ctxt->state->value;
8513*7c568831SAndroid Build Coastguard Worker oldendvalue = ctxt->state->endvalue;
8514*7c568831SAndroid Build Coastguard Worker ctxt->state->value = (xmlChar *) value;
8515*7c568831SAndroid Build Coastguard Worker ctxt->state->endvalue = NULL;
8516*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateValue(ctxt, define->content);
8517*7c568831SAndroid Build Coastguard Worker ctxt->state->value = (xmlChar *) oldvalue;
8518*7c568831SAndroid Build Coastguard Worker ctxt->state->endvalue = (xmlChar *) oldendvalue;
8519*7c568831SAndroid Build Coastguard Worker }
8520*7c568831SAndroid Build Coastguard Worker if ((result != NULL) && (lib != NULL) && (lib->freef != NULL))
8521*7c568831SAndroid Build Coastguard Worker lib->freef(lib->data, result);
8522*7c568831SAndroid Build Coastguard Worker return (ret);
8523*7c568831SAndroid Build Coastguard Worker }
8524*7c568831SAndroid Build Coastguard Worker
8525*7c568831SAndroid Build Coastguard Worker /**
8526*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGNextValue:
8527*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
8528*7c568831SAndroid Build Coastguard Worker *
8529*7c568831SAndroid Build Coastguard Worker * Skip to the next value when validating within a list
8530*7c568831SAndroid Build Coastguard Worker *
8531*7c568831SAndroid Build Coastguard Worker * Returns 0 if the operation succeeded or an error code.
8532*7c568831SAndroid Build Coastguard Worker */
8533*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGNextValue(xmlRelaxNGValidCtxtPtr ctxt)8534*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNextValue(xmlRelaxNGValidCtxtPtr ctxt)
8535*7c568831SAndroid Build Coastguard Worker {
8536*7c568831SAndroid Build Coastguard Worker xmlChar *cur;
8537*7c568831SAndroid Build Coastguard Worker
8538*7c568831SAndroid Build Coastguard Worker cur = ctxt->state->value;
8539*7c568831SAndroid Build Coastguard Worker if ((cur == NULL) || (ctxt->state->endvalue == NULL)) {
8540*7c568831SAndroid Build Coastguard Worker ctxt->state->value = NULL;
8541*7c568831SAndroid Build Coastguard Worker ctxt->state->endvalue = NULL;
8542*7c568831SAndroid Build Coastguard Worker return (0);
8543*7c568831SAndroid Build Coastguard Worker }
8544*7c568831SAndroid Build Coastguard Worker while (*cur != 0)
8545*7c568831SAndroid Build Coastguard Worker cur++;
8546*7c568831SAndroid Build Coastguard Worker while ((cur != ctxt->state->endvalue) && (*cur == 0))
8547*7c568831SAndroid Build Coastguard Worker cur++;
8548*7c568831SAndroid Build Coastguard Worker if (cur == ctxt->state->endvalue)
8549*7c568831SAndroid Build Coastguard Worker ctxt->state->value = NULL;
8550*7c568831SAndroid Build Coastguard Worker else
8551*7c568831SAndroid Build Coastguard Worker ctxt->state->value = cur;
8552*7c568831SAndroid Build Coastguard Worker return (0);
8553*7c568831SAndroid Build Coastguard Worker }
8554*7c568831SAndroid Build Coastguard Worker
8555*7c568831SAndroid Build Coastguard Worker /**
8556*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidateValueList:
8557*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
8558*7c568831SAndroid Build Coastguard Worker * @defines: the list of definitions to verify
8559*7c568831SAndroid Build Coastguard Worker *
8560*7c568831SAndroid Build Coastguard Worker * Validate the given set of definitions for the current value
8561*7c568831SAndroid Build Coastguard Worker *
8562*7c568831SAndroid Build Coastguard Worker * Returns 0 if the validation succeeded or an error code.
8563*7c568831SAndroid Build Coastguard Worker */
8564*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGValidateValueList(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGDefinePtr defines)8565*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateValueList(xmlRelaxNGValidCtxtPtr ctxt,
8566*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr defines)
8567*7c568831SAndroid Build Coastguard Worker {
8568*7c568831SAndroid Build Coastguard Worker int ret = 0;
8569*7c568831SAndroid Build Coastguard Worker
8570*7c568831SAndroid Build Coastguard Worker while (defines != NULL) {
8571*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateValue(ctxt, defines);
8572*7c568831SAndroid Build Coastguard Worker if (ret != 0)
8573*7c568831SAndroid Build Coastguard Worker break;
8574*7c568831SAndroid Build Coastguard Worker defines = defines->next;
8575*7c568831SAndroid Build Coastguard Worker }
8576*7c568831SAndroid Build Coastguard Worker return (ret);
8577*7c568831SAndroid Build Coastguard Worker }
8578*7c568831SAndroid Build Coastguard Worker
8579*7c568831SAndroid Build Coastguard Worker /**
8580*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidateValue:
8581*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
8582*7c568831SAndroid Build Coastguard Worker * @define: the definition to verify
8583*7c568831SAndroid Build Coastguard Worker *
8584*7c568831SAndroid Build Coastguard Worker * Validate the given definition for the current value
8585*7c568831SAndroid Build Coastguard Worker *
8586*7c568831SAndroid Build Coastguard Worker * Returns 0 if the validation succeeded or an error code.
8587*7c568831SAndroid Build Coastguard Worker */
8588*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGDefinePtr define)8589*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
8590*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr define)
8591*7c568831SAndroid Build Coastguard Worker {
8592*7c568831SAndroid Build Coastguard Worker int ret = 0, oldflags;
8593*7c568831SAndroid Build Coastguard Worker xmlChar *value;
8594*7c568831SAndroid Build Coastguard Worker
8595*7c568831SAndroid Build Coastguard Worker value = ctxt->state->value;
8596*7c568831SAndroid Build Coastguard Worker switch (define->type) {
8597*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EMPTY:{
8598*7c568831SAndroid Build Coastguard Worker if ((value != NULL) && (value[0] != 0)) {
8599*7c568831SAndroid Build Coastguard Worker int idx = 0;
8600*7c568831SAndroid Build Coastguard Worker
8601*7c568831SAndroid Build Coastguard Worker while (IS_BLANK_CH(value[idx]))
8602*7c568831SAndroid Build Coastguard Worker idx++;
8603*7c568831SAndroid Build Coastguard Worker if (value[idx] != 0)
8604*7c568831SAndroid Build Coastguard Worker ret = -1;
8605*7c568831SAndroid Build Coastguard Worker }
8606*7c568831SAndroid Build Coastguard Worker break;
8607*7c568831SAndroid Build Coastguard Worker }
8608*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_TEXT:
8609*7c568831SAndroid Build Coastguard Worker break;
8610*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_VALUE:{
8611*7c568831SAndroid Build Coastguard Worker if (!xmlStrEqual(value, define->value)) {
8612*7c568831SAndroid Build Coastguard Worker if (define->name != NULL) {
8613*7c568831SAndroid Build Coastguard Worker xmlRelaxNGTypeLibraryPtr lib;
8614*7c568831SAndroid Build Coastguard Worker
8615*7c568831SAndroid Build Coastguard Worker lib = (xmlRelaxNGTypeLibraryPtr) define->data;
8616*7c568831SAndroid Build Coastguard Worker if ((lib != NULL) && (lib->comp != NULL)) {
8617*7c568831SAndroid Build Coastguard Worker ret = lib->comp(lib->data, define->name,
8618*7c568831SAndroid Build Coastguard Worker define->value, define->node,
8619*7c568831SAndroid Build Coastguard Worker (void *) define->attrs,
8620*7c568831SAndroid Build Coastguard Worker value, ctxt->state->node);
8621*7c568831SAndroid Build Coastguard Worker } else
8622*7c568831SAndroid Build Coastguard Worker ret = -1;
8623*7c568831SAndroid Build Coastguard Worker if (ret < 0) {
8624*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_TYPECMP,
8625*7c568831SAndroid Build Coastguard Worker define->name);
8626*7c568831SAndroid Build Coastguard Worker return (-1);
8627*7c568831SAndroid Build Coastguard Worker } else if (ret == 1) {
8628*7c568831SAndroid Build Coastguard Worker ret = 0;
8629*7c568831SAndroid Build Coastguard Worker } else {
8630*7c568831SAndroid Build Coastguard Worker ret = -1;
8631*7c568831SAndroid Build Coastguard Worker }
8632*7c568831SAndroid Build Coastguard Worker } else {
8633*7c568831SAndroid Build Coastguard Worker xmlChar *nval, *nvalue;
8634*7c568831SAndroid Build Coastguard Worker
8635*7c568831SAndroid Build Coastguard Worker /*
8636*7c568831SAndroid Build Coastguard Worker * TODO: trivial optimizations are possible by
8637*7c568831SAndroid Build Coastguard Worker * computing at compile-time
8638*7c568831SAndroid Build Coastguard Worker */
8639*7c568831SAndroid Build Coastguard Worker nval = xmlRelaxNGNormalize(ctxt, define->value);
8640*7c568831SAndroid Build Coastguard Worker nvalue = xmlRelaxNGNormalize(ctxt, value);
8641*7c568831SAndroid Build Coastguard Worker
8642*7c568831SAndroid Build Coastguard Worker if ((nval == NULL) || (nvalue == NULL) ||
8643*7c568831SAndroid Build Coastguard Worker (!xmlStrEqual(nval, nvalue)))
8644*7c568831SAndroid Build Coastguard Worker ret = -1;
8645*7c568831SAndroid Build Coastguard Worker if (nval != NULL)
8646*7c568831SAndroid Build Coastguard Worker xmlFree(nval);
8647*7c568831SAndroid Build Coastguard Worker if (nvalue != NULL)
8648*7c568831SAndroid Build Coastguard Worker xmlFree(nvalue);
8649*7c568831SAndroid Build Coastguard Worker }
8650*7c568831SAndroid Build Coastguard Worker }
8651*7c568831SAndroid Build Coastguard Worker if (ret == 0)
8652*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNextValue(ctxt);
8653*7c568831SAndroid Build Coastguard Worker break;
8654*7c568831SAndroid Build Coastguard Worker }
8655*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DATATYPE:{
8656*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateDatatype(ctxt, value, define,
8657*7c568831SAndroid Build Coastguard Worker ctxt->state->seq);
8658*7c568831SAndroid Build Coastguard Worker if (ret == 0)
8659*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNextValue(ctxt);
8660*7c568831SAndroid Build Coastguard Worker
8661*7c568831SAndroid Build Coastguard Worker break;
8662*7c568831SAndroid Build Coastguard Worker }
8663*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_CHOICE:{
8664*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr list = define->content;
8665*7c568831SAndroid Build Coastguard Worker xmlChar *oldvalue;
8666*7c568831SAndroid Build Coastguard Worker
8667*7c568831SAndroid Build Coastguard Worker oldflags = ctxt->flags;
8668*7c568831SAndroid Build Coastguard Worker ctxt->flags |= FLAGS_IGNORABLE;
8669*7c568831SAndroid Build Coastguard Worker
8670*7c568831SAndroid Build Coastguard Worker oldvalue = ctxt->state->value;
8671*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
8672*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateValue(ctxt, list);
8673*7c568831SAndroid Build Coastguard Worker if (ret == 0) {
8674*7c568831SAndroid Build Coastguard Worker break;
8675*7c568831SAndroid Build Coastguard Worker }
8676*7c568831SAndroid Build Coastguard Worker ctxt->state->value = oldvalue;
8677*7c568831SAndroid Build Coastguard Worker list = list->next;
8678*7c568831SAndroid Build Coastguard Worker }
8679*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
8680*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
8681*7c568831SAndroid Build Coastguard Worker if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
8682*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpValidError(ctxt);
8683*7c568831SAndroid Build Coastguard Worker } else {
8684*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr > 0)
8685*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPopErrors(ctxt, 0);
8686*7c568831SAndroid Build Coastguard Worker }
8687*7c568831SAndroid Build Coastguard Worker break;
8688*7c568831SAndroid Build Coastguard Worker }
8689*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_LIST:{
8690*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr list = define->content;
8691*7c568831SAndroid Build Coastguard Worker xmlChar *oldvalue, *oldend, *val, *cur;
8692*7c568831SAndroid Build Coastguard Worker
8693*7c568831SAndroid Build Coastguard Worker oldvalue = ctxt->state->value;
8694*7c568831SAndroid Build Coastguard Worker oldend = ctxt->state->endvalue;
8695*7c568831SAndroid Build Coastguard Worker
8696*7c568831SAndroid Build Coastguard Worker val = xmlStrdup(oldvalue);
8697*7c568831SAndroid Build Coastguard Worker if (val == NULL) {
8698*7c568831SAndroid Build Coastguard Worker val = xmlStrdup(BAD_CAST "");
8699*7c568831SAndroid Build Coastguard Worker }
8700*7c568831SAndroid Build Coastguard Worker if (val == NULL) {
8701*7c568831SAndroid Build Coastguard Worker VALID_ERR(XML_RELAXNG_ERR_NOSTATE);
8702*7c568831SAndroid Build Coastguard Worker return (-1);
8703*7c568831SAndroid Build Coastguard Worker }
8704*7c568831SAndroid Build Coastguard Worker cur = val;
8705*7c568831SAndroid Build Coastguard Worker while (*cur != 0) {
8706*7c568831SAndroid Build Coastguard Worker if (IS_BLANK_CH(*cur)) {
8707*7c568831SAndroid Build Coastguard Worker *cur = 0;
8708*7c568831SAndroid Build Coastguard Worker cur++;
8709*7c568831SAndroid Build Coastguard Worker while (IS_BLANK_CH(*cur))
8710*7c568831SAndroid Build Coastguard Worker *cur++ = 0;
8711*7c568831SAndroid Build Coastguard Worker } else
8712*7c568831SAndroid Build Coastguard Worker cur++;
8713*7c568831SAndroid Build Coastguard Worker }
8714*7c568831SAndroid Build Coastguard Worker ctxt->state->endvalue = cur;
8715*7c568831SAndroid Build Coastguard Worker cur = val;
8716*7c568831SAndroid Build Coastguard Worker while ((*cur == 0) && (cur != ctxt->state->endvalue))
8717*7c568831SAndroid Build Coastguard Worker cur++;
8718*7c568831SAndroid Build Coastguard Worker
8719*7c568831SAndroid Build Coastguard Worker ctxt->state->value = cur;
8720*7c568831SAndroid Build Coastguard Worker
8721*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
8722*7c568831SAndroid Build Coastguard Worker if (ctxt->state->value == ctxt->state->endvalue)
8723*7c568831SAndroid Build Coastguard Worker ctxt->state->value = NULL;
8724*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateValue(ctxt, list);
8725*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
8726*7c568831SAndroid Build Coastguard Worker break;
8727*7c568831SAndroid Build Coastguard Worker }
8728*7c568831SAndroid Build Coastguard Worker list = list->next;
8729*7c568831SAndroid Build Coastguard Worker }
8730*7c568831SAndroid Build Coastguard Worker
8731*7c568831SAndroid Build Coastguard Worker if ((ret == 0) && (ctxt->state->value != NULL) &&
8732*7c568831SAndroid Build Coastguard Worker (ctxt->state->value != ctxt->state->endvalue)) {
8733*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_LISTEXTRA,
8734*7c568831SAndroid Build Coastguard Worker ctxt->state->value);
8735*7c568831SAndroid Build Coastguard Worker ret = -1;
8736*7c568831SAndroid Build Coastguard Worker }
8737*7c568831SAndroid Build Coastguard Worker xmlFree(val);
8738*7c568831SAndroid Build Coastguard Worker ctxt->state->value = oldvalue;
8739*7c568831SAndroid Build Coastguard Worker ctxt->state->endvalue = oldend;
8740*7c568831SAndroid Build Coastguard Worker break;
8741*7c568831SAndroid Build Coastguard Worker }
8742*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ONEORMORE:
8743*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateValueList(ctxt, define->content);
8744*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
8745*7c568831SAndroid Build Coastguard Worker break;
8746*7c568831SAndroid Build Coastguard Worker }
8747*7c568831SAndroid Build Coastguard Worker /* Falls through. */
8748*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ZEROORMORE:{
8749*7c568831SAndroid Build Coastguard Worker xmlChar *cur, *temp;
8750*7c568831SAndroid Build Coastguard Worker
8751*7c568831SAndroid Build Coastguard Worker if ((ctxt->state->value == NULL) ||
8752*7c568831SAndroid Build Coastguard Worker (*ctxt->state->value == 0)) {
8753*7c568831SAndroid Build Coastguard Worker ret = 0;
8754*7c568831SAndroid Build Coastguard Worker break;
8755*7c568831SAndroid Build Coastguard Worker }
8756*7c568831SAndroid Build Coastguard Worker oldflags = ctxt->flags;
8757*7c568831SAndroid Build Coastguard Worker ctxt->flags |= FLAGS_IGNORABLE;
8758*7c568831SAndroid Build Coastguard Worker cur = ctxt->state->value;
8759*7c568831SAndroid Build Coastguard Worker temp = NULL;
8760*7c568831SAndroid Build Coastguard Worker while ((cur != NULL) && (cur != ctxt->state->endvalue) &&
8761*7c568831SAndroid Build Coastguard Worker (temp != cur)) {
8762*7c568831SAndroid Build Coastguard Worker temp = cur;
8763*7c568831SAndroid Build Coastguard Worker ret =
8764*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateValueList(ctxt, define->content);
8765*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
8766*7c568831SAndroid Build Coastguard Worker ctxt->state->value = temp;
8767*7c568831SAndroid Build Coastguard Worker ret = 0;
8768*7c568831SAndroid Build Coastguard Worker break;
8769*7c568831SAndroid Build Coastguard Worker }
8770*7c568831SAndroid Build Coastguard Worker cur = ctxt->state->value;
8771*7c568831SAndroid Build Coastguard Worker }
8772*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
8773*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr > 0)
8774*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPopErrors(ctxt, 0);
8775*7c568831SAndroid Build Coastguard Worker break;
8776*7c568831SAndroid Build Coastguard Worker }
8777*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_OPTIONAL:{
8778*7c568831SAndroid Build Coastguard Worker xmlChar *temp;
8779*7c568831SAndroid Build Coastguard Worker
8780*7c568831SAndroid Build Coastguard Worker if ((ctxt->state->value == NULL) ||
8781*7c568831SAndroid Build Coastguard Worker (*ctxt->state->value == 0)) {
8782*7c568831SAndroid Build Coastguard Worker ret = 0;
8783*7c568831SAndroid Build Coastguard Worker break;
8784*7c568831SAndroid Build Coastguard Worker }
8785*7c568831SAndroid Build Coastguard Worker oldflags = ctxt->flags;
8786*7c568831SAndroid Build Coastguard Worker ctxt->flags |= FLAGS_IGNORABLE;
8787*7c568831SAndroid Build Coastguard Worker temp = ctxt->state->value;
8788*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateValue(ctxt, define->content);
8789*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
8790*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
8791*7c568831SAndroid Build Coastguard Worker ctxt->state->value = temp;
8792*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr > 0)
8793*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPopErrors(ctxt, 0);
8794*7c568831SAndroid Build Coastguard Worker ret = 0;
8795*7c568831SAndroid Build Coastguard Worker break;
8796*7c568831SAndroid Build Coastguard Worker }
8797*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr > 0)
8798*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPopErrors(ctxt, 0);
8799*7c568831SAndroid Build Coastguard Worker break;
8800*7c568831SAndroid Build Coastguard Worker }
8801*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXCEPT:{
8802*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr list;
8803*7c568831SAndroid Build Coastguard Worker
8804*7c568831SAndroid Build Coastguard Worker list = define->content;
8805*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
8806*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateValue(ctxt, list);
8807*7c568831SAndroid Build Coastguard Worker if (ret == 0) {
8808*7c568831SAndroid Build Coastguard Worker ret = -1;
8809*7c568831SAndroid Build Coastguard Worker break;
8810*7c568831SAndroid Build Coastguard Worker } else
8811*7c568831SAndroid Build Coastguard Worker ret = 0;
8812*7c568831SAndroid Build Coastguard Worker list = list->next;
8813*7c568831SAndroid Build Coastguard Worker }
8814*7c568831SAndroid Build Coastguard Worker break;
8815*7c568831SAndroid Build Coastguard Worker }
8816*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DEF:
8817*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_GROUP:{
8818*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr list;
8819*7c568831SAndroid Build Coastguard Worker
8820*7c568831SAndroid Build Coastguard Worker list = define->content;
8821*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
8822*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateValue(ctxt, list);
8823*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
8824*7c568831SAndroid Build Coastguard Worker ret = -1;
8825*7c568831SAndroid Build Coastguard Worker break;
8826*7c568831SAndroid Build Coastguard Worker } else
8827*7c568831SAndroid Build Coastguard Worker ret = 0;
8828*7c568831SAndroid Build Coastguard Worker list = list->next;
8829*7c568831SAndroid Build Coastguard Worker }
8830*7c568831SAndroid Build Coastguard Worker break;
8831*7c568831SAndroid Build Coastguard Worker }
8832*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_REF:
8833*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARENTREF:
8834*7c568831SAndroid Build Coastguard Worker if (define->content == NULL) {
8835*7c568831SAndroid Build Coastguard Worker VALID_ERR(XML_RELAXNG_ERR_NODEFINE);
8836*7c568831SAndroid Build Coastguard Worker ret = -1;
8837*7c568831SAndroid Build Coastguard Worker } else {
8838*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateValue(ctxt, define->content);
8839*7c568831SAndroid Build Coastguard Worker }
8840*7c568831SAndroid Build Coastguard Worker break;
8841*7c568831SAndroid Build Coastguard Worker default:
8842*7c568831SAndroid Build Coastguard Worker /* TODO */
8843*7c568831SAndroid Build Coastguard Worker ret = -1;
8844*7c568831SAndroid Build Coastguard Worker }
8845*7c568831SAndroid Build Coastguard Worker return (ret);
8846*7c568831SAndroid Build Coastguard Worker }
8847*7c568831SAndroid Build Coastguard Worker
8848*7c568831SAndroid Build Coastguard Worker /**
8849*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidateValueContent:
8850*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
8851*7c568831SAndroid Build Coastguard Worker * @defines: the list of definitions to verify
8852*7c568831SAndroid Build Coastguard Worker *
8853*7c568831SAndroid Build Coastguard Worker * Validate the given definitions for the current value
8854*7c568831SAndroid Build Coastguard Worker *
8855*7c568831SAndroid Build Coastguard Worker * Returns 0 if the validation succeeded or an error code.
8856*7c568831SAndroid Build Coastguard Worker */
8857*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGValidateValueContent(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGDefinePtr defines)8858*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateValueContent(xmlRelaxNGValidCtxtPtr ctxt,
8859*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr defines)
8860*7c568831SAndroid Build Coastguard Worker {
8861*7c568831SAndroid Build Coastguard Worker int ret = 0;
8862*7c568831SAndroid Build Coastguard Worker
8863*7c568831SAndroid Build Coastguard Worker while (defines != NULL) {
8864*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateValue(ctxt, defines);
8865*7c568831SAndroid Build Coastguard Worker if (ret != 0)
8866*7c568831SAndroid Build Coastguard Worker break;
8867*7c568831SAndroid Build Coastguard Worker defines = defines->next;
8868*7c568831SAndroid Build Coastguard Worker }
8869*7c568831SAndroid Build Coastguard Worker return (ret);
8870*7c568831SAndroid Build Coastguard Worker }
8871*7c568831SAndroid Build Coastguard Worker
8872*7c568831SAndroid Build Coastguard Worker /**
8873*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGAttributeMatch:
8874*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
8875*7c568831SAndroid Build Coastguard Worker * @define: the definition to check
8876*7c568831SAndroid Build Coastguard Worker * @prop: the attribute
8877*7c568831SAndroid Build Coastguard Worker *
8878*7c568831SAndroid Build Coastguard Worker * Check if the attribute matches the definition nameClass
8879*7c568831SAndroid Build Coastguard Worker *
8880*7c568831SAndroid Build Coastguard Worker * Returns 1 if the attribute matches, 0 if no, or -1 in case of error
8881*7c568831SAndroid Build Coastguard Worker */
8882*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGAttributeMatch(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGDefinePtr define,xmlAttrPtr prop)8883*7c568831SAndroid Build Coastguard Worker xmlRelaxNGAttributeMatch(xmlRelaxNGValidCtxtPtr ctxt,
8884*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr define, xmlAttrPtr prop)
8885*7c568831SAndroid Build Coastguard Worker {
8886*7c568831SAndroid Build Coastguard Worker int ret;
8887*7c568831SAndroid Build Coastguard Worker
8888*7c568831SAndroid Build Coastguard Worker if (define->name != NULL) {
8889*7c568831SAndroid Build Coastguard Worker if (!xmlStrEqual(define->name, prop->name))
8890*7c568831SAndroid Build Coastguard Worker return (0);
8891*7c568831SAndroid Build Coastguard Worker }
8892*7c568831SAndroid Build Coastguard Worker if (define->ns != NULL) {
8893*7c568831SAndroid Build Coastguard Worker if (define->ns[0] == 0) {
8894*7c568831SAndroid Build Coastguard Worker if (prop->ns != NULL)
8895*7c568831SAndroid Build Coastguard Worker return (0);
8896*7c568831SAndroid Build Coastguard Worker } else {
8897*7c568831SAndroid Build Coastguard Worker if ((prop->ns == NULL) ||
8898*7c568831SAndroid Build Coastguard Worker (!xmlStrEqual(define->ns, prop->ns->href)))
8899*7c568831SAndroid Build Coastguard Worker return (0);
8900*7c568831SAndroid Build Coastguard Worker }
8901*7c568831SAndroid Build Coastguard Worker }
8902*7c568831SAndroid Build Coastguard Worker if (define->nameClass == NULL)
8903*7c568831SAndroid Build Coastguard Worker return (1);
8904*7c568831SAndroid Build Coastguard Worker define = define->nameClass;
8905*7c568831SAndroid Build Coastguard Worker if (define->type == XML_RELAXNG_EXCEPT) {
8906*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr list;
8907*7c568831SAndroid Build Coastguard Worker
8908*7c568831SAndroid Build Coastguard Worker list = define->content;
8909*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
8910*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGAttributeMatch(ctxt, list, prop);
8911*7c568831SAndroid Build Coastguard Worker if (ret == 1)
8912*7c568831SAndroid Build Coastguard Worker return (0);
8913*7c568831SAndroid Build Coastguard Worker if (ret < 0)
8914*7c568831SAndroid Build Coastguard Worker return (ret);
8915*7c568831SAndroid Build Coastguard Worker list = list->next;
8916*7c568831SAndroid Build Coastguard Worker }
8917*7c568831SAndroid Build Coastguard Worker } else if (define->type == XML_RELAXNG_CHOICE) {
8918*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr list;
8919*7c568831SAndroid Build Coastguard Worker
8920*7c568831SAndroid Build Coastguard Worker list = define->nameClass;
8921*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
8922*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGAttributeMatch(ctxt, list, prop);
8923*7c568831SAndroid Build Coastguard Worker if (ret == 1)
8924*7c568831SAndroid Build Coastguard Worker return (1);
8925*7c568831SAndroid Build Coastguard Worker if (ret < 0)
8926*7c568831SAndroid Build Coastguard Worker return (ret);
8927*7c568831SAndroid Build Coastguard Worker list = list->next;
8928*7c568831SAndroid Build Coastguard Worker }
8929*7c568831SAndroid Build Coastguard Worker return (0);
8930*7c568831SAndroid Build Coastguard Worker } else {
8931*7c568831SAndroid Build Coastguard Worker /* TODO */
8932*7c568831SAndroid Build Coastguard Worker return (0);
8933*7c568831SAndroid Build Coastguard Worker }
8934*7c568831SAndroid Build Coastguard Worker return (1);
8935*7c568831SAndroid Build Coastguard Worker }
8936*7c568831SAndroid Build Coastguard Worker
8937*7c568831SAndroid Build Coastguard Worker /**
8938*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidateAttribute:
8939*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
8940*7c568831SAndroid Build Coastguard Worker * @define: the definition to verify
8941*7c568831SAndroid Build Coastguard Worker *
8942*7c568831SAndroid Build Coastguard Worker * Validate the given attribute definition for that node
8943*7c568831SAndroid Build Coastguard Worker *
8944*7c568831SAndroid Build Coastguard Worker * Returns 0 if the validation succeeded or an error code.
8945*7c568831SAndroid Build Coastguard Worker */
8946*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGValidateAttribute(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGDefinePtr define)8947*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateAttribute(xmlRelaxNGValidCtxtPtr ctxt,
8948*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr define)
8949*7c568831SAndroid Build Coastguard Worker {
8950*7c568831SAndroid Build Coastguard Worker int ret = 0, i;
8951*7c568831SAndroid Build Coastguard Worker xmlChar *value, *oldvalue;
8952*7c568831SAndroid Build Coastguard Worker xmlAttrPtr prop = NULL, tmp;
8953*7c568831SAndroid Build Coastguard Worker xmlNodePtr oldseq;
8954*7c568831SAndroid Build Coastguard Worker
8955*7c568831SAndroid Build Coastguard Worker if (ctxt->state->nbAttrLeft <= 0)
8956*7c568831SAndroid Build Coastguard Worker return (-1);
8957*7c568831SAndroid Build Coastguard Worker if (define->name != NULL) {
8958*7c568831SAndroid Build Coastguard Worker for (i = 0; i < ctxt->state->nbAttrs; i++) {
8959*7c568831SAndroid Build Coastguard Worker tmp = ctxt->state->attrs[i];
8960*7c568831SAndroid Build Coastguard Worker if ((tmp != NULL) && (xmlStrEqual(define->name, tmp->name))) {
8961*7c568831SAndroid Build Coastguard Worker if ((((define->ns == NULL) || (define->ns[0] == 0)) &&
8962*7c568831SAndroid Build Coastguard Worker (tmp->ns == NULL)) ||
8963*7c568831SAndroid Build Coastguard Worker ((tmp->ns != NULL) &&
8964*7c568831SAndroid Build Coastguard Worker (xmlStrEqual(define->ns, tmp->ns->href)))) {
8965*7c568831SAndroid Build Coastguard Worker prop = tmp;
8966*7c568831SAndroid Build Coastguard Worker break;
8967*7c568831SAndroid Build Coastguard Worker }
8968*7c568831SAndroid Build Coastguard Worker }
8969*7c568831SAndroid Build Coastguard Worker }
8970*7c568831SAndroid Build Coastguard Worker if (prop != NULL) {
8971*7c568831SAndroid Build Coastguard Worker value = xmlNodeListGetString(prop->doc, prop->children, 1);
8972*7c568831SAndroid Build Coastguard Worker oldvalue = ctxt->state->value;
8973*7c568831SAndroid Build Coastguard Worker oldseq = ctxt->state->seq;
8974*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = (xmlNodePtr) prop;
8975*7c568831SAndroid Build Coastguard Worker ctxt->state->value = value;
8976*7c568831SAndroid Build Coastguard Worker ctxt->state->endvalue = NULL;
8977*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateValueContent(ctxt, define->content);
8978*7c568831SAndroid Build Coastguard Worker if (ctxt->state->value != NULL)
8979*7c568831SAndroid Build Coastguard Worker value = ctxt->state->value;
8980*7c568831SAndroid Build Coastguard Worker if (value != NULL)
8981*7c568831SAndroid Build Coastguard Worker xmlFree(value);
8982*7c568831SAndroid Build Coastguard Worker ctxt->state->value = oldvalue;
8983*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = oldseq;
8984*7c568831SAndroid Build Coastguard Worker if (ret == 0) {
8985*7c568831SAndroid Build Coastguard Worker /*
8986*7c568831SAndroid Build Coastguard Worker * flag the attribute as processed
8987*7c568831SAndroid Build Coastguard Worker */
8988*7c568831SAndroid Build Coastguard Worker ctxt->state->attrs[i] = NULL;
8989*7c568831SAndroid Build Coastguard Worker ctxt->state->nbAttrLeft--;
8990*7c568831SAndroid Build Coastguard Worker }
8991*7c568831SAndroid Build Coastguard Worker } else {
8992*7c568831SAndroid Build Coastguard Worker ret = -1;
8993*7c568831SAndroid Build Coastguard Worker }
8994*7c568831SAndroid Build Coastguard Worker } else {
8995*7c568831SAndroid Build Coastguard Worker for (i = 0; i < ctxt->state->nbAttrs; i++) {
8996*7c568831SAndroid Build Coastguard Worker tmp = ctxt->state->attrs[i];
8997*7c568831SAndroid Build Coastguard Worker if ((tmp != NULL) &&
8998*7c568831SAndroid Build Coastguard Worker (xmlRelaxNGAttributeMatch(ctxt, define, tmp) == 1)) {
8999*7c568831SAndroid Build Coastguard Worker prop = tmp;
9000*7c568831SAndroid Build Coastguard Worker break;
9001*7c568831SAndroid Build Coastguard Worker }
9002*7c568831SAndroid Build Coastguard Worker }
9003*7c568831SAndroid Build Coastguard Worker if (prop != NULL) {
9004*7c568831SAndroid Build Coastguard Worker value = xmlNodeListGetString(prop->doc, prop->children, 1);
9005*7c568831SAndroid Build Coastguard Worker oldvalue = ctxt->state->value;
9006*7c568831SAndroid Build Coastguard Worker oldseq = ctxt->state->seq;
9007*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = (xmlNodePtr) prop;
9008*7c568831SAndroid Build Coastguard Worker ctxt->state->value = value;
9009*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateValueContent(ctxt, define->content);
9010*7c568831SAndroid Build Coastguard Worker if (ctxt->state->value != NULL)
9011*7c568831SAndroid Build Coastguard Worker value = ctxt->state->value;
9012*7c568831SAndroid Build Coastguard Worker if (value != NULL)
9013*7c568831SAndroid Build Coastguard Worker xmlFree(value);
9014*7c568831SAndroid Build Coastguard Worker ctxt->state->value = oldvalue;
9015*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = oldseq;
9016*7c568831SAndroid Build Coastguard Worker if (ret == 0) {
9017*7c568831SAndroid Build Coastguard Worker /*
9018*7c568831SAndroid Build Coastguard Worker * flag the attribute as processed
9019*7c568831SAndroid Build Coastguard Worker */
9020*7c568831SAndroid Build Coastguard Worker ctxt->state->attrs[i] = NULL;
9021*7c568831SAndroid Build Coastguard Worker ctxt->state->nbAttrLeft--;
9022*7c568831SAndroid Build Coastguard Worker }
9023*7c568831SAndroid Build Coastguard Worker } else {
9024*7c568831SAndroid Build Coastguard Worker ret = -1;
9025*7c568831SAndroid Build Coastguard Worker }
9026*7c568831SAndroid Build Coastguard Worker }
9027*7c568831SAndroid Build Coastguard Worker
9028*7c568831SAndroid Build Coastguard Worker return (ret);
9029*7c568831SAndroid Build Coastguard Worker }
9030*7c568831SAndroid Build Coastguard Worker
9031*7c568831SAndroid Build Coastguard Worker /**
9032*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidateAttributeList:
9033*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
9034*7c568831SAndroid Build Coastguard Worker * @define: the list of definition to verify
9035*7c568831SAndroid Build Coastguard Worker *
9036*7c568831SAndroid Build Coastguard Worker * Validate the given node against the list of attribute definitions
9037*7c568831SAndroid Build Coastguard Worker *
9038*7c568831SAndroid Build Coastguard Worker * Returns 0 if the validation succeeded or an error code.
9039*7c568831SAndroid Build Coastguard Worker */
9040*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGValidateAttributeList(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGDefinePtr defines)9041*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateAttributeList(xmlRelaxNGValidCtxtPtr ctxt,
9042*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr defines)
9043*7c568831SAndroid Build Coastguard Worker {
9044*7c568831SAndroid Build Coastguard Worker int ret = 0, res;
9045*7c568831SAndroid Build Coastguard Worker int needmore = 0;
9046*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr cur;
9047*7c568831SAndroid Build Coastguard Worker
9048*7c568831SAndroid Build Coastguard Worker cur = defines;
9049*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
9050*7c568831SAndroid Build Coastguard Worker if (cur->type == XML_RELAXNG_ATTRIBUTE) {
9051*7c568831SAndroid Build Coastguard Worker if (xmlRelaxNGValidateAttribute(ctxt, cur) != 0)
9052*7c568831SAndroid Build Coastguard Worker ret = -1;
9053*7c568831SAndroid Build Coastguard Worker } else
9054*7c568831SAndroid Build Coastguard Worker needmore = 1;
9055*7c568831SAndroid Build Coastguard Worker cur = cur->next;
9056*7c568831SAndroid Build Coastguard Worker }
9057*7c568831SAndroid Build Coastguard Worker if (!needmore)
9058*7c568831SAndroid Build Coastguard Worker return (ret);
9059*7c568831SAndroid Build Coastguard Worker cur = defines;
9060*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
9061*7c568831SAndroid Build Coastguard Worker if (cur->type != XML_RELAXNG_ATTRIBUTE) {
9062*7c568831SAndroid Build Coastguard Worker if ((ctxt->state != NULL) || (ctxt->states != NULL)) {
9063*7c568831SAndroid Build Coastguard Worker res = xmlRelaxNGValidateDefinition(ctxt, cur);
9064*7c568831SAndroid Build Coastguard Worker if (res < 0)
9065*7c568831SAndroid Build Coastguard Worker ret = -1;
9066*7c568831SAndroid Build Coastguard Worker } else {
9067*7c568831SAndroid Build Coastguard Worker VALID_ERR(XML_RELAXNG_ERR_NOSTATE);
9068*7c568831SAndroid Build Coastguard Worker return (-1);
9069*7c568831SAndroid Build Coastguard Worker }
9070*7c568831SAndroid Build Coastguard Worker if (res == -1) /* continues on -2 */
9071*7c568831SAndroid Build Coastguard Worker break;
9072*7c568831SAndroid Build Coastguard Worker }
9073*7c568831SAndroid Build Coastguard Worker cur = cur->next;
9074*7c568831SAndroid Build Coastguard Worker }
9075*7c568831SAndroid Build Coastguard Worker
9076*7c568831SAndroid Build Coastguard Worker return (ret);
9077*7c568831SAndroid Build Coastguard Worker }
9078*7c568831SAndroid Build Coastguard Worker
9079*7c568831SAndroid Build Coastguard Worker /**
9080*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGNodeMatchesList:
9081*7c568831SAndroid Build Coastguard Worker * @node: the node
9082*7c568831SAndroid Build Coastguard Worker * @list: a NULL terminated array of definitions
9083*7c568831SAndroid Build Coastguard Worker *
9084*7c568831SAndroid Build Coastguard Worker * Check if a node can be matched by one of the definitions
9085*7c568831SAndroid Build Coastguard Worker *
9086*7c568831SAndroid Build Coastguard Worker * Returns 1 if matches 0 otherwise
9087*7c568831SAndroid Build Coastguard Worker */
9088*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGNodeMatchesList(xmlNodePtr node,xmlRelaxNGDefinePtr * list)9089*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNodeMatchesList(xmlNodePtr node, xmlRelaxNGDefinePtr * list)
9090*7c568831SAndroid Build Coastguard Worker {
9091*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr cur;
9092*7c568831SAndroid Build Coastguard Worker int i = 0, tmp;
9093*7c568831SAndroid Build Coastguard Worker
9094*7c568831SAndroid Build Coastguard Worker if ((node == NULL) || (list == NULL))
9095*7c568831SAndroid Build Coastguard Worker return (0);
9096*7c568831SAndroid Build Coastguard Worker
9097*7c568831SAndroid Build Coastguard Worker cur = list[i++];
9098*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
9099*7c568831SAndroid Build Coastguard Worker if ((node->type == XML_ELEMENT_NODE) &&
9100*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_ELEMENT)) {
9101*7c568831SAndroid Build Coastguard Worker tmp = xmlRelaxNGElementMatch(NULL, cur, node);
9102*7c568831SAndroid Build Coastguard Worker if (tmp == 1)
9103*7c568831SAndroid Build Coastguard Worker return (1);
9104*7c568831SAndroid Build Coastguard Worker } else if (((node->type == XML_TEXT_NODE) ||
9105*7c568831SAndroid Build Coastguard Worker (node->type == XML_CDATA_SECTION_NODE)) &&
9106*7c568831SAndroid Build Coastguard Worker ((cur->type == XML_RELAXNG_DATATYPE) ||
9107*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_LIST) ||
9108*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_TEXT) ||
9109*7c568831SAndroid Build Coastguard Worker (cur->type == XML_RELAXNG_VALUE))) {
9110*7c568831SAndroid Build Coastguard Worker return (1);
9111*7c568831SAndroid Build Coastguard Worker }
9112*7c568831SAndroid Build Coastguard Worker cur = list[i++];
9113*7c568831SAndroid Build Coastguard Worker }
9114*7c568831SAndroid Build Coastguard Worker return (0);
9115*7c568831SAndroid Build Coastguard Worker }
9116*7c568831SAndroid Build Coastguard Worker
9117*7c568831SAndroid Build Coastguard Worker /**
9118*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidateInterleave:
9119*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
9120*7c568831SAndroid Build Coastguard Worker * @define: the definition to verify
9121*7c568831SAndroid Build Coastguard Worker *
9122*7c568831SAndroid Build Coastguard Worker * Validate an interleave definition for a node.
9123*7c568831SAndroid Build Coastguard Worker *
9124*7c568831SAndroid Build Coastguard Worker * Returns 0 if the validation succeeded or an error code.
9125*7c568831SAndroid Build Coastguard Worker */
9126*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGDefinePtr define)9127*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt,
9128*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr define)
9129*7c568831SAndroid Build Coastguard Worker {
9130*7c568831SAndroid Build Coastguard Worker int ret = 0, i, nbgroups;
9131*7c568831SAndroid Build Coastguard Worker int errNr = ctxt->errNr;
9132*7c568831SAndroid Build Coastguard Worker int oldflags;
9133*7c568831SAndroid Build Coastguard Worker
9134*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr oldstate;
9135*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPartitionPtr partitions;
9136*7c568831SAndroid Build Coastguard Worker xmlRelaxNGInterleaveGroupPtr group = NULL;
9137*7c568831SAndroid Build Coastguard Worker xmlNodePtr cur, start, last = NULL, lastchg = NULL, lastelem;
9138*7c568831SAndroid Build Coastguard Worker xmlNodePtr *list = NULL, *lasts = NULL;
9139*7c568831SAndroid Build Coastguard Worker
9140*7c568831SAndroid Build Coastguard Worker if (define->data != NULL) {
9141*7c568831SAndroid Build Coastguard Worker partitions = (xmlRelaxNGPartitionPtr) define->data;
9142*7c568831SAndroid Build Coastguard Worker nbgroups = partitions->nbgroups;
9143*7c568831SAndroid Build Coastguard Worker } else {
9144*7c568831SAndroid Build Coastguard Worker VALID_ERR(XML_RELAXNG_ERR_INTERNODATA);
9145*7c568831SAndroid Build Coastguard Worker return (-1);
9146*7c568831SAndroid Build Coastguard Worker }
9147*7c568831SAndroid Build Coastguard Worker /*
9148*7c568831SAndroid Build Coastguard Worker * Optimizations for MIXED
9149*7c568831SAndroid Build Coastguard Worker */
9150*7c568831SAndroid Build Coastguard Worker oldflags = ctxt->flags;
9151*7c568831SAndroid Build Coastguard Worker if (define->dflags & IS_MIXED) {
9152*7c568831SAndroid Build Coastguard Worker ctxt->flags |= FLAGS_MIXED_CONTENT;
9153*7c568831SAndroid Build Coastguard Worker if (nbgroups == 2) {
9154*7c568831SAndroid Build Coastguard Worker /*
9155*7c568831SAndroid Build Coastguard Worker * this is a pure <mixed> case
9156*7c568831SAndroid Build Coastguard Worker */
9157*7c568831SAndroid Build Coastguard Worker if (ctxt->state != NULL)
9158*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt,
9159*7c568831SAndroid Build Coastguard Worker ctxt->state->seq);
9160*7c568831SAndroid Build Coastguard Worker if (partitions->groups[0]->rule->type == XML_RELAXNG_TEXT)
9161*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateDefinition(ctxt,
9162*7c568831SAndroid Build Coastguard Worker partitions->groups[1]->
9163*7c568831SAndroid Build Coastguard Worker rule);
9164*7c568831SAndroid Build Coastguard Worker else
9165*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateDefinition(ctxt,
9166*7c568831SAndroid Build Coastguard Worker partitions->groups[0]->
9167*7c568831SAndroid Build Coastguard Worker rule);
9168*7c568831SAndroid Build Coastguard Worker if (ret == 0) {
9169*7c568831SAndroid Build Coastguard Worker if (ctxt->state != NULL)
9170*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt,
9171*7c568831SAndroid Build Coastguard Worker ctxt->state->
9172*7c568831SAndroid Build Coastguard Worker seq);
9173*7c568831SAndroid Build Coastguard Worker }
9174*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
9175*7c568831SAndroid Build Coastguard Worker return (ret);
9176*7c568831SAndroid Build Coastguard Worker }
9177*7c568831SAndroid Build Coastguard Worker }
9178*7c568831SAndroid Build Coastguard Worker
9179*7c568831SAndroid Build Coastguard Worker /*
9180*7c568831SAndroid Build Coastguard Worker * Build arrays to store the first and last node of the chain
9181*7c568831SAndroid Build Coastguard Worker * pertaining to each group
9182*7c568831SAndroid Build Coastguard Worker */
9183*7c568831SAndroid Build Coastguard Worker list = (xmlNodePtr *) xmlMalloc(nbgroups * sizeof(xmlNodePtr));
9184*7c568831SAndroid Build Coastguard Worker if (list == NULL) {
9185*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
9186*7c568831SAndroid Build Coastguard Worker return (-1);
9187*7c568831SAndroid Build Coastguard Worker }
9188*7c568831SAndroid Build Coastguard Worker memset(list, 0, nbgroups * sizeof(xmlNodePtr));
9189*7c568831SAndroid Build Coastguard Worker lasts = (xmlNodePtr *) xmlMalloc(nbgroups * sizeof(xmlNodePtr));
9190*7c568831SAndroid Build Coastguard Worker if (lasts == NULL) {
9191*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
9192*7c568831SAndroid Build Coastguard Worker return (-1);
9193*7c568831SAndroid Build Coastguard Worker }
9194*7c568831SAndroid Build Coastguard Worker memset(lasts, 0, nbgroups * sizeof(xmlNodePtr));
9195*7c568831SAndroid Build Coastguard Worker
9196*7c568831SAndroid Build Coastguard Worker /*
9197*7c568831SAndroid Build Coastguard Worker * Walk the sequence of children finding the right group and
9198*7c568831SAndroid Build Coastguard Worker * sorting them in sequences.
9199*7c568831SAndroid Build Coastguard Worker */
9200*7c568831SAndroid Build Coastguard Worker cur = ctxt->state->seq;
9201*7c568831SAndroid Build Coastguard Worker cur = xmlRelaxNGSkipIgnored(ctxt, cur);
9202*7c568831SAndroid Build Coastguard Worker start = cur;
9203*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
9204*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = cur;
9205*7c568831SAndroid Build Coastguard Worker if ((partitions->triage != NULL) &&
9206*7c568831SAndroid Build Coastguard Worker (partitions->flags & IS_DETERMINIST)) {
9207*7c568831SAndroid Build Coastguard Worker void *tmp = NULL;
9208*7c568831SAndroid Build Coastguard Worker
9209*7c568831SAndroid Build Coastguard Worker if ((cur->type == XML_TEXT_NODE) ||
9210*7c568831SAndroid Build Coastguard Worker (cur->type == XML_CDATA_SECTION_NODE)) {
9211*7c568831SAndroid Build Coastguard Worker tmp = xmlHashLookup2(partitions->triage, BAD_CAST "#text",
9212*7c568831SAndroid Build Coastguard Worker NULL);
9213*7c568831SAndroid Build Coastguard Worker } else if (cur->type == XML_ELEMENT_NODE) {
9214*7c568831SAndroid Build Coastguard Worker if (cur->ns != NULL) {
9215*7c568831SAndroid Build Coastguard Worker tmp = xmlHashLookup2(partitions->triage, cur->name,
9216*7c568831SAndroid Build Coastguard Worker cur->ns->href);
9217*7c568831SAndroid Build Coastguard Worker if (tmp == NULL)
9218*7c568831SAndroid Build Coastguard Worker tmp = xmlHashLookup2(partitions->triage,
9219*7c568831SAndroid Build Coastguard Worker BAD_CAST "#any",
9220*7c568831SAndroid Build Coastguard Worker cur->ns->href);
9221*7c568831SAndroid Build Coastguard Worker } else
9222*7c568831SAndroid Build Coastguard Worker tmp =
9223*7c568831SAndroid Build Coastguard Worker xmlHashLookup2(partitions->triage, cur->name,
9224*7c568831SAndroid Build Coastguard Worker NULL);
9225*7c568831SAndroid Build Coastguard Worker if (tmp == NULL)
9226*7c568831SAndroid Build Coastguard Worker tmp =
9227*7c568831SAndroid Build Coastguard Worker xmlHashLookup2(partitions->triage, BAD_CAST "#any",
9228*7c568831SAndroid Build Coastguard Worker NULL);
9229*7c568831SAndroid Build Coastguard Worker }
9230*7c568831SAndroid Build Coastguard Worker
9231*7c568831SAndroid Build Coastguard Worker if (tmp == NULL) {
9232*7c568831SAndroid Build Coastguard Worker i = nbgroups;
9233*7c568831SAndroid Build Coastguard Worker } else {
9234*7c568831SAndroid Build Coastguard Worker i = ((ptrdiff_t) tmp) - 1;
9235*7c568831SAndroid Build Coastguard Worker if (partitions->flags & IS_NEEDCHECK) {
9236*7c568831SAndroid Build Coastguard Worker group = partitions->groups[i];
9237*7c568831SAndroid Build Coastguard Worker if (!xmlRelaxNGNodeMatchesList(cur, group->defs))
9238*7c568831SAndroid Build Coastguard Worker i = nbgroups;
9239*7c568831SAndroid Build Coastguard Worker }
9240*7c568831SAndroid Build Coastguard Worker }
9241*7c568831SAndroid Build Coastguard Worker } else {
9242*7c568831SAndroid Build Coastguard Worker for (i = 0; i < nbgroups; i++) {
9243*7c568831SAndroid Build Coastguard Worker group = partitions->groups[i];
9244*7c568831SAndroid Build Coastguard Worker if (group == NULL)
9245*7c568831SAndroid Build Coastguard Worker continue;
9246*7c568831SAndroid Build Coastguard Worker if (xmlRelaxNGNodeMatchesList(cur, group->defs))
9247*7c568831SAndroid Build Coastguard Worker break;
9248*7c568831SAndroid Build Coastguard Worker }
9249*7c568831SAndroid Build Coastguard Worker }
9250*7c568831SAndroid Build Coastguard Worker /*
9251*7c568831SAndroid Build Coastguard Worker * We break as soon as an element not matched is found
9252*7c568831SAndroid Build Coastguard Worker */
9253*7c568831SAndroid Build Coastguard Worker if (i >= nbgroups) {
9254*7c568831SAndroid Build Coastguard Worker break;
9255*7c568831SAndroid Build Coastguard Worker }
9256*7c568831SAndroid Build Coastguard Worker if (lasts[i] != NULL) {
9257*7c568831SAndroid Build Coastguard Worker lasts[i]->next = cur;
9258*7c568831SAndroid Build Coastguard Worker lasts[i] = cur;
9259*7c568831SAndroid Build Coastguard Worker } else {
9260*7c568831SAndroid Build Coastguard Worker list[i] = cur;
9261*7c568831SAndroid Build Coastguard Worker lasts[i] = cur;
9262*7c568831SAndroid Build Coastguard Worker }
9263*7c568831SAndroid Build Coastguard Worker if (cur->next != NULL)
9264*7c568831SAndroid Build Coastguard Worker lastchg = cur->next;
9265*7c568831SAndroid Build Coastguard Worker else
9266*7c568831SAndroid Build Coastguard Worker lastchg = cur;
9267*7c568831SAndroid Build Coastguard Worker cur = xmlRelaxNGSkipIgnored(ctxt, cur->next);
9268*7c568831SAndroid Build Coastguard Worker }
9269*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
9270*7c568831SAndroid Build Coastguard Worker VALID_ERR(XML_RELAXNG_ERR_INTERSEQ);
9271*7c568831SAndroid Build Coastguard Worker ret = -1;
9272*7c568831SAndroid Build Coastguard Worker goto done;
9273*7c568831SAndroid Build Coastguard Worker }
9274*7c568831SAndroid Build Coastguard Worker lastelem = cur;
9275*7c568831SAndroid Build Coastguard Worker oldstate = ctxt->state;
9276*7c568831SAndroid Build Coastguard Worker for (i = 0; i < nbgroups; i++) {
9277*7c568831SAndroid Build Coastguard Worker ctxt->state = xmlRelaxNGCopyValidState(ctxt, oldstate);
9278*7c568831SAndroid Build Coastguard Worker if (ctxt->state == NULL) {
9279*7c568831SAndroid Build Coastguard Worker ret = -1;
9280*7c568831SAndroid Build Coastguard Worker break;
9281*7c568831SAndroid Build Coastguard Worker }
9282*7c568831SAndroid Build Coastguard Worker group = partitions->groups[i];
9283*7c568831SAndroid Build Coastguard Worker if (lasts[i] != NULL) {
9284*7c568831SAndroid Build Coastguard Worker last = lasts[i]->next;
9285*7c568831SAndroid Build Coastguard Worker lasts[i]->next = NULL;
9286*7c568831SAndroid Build Coastguard Worker }
9287*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = list[i];
9288*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateDefinition(ctxt, group->rule);
9289*7c568831SAndroid Build Coastguard Worker if (ret != 0)
9290*7c568831SAndroid Build Coastguard Worker break;
9291*7c568831SAndroid Build Coastguard Worker if (ctxt->state != NULL) {
9292*7c568831SAndroid Build Coastguard Worker cur = ctxt->state->seq;
9293*7c568831SAndroid Build Coastguard Worker cur = xmlRelaxNGSkipIgnored(ctxt, cur);
9294*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, oldstate);
9295*7c568831SAndroid Build Coastguard Worker oldstate = ctxt->state;
9296*7c568831SAndroid Build Coastguard Worker ctxt->state = NULL;
9297*7c568831SAndroid Build Coastguard Worker if (cur != NULL
9298*7c568831SAndroid Build Coastguard Worker /* there's a nasty violation of context-free unambiguities,
9299*7c568831SAndroid Build Coastguard Worker since in open-name-class context, interleave in the
9300*7c568831SAndroid Build Coastguard Worker production shall finish without caring about anything
9301*7c568831SAndroid Build Coastguard Worker else that is OK to follow in that case -- it would
9302*7c568831SAndroid Build Coastguard Worker otherwise get marked as "extra content" and would
9303*7c568831SAndroid Build Coastguard Worker hence fail the validation, hence this perhaps
9304*7c568831SAndroid Build Coastguard Worker dirty attempt to rectify such a situation */
9305*7c568831SAndroid Build Coastguard Worker && (define->parent->type != XML_RELAXNG_DEF
9306*7c568831SAndroid Build Coastguard Worker || !xmlStrEqual(define->parent->name,
9307*7c568831SAndroid Build Coastguard Worker (const xmlChar *) "open-name-class"))) {
9308*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name);
9309*7c568831SAndroid Build Coastguard Worker ret = -1;
9310*7c568831SAndroid Build Coastguard Worker ctxt->state = oldstate;
9311*7c568831SAndroid Build Coastguard Worker goto done;
9312*7c568831SAndroid Build Coastguard Worker }
9313*7c568831SAndroid Build Coastguard Worker } else if (ctxt->states != NULL) {
9314*7c568831SAndroid Build Coastguard Worker int j;
9315*7c568831SAndroid Build Coastguard Worker int found = 0;
9316*7c568831SAndroid Build Coastguard Worker int best = -1;
9317*7c568831SAndroid Build Coastguard Worker int lowattr = -1;
9318*7c568831SAndroid Build Coastguard Worker
9319*7c568831SAndroid Build Coastguard Worker /*
9320*7c568831SAndroid Build Coastguard Worker * PBM: what happen if there is attributes checks in the interleaves
9321*7c568831SAndroid Build Coastguard Worker */
9322*7c568831SAndroid Build Coastguard Worker
9323*7c568831SAndroid Build Coastguard Worker for (j = 0; j < ctxt->states->nbState; j++) {
9324*7c568831SAndroid Build Coastguard Worker cur = ctxt->states->tabState[j]->seq;
9325*7c568831SAndroid Build Coastguard Worker cur = xmlRelaxNGSkipIgnored(ctxt, cur);
9326*7c568831SAndroid Build Coastguard Worker if (cur == NULL) {
9327*7c568831SAndroid Build Coastguard Worker if (found == 0) {
9328*7c568831SAndroid Build Coastguard Worker lowattr = ctxt->states->tabState[j]->nbAttrLeft;
9329*7c568831SAndroid Build Coastguard Worker best = j;
9330*7c568831SAndroid Build Coastguard Worker }
9331*7c568831SAndroid Build Coastguard Worker found = 1;
9332*7c568831SAndroid Build Coastguard Worker if (ctxt->states->tabState[j]->nbAttrLeft <= lowattr) {
9333*7c568831SAndroid Build Coastguard Worker /* try to keep the latest one to mach old heuristic */
9334*7c568831SAndroid Build Coastguard Worker lowattr = ctxt->states->tabState[j]->nbAttrLeft;
9335*7c568831SAndroid Build Coastguard Worker best = j;
9336*7c568831SAndroid Build Coastguard Worker }
9337*7c568831SAndroid Build Coastguard Worker if (lowattr == 0)
9338*7c568831SAndroid Build Coastguard Worker break;
9339*7c568831SAndroid Build Coastguard Worker } else if (found == 0) {
9340*7c568831SAndroid Build Coastguard Worker if (lowattr == -1) {
9341*7c568831SAndroid Build Coastguard Worker lowattr = ctxt->states->tabState[j]->nbAttrLeft;
9342*7c568831SAndroid Build Coastguard Worker best = j;
9343*7c568831SAndroid Build Coastguard Worker } else
9344*7c568831SAndroid Build Coastguard Worker if (ctxt->states->tabState[j]->nbAttrLeft <= lowattr) {
9345*7c568831SAndroid Build Coastguard Worker /* try to keep the latest one to mach old heuristic */
9346*7c568831SAndroid Build Coastguard Worker lowattr = ctxt->states->tabState[j]->nbAttrLeft;
9347*7c568831SAndroid Build Coastguard Worker best = j;
9348*7c568831SAndroid Build Coastguard Worker }
9349*7c568831SAndroid Build Coastguard Worker }
9350*7c568831SAndroid Build Coastguard Worker }
9351*7c568831SAndroid Build Coastguard Worker /*
9352*7c568831SAndroid Build Coastguard Worker * BIG PBM: here we pick only one restarting point :-(
9353*7c568831SAndroid Build Coastguard Worker */
9354*7c568831SAndroid Build Coastguard Worker if (ctxt->states->nbState > 0) {
9355*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, oldstate);
9356*7c568831SAndroid Build Coastguard Worker if (best != -1) {
9357*7c568831SAndroid Build Coastguard Worker oldstate = ctxt->states->tabState[best];
9358*7c568831SAndroid Build Coastguard Worker ctxt->states->tabState[best] = NULL;
9359*7c568831SAndroid Build Coastguard Worker } else {
9360*7c568831SAndroid Build Coastguard Worker oldstate =
9361*7c568831SAndroid Build Coastguard Worker ctxt->states->tabState[ctxt->states->nbState - 1];
9362*7c568831SAndroid Build Coastguard Worker ctxt->states->tabState[ctxt->states->nbState - 1] = NULL;
9363*7c568831SAndroid Build Coastguard Worker ctxt->states->nbState--;
9364*7c568831SAndroid Build Coastguard Worker }
9365*7c568831SAndroid Build Coastguard Worker }
9366*7c568831SAndroid Build Coastguard Worker for (j = 0; j < ctxt->states->nbState ; j++) {
9367*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, ctxt->states->tabState[j]);
9368*7c568831SAndroid Build Coastguard Worker }
9369*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(ctxt, ctxt->states);
9370*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
9371*7c568831SAndroid Build Coastguard Worker if (found == 0) {
9372*7c568831SAndroid Build Coastguard Worker if (cur == NULL) {
9373*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA,
9374*7c568831SAndroid Build Coastguard Worker (const xmlChar *) "noname");
9375*7c568831SAndroid Build Coastguard Worker } else {
9376*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name);
9377*7c568831SAndroid Build Coastguard Worker }
9378*7c568831SAndroid Build Coastguard Worker ret = -1;
9379*7c568831SAndroid Build Coastguard Worker ctxt->state = oldstate;
9380*7c568831SAndroid Build Coastguard Worker goto done;
9381*7c568831SAndroid Build Coastguard Worker }
9382*7c568831SAndroid Build Coastguard Worker } else {
9383*7c568831SAndroid Build Coastguard Worker ret = -1;
9384*7c568831SAndroid Build Coastguard Worker break;
9385*7c568831SAndroid Build Coastguard Worker }
9386*7c568831SAndroid Build Coastguard Worker if (lasts[i] != NULL) {
9387*7c568831SAndroid Build Coastguard Worker lasts[i]->next = last;
9388*7c568831SAndroid Build Coastguard Worker }
9389*7c568831SAndroid Build Coastguard Worker }
9390*7c568831SAndroid Build Coastguard Worker if (ctxt->state != NULL)
9391*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, ctxt->state);
9392*7c568831SAndroid Build Coastguard Worker ctxt->state = oldstate;
9393*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = lastelem;
9394*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
9395*7c568831SAndroid Build Coastguard Worker VALID_ERR(XML_RELAXNG_ERR_INTERSEQ);
9396*7c568831SAndroid Build Coastguard Worker ret = -1;
9397*7c568831SAndroid Build Coastguard Worker goto done;
9398*7c568831SAndroid Build Coastguard Worker }
9399*7c568831SAndroid Build Coastguard Worker
9400*7c568831SAndroid Build Coastguard Worker done:
9401*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
9402*7c568831SAndroid Build Coastguard Worker /*
9403*7c568831SAndroid Build Coastguard Worker * builds the next links chain from the prev one
9404*7c568831SAndroid Build Coastguard Worker */
9405*7c568831SAndroid Build Coastguard Worker cur = lastchg;
9406*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
9407*7c568831SAndroid Build Coastguard Worker if ((cur == start) || (cur->prev == NULL))
9408*7c568831SAndroid Build Coastguard Worker break;
9409*7c568831SAndroid Build Coastguard Worker cur->prev->next = cur;
9410*7c568831SAndroid Build Coastguard Worker cur = cur->prev;
9411*7c568831SAndroid Build Coastguard Worker }
9412*7c568831SAndroid Build Coastguard Worker if (ret == 0) {
9413*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr > errNr)
9414*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPopErrors(ctxt, errNr);
9415*7c568831SAndroid Build Coastguard Worker }
9416*7c568831SAndroid Build Coastguard Worker
9417*7c568831SAndroid Build Coastguard Worker xmlFree(list);
9418*7c568831SAndroid Build Coastguard Worker xmlFree(lasts);
9419*7c568831SAndroid Build Coastguard Worker return (ret);
9420*7c568831SAndroid Build Coastguard Worker }
9421*7c568831SAndroid Build Coastguard Worker
9422*7c568831SAndroid Build Coastguard Worker /**
9423*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidateDefinitionList:
9424*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
9425*7c568831SAndroid Build Coastguard Worker * @define: the list of definition to verify
9426*7c568831SAndroid Build Coastguard Worker *
9427*7c568831SAndroid Build Coastguard Worker * Validate the given node content against the (list) of definitions
9428*7c568831SAndroid Build Coastguard Worker *
9429*7c568831SAndroid Build Coastguard Worker * Returns 0 if the validation succeeded or an error code.
9430*7c568831SAndroid Build Coastguard Worker */
9431*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGValidateDefinitionList(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGDefinePtr defines)9432*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateDefinitionList(xmlRelaxNGValidCtxtPtr ctxt,
9433*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr defines)
9434*7c568831SAndroid Build Coastguard Worker {
9435*7c568831SAndroid Build Coastguard Worker int ret = 0, res;
9436*7c568831SAndroid Build Coastguard Worker
9437*7c568831SAndroid Build Coastguard Worker
9438*7c568831SAndroid Build Coastguard Worker if (defines == NULL) {
9439*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_INTERNAL,
9440*7c568831SAndroid Build Coastguard Worker BAD_CAST "NULL definition list");
9441*7c568831SAndroid Build Coastguard Worker return (-1);
9442*7c568831SAndroid Build Coastguard Worker }
9443*7c568831SAndroid Build Coastguard Worker while (defines != NULL) {
9444*7c568831SAndroid Build Coastguard Worker if ((ctxt->state != NULL) || (ctxt->states != NULL)) {
9445*7c568831SAndroid Build Coastguard Worker res = xmlRelaxNGValidateDefinition(ctxt, defines);
9446*7c568831SAndroid Build Coastguard Worker if (res < 0)
9447*7c568831SAndroid Build Coastguard Worker ret = -1;
9448*7c568831SAndroid Build Coastguard Worker } else {
9449*7c568831SAndroid Build Coastguard Worker VALID_ERR(XML_RELAXNG_ERR_NOSTATE);
9450*7c568831SAndroid Build Coastguard Worker return (-1);
9451*7c568831SAndroid Build Coastguard Worker }
9452*7c568831SAndroid Build Coastguard Worker if (res == -1) /* continues on -2 */
9453*7c568831SAndroid Build Coastguard Worker break;
9454*7c568831SAndroid Build Coastguard Worker defines = defines->next;
9455*7c568831SAndroid Build Coastguard Worker }
9456*7c568831SAndroid Build Coastguard Worker
9457*7c568831SAndroid Build Coastguard Worker return (ret);
9458*7c568831SAndroid Build Coastguard Worker }
9459*7c568831SAndroid Build Coastguard Worker
9460*7c568831SAndroid Build Coastguard Worker /**
9461*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGElementMatch:
9462*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
9463*7c568831SAndroid Build Coastguard Worker * @define: the definition to check
9464*7c568831SAndroid Build Coastguard Worker * @elem: the element
9465*7c568831SAndroid Build Coastguard Worker *
9466*7c568831SAndroid Build Coastguard Worker * Check if the element matches the definition nameClass
9467*7c568831SAndroid Build Coastguard Worker *
9468*7c568831SAndroid Build Coastguard Worker * Returns 1 if the element matches, 0 if no, or -1 in case of error
9469*7c568831SAndroid Build Coastguard Worker */
9470*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGDefinePtr define,xmlNodePtr elem)9471*7c568831SAndroid Build Coastguard Worker xmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,
9472*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr define, xmlNodePtr elem)
9473*7c568831SAndroid Build Coastguard Worker {
9474*7c568831SAndroid Build Coastguard Worker int ret = 0, oldflags = 0;
9475*7c568831SAndroid Build Coastguard Worker
9476*7c568831SAndroid Build Coastguard Worker if (define->name != NULL) {
9477*7c568831SAndroid Build Coastguard Worker if (!xmlStrEqual(elem->name, define->name)) {
9478*7c568831SAndroid Build Coastguard Worker VALID_ERR3(XML_RELAXNG_ERR_ELEMNAME, define->name, elem->name);
9479*7c568831SAndroid Build Coastguard Worker return (0);
9480*7c568831SAndroid Build Coastguard Worker }
9481*7c568831SAndroid Build Coastguard Worker }
9482*7c568831SAndroid Build Coastguard Worker if ((define->ns != NULL) && (define->ns[0] != 0)) {
9483*7c568831SAndroid Build Coastguard Worker if (elem->ns == NULL) {
9484*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_ELEMNONS, elem->name);
9485*7c568831SAndroid Build Coastguard Worker return (0);
9486*7c568831SAndroid Build Coastguard Worker } else if (!xmlStrEqual(elem->ns->href, define->ns)) {
9487*7c568831SAndroid Build Coastguard Worker VALID_ERR3(XML_RELAXNG_ERR_ELEMWRONGNS,
9488*7c568831SAndroid Build Coastguard Worker elem->name, define->ns);
9489*7c568831SAndroid Build Coastguard Worker return (0);
9490*7c568831SAndroid Build Coastguard Worker }
9491*7c568831SAndroid Build Coastguard Worker } else if ((elem->ns != NULL) && (define->ns != NULL) &&
9492*7c568831SAndroid Build Coastguard Worker (define->name == NULL)) {
9493*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_ELEMEXTRANS, elem->name);
9494*7c568831SAndroid Build Coastguard Worker return (0);
9495*7c568831SAndroid Build Coastguard Worker } else if ((elem->ns != NULL) && (define->name != NULL)) {
9496*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_ELEMEXTRANS, define->name);
9497*7c568831SAndroid Build Coastguard Worker return (0);
9498*7c568831SAndroid Build Coastguard Worker }
9499*7c568831SAndroid Build Coastguard Worker
9500*7c568831SAndroid Build Coastguard Worker if (define->nameClass == NULL)
9501*7c568831SAndroid Build Coastguard Worker return (1);
9502*7c568831SAndroid Build Coastguard Worker
9503*7c568831SAndroid Build Coastguard Worker define = define->nameClass;
9504*7c568831SAndroid Build Coastguard Worker if (define->type == XML_RELAXNG_EXCEPT) {
9505*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr list;
9506*7c568831SAndroid Build Coastguard Worker
9507*7c568831SAndroid Build Coastguard Worker if (ctxt != NULL) {
9508*7c568831SAndroid Build Coastguard Worker oldflags = ctxt->flags;
9509*7c568831SAndroid Build Coastguard Worker ctxt->flags |= FLAGS_IGNORABLE;
9510*7c568831SAndroid Build Coastguard Worker }
9511*7c568831SAndroid Build Coastguard Worker
9512*7c568831SAndroid Build Coastguard Worker list = define->content;
9513*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
9514*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGElementMatch(ctxt, list, elem);
9515*7c568831SAndroid Build Coastguard Worker if (ret == 1) {
9516*7c568831SAndroid Build Coastguard Worker if (ctxt != NULL)
9517*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
9518*7c568831SAndroid Build Coastguard Worker return (0);
9519*7c568831SAndroid Build Coastguard Worker }
9520*7c568831SAndroid Build Coastguard Worker if (ret < 0) {
9521*7c568831SAndroid Build Coastguard Worker if (ctxt != NULL)
9522*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
9523*7c568831SAndroid Build Coastguard Worker return (ret);
9524*7c568831SAndroid Build Coastguard Worker }
9525*7c568831SAndroid Build Coastguard Worker list = list->next;
9526*7c568831SAndroid Build Coastguard Worker }
9527*7c568831SAndroid Build Coastguard Worker ret = 1;
9528*7c568831SAndroid Build Coastguard Worker if (ctxt != NULL) {
9529*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
9530*7c568831SAndroid Build Coastguard Worker }
9531*7c568831SAndroid Build Coastguard Worker } else if (define->type == XML_RELAXNG_CHOICE) {
9532*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr list;
9533*7c568831SAndroid Build Coastguard Worker
9534*7c568831SAndroid Build Coastguard Worker if (ctxt != NULL) {
9535*7c568831SAndroid Build Coastguard Worker oldflags = ctxt->flags;
9536*7c568831SAndroid Build Coastguard Worker ctxt->flags |= FLAGS_IGNORABLE;
9537*7c568831SAndroid Build Coastguard Worker }
9538*7c568831SAndroid Build Coastguard Worker
9539*7c568831SAndroid Build Coastguard Worker list = define->nameClass;
9540*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
9541*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGElementMatch(ctxt, list, elem);
9542*7c568831SAndroid Build Coastguard Worker if (ret == 1) {
9543*7c568831SAndroid Build Coastguard Worker if (ctxt != NULL)
9544*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
9545*7c568831SAndroid Build Coastguard Worker return (1);
9546*7c568831SAndroid Build Coastguard Worker }
9547*7c568831SAndroid Build Coastguard Worker if (ret < 0) {
9548*7c568831SAndroid Build Coastguard Worker if (ctxt != NULL)
9549*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
9550*7c568831SAndroid Build Coastguard Worker return (ret);
9551*7c568831SAndroid Build Coastguard Worker }
9552*7c568831SAndroid Build Coastguard Worker list = list->next;
9553*7c568831SAndroid Build Coastguard Worker }
9554*7c568831SAndroid Build Coastguard Worker if (ctxt != NULL) {
9555*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
9556*7c568831SAndroid Build Coastguard Worker if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
9557*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpValidError(ctxt);
9558*7c568831SAndroid Build Coastguard Worker } else {
9559*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr > 0)
9560*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPopErrors(ctxt, 0);
9561*7c568831SAndroid Build Coastguard Worker }
9562*7c568831SAndroid Build Coastguard Worker }
9563*7c568831SAndroid Build Coastguard Worker ret = 0;
9564*7c568831SAndroid Build Coastguard Worker if (ctxt != NULL) {
9565*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
9566*7c568831SAndroid Build Coastguard Worker }
9567*7c568831SAndroid Build Coastguard Worker } else {
9568*7c568831SAndroid Build Coastguard Worker /* TODO */
9569*7c568831SAndroid Build Coastguard Worker ret = -1;
9570*7c568831SAndroid Build Coastguard Worker }
9571*7c568831SAndroid Build Coastguard Worker return (ret);
9572*7c568831SAndroid Build Coastguard Worker }
9573*7c568831SAndroid Build Coastguard Worker
9574*7c568831SAndroid Build Coastguard Worker /**
9575*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGBestState:
9576*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
9577*7c568831SAndroid Build Coastguard Worker *
9578*7c568831SAndroid Build Coastguard Worker * Find the "best" state in the ctxt->states list of states to report
9579*7c568831SAndroid Build Coastguard Worker * errors about. I.e. a state with no element left in the child list
9580*7c568831SAndroid Build Coastguard Worker * or the one with the less attributes left.
9581*7c568831SAndroid Build Coastguard Worker * This is called only if a validation error was detected
9582*7c568831SAndroid Build Coastguard Worker *
9583*7c568831SAndroid Build Coastguard Worker * Returns the index of the "best" state or -1 in case of error
9584*7c568831SAndroid Build Coastguard Worker */
9585*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGBestState(xmlRelaxNGValidCtxtPtr ctxt)9586*7c568831SAndroid Build Coastguard Worker xmlRelaxNGBestState(xmlRelaxNGValidCtxtPtr ctxt)
9587*7c568831SAndroid Build Coastguard Worker {
9588*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr state;
9589*7c568831SAndroid Build Coastguard Worker int i, tmp;
9590*7c568831SAndroid Build Coastguard Worker int best = -1;
9591*7c568831SAndroid Build Coastguard Worker int value = 1000000;
9592*7c568831SAndroid Build Coastguard Worker
9593*7c568831SAndroid Build Coastguard Worker if ((ctxt == NULL) || (ctxt->states == NULL) ||
9594*7c568831SAndroid Build Coastguard Worker (ctxt->states->nbState <= 0))
9595*7c568831SAndroid Build Coastguard Worker return (-1);
9596*7c568831SAndroid Build Coastguard Worker
9597*7c568831SAndroid Build Coastguard Worker for (i = 0; i < ctxt->states->nbState; i++) {
9598*7c568831SAndroid Build Coastguard Worker state = ctxt->states->tabState[i];
9599*7c568831SAndroid Build Coastguard Worker if (state == NULL)
9600*7c568831SAndroid Build Coastguard Worker continue;
9601*7c568831SAndroid Build Coastguard Worker if (state->seq != NULL) {
9602*7c568831SAndroid Build Coastguard Worker if ((best == -1) || (value > 100000)) {
9603*7c568831SAndroid Build Coastguard Worker value = 100000;
9604*7c568831SAndroid Build Coastguard Worker best = i;
9605*7c568831SAndroid Build Coastguard Worker }
9606*7c568831SAndroid Build Coastguard Worker } else {
9607*7c568831SAndroid Build Coastguard Worker tmp = state->nbAttrLeft;
9608*7c568831SAndroid Build Coastguard Worker if ((best == -1) || (value > tmp)) {
9609*7c568831SAndroid Build Coastguard Worker value = tmp;
9610*7c568831SAndroid Build Coastguard Worker best = i;
9611*7c568831SAndroid Build Coastguard Worker }
9612*7c568831SAndroid Build Coastguard Worker }
9613*7c568831SAndroid Build Coastguard Worker }
9614*7c568831SAndroid Build Coastguard Worker return (best);
9615*7c568831SAndroid Build Coastguard Worker }
9616*7c568831SAndroid Build Coastguard Worker
9617*7c568831SAndroid Build Coastguard Worker /**
9618*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGLogBestError:
9619*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
9620*7c568831SAndroid Build Coastguard Worker *
9621*7c568831SAndroid Build Coastguard Worker * Find the "best" state in the ctxt->states list of states to report
9622*7c568831SAndroid Build Coastguard Worker * errors about and log it.
9623*7c568831SAndroid Build Coastguard Worker */
9624*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGLogBestError(xmlRelaxNGValidCtxtPtr ctxt)9625*7c568831SAndroid Build Coastguard Worker xmlRelaxNGLogBestError(xmlRelaxNGValidCtxtPtr ctxt)
9626*7c568831SAndroid Build Coastguard Worker {
9627*7c568831SAndroid Build Coastguard Worker int best;
9628*7c568831SAndroid Build Coastguard Worker
9629*7c568831SAndroid Build Coastguard Worker if ((ctxt == NULL) || (ctxt->states == NULL) ||
9630*7c568831SAndroid Build Coastguard Worker (ctxt->states->nbState <= 0))
9631*7c568831SAndroid Build Coastguard Worker return;
9632*7c568831SAndroid Build Coastguard Worker
9633*7c568831SAndroid Build Coastguard Worker best = xmlRelaxNGBestState(ctxt);
9634*7c568831SAndroid Build Coastguard Worker if ((best >= 0) && (best < ctxt->states->nbState)) {
9635*7c568831SAndroid Build Coastguard Worker ctxt->state = ctxt->states->tabState[best];
9636*7c568831SAndroid Build Coastguard Worker
9637*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateElementEnd(ctxt, 1);
9638*7c568831SAndroid Build Coastguard Worker }
9639*7c568831SAndroid Build Coastguard Worker }
9640*7c568831SAndroid Build Coastguard Worker
9641*7c568831SAndroid Build Coastguard Worker /**
9642*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidateElementEnd:
9643*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
9644*7c568831SAndroid Build Coastguard Worker * @dolog: indicate that error logging should be done
9645*7c568831SAndroid Build Coastguard Worker *
9646*7c568831SAndroid Build Coastguard Worker * Validate the end of the element, implements check that
9647*7c568831SAndroid Build Coastguard Worker * there is nothing left not consumed in the element content
9648*7c568831SAndroid Build Coastguard Worker * or in the attribute list.
9649*7c568831SAndroid Build Coastguard Worker *
9650*7c568831SAndroid Build Coastguard Worker * Returns 0 if the validation succeeded or an error code.
9651*7c568831SAndroid Build Coastguard Worker */
9652*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt,int dolog)9653*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt, int dolog)
9654*7c568831SAndroid Build Coastguard Worker {
9655*7c568831SAndroid Build Coastguard Worker int i;
9656*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr state;
9657*7c568831SAndroid Build Coastguard Worker
9658*7c568831SAndroid Build Coastguard Worker state = ctxt->state;
9659*7c568831SAndroid Build Coastguard Worker if (state->seq != NULL) {
9660*7c568831SAndroid Build Coastguard Worker state->seq = xmlRelaxNGSkipIgnored(ctxt, state->seq);
9661*7c568831SAndroid Build Coastguard Worker if (state->seq != NULL) {
9662*7c568831SAndroid Build Coastguard Worker if (dolog) {
9663*7c568831SAndroid Build Coastguard Worker VALID_ERR3(XML_RELAXNG_ERR_EXTRACONTENT,
9664*7c568831SAndroid Build Coastguard Worker state->node->name, state->seq->name);
9665*7c568831SAndroid Build Coastguard Worker }
9666*7c568831SAndroid Build Coastguard Worker return (-1);
9667*7c568831SAndroid Build Coastguard Worker }
9668*7c568831SAndroid Build Coastguard Worker }
9669*7c568831SAndroid Build Coastguard Worker for (i = 0; i < state->nbAttrs; i++) {
9670*7c568831SAndroid Build Coastguard Worker if (state->attrs[i] != NULL) {
9671*7c568831SAndroid Build Coastguard Worker if (dolog) {
9672*7c568831SAndroid Build Coastguard Worker VALID_ERR3(XML_RELAXNG_ERR_INVALIDATTR,
9673*7c568831SAndroid Build Coastguard Worker state->attrs[i]->name, state->node->name);
9674*7c568831SAndroid Build Coastguard Worker }
9675*7c568831SAndroid Build Coastguard Worker return (-1 - i);
9676*7c568831SAndroid Build Coastguard Worker }
9677*7c568831SAndroid Build Coastguard Worker }
9678*7c568831SAndroid Build Coastguard Worker return (0);
9679*7c568831SAndroid Build Coastguard Worker }
9680*7c568831SAndroid Build Coastguard Worker
9681*7c568831SAndroid Build Coastguard Worker /**
9682*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidateState:
9683*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
9684*7c568831SAndroid Build Coastguard Worker * @define: the definition to verify
9685*7c568831SAndroid Build Coastguard Worker *
9686*7c568831SAndroid Build Coastguard Worker * Validate the current state against the definition
9687*7c568831SAndroid Build Coastguard Worker *
9688*7c568831SAndroid Build Coastguard Worker * Returns 0 if the validation succeeded or an error code.
9689*7c568831SAndroid Build Coastguard Worker */
9690*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGDefinePtr define)9691*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
9692*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr define)
9693*7c568831SAndroid Build Coastguard Worker {
9694*7c568831SAndroid Build Coastguard Worker xmlNodePtr node;
9695*7c568831SAndroid Build Coastguard Worker int ret = 0, i, tmp, oldflags, errNr;
9696*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr oldstate = NULL, state;
9697*7c568831SAndroid Build Coastguard Worker
9698*7c568831SAndroid Build Coastguard Worker if (define == NULL) {
9699*7c568831SAndroid Build Coastguard Worker VALID_ERR(XML_RELAXNG_ERR_NODEFINE);
9700*7c568831SAndroid Build Coastguard Worker return (-1);
9701*7c568831SAndroid Build Coastguard Worker }
9702*7c568831SAndroid Build Coastguard Worker
9703*7c568831SAndroid Build Coastguard Worker if (ctxt->state != NULL) {
9704*7c568831SAndroid Build Coastguard Worker node = ctxt->state->seq;
9705*7c568831SAndroid Build Coastguard Worker } else {
9706*7c568831SAndroid Build Coastguard Worker node = NULL;
9707*7c568831SAndroid Build Coastguard Worker }
9708*7c568831SAndroid Build Coastguard Worker ctxt->depth++;
9709*7c568831SAndroid Build Coastguard Worker switch (define->type) {
9710*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EMPTY:
9711*7c568831SAndroid Build Coastguard Worker ret = 0;
9712*7c568831SAndroid Build Coastguard Worker break;
9713*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOT_ALLOWED:
9714*7c568831SAndroid Build Coastguard Worker ret = -1;
9715*7c568831SAndroid Build Coastguard Worker break;
9716*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_TEXT:
9717*7c568831SAndroid Build Coastguard Worker while ((node != NULL) &&
9718*7c568831SAndroid Build Coastguard Worker ((node->type == XML_TEXT_NODE) ||
9719*7c568831SAndroid Build Coastguard Worker (node->type == XML_COMMENT_NODE) ||
9720*7c568831SAndroid Build Coastguard Worker (node->type == XML_PI_NODE) ||
9721*7c568831SAndroid Build Coastguard Worker (node->type == XML_CDATA_SECTION_NODE)))
9722*7c568831SAndroid Build Coastguard Worker node = node->next;
9723*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = node;
9724*7c568831SAndroid Build Coastguard Worker break;
9725*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ELEMENT:
9726*7c568831SAndroid Build Coastguard Worker errNr = ctxt->errNr;
9727*7c568831SAndroid Build Coastguard Worker node = xmlRelaxNGSkipIgnored(ctxt, node);
9728*7c568831SAndroid Build Coastguard Worker if (node == NULL) {
9729*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_NOELEM, define->name);
9730*7c568831SAndroid Build Coastguard Worker ret = -1;
9731*7c568831SAndroid Build Coastguard Worker if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
9732*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpValidError(ctxt);
9733*7c568831SAndroid Build Coastguard Worker break;
9734*7c568831SAndroid Build Coastguard Worker }
9735*7c568831SAndroid Build Coastguard Worker if (node->type != XML_ELEMENT_NODE) {
9736*7c568831SAndroid Build Coastguard Worker VALID_ERR(XML_RELAXNG_ERR_NOTELEM);
9737*7c568831SAndroid Build Coastguard Worker ret = -1;
9738*7c568831SAndroid Build Coastguard Worker if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
9739*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpValidError(ctxt);
9740*7c568831SAndroid Build Coastguard Worker break;
9741*7c568831SAndroid Build Coastguard Worker }
9742*7c568831SAndroid Build Coastguard Worker /*
9743*7c568831SAndroid Build Coastguard Worker * This node was already validated successfully against
9744*7c568831SAndroid Build Coastguard Worker * this definition.
9745*7c568831SAndroid Build Coastguard Worker */
9746*7c568831SAndroid Build Coastguard Worker if (node->psvi == define) {
9747*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt, node->next);
9748*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr > errNr)
9749*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPopErrors(ctxt, errNr);
9750*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr != 0) {
9751*7c568831SAndroid Build Coastguard Worker while ((ctxt->err != NULL) &&
9752*7c568831SAndroid Build Coastguard Worker (((ctxt->err->err == XML_RELAXNG_ERR_ELEMNAME)
9753*7c568831SAndroid Build Coastguard Worker && (xmlStrEqual(ctxt->err->arg2, node->name)))
9754*7c568831SAndroid Build Coastguard Worker ||
9755*7c568831SAndroid Build Coastguard Worker ((ctxt->err->err ==
9756*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_ERR_ELEMEXTRANS)
9757*7c568831SAndroid Build Coastguard Worker && (xmlStrEqual(ctxt->err->arg1, node->name)))
9758*7c568831SAndroid Build Coastguard Worker || (ctxt->err->err == XML_RELAXNG_ERR_NOELEM)
9759*7c568831SAndroid Build Coastguard Worker || (ctxt->err->err ==
9760*7c568831SAndroid Build Coastguard Worker XML_RELAXNG_ERR_NOTELEM)))
9761*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidErrorPop(ctxt);
9762*7c568831SAndroid Build Coastguard Worker }
9763*7c568831SAndroid Build Coastguard Worker break;
9764*7c568831SAndroid Build Coastguard Worker }
9765*7c568831SAndroid Build Coastguard Worker
9766*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGElementMatch(ctxt, define, node);
9767*7c568831SAndroid Build Coastguard Worker if (ret <= 0) {
9768*7c568831SAndroid Build Coastguard Worker ret = -1;
9769*7c568831SAndroid Build Coastguard Worker if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
9770*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpValidError(ctxt);
9771*7c568831SAndroid Build Coastguard Worker break;
9772*7c568831SAndroid Build Coastguard Worker }
9773*7c568831SAndroid Build Coastguard Worker ret = 0;
9774*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr != 0) {
9775*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr > errNr)
9776*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPopErrors(ctxt, errNr);
9777*7c568831SAndroid Build Coastguard Worker while ((ctxt->err != NULL) &&
9778*7c568831SAndroid Build Coastguard Worker (((ctxt->err->err == XML_RELAXNG_ERR_ELEMNAME) &&
9779*7c568831SAndroid Build Coastguard Worker (xmlStrEqual(ctxt->err->arg2, node->name))) ||
9780*7c568831SAndroid Build Coastguard Worker ((ctxt->err->err == XML_RELAXNG_ERR_ELEMEXTRANS) &&
9781*7c568831SAndroid Build Coastguard Worker (xmlStrEqual(ctxt->err->arg1, node->name))) ||
9782*7c568831SAndroid Build Coastguard Worker (ctxt->err->err == XML_RELAXNG_ERR_NOELEM) ||
9783*7c568831SAndroid Build Coastguard Worker (ctxt->err->err == XML_RELAXNG_ERR_NOTELEM)))
9784*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidErrorPop(ctxt);
9785*7c568831SAndroid Build Coastguard Worker }
9786*7c568831SAndroid Build Coastguard Worker errNr = ctxt->errNr;
9787*7c568831SAndroid Build Coastguard Worker
9788*7c568831SAndroid Build Coastguard Worker oldflags = ctxt->flags;
9789*7c568831SAndroid Build Coastguard Worker if (ctxt->flags & FLAGS_MIXED_CONTENT) {
9790*7c568831SAndroid Build Coastguard Worker ctxt->flags -= FLAGS_MIXED_CONTENT;
9791*7c568831SAndroid Build Coastguard Worker }
9792*7c568831SAndroid Build Coastguard Worker state = xmlRelaxNGNewValidState(ctxt, node);
9793*7c568831SAndroid Build Coastguard Worker if (state == NULL) {
9794*7c568831SAndroid Build Coastguard Worker ret = -1;
9795*7c568831SAndroid Build Coastguard Worker if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
9796*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpValidError(ctxt);
9797*7c568831SAndroid Build Coastguard Worker break;
9798*7c568831SAndroid Build Coastguard Worker }
9799*7c568831SAndroid Build Coastguard Worker
9800*7c568831SAndroid Build Coastguard Worker oldstate = ctxt->state;
9801*7c568831SAndroid Build Coastguard Worker ctxt->state = state;
9802*7c568831SAndroid Build Coastguard Worker if (define->attrs != NULL) {
9803*7c568831SAndroid Build Coastguard Worker tmp = xmlRelaxNGValidateAttributeList(ctxt, define->attrs);
9804*7c568831SAndroid Build Coastguard Worker if (tmp != 0) {
9805*7c568831SAndroid Build Coastguard Worker ret = -1;
9806*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_ATTRVALID, node->name);
9807*7c568831SAndroid Build Coastguard Worker }
9808*7c568831SAndroid Build Coastguard Worker }
9809*7c568831SAndroid Build Coastguard Worker if (define->contModel != NULL) {
9810*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr nstate, tmpstate = ctxt->state;
9811*7c568831SAndroid Build Coastguard Worker xmlRelaxNGStatesPtr tmpstates = ctxt->states;
9812*7c568831SAndroid Build Coastguard Worker xmlNodePtr nseq;
9813*7c568831SAndroid Build Coastguard Worker
9814*7c568831SAndroid Build Coastguard Worker nstate = xmlRelaxNGNewValidState(ctxt, node);
9815*7c568831SAndroid Build Coastguard Worker ctxt->state = nstate;
9816*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
9817*7c568831SAndroid Build Coastguard Worker
9818*7c568831SAndroid Build Coastguard Worker tmp = xmlRelaxNGValidateCompiledContent(ctxt,
9819*7c568831SAndroid Build Coastguard Worker define->contModel,
9820*7c568831SAndroid Build Coastguard Worker ctxt->state->seq);
9821*7c568831SAndroid Build Coastguard Worker nseq = ctxt->state->seq;
9822*7c568831SAndroid Build Coastguard Worker ctxt->state = tmpstate;
9823*7c568831SAndroid Build Coastguard Worker ctxt->states = tmpstates;
9824*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, nstate);
9825*7c568831SAndroid Build Coastguard Worker
9826*7c568831SAndroid Build Coastguard Worker if (tmp != 0)
9827*7c568831SAndroid Build Coastguard Worker ret = -1;
9828*7c568831SAndroid Build Coastguard Worker
9829*7c568831SAndroid Build Coastguard Worker if (ctxt->states != NULL) {
9830*7c568831SAndroid Build Coastguard Worker tmp = -1;
9831*7c568831SAndroid Build Coastguard Worker
9832*7c568831SAndroid Build Coastguard Worker for (i = 0; i < ctxt->states->nbState; i++) {
9833*7c568831SAndroid Build Coastguard Worker state = ctxt->states->tabState[i];
9834*7c568831SAndroid Build Coastguard Worker ctxt->state = state;
9835*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = nseq;
9836*7c568831SAndroid Build Coastguard Worker
9837*7c568831SAndroid Build Coastguard Worker if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
9838*7c568831SAndroid Build Coastguard Worker tmp = 0;
9839*7c568831SAndroid Build Coastguard Worker break;
9840*7c568831SAndroid Build Coastguard Worker }
9841*7c568831SAndroid Build Coastguard Worker }
9842*7c568831SAndroid Build Coastguard Worker if (tmp != 0) {
9843*7c568831SAndroid Build Coastguard Worker /*
9844*7c568831SAndroid Build Coastguard Worker * validation error, log the message for the "best" one
9845*7c568831SAndroid Build Coastguard Worker */
9846*7c568831SAndroid Build Coastguard Worker ctxt->flags |= FLAGS_IGNORABLE;
9847*7c568831SAndroid Build Coastguard Worker xmlRelaxNGLogBestError(ctxt);
9848*7c568831SAndroid Build Coastguard Worker }
9849*7c568831SAndroid Build Coastguard Worker for (i = 0; i < ctxt->states->nbState; i++) {
9850*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt,
9851*7c568831SAndroid Build Coastguard Worker ctxt->states->
9852*7c568831SAndroid Build Coastguard Worker tabState[i]);
9853*7c568831SAndroid Build Coastguard Worker }
9854*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(ctxt, ctxt->states);
9855*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
9856*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
9857*7c568831SAndroid Build Coastguard Worker if ((ret == 0) && (tmp == -1))
9858*7c568831SAndroid Build Coastguard Worker ret = -1;
9859*7c568831SAndroid Build Coastguard Worker } else {
9860*7c568831SAndroid Build Coastguard Worker state = ctxt->state;
9861*7c568831SAndroid Build Coastguard Worker if (ctxt->state != NULL)
9862*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = nseq;
9863*7c568831SAndroid Build Coastguard Worker if (ret == 0)
9864*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
9865*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, state);
9866*7c568831SAndroid Build Coastguard Worker }
9867*7c568831SAndroid Build Coastguard Worker } else {
9868*7c568831SAndroid Build Coastguard Worker if (define->content != NULL) {
9869*7c568831SAndroid Build Coastguard Worker tmp = xmlRelaxNGValidateDefinitionList(ctxt,
9870*7c568831SAndroid Build Coastguard Worker define->
9871*7c568831SAndroid Build Coastguard Worker content);
9872*7c568831SAndroid Build Coastguard Worker if (tmp != 0) {
9873*7c568831SAndroid Build Coastguard Worker ret = -1;
9874*7c568831SAndroid Build Coastguard Worker if (ctxt->state == NULL) {
9875*7c568831SAndroid Build Coastguard Worker ctxt->state = oldstate;
9876*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_CONTENTVALID,
9877*7c568831SAndroid Build Coastguard Worker node->name);
9878*7c568831SAndroid Build Coastguard Worker ctxt->state = NULL;
9879*7c568831SAndroid Build Coastguard Worker } else {
9880*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_CONTENTVALID,
9881*7c568831SAndroid Build Coastguard Worker node->name);
9882*7c568831SAndroid Build Coastguard Worker }
9883*7c568831SAndroid Build Coastguard Worker
9884*7c568831SAndroid Build Coastguard Worker }
9885*7c568831SAndroid Build Coastguard Worker }
9886*7c568831SAndroid Build Coastguard Worker if (ctxt->states != NULL) {
9887*7c568831SAndroid Build Coastguard Worker tmp = -1;
9888*7c568831SAndroid Build Coastguard Worker
9889*7c568831SAndroid Build Coastguard Worker for (i = 0; i < ctxt->states->nbState; i++) {
9890*7c568831SAndroid Build Coastguard Worker state = ctxt->states->tabState[i];
9891*7c568831SAndroid Build Coastguard Worker ctxt->state = state;
9892*7c568831SAndroid Build Coastguard Worker
9893*7c568831SAndroid Build Coastguard Worker if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
9894*7c568831SAndroid Build Coastguard Worker tmp = 0;
9895*7c568831SAndroid Build Coastguard Worker break;
9896*7c568831SAndroid Build Coastguard Worker }
9897*7c568831SAndroid Build Coastguard Worker }
9898*7c568831SAndroid Build Coastguard Worker if (tmp != 0) {
9899*7c568831SAndroid Build Coastguard Worker /*
9900*7c568831SAndroid Build Coastguard Worker * validation error, log the message for the "best" one
9901*7c568831SAndroid Build Coastguard Worker */
9902*7c568831SAndroid Build Coastguard Worker ctxt->flags |= FLAGS_IGNORABLE;
9903*7c568831SAndroid Build Coastguard Worker xmlRelaxNGLogBestError(ctxt);
9904*7c568831SAndroid Build Coastguard Worker }
9905*7c568831SAndroid Build Coastguard Worker for (i = 0; i < ctxt->states->nbState; i++) {
9906*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt,
9907*7c568831SAndroid Build Coastguard Worker ctxt->states->tabState[i]);
9908*7c568831SAndroid Build Coastguard Worker ctxt->states->tabState[i] = NULL;
9909*7c568831SAndroid Build Coastguard Worker }
9910*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(ctxt, ctxt->states);
9911*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
9912*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
9913*7c568831SAndroid Build Coastguard Worker if ((ret == 0) && (tmp == -1))
9914*7c568831SAndroid Build Coastguard Worker ret = -1;
9915*7c568831SAndroid Build Coastguard Worker } else {
9916*7c568831SAndroid Build Coastguard Worker state = ctxt->state;
9917*7c568831SAndroid Build Coastguard Worker if (ret == 0)
9918*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
9919*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, state);
9920*7c568831SAndroid Build Coastguard Worker }
9921*7c568831SAndroid Build Coastguard Worker }
9922*7c568831SAndroid Build Coastguard Worker if (ret == 0) {
9923*7c568831SAndroid Build Coastguard Worker node->psvi = define;
9924*7c568831SAndroid Build Coastguard Worker }
9925*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
9926*7c568831SAndroid Build Coastguard Worker ctxt->state = oldstate;
9927*7c568831SAndroid Build Coastguard Worker if (oldstate != NULL)
9928*7c568831SAndroid Build Coastguard Worker oldstate->seq = xmlRelaxNGSkipIgnored(ctxt, node->next);
9929*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
9930*7c568831SAndroid Build Coastguard Worker if ((ctxt->flags & FLAGS_IGNORABLE) == 0) {
9931*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpValidError(ctxt);
9932*7c568831SAndroid Build Coastguard Worker ret = 0;
9933*7c568831SAndroid Build Coastguard Worker #if 0
9934*7c568831SAndroid Build Coastguard Worker } else {
9935*7c568831SAndroid Build Coastguard Worker ret = -2;
9936*7c568831SAndroid Build Coastguard Worker #endif
9937*7c568831SAndroid Build Coastguard Worker }
9938*7c568831SAndroid Build Coastguard Worker } else {
9939*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr > errNr)
9940*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPopErrors(ctxt, errNr);
9941*7c568831SAndroid Build Coastguard Worker }
9942*7c568831SAndroid Build Coastguard Worker
9943*7c568831SAndroid Build Coastguard Worker break;
9944*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_OPTIONAL:{
9945*7c568831SAndroid Build Coastguard Worker errNr = ctxt->errNr;
9946*7c568831SAndroid Build Coastguard Worker oldflags = ctxt->flags;
9947*7c568831SAndroid Build Coastguard Worker ctxt->flags |= FLAGS_IGNORABLE;
9948*7c568831SAndroid Build Coastguard Worker oldstate = xmlRelaxNGCopyValidState(ctxt, ctxt->state);
9949*7c568831SAndroid Build Coastguard Worker ret =
9950*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateDefinitionList(ctxt,
9951*7c568831SAndroid Build Coastguard Worker define->content);
9952*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
9953*7c568831SAndroid Build Coastguard Worker if (ctxt->state != NULL)
9954*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, ctxt->state);
9955*7c568831SAndroid Build Coastguard Worker ctxt->state = oldstate;
9956*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
9957*7c568831SAndroid Build Coastguard Worker ret = 0;
9958*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr > errNr)
9959*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPopErrors(ctxt, errNr);
9960*7c568831SAndroid Build Coastguard Worker break;
9961*7c568831SAndroid Build Coastguard Worker }
9962*7c568831SAndroid Build Coastguard Worker if (ctxt->states != NULL) {
9963*7c568831SAndroid Build Coastguard Worker xmlRelaxNGAddStates(ctxt, ctxt->states, oldstate);
9964*7c568831SAndroid Build Coastguard Worker } else {
9965*7c568831SAndroid Build Coastguard Worker ctxt->states = xmlRelaxNGNewStates(ctxt, 1);
9966*7c568831SAndroid Build Coastguard Worker if (ctxt->states == NULL) {
9967*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, oldstate);
9968*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
9969*7c568831SAndroid Build Coastguard Worker ret = -1;
9970*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr > errNr)
9971*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPopErrors(ctxt, errNr);
9972*7c568831SAndroid Build Coastguard Worker break;
9973*7c568831SAndroid Build Coastguard Worker }
9974*7c568831SAndroid Build Coastguard Worker xmlRelaxNGAddStates(ctxt, ctxt->states, oldstate);
9975*7c568831SAndroid Build Coastguard Worker xmlRelaxNGAddStates(ctxt, ctxt->states, ctxt->state);
9976*7c568831SAndroid Build Coastguard Worker ctxt->state = NULL;
9977*7c568831SAndroid Build Coastguard Worker }
9978*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
9979*7c568831SAndroid Build Coastguard Worker ret = 0;
9980*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr > errNr)
9981*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPopErrors(ctxt, errNr);
9982*7c568831SAndroid Build Coastguard Worker break;
9983*7c568831SAndroid Build Coastguard Worker }
9984*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ONEORMORE:
9985*7c568831SAndroid Build Coastguard Worker errNr = ctxt->errNr;
9986*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateDefinitionList(ctxt, define->content);
9987*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
9988*7c568831SAndroid Build Coastguard Worker break;
9989*7c568831SAndroid Build Coastguard Worker }
9990*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr > errNr)
9991*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPopErrors(ctxt, errNr);
9992*7c568831SAndroid Build Coastguard Worker /* Falls through. */
9993*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ZEROORMORE:{
9994*7c568831SAndroid Build Coastguard Worker int progress;
9995*7c568831SAndroid Build Coastguard Worker xmlRelaxNGStatesPtr states = NULL, res = NULL;
9996*7c568831SAndroid Build Coastguard Worker int base, j;
9997*7c568831SAndroid Build Coastguard Worker
9998*7c568831SAndroid Build Coastguard Worker errNr = ctxt->errNr;
9999*7c568831SAndroid Build Coastguard Worker res = xmlRelaxNGNewStates(ctxt, 1);
10000*7c568831SAndroid Build Coastguard Worker if (res == NULL) {
10001*7c568831SAndroid Build Coastguard Worker ret = -1;
10002*7c568831SAndroid Build Coastguard Worker break;
10003*7c568831SAndroid Build Coastguard Worker }
10004*7c568831SAndroid Build Coastguard Worker /*
10005*7c568831SAndroid Build Coastguard Worker * All the input states are also exit states
10006*7c568831SAndroid Build Coastguard Worker */
10007*7c568831SAndroid Build Coastguard Worker if (ctxt->state != NULL) {
10008*7c568831SAndroid Build Coastguard Worker xmlRelaxNGAddStates(ctxt, res,
10009*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCopyValidState(ctxt,
10010*7c568831SAndroid Build Coastguard Worker ctxt->
10011*7c568831SAndroid Build Coastguard Worker state));
10012*7c568831SAndroid Build Coastguard Worker } else {
10013*7c568831SAndroid Build Coastguard Worker for (j = 0; j < ctxt->states->nbState; j++) {
10014*7c568831SAndroid Build Coastguard Worker xmlRelaxNGAddStates(ctxt, res,
10015*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCopyValidState(ctxt,
10016*7c568831SAndroid Build Coastguard Worker ctxt->states->tabState[j]));
10017*7c568831SAndroid Build Coastguard Worker }
10018*7c568831SAndroid Build Coastguard Worker }
10019*7c568831SAndroid Build Coastguard Worker oldflags = ctxt->flags;
10020*7c568831SAndroid Build Coastguard Worker ctxt->flags |= FLAGS_IGNORABLE;
10021*7c568831SAndroid Build Coastguard Worker do {
10022*7c568831SAndroid Build Coastguard Worker progress = 0;
10023*7c568831SAndroid Build Coastguard Worker base = res->nbState;
10024*7c568831SAndroid Build Coastguard Worker
10025*7c568831SAndroid Build Coastguard Worker if (ctxt->states != NULL) {
10026*7c568831SAndroid Build Coastguard Worker states = ctxt->states;
10027*7c568831SAndroid Build Coastguard Worker for (i = 0; i < states->nbState; i++) {
10028*7c568831SAndroid Build Coastguard Worker ctxt->state = states->tabState[i];
10029*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
10030*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateDefinitionList(ctxt,
10031*7c568831SAndroid Build Coastguard Worker define->
10032*7c568831SAndroid Build Coastguard Worker content);
10033*7c568831SAndroid Build Coastguard Worker if (ret == 0) {
10034*7c568831SAndroid Build Coastguard Worker if (ctxt->state != NULL) {
10035*7c568831SAndroid Build Coastguard Worker tmp = xmlRelaxNGAddStates(ctxt, res,
10036*7c568831SAndroid Build Coastguard Worker ctxt->state);
10037*7c568831SAndroid Build Coastguard Worker ctxt->state = NULL;
10038*7c568831SAndroid Build Coastguard Worker if (tmp == 1)
10039*7c568831SAndroid Build Coastguard Worker progress = 1;
10040*7c568831SAndroid Build Coastguard Worker } else if (ctxt->states != NULL) {
10041*7c568831SAndroid Build Coastguard Worker for (j = 0; j < ctxt->states->nbState;
10042*7c568831SAndroid Build Coastguard Worker j++) {
10043*7c568831SAndroid Build Coastguard Worker tmp =
10044*7c568831SAndroid Build Coastguard Worker xmlRelaxNGAddStates(ctxt, res,
10045*7c568831SAndroid Build Coastguard Worker ctxt->states->tabState[j]);
10046*7c568831SAndroid Build Coastguard Worker if (tmp == 1)
10047*7c568831SAndroid Build Coastguard Worker progress = 1;
10048*7c568831SAndroid Build Coastguard Worker }
10049*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(ctxt,
10050*7c568831SAndroid Build Coastguard Worker ctxt->states);
10051*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
10052*7c568831SAndroid Build Coastguard Worker }
10053*7c568831SAndroid Build Coastguard Worker } else {
10054*7c568831SAndroid Build Coastguard Worker if (ctxt->state != NULL) {
10055*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt,
10056*7c568831SAndroid Build Coastguard Worker ctxt->state);
10057*7c568831SAndroid Build Coastguard Worker ctxt->state = NULL;
10058*7c568831SAndroid Build Coastguard Worker }
10059*7c568831SAndroid Build Coastguard Worker }
10060*7c568831SAndroid Build Coastguard Worker }
10061*7c568831SAndroid Build Coastguard Worker } else {
10062*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateDefinitionList(ctxt,
10063*7c568831SAndroid Build Coastguard Worker define->
10064*7c568831SAndroid Build Coastguard Worker content);
10065*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
10066*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, ctxt->state);
10067*7c568831SAndroid Build Coastguard Worker ctxt->state = NULL;
10068*7c568831SAndroid Build Coastguard Worker } else {
10069*7c568831SAndroid Build Coastguard Worker base = res->nbState;
10070*7c568831SAndroid Build Coastguard Worker if (ctxt->state != NULL) {
10071*7c568831SAndroid Build Coastguard Worker tmp = xmlRelaxNGAddStates(ctxt, res,
10072*7c568831SAndroid Build Coastguard Worker ctxt->state);
10073*7c568831SAndroid Build Coastguard Worker ctxt->state = NULL;
10074*7c568831SAndroid Build Coastguard Worker if (tmp == 1)
10075*7c568831SAndroid Build Coastguard Worker progress = 1;
10076*7c568831SAndroid Build Coastguard Worker } else if (ctxt->states != NULL) {
10077*7c568831SAndroid Build Coastguard Worker for (j = 0; j < ctxt->states->nbState; j++) {
10078*7c568831SAndroid Build Coastguard Worker tmp = xmlRelaxNGAddStates(ctxt, res,
10079*7c568831SAndroid Build Coastguard Worker ctxt->states->tabState[j]);
10080*7c568831SAndroid Build Coastguard Worker if (tmp == 1)
10081*7c568831SAndroid Build Coastguard Worker progress = 1;
10082*7c568831SAndroid Build Coastguard Worker }
10083*7c568831SAndroid Build Coastguard Worker if (states == NULL) {
10084*7c568831SAndroid Build Coastguard Worker states = ctxt->states;
10085*7c568831SAndroid Build Coastguard Worker } else {
10086*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(ctxt,
10087*7c568831SAndroid Build Coastguard Worker ctxt->states);
10088*7c568831SAndroid Build Coastguard Worker }
10089*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
10090*7c568831SAndroid Build Coastguard Worker }
10091*7c568831SAndroid Build Coastguard Worker }
10092*7c568831SAndroid Build Coastguard Worker }
10093*7c568831SAndroid Build Coastguard Worker if (progress) {
10094*7c568831SAndroid Build Coastguard Worker /*
10095*7c568831SAndroid Build Coastguard Worker * Collect all the new nodes added at that step
10096*7c568831SAndroid Build Coastguard Worker * and make them the new node set
10097*7c568831SAndroid Build Coastguard Worker */
10098*7c568831SAndroid Build Coastguard Worker if (res->nbState - base == 1) {
10099*7c568831SAndroid Build Coastguard Worker ctxt->state = xmlRelaxNGCopyValidState(ctxt,
10100*7c568831SAndroid Build Coastguard Worker res->
10101*7c568831SAndroid Build Coastguard Worker tabState
10102*7c568831SAndroid Build Coastguard Worker [base]);
10103*7c568831SAndroid Build Coastguard Worker } else {
10104*7c568831SAndroid Build Coastguard Worker if (states == NULL) {
10105*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNewStates(ctxt,
10106*7c568831SAndroid Build Coastguard Worker res->nbState - base);
10107*7c568831SAndroid Build Coastguard Worker states = ctxt->states;
10108*7c568831SAndroid Build Coastguard Worker if (states == NULL) {
10109*7c568831SAndroid Build Coastguard Worker progress = 0;
10110*7c568831SAndroid Build Coastguard Worker break;
10111*7c568831SAndroid Build Coastguard Worker }
10112*7c568831SAndroid Build Coastguard Worker }
10113*7c568831SAndroid Build Coastguard Worker states->nbState = 0;
10114*7c568831SAndroid Build Coastguard Worker for (i = base; i < res->nbState; i++)
10115*7c568831SAndroid Build Coastguard Worker xmlRelaxNGAddStates(ctxt, states,
10116*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCopyValidState
10117*7c568831SAndroid Build Coastguard Worker (ctxt, res->tabState[i]));
10118*7c568831SAndroid Build Coastguard Worker ctxt->states = states;
10119*7c568831SAndroid Build Coastguard Worker }
10120*7c568831SAndroid Build Coastguard Worker }
10121*7c568831SAndroid Build Coastguard Worker } while (progress == 1);
10122*7c568831SAndroid Build Coastguard Worker if (states != NULL) {
10123*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(ctxt, states);
10124*7c568831SAndroid Build Coastguard Worker }
10125*7c568831SAndroid Build Coastguard Worker ctxt->states = res;
10126*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
10127*7c568831SAndroid Build Coastguard Worker #if 0
10128*7c568831SAndroid Build Coastguard Worker /*
10129*7c568831SAndroid Build Coastguard Worker * errors may have to be propagated back...
10130*7c568831SAndroid Build Coastguard Worker */
10131*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr > errNr)
10132*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPopErrors(ctxt, errNr);
10133*7c568831SAndroid Build Coastguard Worker #endif
10134*7c568831SAndroid Build Coastguard Worker ret = 0;
10135*7c568831SAndroid Build Coastguard Worker break;
10136*7c568831SAndroid Build Coastguard Worker }
10137*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_CHOICE:{
10138*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr list = NULL;
10139*7c568831SAndroid Build Coastguard Worker xmlRelaxNGStatesPtr states = NULL;
10140*7c568831SAndroid Build Coastguard Worker
10141*7c568831SAndroid Build Coastguard Worker node = xmlRelaxNGSkipIgnored(ctxt, node);
10142*7c568831SAndroid Build Coastguard Worker
10143*7c568831SAndroid Build Coastguard Worker errNr = ctxt->errNr;
10144*7c568831SAndroid Build Coastguard Worker if ((define->dflags & IS_TRIABLE) && (define->data != NULL) &&
10145*7c568831SAndroid Build Coastguard Worker (node != NULL)) {
10146*7c568831SAndroid Build Coastguard Worker /*
10147*7c568831SAndroid Build Coastguard Worker * node == NULL can't be optimized since IS_TRIABLE
10148*7c568831SAndroid Build Coastguard Worker * doesn't account for choice which may lead to
10149*7c568831SAndroid Build Coastguard Worker * only attributes.
10150*7c568831SAndroid Build Coastguard Worker */
10151*7c568831SAndroid Build Coastguard Worker xmlHashTablePtr triage =
10152*7c568831SAndroid Build Coastguard Worker (xmlHashTablePtr) define->data;
10153*7c568831SAndroid Build Coastguard Worker
10154*7c568831SAndroid Build Coastguard Worker /*
10155*7c568831SAndroid Build Coastguard Worker * Something we can optimize cleanly there is only one
10156*7c568831SAndroid Build Coastguard Worker * possible branch out !
10157*7c568831SAndroid Build Coastguard Worker */
10158*7c568831SAndroid Build Coastguard Worker if ((node->type == XML_TEXT_NODE) ||
10159*7c568831SAndroid Build Coastguard Worker (node->type == XML_CDATA_SECTION_NODE)) {
10160*7c568831SAndroid Build Coastguard Worker list =
10161*7c568831SAndroid Build Coastguard Worker xmlHashLookup2(triage, BAD_CAST "#text", NULL);
10162*7c568831SAndroid Build Coastguard Worker } else if (node->type == XML_ELEMENT_NODE) {
10163*7c568831SAndroid Build Coastguard Worker if (node->ns != NULL) {
10164*7c568831SAndroid Build Coastguard Worker list = xmlHashLookup2(triage, node->name,
10165*7c568831SAndroid Build Coastguard Worker node->ns->href);
10166*7c568831SAndroid Build Coastguard Worker if (list == NULL)
10167*7c568831SAndroid Build Coastguard Worker list =
10168*7c568831SAndroid Build Coastguard Worker xmlHashLookup2(triage, BAD_CAST "#any",
10169*7c568831SAndroid Build Coastguard Worker node->ns->href);
10170*7c568831SAndroid Build Coastguard Worker } else
10171*7c568831SAndroid Build Coastguard Worker list =
10172*7c568831SAndroid Build Coastguard Worker xmlHashLookup2(triage, node->name, NULL);
10173*7c568831SAndroid Build Coastguard Worker if (list == NULL)
10174*7c568831SAndroid Build Coastguard Worker list =
10175*7c568831SAndroid Build Coastguard Worker xmlHashLookup2(triage, BAD_CAST "#any",
10176*7c568831SAndroid Build Coastguard Worker NULL);
10177*7c568831SAndroid Build Coastguard Worker }
10178*7c568831SAndroid Build Coastguard Worker if (list == NULL) {
10179*7c568831SAndroid Build Coastguard Worker ret = -1;
10180*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_ELEMWRONG, node->name);
10181*7c568831SAndroid Build Coastguard Worker break;
10182*7c568831SAndroid Build Coastguard Worker }
10183*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateDefinition(ctxt, list);
10184*7c568831SAndroid Build Coastguard Worker if (ret == 0) {
10185*7c568831SAndroid Build Coastguard Worker }
10186*7c568831SAndroid Build Coastguard Worker break;
10187*7c568831SAndroid Build Coastguard Worker }
10188*7c568831SAndroid Build Coastguard Worker
10189*7c568831SAndroid Build Coastguard Worker list = define->content;
10190*7c568831SAndroid Build Coastguard Worker oldflags = ctxt->flags;
10191*7c568831SAndroid Build Coastguard Worker ctxt->flags |= FLAGS_IGNORABLE;
10192*7c568831SAndroid Build Coastguard Worker
10193*7c568831SAndroid Build Coastguard Worker while (list != NULL) {
10194*7c568831SAndroid Build Coastguard Worker oldstate = xmlRelaxNGCopyValidState(ctxt, ctxt->state);
10195*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateDefinition(ctxt, list);
10196*7c568831SAndroid Build Coastguard Worker if (ret == 0) {
10197*7c568831SAndroid Build Coastguard Worker if (states == NULL) {
10198*7c568831SAndroid Build Coastguard Worker states = xmlRelaxNGNewStates(ctxt, 1);
10199*7c568831SAndroid Build Coastguard Worker }
10200*7c568831SAndroid Build Coastguard Worker if (ctxt->state != NULL) {
10201*7c568831SAndroid Build Coastguard Worker xmlRelaxNGAddStates(ctxt, states, ctxt->state);
10202*7c568831SAndroid Build Coastguard Worker } else if (ctxt->states != NULL) {
10203*7c568831SAndroid Build Coastguard Worker for (i = 0; i < ctxt->states->nbState; i++) {
10204*7c568831SAndroid Build Coastguard Worker xmlRelaxNGAddStates(ctxt, states,
10205*7c568831SAndroid Build Coastguard Worker ctxt->states->
10206*7c568831SAndroid Build Coastguard Worker tabState[i]);
10207*7c568831SAndroid Build Coastguard Worker }
10208*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(ctxt, ctxt->states);
10209*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
10210*7c568831SAndroid Build Coastguard Worker }
10211*7c568831SAndroid Build Coastguard Worker } else {
10212*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, ctxt->state);
10213*7c568831SAndroid Build Coastguard Worker }
10214*7c568831SAndroid Build Coastguard Worker ctxt->state = oldstate;
10215*7c568831SAndroid Build Coastguard Worker list = list->next;
10216*7c568831SAndroid Build Coastguard Worker }
10217*7c568831SAndroid Build Coastguard Worker if (states != NULL) {
10218*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, oldstate);
10219*7c568831SAndroid Build Coastguard Worker ctxt->states = states;
10220*7c568831SAndroid Build Coastguard Worker ctxt->state = NULL;
10221*7c568831SAndroid Build Coastguard Worker ret = 0;
10222*7c568831SAndroid Build Coastguard Worker } else {
10223*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
10224*7c568831SAndroid Build Coastguard Worker }
10225*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
10226*7c568831SAndroid Build Coastguard Worker if (ret != 0) {
10227*7c568831SAndroid Build Coastguard Worker if ((ctxt->flags & FLAGS_IGNORABLE) == 0) {
10228*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpValidError(ctxt);
10229*7c568831SAndroid Build Coastguard Worker }
10230*7c568831SAndroid Build Coastguard Worker } else {
10231*7c568831SAndroid Build Coastguard Worker if (ctxt->errNr > errNr)
10232*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPopErrors(ctxt, errNr);
10233*7c568831SAndroid Build Coastguard Worker }
10234*7c568831SAndroid Build Coastguard Worker break;
10235*7c568831SAndroid Build Coastguard Worker }
10236*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DEF:
10237*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_GROUP:
10238*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateDefinitionList(ctxt, define->content);
10239*7c568831SAndroid Build Coastguard Worker break;
10240*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_INTERLEAVE:
10241*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateInterleave(ctxt, define);
10242*7c568831SAndroid Build Coastguard Worker break;
10243*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_ATTRIBUTE:
10244*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateAttribute(ctxt, define);
10245*7c568831SAndroid Build Coastguard Worker break;
10246*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_START:
10247*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_NOOP:
10248*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_REF:
10249*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXTERNALREF:
10250*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARENTREF:
10251*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateDefinition(ctxt, define->content);
10252*7c568831SAndroid Build Coastguard Worker break;
10253*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_DATATYPE:{
10254*7c568831SAndroid Build Coastguard Worker xmlNodePtr child;
10255*7c568831SAndroid Build Coastguard Worker xmlChar *content = NULL;
10256*7c568831SAndroid Build Coastguard Worker
10257*7c568831SAndroid Build Coastguard Worker child = node;
10258*7c568831SAndroid Build Coastguard Worker while (child != NULL) {
10259*7c568831SAndroid Build Coastguard Worker if (child->type == XML_ELEMENT_NODE) {
10260*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_DATAELEM,
10261*7c568831SAndroid Build Coastguard Worker node->parent->name);
10262*7c568831SAndroid Build Coastguard Worker ret = -1;
10263*7c568831SAndroid Build Coastguard Worker break;
10264*7c568831SAndroid Build Coastguard Worker } else if ((child->type == XML_TEXT_NODE) ||
10265*7c568831SAndroid Build Coastguard Worker (child->type == XML_CDATA_SECTION_NODE)) {
10266*7c568831SAndroid Build Coastguard Worker content = xmlStrcat(content, child->content);
10267*7c568831SAndroid Build Coastguard Worker }
10268*7c568831SAndroid Build Coastguard Worker /* TODO: handle entities ... */
10269*7c568831SAndroid Build Coastguard Worker child = child->next;
10270*7c568831SAndroid Build Coastguard Worker }
10271*7c568831SAndroid Build Coastguard Worker if (ret == -1) {
10272*7c568831SAndroid Build Coastguard Worker if (content != NULL)
10273*7c568831SAndroid Build Coastguard Worker xmlFree(content);
10274*7c568831SAndroid Build Coastguard Worker break;
10275*7c568831SAndroid Build Coastguard Worker }
10276*7c568831SAndroid Build Coastguard Worker if (content == NULL) {
10277*7c568831SAndroid Build Coastguard Worker content = xmlStrdup(BAD_CAST "");
10278*7c568831SAndroid Build Coastguard Worker if (content == NULL) {
10279*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
10280*7c568831SAndroid Build Coastguard Worker ret = -1;
10281*7c568831SAndroid Build Coastguard Worker break;
10282*7c568831SAndroid Build Coastguard Worker }
10283*7c568831SAndroid Build Coastguard Worker }
10284*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateDatatype(ctxt, content, define,
10285*7c568831SAndroid Build Coastguard Worker ctxt->state->seq);
10286*7c568831SAndroid Build Coastguard Worker if (ret == -1) {
10287*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_DATATYPE, define->name);
10288*7c568831SAndroid Build Coastguard Worker } else if (ret == 0) {
10289*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = NULL;
10290*7c568831SAndroid Build Coastguard Worker }
10291*7c568831SAndroid Build Coastguard Worker if (content != NULL)
10292*7c568831SAndroid Build Coastguard Worker xmlFree(content);
10293*7c568831SAndroid Build Coastguard Worker break;
10294*7c568831SAndroid Build Coastguard Worker }
10295*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_VALUE:{
10296*7c568831SAndroid Build Coastguard Worker xmlChar *content = NULL;
10297*7c568831SAndroid Build Coastguard Worker xmlChar *oldvalue;
10298*7c568831SAndroid Build Coastguard Worker xmlNodePtr child;
10299*7c568831SAndroid Build Coastguard Worker
10300*7c568831SAndroid Build Coastguard Worker child = node;
10301*7c568831SAndroid Build Coastguard Worker while (child != NULL) {
10302*7c568831SAndroid Build Coastguard Worker if (child->type == XML_ELEMENT_NODE) {
10303*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_VALELEM,
10304*7c568831SAndroid Build Coastguard Worker node->parent->name);
10305*7c568831SAndroid Build Coastguard Worker ret = -1;
10306*7c568831SAndroid Build Coastguard Worker break;
10307*7c568831SAndroid Build Coastguard Worker } else if ((child->type == XML_TEXT_NODE) ||
10308*7c568831SAndroid Build Coastguard Worker (child->type == XML_CDATA_SECTION_NODE)) {
10309*7c568831SAndroid Build Coastguard Worker content = xmlStrcat(content, child->content);
10310*7c568831SAndroid Build Coastguard Worker }
10311*7c568831SAndroid Build Coastguard Worker /* TODO: handle entities ... */
10312*7c568831SAndroid Build Coastguard Worker child = child->next;
10313*7c568831SAndroid Build Coastguard Worker }
10314*7c568831SAndroid Build Coastguard Worker if (ret == -1) {
10315*7c568831SAndroid Build Coastguard Worker if (content != NULL)
10316*7c568831SAndroid Build Coastguard Worker xmlFree(content);
10317*7c568831SAndroid Build Coastguard Worker break;
10318*7c568831SAndroid Build Coastguard Worker }
10319*7c568831SAndroid Build Coastguard Worker if (content == NULL) {
10320*7c568831SAndroid Build Coastguard Worker content = xmlStrdup(BAD_CAST "");
10321*7c568831SAndroid Build Coastguard Worker if (content == NULL) {
10322*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
10323*7c568831SAndroid Build Coastguard Worker ret = -1;
10324*7c568831SAndroid Build Coastguard Worker break;
10325*7c568831SAndroid Build Coastguard Worker }
10326*7c568831SAndroid Build Coastguard Worker }
10327*7c568831SAndroid Build Coastguard Worker oldvalue = ctxt->state->value;
10328*7c568831SAndroid Build Coastguard Worker ctxt->state->value = content;
10329*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateValue(ctxt, define);
10330*7c568831SAndroid Build Coastguard Worker ctxt->state->value = oldvalue;
10331*7c568831SAndroid Build Coastguard Worker if (ret == -1) {
10332*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_VALUE, define->name);
10333*7c568831SAndroid Build Coastguard Worker } else if (ret == 0) {
10334*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = NULL;
10335*7c568831SAndroid Build Coastguard Worker }
10336*7c568831SAndroid Build Coastguard Worker if (content != NULL)
10337*7c568831SAndroid Build Coastguard Worker xmlFree(content);
10338*7c568831SAndroid Build Coastguard Worker break;
10339*7c568831SAndroid Build Coastguard Worker }
10340*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_LIST:{
10341*7c568831SAndroid Build Coastguard Worker xmlChar *content;
10342*7c568831SAndroid Build Coastguard Worker xmlNodePtr child;
10343*7c568831SAndroid Build Coastguard Worker xmlChar *oldvalue, *oldendvalue;
10344*7c568831SAndroid Build Coastguard Worker int len;
10345*7c568831SAndroid Build Coastguard Worker
10346*7c568831SAndroid Build Coastguard Worker /*
10347*7c568831SAndroid Build Coastguard Worker * Make sure it's only text nodes
10348*7c568831SAndroid Build Coastguard Worker */
10349*7c568831SAndroid Build Coastguard Worker
10350*7c568831SAndroid Build Coastguard Worker content = NULL;
10351*7c568831SAndroid Build Coastguard Worker child = node;
10352*7c568831SAndroid Build Coastguard Worker while (child != NULL) {
10353*7c568831SAndroid Build Coastguard Worker if (child->type == XML_ELEMENT_NODE) {
10354*7c568831SAndroid Build Coastguard Worker VALID_ERR2(XML_RELAXNG_ERR_LISTELEM,
10355*7c568831SAndroid Build Coastguard Worker node->parent->name);
10356*7c568831SAndroid Build Coastguard Worker ret = -1;
10357*7c568831SAndroid Build Coastguard Worker break;
10358*7c568831SAndroid Build Coastguard Worker } else if ((child->type == XML_TEXT_NODE) ||
10359*7c568831SAndroid Build Coastguard Worker (child->type == XML_CDATA_SECTION_NODE)) {
10360*7c568831SAndroid Build Coastguard Worker content = xmlStrcat(content, child->content);
10361*7c568831SAndroid Build Coastguard Worker }
10362*7c568831SAndroid Build Coastguard Worker /* TODO: handle entities ... */
10363*7c568831SAndroid Build Coastguard Worker child = child->next;
10364*7c568831SAndroid Build Coastguard Worker }
10365*7c568831SAndroid Build Coastguard Worker if (ret == -1) {
10366*7c568831SAndroid Build Coastguard Worker if (content != NULL)
10367*7c568831SAndroid Build Coastguard Worker xmlFree(content);
10368*7c568831SAndroid Build Coastguard Worker break;
10369*7c568831SAndroid Build Coastguard Worker }
10370*7c568831SAndroid Build Coastguard Worker if (content == NULL) {
10371*7c568831SAndroid Build Coastguard Worker content = xmlStrdup(BAD_CAST "");
10372*7c568831SAndroid Build Coastguard Worker if (content == NULL) {
10373*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(ctxt);
10374*7c568831SAndroid Build Coastguard Worker ret = -1;
10375*7c568831SAndroid Build Coastguard Worker break;
10376*7c568831SAndroid Build Coastguard Worker }
10377*7c568831SAndroid Build Coastguard Worker }
10378*7c568831SAndroid Build Coastguard Worker len = xmlStrlen(content);
10379*7c568831SAndroid Build Coastguard Worker oldvalue = ctxt->state->value;
10380*7c568831SAndroid Build Coastguard Worker oldendvalue = ctxt->state->endvalue;
10381*7c568831SAndroid Build Coastguard Worker ctxt->state->value = content;
10382*7c568831SAndroid Build Coastguard Worker ctxt->state->endvalue = content + len;
10383*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateValue(ctxt, define);
10384*7c568831SAndroid Build Coastguard Worker ctxt->state->value = oldvalue;
10385*7c568831SAndroid Build Coastguard Worker ctxt->state->endvalue = oldendvalue;
10386*7c568831SAndroid Build Coastguard Worker if (ret == -1) {
10387*7c568831SAndroid Build Coastguard Worker VALID_ERR(XML_RELAXNG_ERR_LIST);
10388*7c568831SAndroid Build Coastguard Worker } else if ((ret == 0) && (node != NULL)) {
10389*7c568831SAndroid Build Coastguard Worker ctxt->state->seq = node->next;
10390*7c568831SAndroid Build Coastguard Worker }
10391*7c568831SAndroid Build Coastguard Worker if (content != NULL)
10392*7c568831SAndroid Build Coastguard Worker xmlFree(content);
10393*7c568831SAndroid Build Coastguard Worker break;
10394*7c568831SAndroid Build Coastguard Worker }
10395*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_EXCEPT:
10396*7c568831SAndroid Build Coastguard Worker case XML_RELAXNG_PARAM:
10397*7c568831SAndroid Build Coastguard Worker /* TODO */
10398*7c568831SAndroid Build Coastguard Worker ret = -1;
10399*7c568831SAndroid Build Coastguard Worker break;
10400*7c568831SAndroid Build Coastguard Worker }
10401*7c568831SAndroid Build Coastguard Worker ctxt->depth--;
10402*7c568831SAndroid Build Coastguard Worker return (ret);
10403*7c568831SAndroid Build Coastguard Worker }
10404*7c568831SAndroid Build Coastguard Worker
10405*7c568831SAndroid Build Coastguard Worker /**
10406*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidateDefinition:
10407*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
10408*7c568831SAndroid Build Coastguard Worker * @define: the definition to verify
10409*7c568831SAndroid Build Coastguard Worker *
10410*7c568831SAndroid Build Coastguard Worker * Validate the current node lists against the definition
10411*7c568831SAndroid Build Coastguard Worker *
10412*7c568831SAndroid Build Coastguard Worker * Returns 0 if the validation succeeded or an error code.
10413*7c568831SAndroid Build Coastguard Worker */
10414*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGDefinePtr define)10415*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,
10416*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDefinePtr define)
10417*7c568831SAndroid Build Coastguard Worker {
10418*7c568831SAndroid Build Coastguard Worker xmlRelaxNGStatesPtr states, res;
10419*7c568831SAndroid Build Coastguard Worker int i, j, k, ret, oldflags;
10420*7c568831SAndroid Build Coastguard Worker
10421*7c568831SAndroid Build Coastguard Worker /*
10422*7c568831SAndroid Build Coastguard Worker * We should NOT have both ctxt->state and ctxt->states
10423*7c568831SAndroid Build Coastguard Worker */
10424*7c568831SAndroid Build Coastguard Worker if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
10425*7c568831SAndroid Build Coastguard Worker /* TODO */
10426*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, ctxt->state);
10427*7c568831SAndroid Build Coastguard Worker ctxt->state = NULL;
10428*7c568831SAndroid Build Coastguard Worker }
10429*7c568831SAndroid Build Coastguard Worker
10430*7c568831SAndroid Build Coastguard Worker if ((ctxt->states == NULL) || (ctxt->states->nbState == 1)) {
10431*7c568831SAndroid Build Coastguard Worker if (ctxt->states != NULL) {
10432*7c568831SAndroid Build Coastguard Worker ctxt->state = ctxt->states->tabState[0];
10433*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(ctxt, ctxt->states);
10434*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
10435*7c568831SAndroid Build Coastguard Worker }
10436*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateState(ctxt, define);
10437*7c568831SAndroid Build Coastguard Worker if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
10438*7c568831SAndroid Build Coastguard Worker /* TODO */
10439*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, ctxt->state);
10440*7c568831SAndroid Build Coastguard Worker ctxt->state = NULL;
10441*7c568831SAndroid Build Coastguard Worker }
10442*7c568831SAndroid Build Coastguard Worker if ((ctxt->states != NULL) && (ctxt->states->nbState == 1)) {
10443*7c568831SAndroid Build Coastguard Worker ctxt->state = ctxt->states->tabState[0];
10444*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(ctxt, ctxt->states);
10445*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
10446*7c568831SAndroid Build Coastguard Worker }
10447*7c568831SAndroid Build Coastguard Worker return (ret);
10448*7c568831SAndroid Build Coastguard Worker }
10449*7c568831SAndroid Build Coastguard Worker
10450*7c568831SAndroid Build Coastguard Worker states = ctxt->states;
10451*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
10452*7c568831SAndroid Build Coastguard Worker res = NULL;
10453*7c568831SAndroid Build Coastguard Worker j = 0;
10454*7c568831SAndroid Build Coastguard Worker oldflags = ctxt->flags;
10455*7c568831SAndroid Build Coastguard Worker ctxt->flags |= FLAGS_IGNORABLE;
10456*7c568831SAndroid Build Coastguard Worker for (i = 0; i < states->nbState; i++) {
10457*7c568831SAndroid Build Coastguard Worker ctxt->state = states->tabState[i];
10458*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
10459*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateState(ctxt, define);
10460*7c568831SAndroid Build Coastguard Worker /*
10461*7c568831SAndroid Build Coastguard Worker * We should NOT have both ctxt->state and ctxt->states
10462*7c568831SAndroid Build Coastguard Worker */
10463*7c568831SAndroid Build Coastguard Worker if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
10464*7c568831SAndroid Build Coastguard Worker /* TODO */
10465*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, ctxt->state);
10466*7c568831SAndroid Build Coastguard Worker ctxt->state = NULL;
10467*7c568831SAndroid Build Coastguard Worker }
10468*7c568831SAndroid Build Coastguard Worker if (ret == 0) {
10469*7c568831SAndroid Build Coastguard Worker if (ctxt->states == NULL) {
10470*7c568831SAndroid Build Coastguard Worker if (res != NULL) {
10471*7c568831SAndroid Build Coastguard Worker /* add the state to the container */
10472*7c568831SAndroid Build Coastguard Worker xmlRelaxNGAddStates(ctxt, res, ctxt->state);
10473*7c568831SAndroid Build Coastguard Worker ctxt->state = NULL;
10474*7c568831SAndroid Build Coastguard Worker } else {
10475*7c568831SAndroid Build Coastguard Worker /* add the state directly in states */
10476*7c568831SAndroid Build Coastguard Worker states->tabState[j++] = ctxt->state;
10477*7c568831SAndroid Build Coastguard Worker ctxt->state = NULL;
10478*7c568831SAndroid Build Coastguard Worker }
10479*7c568831SAndroid Build Coastguard Worker } else {
10480*7c568831SAndroid Build Coastguard Worker if (res == NULL) {
10481*7c568831SAndroid Build Coastguard Worker /* make it the new container and copy other results */
10482*7c568831SAndroid Build Coastguard Worker res = ctxt->states;
10483*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
10484*7c568831SAndroid Build Coastguard Worker for (k = 0; k < j; k++)
10485*7c568831SAndroid Build Coastguard Worker xmlRelaxNGAddStates(ctxt, res,
10486*7c568831SAndroid Build Coastguard Worker states->tabState[k]);
10487*7c568831SAndroid Build Coastguard Worker } else {
10488*7c568831SAndroid Build Coastguard Worker /* add all the new results to res and reff the container */
10489*7c568831SAndroid Build Coastguard Worker for (k = 0; k < ctxt->states->nbState; k++)
10490*7c568831SAndroid Build Coastguard Worker xmlRelaxNGAddStates(ctxt, res,
10491*7c568831SAndroid Build Coastguard Worker ctxt->states->tabState[k]);
10492*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(ctxt, ctxt->states);
10493*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
10494*7c568831SAndroid Build Coastguard Worker }
10495*7c568831SAndroid Build Coastguard Worker }
10496*7c568831SAndroid Build Coastguard Worker } else {
10497*7c568831SAndroid Build Coastguard Worker if (ctxt->state != NULL) {
10498*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, ctxt->state);
10499*7c568831SAndroid Build Coastguard Worker ctxt->state = NULL;
10500*7c568831SAndroid Build Coastguard Worker } else if (ctxt->states != NULL) {
10501*7c568831SAndroid Build Coastguard Worker for (k = 0; k < ctxt->states->nbState; k++)
10502*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt,
10503*7c568831SAndroid Build Coastguard Worker ctxt->states->tabState[k]);
10504*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(ctxt, ctxt->states);
10505*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
10506*7c568831SAndroid Build Coastguard Worker }
10507*7c568831SAndroid Build Coastguard Worker }
10508*7c568831SAndroid Build Coastguard Worker }
10509*7c568831SAndroid Build Coastguard Worker ctxt->flags = oldflags;
10510*7c568831SAndroid Build Coastguard Worker if (res != NULL) {
10511*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(ctxt, states);
10512*7c568831SAndroid Build Coastguard Worker ctxt->states = res;
10513*7c568831SAndroid Build Coastguard Worker ret = 0;
10514*7c568831SAndroid Build Coastguard Worker } else if (j > 1) {
10515*7c568831SAndroid Build Coastguard Worker states->nbState = j;
10516*7c568831SAndroid Build Coastguard Worker ctxt->states = states;
10517*7c568831SAndroid Build Coastguard Worker ret = 0;
10518*7c568831SAndroid Build Coastguard Worker } else if (j == 1) {
10519*7c568831SAndroid Build Coastguard Worker ctxt->state = states->tabState[0];
10520*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(ctxt, states);
10521*7c568831SAndroid Build Coastguard Worker ret = 0;
10522*7c568831SAndroid Build Coastguard Worker } else {
10523*7c568831SAndroid Build Coastguard Worker ret = -1;
10524*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(ctxt, states);
10525*7c568831SAndroid Build Coastguard Worker if (ctxt->states != NULL) {
10526*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(ctxt, ctxt->states);
10527*7c568831SAndroid Build Coastguard Worker ctxt->states = NULL;
10528*7c568831SAndroid Build Coastguard Worker }
10529*7c568831SAndroid Build Coastguard Worker }
10530*7c568831SAndroid Build Coastguard Worker if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
10531*7c568831SAndroid Build Coastguard Worker /* TODO */
10532*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, ctxt->state);
10533*7c568831SAndroid Build Coastguard Worker ctxt->state = NULL;
10534*7c568831SAndroid Build Coastguard Worker }
10535*7c568831SAndroid Build Coastguard Worker return (ret);
10536*7c568831SAndroid Build Coastguard Worker }
10537*7c568831SAndroid Build Coastguard Worker
10538*7c568831SAndroid Build Coastguard Worker /**
10539*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidateDocument:
10540*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
10541*7c568831SAndroid Build Coastguard Worker * @doc: the document
10542*7c568831SAndroid Build Coastguard Worker *
10543*7c568831SAndroid Build Coastguard Worker * Validate the given document
10544*7c568831SAndroid Build Coastguard Worker *
10545*7c568831SAndroid Build Coastguard Worker * Returns 0 if the validation succeeded or an error code.
10546*7c568831SAndroid Build Coastguard Worker */
10547*7c568831SAndroid Build Coastguard Worker static int
xmlRelaxNGValidateDocument(xmlRelaxNGValidCtxtPtr ctxt,xmlDocPtr doc)10548*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateDocument(xmlRelaxNGValidCtxtPtr ctxt, xmlDocPtr doc)
10549*7c568831SAndroid Build Coastguard Worker {
10550*7c568831SAndroid Build Coastguard Worker int ret;
10551*7c568831SAndroid Build Coastguard Worker xmlRelaxNGPtr schema;
10552*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGrammarPtr grammar;
10553*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidStatePtr state;
10554*7c568831SAndroid Build Coastguard Worker xmlNodePtr node;
10555*7c568831SAndroid Build Coastguard Worker
10556*7c568831SAndroid Build Coastguard Worker if ((ctxt == NULL) || (ctxt->schema == NULL) || (doc == NULL))
10557*7c568831SAndroid Build Coastguard Worker return (-1);
10558*7c568831SAndroid Build Coastguard Worker
10559*7c568831SAndroid Build Coastguard Worker ctxt->errNo = XML_RELAXNG_OK;
10560*7c568831SAndroid Build Coastguard Worker schema = ctxt->schema;
10561*7c568831SAndroid Build Coastguard Worker grammar = schema->topgrammar;
10562*7c568831SAndroid Build Coastguard Worker if (grammar == NULL) {
10563*7c568831SAndroid Build Coastguard Worker VALID_ERR(XML_RELAXNG_ERR_NOGRAMMAR);
10564*7c568831SAndroid Build Coastguard Worker return (-1);
10565*7c568831SAndroid Build Coastguard Worker }
10566*7c568831SAndroid Build Coastguard Worker state = xmlRelaxNGNewValidState(ctxt, NULL);
10567*7c568831SAndroid Build Coastguard Worker ctxt->state = state;
10568*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateDefinition(ctxt, grammar->start);
10569*7c568831SAndroid Build Coastguard Worker if ((ctxt->state != NULL) && (state->seq != NULL)) {
10570*7c568831SAndroid Build Coastguard Worker state = ctxt->state;
10571*7c568831SAndroid Build Coastguard Worker node = state->seq;
10572*7c568831SAndroid Build Coastguard Worker node = xmlRelaxNGSkipIgnored(ctxt, node);
10573*7c568831SAndroid Build Coastguard Worker if (node != NULL) {
10574*7c568831SAndroid Build Coastguard Worker if (ret != -1) {
10575*7c568831SAndroid Build Coastguard Worker VALID_ERR(XML_RELAXNG_ERR_EXTRADATA);
10576*7c568831SAndroid Build Coastguard Worker ret = -1;
10577*7c568831SAndroid Build Coastguard Worker }
10578*7c568831SAndroid Build Coastguard Worker }
10579*7c568831SAndroid Build Coastguard Worker } else if (ctxt->states != NULL) {
10580*7c568831SAndroid Build Coastguard Worker int i;
10581*7c568831SAndroid Build Coastguard Worker int tmp = -1;
10582*7c568831SAndroid Build Coastguard Worker
10583*7c568831SAndroid Build Coastguard Worker for (i = 0; i < ctxt->states->nbState; i++) {
10584*7c568831SAndroid Build Coastguard Worker state = ctxt->states->tabState[i];
10585*7c568831SAndroid Build Coastguard Worker node = state->seq;
10586*7c568831SAndroid Build Coastguard Worker node = xmlRelaxNGSkipIgnored(ctxt, node);
10587*7c568831SAndroid Build Coastguard Worker if (node == NULL)
10588*7c568831SAndroid Build Coastguard Worker tmp = 0;
10589*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, state);
10590*7c568831SAndroid Build Coastguard Worker }
10591*7c568831SAndroid Build Coastguard Worker if (tmp == -1) {
10592*7c568831SAndroid Build Coastguard Worker if (ret != -1) {
10593*7c568831SAndroid Build Coastguard Worker VALID_ERR(XML_RELAXNG_ERR_EXTRADATA);
10594*7c568831SAndroid Build Coastguard Worker ret = -1;
10595*7c568831SAndroid Build Coastguard Worker }
10596*7c568831SAndroid Build Coastguard Worker }
10597*7c568831SAndroid Build Coastguard Worker }
10598*7c568831SAndroid Build Coastguard Worker if (ctxt->state != NULL) {
10599*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(ctxt, ctxt->state);
10600*7c568831SAndroid Build Coastguard Worker ctxt->state = NULL;
10601*7c568831SAndroid Build Coastguard Worker }
10602*7c568831SAndroid Build Coastguard Worker if (ret != 0)
10603*7c568831SAndroid Build Coastguard Worker xmlRelaxNGDumpValidError(ctxt);
10604*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_VALID_ENABLED
10605*7c568831SAndroid Build Coastguard Worker if (ctxt->idref == 1) {
10606*7c568831SAndroid Build Coastguard Worker xmlValidCtxt vctxt;
10607*7c568831SAndroid Build Coastguard Worker
10608*7c568831SAndroid Build Coastguard Worker memset(&vctxt, 0, sizeof(xmlValidCtxt));
10609*7c568831SAndroid Build Coastguard Worker vctxt.valid = 1;
10610*7c568831SAndroid Build Coastguard Worker
10611*7c568831SAndroid Build Coastguard Worker if (ctxt->error == NULL) {
10612*7c568831SAndroid Build Coastguard Worker vctxt.error = xmlGenericError;
10613*7c568831SAndroid Build Coastguard Worker vctxt.warning = xmlGenericError;
10614*7c568831SAndroid Build Coastguard Worker vctxt.userData = xmlGenericErrorContext;
10615*7c568831SAndroid Build Coastguard Worker } else {
10616*7c568831SAndroid Build Coastguard Worker vctxt.error = ctxt->error;
10617*7c568831SAndroid Build Coastguard Worker vctxt.warning = ctxt->warning;
10618*7c568831SAndroid Build Coastguard Worker vctxt.userData = ctxt->userData;
10619*7c568831SAndroid Build Coastguard Worker }
10620*7c568831SAndroid Build Coastguard Worker
10621*7c568831SAndroid Build Coastguard Worker if (xmlValidateDocumentFinal(&vctxt, doc) != 1)
10622*7c568831SAndroid Build Coastguard Worker ret = -1;
10623*7c568831SAndroid Build Coastguard Worker }
10624*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_VALID_ENABLED */
10625*7c568831SAndroid Build Coastguard Worker if ((ret == 0) && (ctxt->errNo != XML_RELAXNG_OK))
10626*7c568831SAndroid Build Coastguard Worker ret = -1;
10627*7c568831SAndroid Build Coastguard Worker
10628*7c568831SAndroid Build Coastguard Worker return (ret);
10629*7c568831SAndroid Build Coastguard Worker }
10630*7c568831SAndroid Build Coastguard Worker
10631*7c568831SAndroid Build Coastguard Worker /**
10632*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGCleanPSVI:
10633*7c568831SAndroid Build Coastguard Worker * @node: an input element or document
10634*7c568831SAndroid Build Coastguard Worker *
10635*7c568831SAndroid Build Coastguard Worker * Call this routine to speed up XPath computation on static documents.
10636*7c568831SAndroid Build Coastguard Worker * This stamps all the element nodes with the document order
10637*7c568831SAndroid Build Coastguard Worker * Like for line information, the order is kept in the element->content
10638*7c568831SAndroid Build Coastguard Worker * field, the value stored is actually - the node number (starting at -1)
10639*7c568831SAndroid Build Coastguard Worker * to be able to differentiate from line numbers.
10640*7c568831SAndroid Build Coastguard Worker *
10641*7c568831SAndroid Build Coastguard Worker * Returns the number of elements found in the document or -1 in case
10642*7c568831SAndroid Build Coastguard Worker * of error.
10643*7c568831SAndroid Build Coastguard Worker */
10644*7c568831SAndroid Build Coastguard Worker static void
xmlRelaxNGCleanPSVI(xmlNodePtr node)10645*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCleanPSVI(xmlNodePtr node) {
10646*7c568831SAndroid Build Coastguard Worker xmlNodePtr cur;
10647*7c568831SAndroid Build Coastguard Worker
10648*7c568831SAndroid Build Coastguard Worker if ((node == NULL) ||
10649*7c568831SAndroid Build Coastguard Worker ((node->type != XML_ELEMENT_NODE) &&
10650*7c568831SAndroid Build Coastguard Worker (node->type != XML_DOCUMENT_NODE) &&
10651*7c568831SAndroid Build Coastguard Worker (node->type != XML_HTML_DOCUMENT_NODE)))
10652*7c568831SAndroid Build Coastguard Worker return;
10653*7c568831SAndroid Build Coastguard Worker if (node->type == XML_ELEMENT_NODE)
10654*7c568831SAndroid Build Coastguard Worker node->psvi = NULL;
10655*7c568831SAndroid Build Coastguard Worker
10656*7c568831SAndroid Build Coastguard Worker cur = node->children;
10657*7c568831SAndroid Build Coastguard Worker while (cur != NULL) {
10658*7c568831SAndroid Build Coastguard Worker if (cur->type == XML_ELEMENT_NODE) {
10659*7c568831SAndroid Build Coastguard Worker cur->psvi = NULL;
10660*7c568831SAndroid Build Coastguard Worker if (cur->children != NULL) {
10661*7c568831SAndroid Build Coastguard Worker cur = cur->children;
10662*7c568831SAndroid Build Coastguard Worker continue;
10663*7c568831SAndroid Build Coastguard Worker }
10664*7c568831SAndroid Build Coastguard Worker }
10665*7c568831SAndroid Build Coastguard Worker if (cur->next != NULL) {
10666*7c568831SAndroid Build Coastguard Worker cur = cur->next;
10667*7c568831SAndroid Build Coastguard Worker continue;
10668*7c568831SAndroid Build Coastguard Worker }
10669*7c568831SAndroid Build Coastguard Worker do {
10670*7c568831SAndroid Build Coastguard Worker cur = cur->parent;
10671*7c568831SAndroid Build Coastguard Worker if (cur == NULL)
10672*7c568831SAndroid Build Coastguard Worker break;
10673*7c568831SAndroid Build Coastguard Worker if (cur == node) {
10674*7c568831SAndroid Build Coastguard Worker cur = NULL;
10675*7c568831SAndroid Build Coastguard Worker break;
10676*7c568831SAndroid Build Coastguard Worker }
10677*7c568831SAndroid Build Coastguard Worker if (cur->next != NULL) {
10678*7c568831SAndroid Build Coastguard Worker cur = cur->next;
10679*7c568831SAndroid Build Coastguard Worker break;
10680*7c568831SAndroid Build Coastguard Worker }
10681*7c568831SAndroid Build Coastguard Worker } while (cur != NULL);
10682*7c568831SAndroid Build Coastguard Worker }
10683*7c568831SAndroid Build Coastguard Worker }
10684*7c568831SAndroid Build Coastguard Worker /************************************************************************
10685*7c568831SAndroid Build Coastguard Worker * *
10686*7c568831SAndroid Build Coastguard Worker * Validation interfaces *
10687*7c568831SAndroid Build Coastguard Worker * *
10688*7c568831SAndroid Build Coastguard Worker ************************************************************************/
10689*7c568831SAndroid Build Coastguard Worker
10690*7c568831SAndroid Build Coastguard Worker /**
10691*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGNewValidCtxt:
10692*7c568831SAndroid Build Coastguard Worker * @schema: a precompiled XML RelaxNGs
10693*7c568831SAndroid Build Coastguard Worker *
10694*7c568831SAndroid Build Coastguard Worker * Create an XML RelaxNGs validation context based on the given schema
10695*7c568831SAndroid Build Coastguard Worker *
10696*7c568831SAndroid Build Coastguard Worker * Returns the validation context or NULL in case of error
10697*7c568831SAndroid Build Coastguard Worker */
10698*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidCtxtPtr
xmlRelaxNGNewValidCtxt(xmlRelaxNGPtr schema)10699*7c568831SAndroid Build Coastguard Worker xmlRelaxNGNewValidCtxt(xmlRelaxNGPtr schema)
10700*7c568831SAndroid Build Coastguard Worker {
10701*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidCtxtPtr ret;
10702*7c568831SAndroid Build Coastguard Worker
10703*7c568831SAndroid Build Coastguard Worker ret = (xmlRelaxNGValidCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGValidCtxt));
10704*7c568831SAndroid Build Coastguard Worker if (ret == NULL) {
10705*7c568831SAndroid Build Coastguard Worker xmlRngVErrMemory(NULL);
10706*7c568831SAndroid Build Coastguard Worker return (NULL);
10707*7c568831SAndroid Build Coastguard Worker }
10708*7c568831SAndroid Build Coastguard Worker memset(ret, 0, sizeof(xmlRelaxNGValidCtxt));
10709*7c568831SAndroid Build Coastguard Worker ret->schema = schema;
10710*7c568831SAndroid Build Coastguard Worker ret->errNr = 0;
10711*7c568831SAndroid Build Coastguard Worker ret->errMax = 0;
10712*7c568831SAndroid Build Coastguard Worker ret->err = NULL;
10713*7c568831SAndroid Build Coastguard Worker ret->errTab = NULL;
10714*7c568831SAndroid Build Coastguard Worker if (schema != NULL)
10715*7c568831SAndroid Build Coastguard Worker ret->idref = schema->idref;
10716*7c568831SAndroid Build Coastguard Worker ret->states = NULL;
10717*7c568831SAndroid Build Coastguard Worker ret->freeState = NULL;
10718*7c568831SAndroid Build Coastguard Worker ret->freeStates = NULL;
10719*7c568831SAndroid Build Coastguard Worker ret->errNo = XML_RELAXNG_OK;
10720*7c568831SAndroid Build Coastguard Worker return (ret);
10721*7c568831SAndroid Build Coastguard Worker }
10722*7c568831SAndroid Build Coastguard Worker
10723*7c568831SAndroid Build Coastguard Worker /**
10724*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGFreeValidCtxt:
10725*7c568831SAndroid Build Coastguard Worker * @ctxt: the schema validation context
10726*7c568831SAndroid Build Coastguard Worker *
10727*7c568831SAndroid Build Coastguard Worker * Free the resources associated to the schema validation context
10728*7c568831SAndroid Build Coastguard Worker */
10729*7c568831SAndroid Build Coastguard Worker void
xmlRelaxNGFreeValidCtxt(xmlRelaxNGValidCtxtPtr ctxt)10730*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidCtxt(xmlRelaxNGValidCtxtPtr ctxt)
10731*7c568831SAndroid Build Coastguard Worker {
10732*7c568831SAndroid Build Coastguard Worker int k;
10733*7c568831SAndroid Build Coastguard Worker
10734*7c568831SAndroid Build Coastguard Worker if (ctxt == NULL)
10735*7c568831SAndroid Build Coastguard Worker return;
10736*7c568831SAndroid Build Coastguard Worker if (ctxt->states != NULL)
10737*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(NULL, ctxt->states);
10738*7c568831SAndroid Build Coastguard Worker if (ctxt->freeState != NULL) {
10739*7c568831SAndroid Build Coastguard Worker for (k = 0; k < ctxt->freeState->nbState; k++) {
10740*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeValidState(NULL, ctxt->freeState->tabState[k]);
10741*7c568831SAndroid Build Coastguard Worker }
10742*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(NULL, ctxt->freeState);
10743*7c568831SAndroid Build Coastguard Worker }
10744*7c568831SAndroid Build Coastguard Worker if (ctxt->freeStates != NULL) {
10745*7c568831SAndroid Build Coastguard Worker for (k = 0; k < ctxt->freeStatesNr; k++) {
10746*7c568831SAndroid Build Coastguard Worker xmlRelaxNGFreeStates(NULL, ctxt->freeStates[k]);
10747*7c568831SAndroid Build Coastguard Worker }
10748*7c568831SAndroid Build Coastguard Worker xmlFree(ctxt->freeStates);
10749*7c568831SAndroid Build Coastguard Worker }
10750*7c568831SAndroid Build Coastguard Worker if (ctxt->errTab != NULL)
10751*7c568831SAndroid Build Coastguard Worker xmlFree(ctxt->errTab);
10752*7c568831SAndroid Build Coastguard Worker if (ctxt->elemTab != NULL) {
10753*7c568831SAndroid Build Coastguard Worker xmlRegExecCtxtPtr exec;
10754*7c568831SAndroid Build Coastguard Worker
10755*7c568831SAndroid Build Coastguard Worker exec = xmlRelaxNGElemPop(ctxt);
10756*7c568831SAndroid Build Coastguard Worker while (exec != NULL) {
10757*7c568831SAndroid Build Coastguard Worker xmlRegFreeExecCtxt(exec);
10758*7c568831SAndroid Build Coastguard Worker exec = xmlRelaxNGElemPop(ctxt);
10759*7c568831SAndroid Build Coastguard Worker }
10760*7c568831SAndroid Build Coastguard Worker xmlFree(ctxt->elemTab);
10761*7c568831SAndroid Build Coastguard Worker }
10762*7c568831SAndroid Build Coastguard Worker xmlFree(ctxt);
10763*7c568831SAndroid Build Coastguard Worker }
10764*7c568831SAndroid Build Coastguard Worker
10765*7c568831SAndroid Build Coastguard Worker /**
10766*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGSetValidErrors:
10767*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
10768*7c568831SAndroid Build Coastguard Worker * @err: the error function
10769*7c568831SAndroid Build Coastguard Worker * @warn: the warning function
10770*7c568831SAndroid Build Coastguard Worker * @ctx: the functions context
10771*7c568831SAndroid Build Coastguard Worker *
10772*7c568831SAndroid Build Coastguard Worker * DEPRECATED: Use xmlRelaxNGSetValidStructuredErrors.
10773*7c568831SAndroid Build Coastguard Worker *
10774*7c568831SAndroid Build Coastguard Worker * Set the error and warning callback information
10775*7c568831SAndroid Build Coastguard Worker */
10776*7c568831SAndroid Build Coastguard Worker void
xmlRelaxNGSetValidErrors(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGValidityErrorFunc err,xmlRelaxNGValidityWarningFunc warn,void * ctx)10777*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSetValidErrors(xmlRelaxNGValidCtxtPtr ctxt,
10778*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidityErrorFunc err,
10779*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidityWarningFunc warn, void *ctx)
10780*7c568831SAndroid Build Coastguard Worker {
10781*7c568831SAndroid Build Coastguard Worker if (ctxt == NULL)
10782*7c568831SAndroid Build Coastguard Worker return;
10783*7c568831SAndroid Build Coastguard Worker ctxt->error = err;
10784*7c568831SAndroid Build Coastguard Worker ctxt->warning = warn;
10785*7c568831SAndroid Build Coastguard Worker ctxt->userData = ctx;
10786*7c568831SAndroid Build Coastguard Worker ctxt->serror = NULL;
10787*7c568831SAndroid Build Coastguard Worker }
10788*7c568831SAndroid Build Coastguard Worker
10789*7c568831SAndroid Build Coastguard Worker /**
10790*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGSetValidStructuredErrors:
10791*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
10792*7c568831SAndroid Build Coastguard Worker * @serror: the structured error function
10793*7c568831SAndroid Build Coastguard Worker * @ctx: the functions context
10794*7c568831SAndroid Build Coastguard Worker *
10795*7c568831SAndroid Build Coastguard Worker * Set the structured error callback
10796*7c568831SAndroid Build Coastguard Worker */
10797*7c568831SAndroid Build Coastguard Worker void
xmlRelaxNGSetValidStructuredErrors(xmlRelaxNGValidCtxtPtr ctxt,xmlStructuredErrorFunc serror,void * ctx)10798*7c568831SAndroid Build Coastguard Worker xmlRelaxNGSetValidStructuredErrors(xmlRelaxNGValidCtxtPtr ctxt,
10799*7c568831SAndroid Build Coastguard Worker xmlStructuredErrorFunc serror, void *ctx)
10800*7c568831SAndroid Build Coastguard Worker {
10801*7c568831SAndroid Build Coastguard Worker if (ctxt == NULL)
10802*7c568831SAndroid Build Coastguard Worker return;
10803*7c568831SAndroid Build Coastguard Worker ctxt->serror = serror;
10804*7c568831SAndroid Build Coastguard Worker ctxt->error = NULL;
10805*7c568831SAndroid Build Coastguard Worker ctxt->warning = NULL;
10806*7c568831SAndroid Build Coastguard Worker ctxt->userData = ctx;
10807*7c568831SAndroid Build Coastguard Worker }
10808*7c568831SAndroid Build Coastguard Worker
10809*7c568831SAndroid Build Coastguard Worker /**
10810*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGGetValidErrors:
10811*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
10812*7c568831SAndroid Build Coastguard Worker * @err: the error function result
10813*7c568831SAndroid Build Coastguard Worker * @warn: the warning function result
10814*7c568831SAndroid Build Coastguard Worker * @ctx: the functions context result
10815*7c568831SAndroid Build Coastguard Worker *
10816*7c568831SAndroid Build Coastguard Worker * Get the error and warning callback information
10817*7c568831SAndroid Build Coastguard Worker *
10818*7c568831SAndroid Build Coastguard Worker * Returns -1 in case of error and 0 otherwise
10819*7c568831SAndroid Build Coastguard Worker */
10820*7c568831SAndroid Build Coastguard Worker int
xmlRelaxNGGetValidErrors(xmlRelaxNGValidCtxtPtr ctxt,xmlRelaxNGValidityErrorFunc * err,xmlRelaxNGValidityWarningFunc * warn,void ** ctx)10821*7c568831SAndroid Build Coastguard Worker xmlRelaxNGGetValidErrors(xmlRelaxNGValidCtxtPtr ctxt,
10822*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidityErrorFunc * err,
10823*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidityWarningFunc * warn, void **ctx)
10824*7c568831SAndroid Build Coastguard Worker {
10825*7c568831SAndroid Build Coastguard Worker if (ctxt == NULL)
10826*7c568831SAndroid Build Coastguard Worker return (-1);
10827*7c568831SAndroid Build Coastguard Worker if (err != NULL)
10828*7c568831SAndroid Build Coastguard Worker *err = ctxt->error;
10829*7c568831SAndroid Build Coastguard Worker if (warn != NULL)
10830*7c568831SAndroid Build Coastguard Worker *warn = ctxt->warning;
10831*7c568831SAndroid Build Coastguard Worker if (ctx != NULL)
10832*7c568831SAndroid Build Coastguard Worker *ctx = ctxt->userData;
10833*7c568831SAndroid Build Coastguard Worker return (0);
10834*7c568831SAndroid Build Coastguard Worker }
10835*7c568831SAndroid Build Coastguard Worker
10836*7c568831SAndroid Build Coastguard Worker /**
10837*7c568831SAndroid Build Coastguard Worker * xmlRelaxNGValidateDoc:
10838*7c568831SAndroid Build Coastguard Worker * @ctxt: a Relax-NG validation context
10839*7c568831SAndroid Build Coastguard Worker * @doc: a parsed document tree
10840*7c568831SAndroid Build Coastguard Worker *
10841*7c568831SAndroid Build Coastguard Worker * Validate a document tree in memory.
10842*7c568831SAndroid Build Coastguard Worker *
10843*7c568831SAndroid Build Coastguard Worker * Returns 0 if the document is valid, a positive error code
10844*7c568831SAndroid Build Coastguard Worker * number otherwise and -1 in case of internal or API error.
10845*7c568831SAndroid Build Coastguard Worker */
10846*7c568831SAndroid Build Coastguard Worker int
xmlRelaxNGValidateDoc(xmlRelaxNGValidCtxtPtr ctxt,xmlDocPtr doc)10847*7c568831SAndroid Build Coastguard Worker xmlRelaxNGValidateDoc(xmlRelaxNGValidCtxtPtr ctxt, xmlDocPtr doc)
10848*7c568831SAndroid Build Coastguard Worker {
10849*7c568831SAndroid Build Coastguard Worker int ret;
10850*7c568831SAndroid Build Coastguard Worker
10851*7c568831SAndroid Build Coastguard Worker if ((ctxt == NULL) || (doc == NULL))
10852*7c568831SAndroid Build Coastguard Worker return (-1);
10853*7c568831SAndroid Build Coastguard Worker
10854*7c568831SAndroid Build Coastguard Worker ctxt->doc = doc;
10855*7c568831SAndroid Build Coastguard Worker
10856*7c568831SAndroid Build Coastguard Worker ret = xmlRelaxNGValidateDocument(ctxt, doc);
10857*7c568831SAndroid Build Coastguard Worker /*
10858*7c568831SAndroid Build Coastguard Worker * Remove all left PSVI
10859*7c568831SAndroid Build Coastguard Worker */
10860*7c568831SAndroid Build Coastguard Worker xmlRelaxNGCleanPSVI((xmlNodePtr) doc);
10861*7c568831SAndroid Build Coastguard Worker
10862*7c568831SAndroid Build Coastguard Worker /*
10863*7c568831SAndroid Build Coastguard Worker * TODO: build error codes
10864*7c568831SAndroid Build Coastguard Worker */
10865*7c568831SAndroid Build Coastguard Worker if (ret == -1)
10866*7c568831SAndroid Build Coastguard Worker return (1);
10867*7c568831SAndroid Build Coastguard Worker return (ret);
10868*7c568831SAndroid Build Coastguard Worker }
10869*7c568831SAndroid Build Coastguard Worker
10870*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_SCHEMAS_ENABLED */
10871