Bug Summary

File:relaxng.c
Location:line 10209, column 9
Description:Value stored to 'progress' is never read

Annotated Source Code

1/*
2 * relaxng.c : implementation of the Relax-NG handling and validity checking
3 *
4 * See Copyright for the status of this software.
5 *
6 * Daniel Veillard <veillard@redhat.com>
7 */
8
9/**
10 * TODO:
11 * - add support for DTD compatibility spec
12 * http://www.oasis-open.org/committees/relax-ng/compatibility-20011203.html
13 * - report better mem allocations pbms at runtime and abort immediately.
14 */
15
16#define IN_LIBXML
17#include "libxml.h"
18
19#ifdef LIBXML_SCHEMAS_ENABLED
20
21#include <string.h>
22#include <stdio.h>
23#include <libxml/xmlmemory.h>
24#include <libxml/parser.h>
25#include <libxml/parserInternals.h>
26#include <libxml/hash.h>
27#include <libxml/uri.h>
28
29#include <libxml/relaxng.h>
30
31#include <libxml/xmlschemastypes.h>
32#include <libxml/xmlautomata.h>
33#include <libxml/xmlregexp.h>
34#include <libxml/xmlschemastypes.h>
35
36/*
37 * The Relax-NG namespace
38 */
39static const xmlChar *xmlRelaxNGNs = (const xmlChar *)
40 "http://relaxng.org/ns/structure/1.0";
41
42#define IS_RELAXNG(node, type)((node != ((void*)0)) && (node->ns != ((void*)0)) &&
(xmlStrEqual__internal_alias(node->name, (const xmlChar *
) type)) && (xmlStrEqual__internal_alias(node->ns->
href, xmlRelaxNGNs)))
\
43 ((node != NULL((void*)0)) && (node->ns != NULL((void*)0)) && \
44 (xmlStrEqualxmlStrEqual__internal_alias(node->name, (const xmlChar *) type)) && \
45 (xmlStrEqualxmlStrEqual__internal_alias(node->ns->href, xmlRelaxNGNs)))
46
47
48#if 0
49#define DEBUG 1
50
51#define DEBUG_GRAMMAR 1
52
53#define DEBUG_CONTENT 1
54
55#define DEBUG_TYPE 1
56
57#define DEBUG_VALID 1
58
59#define DEBUG_INTERLEAVE 1
60
61#define DEBUG_LIST 1
62
63#define DEBUG_INCLUDE 1
64
65#define DEBUG_ERROR 1
66
67#define DEBUG_COMPILE 1
68
69#define DEBUG_PROGRESSIVE 1
70#endif
71
72#define MAX_ERROR5 5
73
74#define TODO(*(__xmlGenericError__internal_alias()))((*(__xmlGenericErrorContext__internal_alias
())), "Unimplemented block at %s:%d\n", "relaxng.c", 74);
\
75 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())), \
76 "Unimplemented block at %s:%d\n", \
77 __FILE__"relaxng.c", __LINE__77);
78
79typedef struct _xmlRelaxNGSchema xmlRelaxNGSchema;
80typedef xmlRelaxNGSchema *xmlRelaxNGSchemaPtr;
81
82typedef struct _xmlRelaxNGDefine xmlRelaxNGDefine;
83typedef xmlRelaxNGDefine *xmlRelaxNGDefinePtr;
84
85typedef struct _xmlRelaxNGDocument xmlRelaxNGDocument;
86typedef xmlRelaxNGDocument *xmlRelaxNGDocumentPtr;
87
88typedef struct _xmlRelaxNGInclude xmlRelaxNGInclude;
89typedef xmlRelaxNGInclude *xmlRelaxNGIncludePtr;
90
91typedef enum {
92 XML_RELAXNG_COMBINE_UNDEFINED = 0, /* undefined */
93 XML_RELAXNG_COMBINE_CHOICE, /* choice */
94 XML_RELAXNG_COMBINE_INTERLEAVE /* interleave */
95} xmlRelaxNGCombine;
96
97typedef enum {
98 XML_RELAXNG_CONTENT_ERROR = -1,
99 XML_RELAXNG_CONTENT_EMPTY = 0,
100 XML_RELAXNG_CONTENT_SIMPLE,
101 XML_RELAXNG_CONTENT_COMPLEX
102} xmlRelaxNGContentType;
103
104typedef struct _xmlRelaxNGGrammar xmlRelaxNGGrammar;
105typedef xmlRelaxNGGrammar *xmlRelaxNGGrammarPtr;
106
107struct _xmlRelaxNGGrammar {
108 xmlRelaxNGGrammarPtr parent; /* the parent grammar if any */
109 xmlRelaxNGGrammarPtr children; /* the children grammar if any */
110 xmlRelaxNGGrammarPtr next; /* the next grammar if any */
111 xmlRelaxNGDefinePtr start; /* <start> content */
112 xmlRelaxNGCombine combine; /* the default combine value */
113 xmlRelaxNGDefinePtr startList; /* list of <start> definitions */
114 xmlHashTablePtr defs; /* define* */
115 xmlHashTablePtr refs; /* references */
116};
117
118
119typedef enum {
120 XML_RELAXNG_NOOP = -1, /* a no operation from simplification */
121 XML_RELAXNG_EMPTY = 0, /* an empty pattern */
122 XML_RELAXNG_NOT_ALLOWED, /* not allowed top */
123 XML_RELAXNG_EXCEPT, /* except present in nameclass defs */
124 XML_RELAXNG_TEXT, /* textual content */
125 XML_RELAXNG_ELEMENT, /* an element */
126 XML_RELAXNG_DATATYPE, /* extenal data type definition */
127 XML_RELAXNG_PARAM, /* extenal data type parameter */
128 XML_RELAXNG_VALUE, /* value from an extenal data type definition */
129 XML_RELAXNG_LIST, /* a list of patterns */
130 XML_RELAXNG_ATTRIBUTE, /* an attrbute following a pattern */
131 XML_RELAXNG_DEF, /* a definition */
132 XML_RELAXNG_REF, /* reference to a definition */
133 XML_RELAXNG_EXTERNALREF, /* reference to an external def */
134 XML_RELAXNG_PARENTREF, /* reference to a def in the parent grammar */
135 XML_RELAXNG_OPTIONAL, /* optional patterns */
136 XML_RELAXNG_ZEROORMORE, /* zero or more non empty patterns */
137 XML_RELAXNG_ONEORMORE, /* one or more non empty patterns */
138 XML_RELAXNG_CHOICE, /* a choice between non empty patterns */
139 XML_RELAXNG_GROUP, /* a pair/group of non empty patterns */
140 XML_RELAXNG_INTERLEAVE, /* interleaving choice of non-empty patterns */
141 XML_RELAXNG_START /* Used to keep track of starts on grammars */
142} xmlRelaxNGType;
143
144#define IS_NULLABLE(1 << 0) (1 << 0)
145#define IS_NOT_NULLABLE(1 << 1) (1 << 1)
146#define IS_INDETERMINIST(1 << 2) (1 << 2)
147#define IS_MIXED(1 << 3) (1 << 3)
148#define IS_TRIABLE(1 << 4) (1 << 4)
149#define IS_PROCESSED(1 << 5) (1 << 5)
150#define IS_COMPILABLE(1 << 6) (1 << 6)
151#define IS_NOT_COMPILABLE(1 << 7) (1 << 7)
152
153struct _xmlRelaxNGDefine {
154 xmlRelaxNGType type; /* the type of definition */
155 xmlNodePtr node; /* the node in the source */
156 xmlChar *name; /* the element local name if present */
157 xmlChar *ns; /* the namespace local name if present */
158 xmlChar *value; /* value when available */
159 void *data; /* data lib or specific pointer */
160 xmlRelaxNGDefinePtr content; /* the expected content */
161 xmlRelaxNGDefinePtr parent; /* the parent definition, if any */
162 xmlRelaxNGDefinePtr next; /* list within grouping sequences */
163 xmlRelaxNGDefinePtr attrs; /* list of attributes for elements */
164 xmlRelaxNGDefinePtr nameClass; /* the nameClass definition if any */
165 xmlRelaxNGDefinePtr nextHash; /* next define in defs/refs hash tables */
166 short depth; /* used for the cycle detection */
167 short dflags; /* define related flags */
168 xmlRegexpPtr contModel; /* a compiled content model if available */
169};
170
171/**
172 * _xmlRelaxNG:
173 *
174 * A RelaxNGs definition
175 */
176struct _xmlRelaxNG {
177 void *_private; /* unused by the library for users or bindings */
178 xmlRelaxNGGrammarPtr topgrammar;
179 xmlDocPtr doc;
180
181 int idref; /* requires idref checking */
182
183 xmlHashTablePtr defs; /* define */
184 xmlHashTablePtr refs; /* references */
185 xmlRelaxNGDocumentPtr documents; /* all the documents loaded */
186 xmlRelaxNGIncludePtr includes; /* all the includes loaded */
187 int defNr; /* number of defines used */
188 xmlRelaxNGDefinePtr *defTab; /* pointer to the allocated definitions */
189
190};
191
192#define XML_RELAXNG_IN_ATTRIBUTE(1 << 0) (1 << 0)
193#define XML_RELAXNG_IN_ONEORMORE(1 << 1) (1 << 1)
194#define XML_RELAXNG_IN_LIST(1 << 2) (1 << 2)
195#define XML_RELAXNG_IN_DATAEXCEPT(1 << 3) (1 << 3)
196#define XML_RELAXNG_IN_START(1 << 4) (1 << 4)
197#define XML_RELAXNG_IN_OOMGROUP(1 << 5) (1 << 5)
198#define XML_RELAXNG_IN_OOMINTERLEAVE(1 << 6) (1 << 6)
199#define XML_RELAXNG_IN_EXTERNALREF(1 << 7) (1 << 7)
200#define XML_RELAXNG_IN_ANYEXCEPT(1 << 8) (1 << 8)
201#define XML_RELAXNG_IN_NSEXCEPT(1 << 9) (1 << 9)
202
203struct _xmlRelaxNGParserCtxt {
204 void *userData; /* user specific data block */
205 xmlRelaxNGValidityErrorFunc error; /* the callback in case of errors */
206 xmlRelaxNGValidityWarningFunc warning; /* the callback in case of warning */
207 xmlStructuredErrorFunc serror;
208 xmlRelaxNGValidErr err;
209
210 xmlRelaxNGPtr schema; /* The schema in use */
211 xmlRelaxNGGrammarPtr grammar; /* the current grammar */
212 xmlRelaxNGGrammarPtr parentgrammar; /* the parent grammar */
213 int flags; /* parser flags */
214 int nbErrors; /* number of errors at parse time */
215 int nbWarnings; /* number of warnings at parse time */
216 const xmlChar *define; /* the current define scope */
217 xmlRelaxNGDefinePtr def; /* the current define */
218
219 int nbInterleaves;
220 xmlHashTablePtr interleaves; /* keep track of all the interleaves */
221
222 xmlRelaxNGDocumentPtr documents; /* all the documents loaded */
223 xmlRelaxNGIncludePtr includes; /* all the includes loaded */
224 xmlChar *URL;
225 xmlDocPtr document;
226
227 int defNr; /* number of defines used */
228 int defMax; /* number of defines aloocated */
229 xmlRelaxNGDefinePtr *defTab; /* pointer to the allocated definitions */
230
231 const char *buffer;
232 int size;
233
234 /* the document stack */
235 xmlRelaxNGDocumentPtr doc; /* Current parsed external ref */
236 int docNr; /* Depth of the parsing stack */
237 int docMax; /* Max depth of the parsing stack */
238 xmlRelaxNGDocumentPtr *docTab; /* array of docs */
239
240 /* the include stack */
241 xmlRelaxNGIncludePtr inc; /* Current parsed include */
242 int incNr; /* Depth of the include parsing stack */
243 int incMax; /* Max depth of the parsing stack */
244 xmlRelaxNGIncludePtr *incTab; /* array of incs */
245
246 int idref; /* requires idref checking */
247
248 /* used to compile content models */
249 xmlAutomataPtr am; /* the automata */
250 xmlAutomataStatePtr state; /* used to build the automata */
251
252 int crng; /* compact syntax and other flags */
253 int freedoc; /* need to free the document */
254};
255
256#define FLAGS_IGNORABLE1 1
257#define FLAGS_NEGATIVE2 2
258#define FLAGS_MIXED_CONTENT4 4
259#define FLAGS_NOERROR8 8
260
261/**
262 * xmlRelaxNGInterleaveGroup:
263 *
264 * A RelaxNGs partition set associated to lists of definitions
265 */
266typedef struct _xmlRelaxNGInterleaveGroup xmlRelaxNGInterleaveGroup;
267typedef xmlRelaxNGInterleaveGroup *xmlRelaxNGInterleaveGroupPtr;
268struct _xmlRelaxNGInterleaveGroup {
269 xmlRelaxNGDefinePtr rule; /* the rule to satisfy */
270 xmlRelaxNGDefinePtr *defs; /* the array of element definitions */
271 xmlRelaxNGDefinePtr *attrs; /* the array of attributes definitions */
272};
273
274#define IS_DETERMINIST1 1
275#define IS_NEEDCHECK2 2
276
277/**
278 * xmlRelaxNGPartitions:
279 *
280 * A RelaxNGs partition associated to an interleave group
281 */
282typedef struct _xmlRelaxNGPartition xmlRelaxNGPartition;
283typedef xmlRelaxNGPartition *xmlRelaxNGPartitionPtr;
284struct _xmlRelaxNGPartition {
285 int nbgroups; /* number of groups in the partitions */
286 xmlHashTablePtr triage; /* hash table used to direct nodes to the
287 * right group when possible */
288 int flags; /* determinist ? */
289 xmlRelaxNGInterleaveGroupPtr *groups;
290};
291
292/**
293 * xmlRelaxNGValidState:
294 *
295 * A RelaxNGs validation state
296 */
297#define MAX_ATTR20 20
298typedef struct _xmlRelaxNGValidState xmlRelaxNGValidState;
299typedef xmlRelaxNGValidState *xmlRelaxNGValidStatePtr;
300struct _xmlRelaxNGValidState {
301 xmlNodePtr node; /* the current node */
302 xmlNodePtr seq; /* the sequence of children left to validate */
303 int nbAttrs; /* the number of attributes */
304 int maxAttrs; /* the size of attrs */
305 int nbAttrLeft; /* the number of attributes left to validate */
306 xmlChar *value; /* the value when operating on string */
307 xmlChar *endvalue; /* the end value when operating on string */
308 xmlAttrPtr *attrs; /* the array of attributes */
309};
310
311/**
312 * xmlRelaxNGStates:
313 *
314 * A RelaxNGs container for validation state
315 */
316typedef struct _xmlRelaxNGStates xmlRelaxNGStates;
317typedef xmlRelaxNGStates *xmlRelaxNGStatesPtr;
318struct _xmlRelaxNGStates {
319 int nbState; /* the number of states */
320 int maxState; /* the size of the array */
321 xmlRelaxNGValidStatePtr *tabState;
322};
323
324#define ERROR_IS_DUP1 1
325
326/**
327 * xmlRelaxNGValidError:
328 *
329 * A RelaxNGs validation error
330 */
331typedef struct _xmlRelaxNGValidError xmlRelaxNGValidError;
332typedef xmlRelaxNGValidError *xmlRelaxNGValidErrorPtr;
333struct _xmlRelaxNGValidError {
334 xmlRelaxNGValidErr err; /* the error number */
335 int flags; /* flags */
336 xmlNodePtr node; /* the current node */
337 xmlNodePtr seq; /* the current child */
338 const xmlChar *arg1; /* first arg */
339 const xmlChar *arg2; /* second arg */
340};
341
342/**
343 * xmlRelaxNGValidCtxt:
344 *
345 * A RelaxNGs validation context
346 */
347
348struct _xmlRelaxNGValidCtxt {
349 void *userData; /* user specific data block */
350 xmlRelaxNGValidityErrorFunc error; /* the callback in case of errors */
351 xmlRelaxNGValidityWarningFunc warning; /* the callback in case of warning */
352 xmlStructuredErrorFunc serror;
353 int nbErrors; /* number of errors in validation */
354
355 xmlRelaxNGPtr schema; /* The schema in use */
356 xmlDocPtr doc; /* the document being validated */
357 int flags; /* validation flags */
358 int depth; /* validation depth */
359 int idref; /* requires idref checking */
360 int errNo; /* the first error found */
361
362 /*
363 * Errors accumulated in branches may have to be stacked to be
364 * provided back when it's sure they affect validation.
365 */
366 xmlRelaxNGValidErrorPtr err; /* Last error */
367 int errNr; /* Depth of the error stack */
368 int errMax; /* Max depth of the error stack */
369 xmlRelaxNGValidErrorPtr errTab; /* stack of errors */
370
371 xmlRelaxNGValidStatePtr state; /* the current validation state */
372 xmlRelaxNGStatesPtr states; /* the accumulated state list */
373
374 xmlRelaxNGStatesPtr freeState; /* the pool of free valid states */
375 int freeStatesNr;
376 int freeStatesMax;
377 xmlRelaxNGStatesPtr *freeStates; /* the pool of free state groups */
378
379 /*
380 * This is used for "progressive" validation
381 */
382 xmlRegExecCtxtPtr elem; /* the current element regexp */
383 int elemNr; /* the number of element validated */
384 int elemMax; /* the max depth of elements */
385 xmlRegExecCtxtPtr *elemTab; /* the stack of regexp runtime */
386 int pstate; /* progressive state */
387 xmlNodePtr pnode; /* the current node */
388 xmlRelaxNGDefinePtr pdef; /* the non-streamable definition */
389 int perr; /* signal error in content model
390 * outside the regexp */
391};
392
393/**
394 * xmlRelaxNGInclude:
395 *
396 * Structure associated to a RelaxNGs document element
397 */
398struct _xmlRelaxNGInclude {
399 xmlRelaxNGIncludePtr next; /* keep a chain of includes */
400 xmlChar *href; /* the normalized href value */
401 xmlDocPtr doc; /* the associated XML document */
402 xmlRelaxNGDefinePtr content; /* the definitions */
403 xmlRelaxNGPtr schema; /* the schema */
404};
405
406/**
407 * xmlRelaxNGDocument:
408 *
409 * Structure associated to a RelaxNGs document element
410 */
411struct _xmlRelaxNGDocument {
412 xmlRelaxNGDocumentPtr next; /* keep a chain of documents */
413 xmlChar *href; /* the normalized href value */
414 xmlDocPtr doc; /* the associated XML document */
415 xmlRelaxNGDefinePtr content; /* the definitions */
416 xmlRelaxNGPtr schema; /* the schema */
417 int externalRef; /* 1 if an external ref */
418};
419
420
421/************************************************************************
422 * *
423 * Some factorized error routines *
424 * *
425 ************************************************************************/
426
427/**
428 * xmlRngPErrMemory:
429 * @ctxt: an Relax-NG parser context
430 * @extra: extra informations
431 *
432 * Handle a redefinition of attribute error
433 */
434static void
435xmlRngPErrMemory(xmlRelaxNGParserCtxtPtr ctxt, const char *extra)
436{
437 xmlStructuredErrorFunc schannel = NULL((void*)0);
438 xmlGenericErrorFunc channel = NULL((void*)0);
439 void *data = NULL((void*)0);
440
441 if (ctxt != NULL((void*)0)) {
442 if (ctxt->serror != NULL((void*)0))
443 schannel = ctxt->serror;
444 else
445 channel = ctxt->error;
446 data = ctxt->userData;
447 ctxt->nbErrors++;
448 }
449 if (extra)
450 __xmlRaiseError(schannel, channel, data,
451 NULL((void*)0), NULL((void*)0), XML_FROM_RELAXNGP,
452 XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL((void*)0), 0, extra,
453 NULL((void*)0), NULL((void*)0), 0, 0,
454 "Memory allocation failed : %s\n", extra);
455 else
456 __xmlRaiseError(schannel, channel, data,
457 NULL((void*)0), NULL((void*)0), XML_FROM_RELAXNGP,
458 XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL((void*)0), 0, NULL((void*)0),
459 NULL((void*)0), NULL((void*)0), 0, 0, "Memory allocation failed\n");
460}
461
462/**
463 * xmlRngVErrMemory:
464 * @ctxt: a Relax-NG validation context
465 * @extra: extra informations
466 *
467 * Handle a redefinition of attribute error
468 */
469static void
470xmlRngVErrMemory(xmlRelaxNGValidCtxtPtr ctxt, const char *extra)
471{
472 xmlStructuredErrorFunc schannel = NULL((void*)0);
473 xmlGenericErrorFunc channel = NULL((void*)0);
474 void *data = NULL((void*)0);
475
476 if (ctxt != NULL((void*)0)) {
477 if (ctxt->serror != NULL((void*)0))
478 schannel = ctxt->serror;
479 else
480 channel = ctxt->error;
481 data = ctxt->userData;
482 ctxt->nbErrors++;
483 }
484 if (extra)
485 __xmlRaiseError(schannel, channel, data,
486 NULL((void*)0), NULL((void*)0), XML_FROM_RELAXNGV,
487 XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL((void*)0), 0, extra,
488 NULL((void*)0), NULL((void*)0), 0, 0,
489 "Memory allocation failed : %s\n", extra);
490 else
491 __xmlRaiseError(schannel, channel, data,
492 NULL((void*)0), NULL((void*)0), XML_FROM_RELAXNGV,
493 XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL((void*)0), 0, NULL((void*)0),
494 NULL((void*)0), NULL((void*)0), 0, 0, "Memory allocation failed\n");
495}
496
497/**
498 * xmlRngPErr:
499 * @ctxt: a Relax-NG parser context
500 * @node: the node raising the error
501 * @error: the error code
502 * @msg: message
503 * @str1: extra info
504 * @str2: extra info
505 *
506 * Handle a Relax NG Parsing error
507 */
508static void
509xmlRngPErr(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node, int error,
510 const char *msg, const xmlChar * str1, const xmlChar * str2)
511{
512 xmlStructuredErrorFunc schannel = NULL((void*)0);
513 xmlGenericErrorFunc channel = NULL((void*)0);
514 void *data = NULL((void*)0);
515
516 if (ctxt != NULL((void*)0)) {
517 if (ctxt->serror != NULL((void*)0))
518 schannel = ctxt->serror;
519 else
520 channel = ctxt->error;
521 data = ctxt->userData;
522 ctxt->nbErrors++;
523 }
524 __xmlRaiseError(schannel, channel, data,
525 NULL((void*)0), node, XML_FROM_RELAXNGP,
526 error, XML_ERR_ERROR, NULL((void*)0), 0,
527 (const char *) str1, (const char *) str2, NULL((void*)0), 0, 0,
528 msg, str1, str2);
529}
530
531/**
532 * xmlRngVErr:
533 * @ctxt: a Relax-NG validation context
534 * @node: the node raising the error
535 * @error: the error code
536 * @msg: message
537 * @str1: extra info
538 * @str2: extra info
539 *
540 * Handle a Relax NG Validation error
541 */
542static void
543xmlRngVErr(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node, int error,
544 const char *msg, const xmlChar * str1, const xmlChar * str2)
545{
546 xmlStructuredErrorFunc schannel = NULL((void*)0);
547 xmlGenericErrorFunc channel = NULL((void*)0);
548 void *data = NULL((void*)0);
549
550 if (ctxt != NULL((void*)0)) {
551 if (ctxt->serror != NULL((void*)0))
552 schannel = ctxt->serror;
553 else
554 channel = ctxt->error;
555 data = ctxt->userData;
556 ctxt->nbErrors++;
557 }
558 __xmlRaiseError(schannel, channel, data,
559 NULL((void*)0), node, XML_FROM_RELAXNGV,
560 error, XML_ERR_ERROR, NULL((void*)0), 0,
561 (const char *) str1, (const char *) str2, NULL((void*)0), 0, 0,
562 msg, str1, str2);
563}
564
565/************************************************************************
566 * *
567 * Preliminary type checking interfaces *
568 * *
569 ************************************************************************/
570
571/**
572 * xmlRelaxNGTypeHave:
573 * @data: data needed for the library
574 * @type: the type name
575 * @value: the value to check
576 *
577 * Function provided by a type library to check if a type is exported
578 *
579 * Returns 1 if yes, 0 if no and -1 in case of error.
580 */
581typedef int (*xmlRelaxNGTypeHave) (void *data, const xmlChar * type);
582
583/**
584 * xmlRelaxNGTypeCheck:
585 * @data: data needed for the library
586 * @type: the type name
587 * @value: the value to check
588 * @result: place to store the result if needed
589 *
590 * Function provided by a type library to check if a value match a type
591 *
592 * Returns 1 if yes, 0 if no and -1 in case of error.
593 */
594typedef int (*xmlRelaxNGTypeCheck) (void *data, const xmlChar * type,
595 const xmlChar * value, void **result,
596 xmlNodePtr node);
597
598/**
599 * xmlRelaxNGFacetCheck:
600 * @data: data needed for the library
601 * @type: the type name
602 * @facet: the facet name
603 * @val: the facet value
604 * @strval: the string value
605 * @value: the value to check
606 *
607 * Function provided by a type library to check a value facet
608 *
609 * Returns 1 if yes, 0 if no and -1 in case of error.
610 */
611typedef int (*xmlRelaxNGFacetCheck) (void *data, const xmlChar * type,
612 const xmlChar * facet,
613 const xmlChar * val,
614 const xmlChar * strval, void *value);
615
616/**
617 * xmlRelaxNGTypeFree:
618 * @data: data needed for the library
619 * @result: the value to free
620 *
621 * Function provided by a type library to free a returned result
622 */
623typedef void (*xmlRelaxNGTypeFree) (void *data, void *result);
624
625/**
626 * xmlRelaxNGTypeCompare:
627 * @data: data needed for the library
628 * @type: the type name
629 * @value1: the first value
630 * @value2: the second value
631 *
632 * Function provided by a type library to compare two values accordingly
633 * to a type.
634 *
635 * Returns 1 if yes, 0 if no and -1 in case of error.
636 */
637typedef int (*xmlRelaxNGTypeCompare) (void *data, const xmlChar * type,
638 const xmlChar * value1,
639 xmlNodePtr ctxt1,
640 void *comp1,
641 const xmlChar * value2,
642 xmlNodePtr ctxt2);
643typedef struct _xmlRelaxNGTypeLibrary xmlRelaxNGTypeLibrary;
644typedef xmlRelaxNGTypeLibrary *xmlRelaxNGTypeLibraryPtr;
645struct _xmlRelaxNGTypeLibrary {
646 const xmlChar *namespace; /* the datatypeLibrary value */
647 void *data; /* data needed for the library */
648 xmlRelaxNGTypeHave have; /* the export function */
649 xmlRelaxNGTypeCheck check; /* the checking function */
650 xmlRelaxNGTypeCompare comp; /* the compare function */
651 xmlRelaxNGFacetCheck facet; /* the facet check function */
652 xmlRelaxNGTypeFree freef; /* the freeing function */
653};
654
655/************************************************************************
656 * *
657 * Allocation functions *
658 * *
659 ************************************************************************/
660static void xmlRelaxNGFreeGrammar(xmlRelaxNGGrammarPtr grammar);
661static void xmlRelaxNGFreeDefine(xmlRelaxNGDefinePtr define);
662static void xmlRelaxNGNormExtSpace(xmlChar * value);
663static void xmlRelaxNGFreeInnerSchema(xmlRelaxNGPtr schema);
664static int xmlRelaxNGEqualValidState(xmlRelaxNGValidCtxtPtr ctxt
665 ATTRIBUTE_UNUSED__attribute__((unused)),
666 xmlRelaxNGValidStatePtr state1,
667 xmlRelaxNGValidStatePtr state2);
668static void xmlRelaxNGFreeValidState(xmlRelaxNGValidCtxtPtr ctxt,
669 xmlRelaxNGValidStatePtr state);
670
671/**
672 * xmlRelaxNGFreeDocument:
673 * @docu: a document structure
674 *
675 * Deallocate a RelaxNG document structure.
676 */
677static void
678xmlRelaxNGFreeDocument(xmlRelaxNGDocumentPtr docu)
679{
680 if (docu == NULL((void*)0))
681 return;
682
683 if (docu->href != NULL((void*)0))
684 xmlFree(docu->href);
685 if (docu->doc != NULL((void*)0))
686 xmlFreeDocxmlFreeDoc__internal_alias(docu->doc);
687 if (docu->schema != NULL((void*)0))
688 xmlRelaxNGFreeInnerSchema(docu->schema);
689 xmlFree(docu);
690}
691
692/**
693 * xmlRelaxNGFreeDocumentList:
694 * @docu: a list of document structure
695 *
696 * Deallocate a RelaxNG document structures.
697 */
698static void
699xmlRelaxNGFreeDocumentList(xmlRelaxNGDocumentPtr docu)
700{
701 xmlRelaxNGDocumentPtr next;
702
703 while (docu != NULL((void*)0)) {
704 next = docu->next;
705 xmlRelaxNGFreeDocument(docu);
706 docu = next;
707 }
708}
709
710/**
711 * xmlRelaxNGFreeInclude:
712 * @incl: a include structure
713 *
714 * Deallocate a RelaxNG include structure.
715 */
716static void
717xmlRelaxNGFreeInclude(xmlRelaxNGIncludePtr incl)
718{
719 if (incl == NULL((void*)0))
720 return;
721
722 if (incl->href != NULL((void*)0))
723 xmlFree(incl->href);
724 if (incl->doc != NULL((void*)0))
725 xmlFreeDocxmlFreeDoc__internal_alias(incl->doc);
726 if (incl->schema != NULL((void*)0))
727 xmlRelaxNGFree(incl->schema);
728 xmlFree(incl);
729}
730
731/**
732 * xmlRelaxNGFreeIncludeList:
733 * @incl: a include structure list
734 *
735 * Deallocate a RelaxNG include structure.
736 */
737static void
738xmlRelaxNGFreeIncludeList(xmlRelaxNGIncludePtr incl)
739{
740 xmlRelaxNGIncludePtr next;
741
742 while (incl != NULL((void*)0)) {
743 next = incl->next;
744 xmlRelaxNGFreeInclude(incl);
745 incl = next;
746 }
747}
748
749/**
750 * xmlRelaxNGNewRelaxNG:
751 * @ctxt: a Relax-NG validation context (optional)
752 *
753 * Allocate a new RelaxNG structure.
754 *
755 * Returns the newly allocated structure or NULL in case or error
756 */
757static xmlRelaxNGPtr
758xmlRelaxNGNewRelaxNG(xmlRelaxNGParserCtxtPtr ctxt)
759{
760 xmlRelaxNGPtr ret;
761
762 ret = (xmlRelaxNGPtr) xmlMalloc(sizeof(xmlRelaxNG));
763 if (ret == NULL((void*)0)) {
764 xmlRngPErrMemory(ctxt, NULL((void*)0));
765 return (NULL((void*)0));
766 }
767 memset(ret, 0, sizeof(xmlRelaxNG));
768
769 return (ret);
770}
771
772/**
773 * xmlRelaxNGFreeInnerSchema:
774 * @schema: a schema structure
775 *
776 * Deallocate a RelaxNG schema structure.
777 */
778static void
779xmlRelaxNGFreeInnerSchema(xmlRelaxNGPtr schema)
780{
781 if (schema == NULL((void*)0))
782 return;
783
784 if (schema->doc != NULL((void*)0))
785 xmlFreeDocxmlFreeDoc__internal_alias(schema->doc);
786 if (schema->defTab != NULL((void*)0)) {
787 int i;
788
789 for (i = 0; i < schema->defNr; i++)
790 xmlRelaxNGFreeDefine(schema->defTab[i]);
791 xmlFree(schema->defTab);
792 }
793
794 xmlFree(schema);
795}
796
797/**
798 * xmlRelaxNGFree:
799 * @schema: a schema structure
800 *
801 * Deallocate a RelaxNG structure.
802 */
803void
804xmlRelaxNGFree(xmlRelaxNGPtr schema)
805{
806 if (schema == NULL((void*)0))
807 return;
808
809 if (schema->topgrammar != NULL((void*)0))
810 xmlRelaxNGFreeGrammar(schema->topgrammar);
811 if (schema->doc != NULL((void*)0))
812 xmlFreeDocxmlFreeDoc__internal_alias(schema->doc);
813 if (schema->documents != NULL((void*)0))
814 xmlRelaxNGFreeDocumentList(schema->documents);
815 if (schema->includes != NULL((void*)0))
816 xmlRelaxNGFreeIncludeList(schema->includes);
817 if (schema->defTab != NULL((void*)0)) {
818 int i;
819
820 for (i = 0; i < schema->defNr; i++)
821 xmlRelaxNGFreeDefine(schema->defTab[i]);
822 xmlFree(schema->defTab);
823 }
824
825 xmlFree(schema);
826}
827
828/**
829 * xmlRelaxNGNewGrammar:
830 * @ctxt: a Relax-NG validation context (optional)
831 *
832 * Allocate a new RelaxNG grammar.
833 *
834 * Returns the newly allocated structure or NULL in case or error
835 */
836static xmlRelaxNGGrammarPtr
837xmlRelaxNGNewGrammar(xmlRelaxNGParserCtxtPtr ctxt)
838{
839 xmlRelaxNGGrammarPtr ret;
840
841 ret = (xmlRelaxNGGrammarPtr) xmlMalloc(sizeof(xmlRelaxNGGrammar));
842 if (ret == NULL((void*)0)) {
843 xmlRngPErrMemory(ctxt, NULL((void*)0));
844 return (NULL((void*)0));
845 }
846 memset(ret, 0, sizeof(xmlRelaxNGGrammar));
847
848 return (ret);
849}
850
851/**
852 * xmlRelaxNGFreeGrammar:
853 * @grammar: a grammar structure
854 *
855 * Deallocate a RelaxNG grammar structure.
856 */
857static void
858xmlRelaxNGFreeGrammar(xmlRelaxNGGrammarPtr grammar)
859{
860 if (grammar == NULL((void*)0))
861 return;
862
863 if (grammar->children != NULL((void*)0)) {
864 xmlRelaxNGFreeGrammar(grammar->children);
865 }
866 if (grammar->next != NULL((void*)0)) {
867 xmlRelaxNGFreeGrammar(grammar->next);
868 }
869 if (grammar->refs != NULL((void*)0)) {
870 xmlHashFreexmlHashFree__internal_alias(grammar->refs, NULL((void*)0));
871 }
872 if (grammar->defs != NULL((void*)0)) {
873 xmlHashFreexmlHashFree__internal_alias(grammar->defs, NULL((void*)0));
874 }
875
876 xmlFree(grammar);
877}
878
879/**
880 * xmlRelaxNGNewDefine:
881 * @ctxt: a Relax-NG validation context
882 * @node: the node in the input document.
883 *
884 * Allocate a new RelaxNG define.
885 *
886 * Returns the newly allocated structure or NULL in case or error
887 */
888static xmlRelaxNGDefinePtr
889xmlRelaxNGNewDefine(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
890{
891 xmlRelaxNGDefinePtr ret;
892
893 if (ctxt->defMax == 0) {
894 ctxt->defMax = 16;
895 ctxt->defNr = 0;
896 ctxt->defTab = (xmlRelaxNGDefinePtr *)
897 xmlMalloc(ctxt->defMax * sizeof(xmlRelaxNGDefinePtr));
898 if (ctxt->defTab == NULL((void*)0)) {
899 xmlRngPErrMemory(ctxt, "allocating define\n");
900 return (NULL((void*)0));
901 }
902 } else if (ctxt->defMax <= ctxt->defNr) {
903 xmlRelaxNGDefinePtr *tmp;
904
905 ctxt->defMax *= 2;
906 tmp = (xmlRelaxNGDefinePtr *) xmlRealloc(ctxt->defTab,
907 ctxt->defMax *
908 sizeof
909 (xmlRelaxNGDefinePtr));
910 if (tmp == NULL((void*)0)) {
911 xmlRngPErrMemory(ctxt, "allocating define\n");
912 return (NULL((void*)0));
913 }
914 ctxt->defTab = tmp;
915 }
916 ret = (xmlRelaxNGDefinePtr) xmlMalloc(sizeof(xmlRelaxNGDefine));
917 if (ret == NULL((void*)0)) {
918 xmlRngPErrMemory(ctxt, "allocating define\n");
919 return (NULL((void*)0));
920 }
921 memset(ret, 0, sizeof(xmlRelaxNGDefine));
922 ctxt->defTab[ctxt->defNr++] = ret;
923 ret->node = node;
924 ret->depth = -1;
925 return (ret);
926}
927
928/**
929 * xmlRelaxNGFreePartition:
930 * @partitions: a partition set structure
931 *
932 * Deallocate RelaxNG partition set structures.
933 */
934static void
935xmlRelaxNGFreePartition(xmlRelaxNGPartitionPtr partitions)
936{
937 xmlRelaxNGInterleaveGroupPtr group;
938 int j;
939
940 if (partitions != NULL((void*)0)) {
941 if (partitions->groups != NULL((void*)0)) {
942 for (j = 0; j < partitions->nbgroups; j++) {
943 group = partitions->groups[j];
944 if (group != NULL((void*)0)) {
945 if (group->defs != NULL((void*)0))
946 xmlFree(group->defs);
947 if (group->attrs != NULL((void*)0))
948 xmlFree(group->attrs);
949 xmlFree(group);
950 }
951 }
952 xmlFree(partitions->groups);
953 }
954 if (partitions->triage != NULL((void*)0)) {
955 xmlHashFreexmlHashFree__internal_alias(partitions->triage, NULL((void*)0));
956 }
957 xmlFree(partitions);
958 }
959}
960
961/**
962 * xmlRelaxNGFreeDefine:
963 * @define: a define structure
964 *
965 * Deallocate a RelaxNG define structure.
966 */
967static void
968xmlRelaxNGFreeDefine(xmlRelaxNGDefinePtr define)
969{
970 if (define == NULL((void*)0))
971 return;
972
973 if ((define->type == XML_RELAXNG_VALUE) && (define->attrs != NULL((void*)0))) {
974 xmlRelaxNGTypeLibraryPtr lib;
975
976 lib = (xmlRelaxNGTypeLibraryPtr) define->data;
977 if ((lib != NULL((void*)0)) && (lib->freef != NULL((void*)0)))
978 lib->freef(lib->data, (void *) define->attrs);
979 }
980 if ((define->data != NULL((void*)0)) && (define->type == XML_RELAXNG_INTERLEAVE))
981 xmlRelaxNGFreePartition((xmlRelaxNGPartitionPtr) define->data);
982 if ((define->data != NULL((void*)0)) && (define->type == XML_RELAXNG_CHOICE))
983 xmlHashFreexmlHashFree__internal_alias((xmlHashTablePtr) define->data, NULL((void*)0));
984 if (define->name != NULL((void*)0))
985 xmlFree(define->name);
986 if (define->ns != NULL((void*)0))
987 xmlFree(define->ns);
988 if (define->value != NULL((void*)0))
989 xmlFree(define->value);
990 if (define->contModel != NULL((void*)0))
991 xmlRegFreeRegexpxmlRegFreeRegexp__internal_alias(define->contModel);
992 xmlFree(define);
993}
994
995/**
996 * xmlRelaxNGNewStates:
997 * @ctxt: a Relax-NG validation context
998 * @size: the default size for the container
999 *
1000 * Allocate a new RelaxNG validation state container
1001 *
1002 * Returns the newly allocated structure or NULL in case or error
1003 */
1004static xmlRelaxNGStatesPtr
1005xmlRelaxNGNewStates(xmlRelaxNGValidCtxtPtr ctxt, int size)
1006{
1007 xmlRelaxNGStatesPtr ret;
1008
1009 if ((ctxt != NULL((void*)0)) &&
1010 (ctxt->freeStates != NULL((void*)0)) && (ctxt->freeStatesNr > 0)) {
1011 ctxt->freeStatesNr--;
1012 ret = ctxt->freeStates[ctxt->freeStatesNr];
1013 ret->nbState = 0;
1014 return (ret);
1015 }
1016 if (size < 16)
1017 size = 16;
1018
1019 ret = (xmlRelaxNGStatesPtr) xmlMalloc(sizeof(xmlRelaxNGStates) +
1020 (size -
1021 1) *
1022 sizeof(xmlRelaxNGValidStatePtr));
1023 if (ret == NULL((void*)0)) {
1024 xmlRngVErrMemory(ctxt, "allocating states\n");
1025 return (NULL((void*)0));
1026 }
1027 ret->nbState = 0;
1028 ret->maxState = size;
1029 ret->tabState = (xmlRelaxNGValidStatePtr *) xmlMalloc((size) *
1030 sizeof
1031 (xmlRelaxNGValidStatePtr));
1032 if (ret->tabState == NULL((void*)0)) {
1033 xmlRngVErrMemory(ctxt, "allocating states\n");
1034 xmlFree(ret);
1035 return (NULL((void*)0));
1036 }
1037 return (ret);
1038}
1039
1040/**
1041 * xmlRelaxNGAddStateUniq:
1042 * @ctxt: a Relax-NG validation context
1043 * @states: the states container
1044 * @state: the validation state
1045 *
1046 * Add a RelaxNG validation state to the container without checking
1047 * for unicity.
1048 *
1049 * Return 1 in case of success and 0 if this is a duplicate and -1 on error
1050 */
1051static int
1052xmlRelaxNGAddStatesUniq(xmlRelaxNGValidCtxtPtr ctxt,
1053 xmlRelaxNGStatesPtr states,
1054 xmlRelaxNGValidStatePtr state)
1055{
1056 if (state == NULL((void*)0)) {
1057 return (-1);
1058 }
1059 if (states->nbState >= states->maxState) {
1060 xmlRelaxNGValidStatePtr *tmp;
1061 int size;
1062
1063 size = states->maxState * 2;
1064 tmp = (xmlRelaxNGValidStatePtr *) xmlRealloc(states->tabState,
1065 (size) *
1066 sizeof
1067 (xmlRelaxNGValidStatePtr));
1068 if (tmp == NULL((void*)0)) {
1069 xmlRngVErrMemory(ctxt, "adding states\n");
1070 return (-1);
1071 }
1072 states->tabState = tmp;
1073 states->maxState = size;
1074 }
1075 states->tabState[states->nbState++] = state;
1076 return (1);
1077}
1078
1079/**
1080 * xmlRelaxNGAddState:
1081 * @ctxt: a Relax-NG validation context
1082 * @states: the states container
1083 * @state: the validation state
1084 *
1085 * Add a RelaxNG validation state to the container
1086 *
1087 * Return 1 in case of success and 0 if this is a duplicate and -1 on error
1088 */
1089static int
1090xmlRelaxNGAddStates(xmlRelaxNGValidCtxtPtr ctxt,
1091 xmlRelaxNGStatesPtr states,
1092 xmlRelaxNGValidStatePtr state)
1093{
1094 int i;
1095
1096 if (state == NULL((void*)0)) {
1097 return (-1);
1098 }
1099 if (states->nbState >= states->maxState) {
1100 xmlRelaxNGValidStatePtr *tmp;
1101 int size;
1102
1103 size = states->maxState * 2;
1104 tmp = (xmlRelaxNGValidStatePtr *) xmlRealloc(states->tabState,
1105 (size) *
1106 sizeof
1107 (xmlRelaxNGValidStatePtr));
1108 if (tmp == NULL((void*)0)) {
1109 xmlRngVErrMemory(ctxt, "adding states\n");
1110 return (-1);
1111 }
1112 states->tabState = tmp;
1113 states->maxState = size;
1114 }
1115 for (i = 0; i < states->nbState; i++) {
1116 if (xmlRelaxNGEqualValidState(ctxt, state, states->tabState[i])) {
1117 xmlRelaxNGFreeValidState(ctxt, state);
1118 return (0);
1119 }
1120 }
1121 states->tabState[states->nbState++] = state;
1122 return (1);
1123}
1124
1125/**
1126 * xmlRelaxNGFreeStates:
1127 * @ctxt: a Relax-NG validation context
1128 * @states: teh container
1129 *
1130 * Free a RelaxNG validation state container
1131 */
1132static void
1133xmlRelaxNGFreeStates(xmlRelaxNGValidCtxtPtr ctxt,
1134 xmlRelaxNGStatesPtr states)
1135{
1136 if (states == NULL((void*)0))
1137 return;
1138 if ((ctxt != NULL((void*)0)) && (ctxt->freeStates == NULL((void*)0))) {
1139 ctxt->freeStatesMax = 40;
1140 ctxt->freeStatesNr = 0;
1141 ctxt->freeStates = (xmlRelaxNGStatesPtr *)
1142 xmlMalloc(ctxt->freeStatesMax * sizeof(xmlRelaxNGStatesPtr));
1143 if (ctxt->freeStates == NULL((void*)0)) {
1144 xmlRngVErrMemory(ctxt, "storing states\n");
1145 }
1146 } else if ((ctxt != NULL((void*)0))
1147 && (ctxt->freeStatesNr >= ctxt->freeStatesMax)) {
1148 xmlRelaxNGStatesPtr *tmp;
1149
1150 tmp = (xmlRelaxNGStatesPtr *) xmlRealloc(ctxt->freeStates,
1151 2 * ctxt->freeStatesMax *
1152 sizeof
1153 (xmlRelaxNGStatesPtr));
1154 if (tmp == NULL((void*)0)) {
1155 xmlRngVErrMemory(ctxt, "storing states\n");
1156 xmlFree(states->tabState);
1157 xmlFree(states);
1158 return;
1159 }
1160 ctxt->freeStates = tmp;
1161 ctxt->freeStatesMax *= 2;
1162 }
1163 if ((ctxt == NULL((void*)0)) || (ctxt->freeStates == NULL((void*)0))) {
1164 xmlFree(states->tabState);
1165 xmlFree(states);
1166 } else {
1167 ctxt->freeStates[ctxt->freeStatesNr++] = states;
1168 }
1169}
1170
1171/**
1172 * xmlRelaxNGNewValidState:
1173 * @ctxt: a Relax-NG validation context
1174 * @node: the current node or NULL for the document
1175 *
1176 * Allocate a new RelaxNG validation state
1177 *
1178 * Returns the newly allocated structure or NULL in case or error
1179 */
1180static xmlRelaxNGValidStatePtr
1181xmlRelaxNGNewValidState(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node)
1182{
1183 xmlRelaxNGValidStatePtr ret;
1184 xmlAttrPtr attr;
1185 xmlAttrPtr attrs[MAX_ATTR20];
1186 int nbAttrs = 0;
1187 xmlNodePtr root = NULL((void*)0);
1188
1189 if (node == NULL((void*)0)) {
1190 root = xmlDocGetRootElementxmlDocGetRootElement__internal_alias(ctxt->doc);
1191 if (root == NULL((void*)0))
1192 return (NULL((void*)0));
1193 } else {
1194 attr = node->properties;
1195 while (attr != NULL((void*)0)) {
1196 if (nbAttrs < MAX_ATTR20)
1197 attrs[nbAttrs++] = attr;
1198 else
1199 nbAttrs++;
1200 attr = attr->next;
1201 }
1202 }
1203 if ((ctxt->freeState != NULL((void*)0)) && (ctxt->freeState->nbState > 0)) {
1204 ctxt->freeState->nbState--;
1205 ret = ctxt->freeState->tabState[ctxt->freeState->nbState];
1206 } else {
1207 ret =
1208 (xmlRelaxNGValidStatePtr)
1209 xmlMalloc(sizeof(xmlRelaxNGValidState));
1210 if (ret == NULL((void*)0)) {
1211 xmlRngVErrMemory(ctxt, "allocating states\n");
1212 return (NULL((void*)0));
1213 }
1214 memset(ret, 0, sizeof(xmlRelaxNGValidState));
1215 }
1216 ret->value = NULL((void*)0);
1217 ret->endvalue = NULL((void*)0);
1218 if (node == NULL((void*)0)) {
1219 ret->node = (xmlNodePtr) ctxt->doc;
1220 ret->seq = root;
1221 } else {
1222 ret->node = node;
1223 ret->seq = node->children;
1224 }
1225 ret->nbAttrs = 0;
1226 if (nbAttrs > 0) {
1227 if (ret->attrs == NULL((void*)0)) {
1228 if (nbAttrs < 4)
1229 ret->maxAttrs = 4;
1230 else
1231 ret->maxAttrs = nbAttrs;
1232 ret->attrs = (xmlAttrPtr *) xmlMalloc(ret->maxAttrs *
1233 sizeof(xmlAttrPtr));
1234 if (ret->attrs == NULL((void*)0)) {
1235 xmlRngVErrMemory(ctxt, "allocating states\n");
1236 return (ret);
1237 }
1238 } else if (ret->maxAttrs < nbAttrs) {
1239 xmlAttrPtr *tmp;
1240
1241 tmp = (xmlAttrPtr *) xmlRealloc(ret->attrs, nbAttrs *
1242 sizeof(xmlAttrPtr));
1243 if (tmp == NULL((void*)0)) {
1244 xmlRngVErrMemory(ctxt, "allocating states\n");
1245 return (ret);
1246 }
1247 ret->attrs = tmp;
1248 ret->maxAttrs = nbAttrs;
1249 }
1250 ret->nbAttrs = nbAttrs;
1251 if (nbAttrs < MAX_ATTR20) {
1252 memcpy(ret->attrs, attrs, sizeof(xmlAttrPtr) * nbAttrs);
1253 } else {
1254 attr = node->properties;
1255 nbAttrs = 0;
1256 while (attr != NULL((void*)0)) {
1257 ret->attrs[nbAttrs++] = attr;
1258 attr = attr->next;
1259 }
1260 }
1261 }
1262 ret->nbAttrLeft = ret->nbAttrs;
1263 return (ret);
1264}
1265
1266/**
1267 * xmlRelaxNGCopyValidState:
1268 * @ctxt: a Relax-NG validation context
1269 * @state: a validation state
1270 *
1271 * Copy the validation state
1272 *
1273 * Returns the newly allocated structure or NULL in case or error
1274 */
1275static xmlRelaxNGValidStatePtr
1276xmlRelaxNGCopyValidState(xmlRelaxNGValidCtxtPtr ctxt,
1277 xmlRelaxNGValidStatePtr state)
1278{
1279 xmlRelaxNGValidStatePtr ret;
1280 unsigned int maxAttrs;
1281 xmlAttrPtr *attrs;
1282
1283 if (state == NULL((void*)0))
1284 return (NULL((void*)0));
1285 if ((ctxt->freeState != NULL((void*)0)) && (ctxt->freeState->nbState > 0)) {
1286 ctxt->freeState->nbState--;
1287 ret = ctxt->freeState->tabState[ctxt->freeState->nbState];
1288 } else {
1289 ret =
1290 (xmlRelaxNGValidStatePtr)
1291 xmlMalloc(sizeof(xmlRelaxNGValidState));
1292 if (ret == NULL((void*)0)) {
1293 xmlRngVErrMemory(ctxt, "allocating states\n");
1294 return (NULL((void*)0));
1295 }
1296 memset(ret, 0, sizeof(xmlRelaxNGValidState));
1297 }
1298 attrs = ret->attrs;
1299 maxAttrs = ret->maxAttrs;
1300 memcpy(ret, state, sizeof(xmlRelaxNGValidState));
1301 ret->attrs = attrs;
1302 ret->maxAttrs = maxAttrs;
1303 if (state->nbAttrs > 0) {
1304 if (ret->attrs == NULL((void*)0)) {
1305 ret->maxAttrs = state->maxAttrs;
1306 ret->attrs = (xmlAttrPtr *) xmlMalloc(ret->maxAttrs *
1307 sizeof(xmlAttrPtr));
1308 if (ret->attrs == NULL((void*)0)) {
1309 xmlRngVErrMemory(ctxt, "allocating states\n");
1310 ret->nbAttrs = 0;
1311 return (ret);
1312 }
1313 } else if (ret->maxAttrs < state->nbAttrs) {
1314 xmlAttrPtr *tmp;
1315
1316 tmp = (xmlAttrPtr *) xmlRealloc(ret->attrs, state->maxAttrs *
1317 sizeof(xmlAttrPtr));
1318 if (tmp == NULL((void*)0)) {
1319 xmlRngVErrMemory(ctxt, "allocating states\n");
1320 ret->nbAttrs = 0;
1321 return (ret);
1322 }
1323 ret->maxAttrs = state->maxAttrs;
1324 ret->attrs = tmp;
1325 }
1326 memcpy(ret->attrs, state->attrs,
1327 state->nbAttrs * sizeof(xmlAttrPtr));
1328 }
1329 return (ret);
1330}
1331
1332/**
1333 * xmlRelaxNGEqualValidState:
1334 * @ctxt: a Relax-NG validation context
1335 * @state1: a validation state
1336 * @state2: a validation state
1337 *
1338 * Compare the validation states for equality
1339 *
1340 * Returns 1 if equald, 0 otherwise
1341 */
1342static int
1343xmlRelaxNGEqualValidState(xmlRelaxNGValidCtxtPtr ctxt ATTRIBUTE_UNUSED__attribute__((unused)),
1344 xmlRelaxNGValidStatePtr state1,
1345 xmlRelaxNGValidStatePtr state2)
1346{
1347 int i;
1348
1349 if ((state1 == NULL((void*)0)) || (state2 == NULL((void*)0)))
1350 return (0);
1351 if (state1 == state2)
1352 return (1);
1353 if (state1->node != state2->node)
1354 return (0);
1355 if (state1->seq != state2->seq)
1356 return (0);
1357 if (state1->nbAttrLeft != state2->nbAttrLeft)
1358 return (0);
1359 if (state1->nbAttrs != state2->nbAttrs)
1360 return (0);
1361 if (state1->endvalue != state2->endvalue)
1362 return (0);
1363 if ((state1->value != state2->value) &&
1364 (!xmlStrEqualxmlStrEqual__internal_alias(state1->value, state2->value)))
1365 return (0);
1366 for (i = 0; i < state1->nbAttrs; i++) {
1367 if (state1->attrs[i] != state2->attrs[i])
1368 return (0);
1369 }
1370 return (1);
1371}
1372
1373/**
1374 * xmlRelaxNGFreeValidState:
1375 * @state: a validation state structure
1376 *
1377 * Deallocate a RelaxNG validation state structure.
1378 */
1379static void
1380xmlRelaxNGFreeValidState(xmlRelaxNGValidCtxtPtr ctxt,
1381 xmlRelaxNGValidStatePtr state)
1382{
1383 if (state == NULL((void*)0))
1384 return;
1385
1386 if ((ctxt != NULL((void*)0)) && (ctxt->freeState == NULL((void*)0))) {
1387 ctxt->freeState = xmlRelaxNGNewStates(ctxt, 40);
1388 }
1389 if ((ctxt == NULL((void*)0)) || (ctxt->freeState == NULL((void*)0))) {
1390 if (state->attrs != NULL((void*)0))
1391 xmlFree(state->attrs);
1392 xmlFree(state);
1393 } else {
1394 xmlRelaxNGAddStatesUniq(ctxt, ctxt->freeState, state);
1395 }
1396}
1397
1398/************************************************************************
1399 * *
1400 * Semi internal functions *
1401 * *
1402 ************************************************************************/
1403
1404/**
1405 * xmlRelaxParserSetFlag:
1406 * @ctxt: a RelaxNG parser context
1407 * @flags: a set of flags values
1408 *
1409 * Semi private function used to pass informations to a parser context
1410 * which are a combination of xmlRelaxNGParserFlag .
1411 *
1412 * Returns 0 if success and -1 in case of error
1413 */
1414int
1415xmlRelaxParserSetFlag(xmlRelaxNGParserCtxtPtr ctxt, int flags)
1416{
1417 if (ctxt == NULL((void*)0)) return(-1);
1418 if (flags & XML_RELAXNGP_FREE_DOC) {
1419 ctxt->crng |= XML_RELAXNGP_FREE_DOC;
1420 flags -= XML_RELAXNGP_FREE_DOC;
1421 }
1422 if (flags & XML_RELAXNGP_CRNG) {
1423 ctxt->crng |= XML_RELAXNGP_CRNG;
1424 flags -= XML_RELAXNGP_CRNG;
1425 }
1426 if (flags != 0) return(-1);
1427 return(0);
1428}
1429
1430/************************************************************************
1431 * *
1432 * Document functions *
1433 * *
1434 ************************************************************************/
1435static xmlDocPtr xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt,
1436 xmlDocPtr doc);
1437
1438/**
1439 * xmlRelaxNGIncludePush:
1440 * @ctxt: the parser context
1441 * @value: the element doc
1442 *
1443 * Pushes a new include on top of the include stack
1444 *
1445 * Returns 0 in case of error, the index in the stack otherwise
1446 */
1447static int
1448xmlRelaxNGIncludePush(xmlRelaxNGParserCtxtPtr ctxt,
1449 xmlRelaxNGIncludePtr value)
1450{
1451 if (ctxt->incTab == NULL((void*)0)) {
1452 ctxt->incMax = 4;
1453 ctxt->incNr = 0;
1454 ctxt->incTab =
1455 (xmlRelaxNGIncludePtr *) xmlMalloc(ctxt->incMax *
1456 sizeof(ctxt->incTab[0]));
1457 if (ctxt->incTab == NULL((void*)0)) {
1458 xmlRngPErrMemory(ctxt, "allocating include\n");
1459 return (0);
1460 }
1461 }
1462 if (ctxt->incNr >= ctxt->incMax) {
1463 ctxt->incMax *= 2;
1464 ctxt->incTab =
1465 (xmlRelaxNGIncludePtr *) xmlRealloc(ctxt->incTab,
1466 ctxt->incMax *
1467 sizeof(ctxt->incTab[0]));
1468 if (ctxt->incTab == NULL((void*)0)) {
1469 xmlRngPErrMemory(ctxt, "allocating include\n");
1470 return (0);
1471 }
1472 }
1473 ctxt->incTab[ctxt->incNr] = value;
1474 ctxt->inc = value;
1475 return (ctxt->incNr++);
1476}
1477
1478/**
1479 * xmlRelaxNGIncludePop:
1480 * @ctxt: the parser context
1481 *
1482 * Pops the top include from the include stack
1483 *
1484 * Returns the include just removed
1485 */
1486static xmlRelaxNGIncludePtr
1487xmlRelaxNGIncludePop(xmlRelaxNGParserCtxtPtr ctxt)
1488{
1489 xmlRelaxNGIncludePtr ret;
1490
1491 if (ctxt->incNr <= 0)
1492 return (NULL((void*)0));
1493 ctxt->incNr--;
1494 if (ctxt->incNr > 0)
1495 ctxt->inc = ctxt->incTab[ctxt->incNr - 1];
1496 else
1497 ctxt->inc = NULL((void*)0);
1498 ret = ctxt->incTab[ctxt->incNr];
1499 ctxt->incTab[ctxt->incNr] = NULL((void*)0);
1500 return (ret);
1501}
1502
1503/**
1504 * xmlRelaxNGRemoveRedefine:
1505 * @ctxt: the parser context
1506 * @URL: the normalized URL
1507 * @target: the included target
1508 * @name: the define name to eliminate
1509 *
1510 * Applies the elimination algorithm of 4.7
1511 *
1512 * Returns 0 in case of error, 1 in case of success.
1513 */
1514static int
1515xmlRelaxNGRemoveRedefine(xmlRelaxNGParserCtxtPtr ctxt,
1516 const xmlChar * URL ATTRIBUTE_UNUSED__attribute__((unused)),
1517 xmlNodePtr target, const xmlChar * name)
1518{
1519 int found = 0;
1520 xmlNodePtr tmp, tmp2;
1521 xmlChar *name2;
1522
1523#ifdef DEBUG_INCLUDE
1524 if (name == NULL((void*)0))
1525 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
1526 "Elimination of <include> start from %s\n", URL);
1527 else
1528 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
1529 "Elimination of <include> define %s from %s\n",
1530 name, URL);
1531#endif
1532 tmp = target;
1533 while (tmp != NULL((void*)0)) {
1534 tmp2 = tmp->next;
1535 if ((name == NULL((void*)0)) && (IS_RELAXNG(tmp, "start")((tmp != ((void*)0)) && (tmp->ns != ((void*)0)) &&
(xmlStrEqual__internal_alias(tmp->name, (const xmlChar *)
"start")) && (xmlStrEqual__internal_alias(tmp->ns
->href, xmlRelaxNGNs)))
)) {
1536 found = 1;
1537 xmlUnlinkNodexmlUnlinkNode__internal_alias(tmp);
1538 xmlFreeNodexmlFreeNode__internal_alias(tmp);
1539 } else if ((name != NULL((void*)0)) && (IS_RELAXNG(tmp, "define")((tmp != ((void*)0)) && (tmp->ns != ((void*)0)) &&
(xmlStrEqual__internal_alias(tmp->name, (const xmlChar *)
"define")) && (xmlStrEqual__internal_alias(tmp->ns
->href, xmlRelaxNGNs)))
)) {
1540 name2 = xmlGetPropxmlGetProp__internal_alias(tmp, BAD_CAST(xmlChar *) "name");
1541 xmlRelaxNGNormExtSpace(name2);
1542 if (name2 != NULL((void*)0)) {
1543 if (xmlStrEqualxmlStrEqual__internal_alias(name, name2)) {
1544 found = 1;
1545 xmlUnlinkNodexmlUnlinkNode__internal_alias(tmp);
1546 xmlFreeNodexmlFreeNode__internal_alias(tmp);
1547 }
1548 xmlFree(name2);
1549 }
1550 } else if (IS_RELAXNG(tmp, "include")((tmp != ((void*)0)) && (tmp->ns != ((void*)0)) &&
(xmlStrEqual__internal_alias(tmp->name, (const xmlChar *)
"include")) && (xmlStrEqual__internal_alias(tmp->
ns->href, xmlRelaxNGNs)))
) {
1551 xmlChar *href = NULL((void*)0);
1552 xmlRelaxNGDocumentPtr inc = tmp->psvi;
1553
1554 if ((inc != NULL((void*)0)) && (inc->doc != NULL((void*)0)) &&
1555 (inc->doc->children != NULL((void*)0))) {
1556
1557 if (xmlStrEqualxmlStrEqual__internal_alias
1558 (inc->doc->children->name, BAD_CAST(xmlChar *) "grammar")) {
1559#ifdef DEBUG_INCLUDE
1560 href = xmlGetPropxmlGetProp__internal_alias(tmp, BAD_CAST(xmlChar *) "href");
1561#endif
1562 if (xmlRelaxNGRemoveRedefine(ctxt, href,
1563 inc->doc->children->
1564 children, name) == 1) {
1565 found = 1;
1566 }
1567#ifdef DEBUG_INCLUDE
1568 if (href != NULL((void*)0))
1569 xmlFree(href);
1570#endif
1571 }
1572 }
1573 }
1574 tmp = tmp2;
1575 }
1576 return (found);
1577}
1578
1579/**
1580 * xmlRelaxNGLoadInclude:
1581 * @ctxt: the parser context
1582 * @URL: the normalized URL
1583 * @node: the include node.
1584 * @ns: the namespace passed from the context.
1585 *
1586 * First lookup if the document is already loaded into the parser context,
1587 * check against recursion. If not found the resource is loaded and
1588 * the content is preprocessed before being returned back to the caller.
1589 *
1590 * Returns the xmlRelaxNGIncludePtr or NULL in case of error
1591 */
1592static xmlRelaxNGIncludePtr
1593xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * URL,
1594 xmlNodePtr node, const xmlChar * ns)
1595{
1596 xmlRelaxNGIncludePtr ret = NULL((void*)0);
1597 xmlDocPtr doc;
1598 int i;
1599 xmlNodePtr root, cur;
1600
1601#ifdef DEBUG_INCLUDE
1602 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
1603 "xmlRelaxNGLoadInclude(%s)\n", URL);
1604#endif
1605
1606 /*
1607 * check against recursion in the stack
1608 */
1609 for (i = 0; i < ctxt->incNr; i++) {
1610 if (xmlStrEqualxmlStrEqual__internal_alias(ctxt->incTab[i]->href, URL)) {
1611 xmlRngPErr(ctxt, NULL((void*)0), XML_RNGP_INCLUDE_RECURSE,
1612 "Detected an Include recursion for %s\n", URL,
1613 NULL((void*)0));
1614 return (NULL((void*)0));
1615 }
1616 }
1617
1618 /*
1619 * load the document
1620 */
1621 doc = xmlReadFilexmlReadFile__internal_alias((const char *) URL,NULL((void*)0),0);
1622 if (doc == NULL((void*)0)) {
1623 xmlRngPErr(ctxt, node, XML_RNGP_PARSE_ERROR,
1624 "xmlRelaxNG: could not load %s\n", URL, NULL((void*)0));
1625 return (NULL((void*)0));
1626 }
1627#ifdef DEBUG_INCLUDE
1628 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())), "Parsed %s Okay\n", URL);
1629#endif
1630
1631 /*
1632 * Allocate the document structures and register it first.
1633 */
1634 ret = (xmlRelaxNGIncludePtr) xmlMalloc(sizeof(xmlRelaxNGInclude));
1635 if (ret == NULL((void*)0)) {
1636 xmlRngPErrMemory(ctxt, "allocating include\n");
1637 xmlFreeDocxmlFreeDoc__internal_alias(doc);
1638 return (NULL((void*)0));
1639 }
1640 memset(ret, 0, sizeof(xmlRelaxNGInclude));
1641 ret->doc = doc;
1642 ret->href = xmlStrdupxmlStrdup__internal_alias(URL);
1643 ret->next = ctxt->includes;
1644 ctxt->includes = ret;
1645
1646 /*
1647 * transmit the ns if needed
1648 */
1649 if (ns != NULL((void*)0)) {
1650 root = xmlDocGetRootElementxmlDocGetRootElement__internal_alias(doc);
1651 if (root != NULL((void*)0)) {
1652 if (xmlHasPropxmlHasProp__internal_alias(root, BAD_CAST(xmlChar *) "ns") == NULL((void*)0)) {
1653 xmlSetPropxmlSetProp__internal_alias(root, BAD_CAST(xmlChar *) "ns", ns);
1654 }
1655 }
1656 }
1657
1658 /*
1659 * push it on the stack
1660 */
1661 xmlRelaxNGIncludePush(ctxt, ret);
1662
1663 /*
1664 * Some preprocessing of the document content, this include recursing
1665 * in the include stack.
1666 */
1667#ifdef DEBUG_INCLUDE
1668 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())), "cleanup of %s\n", URL);
1669#endif
1670
1671 doc = xmlRelaxNGCleanupDoc(ctxt, doc);
1672 if (doc == NULL((void*)0)) {
1673 ctxt->inc = NULL((void*)0);
1674 return (NULL((void*)0));
1675 }
1676
1677 /*
1678 * Pop up the include from the stack
1679 */
1680 xmlRelaxNGIncludePop(ctxt);
1681
1682#ifdef DEBUG_INCLUDE
1683 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())), "Checking of %s\n", URL);
1684#endif
1685 /*
1686 * Check that the top element is a grammar
1687 */
1688 root = xmlDocGetRootElementxmlDocGetRootElement__internal_alias(doc);
1689 if (root == NULL((void*)0)) {
1690 xmlRngPErr(ctxt, node, XML_RNGP_EMPTY,
1691 "xmlRelaxNG: included document is empty %s\n", URL,
1692 NULL((void*)0));
1693 return (NULL((void*)0));
1694 }
1695 if (!IS_RELAXNG(root, "grammar")((root != ((void*)0)) && (root->ns != ((void*)0)) &&
(xmlStrEqual__internal_alias(root->name, (const xmlChar *
) "grammar")) && (xmlStrEqual__internal_alias(root->
ns->href, xmlRelaxNGNs)))
) {
1696 xmlRngPErr(ctxt, node, XML_RNGP_GRAMMAR_MISSING,
1697 "xmlRelaxNG: included document %s root is not a grammar\n",
1698 URL, NULL((void*)0));
1699 return (NULL((void*)0));
1700 }
1701
1702 /*
1703 * Elimination of redefined rules in the include.
1704 */
1705 cur = node->children;
1706 while (cur != NULL((void*)0)) {
1707 if (IS_RELAXNG(cur, "start")((cur != ((void*)0)) && (cur->ns != ((void*)0)) &&
(xmlStrEqual__internal_alias(cur->name, (const xmlChar *)
"start")) && (xmlStrEqual__internal_alias(cur->ns
->href, xmlRelaxNGNs)))
) {
1708 int found = 0;
1709
1710 found =
1711 xmlRelaxNGRemoveRedefine(ctxt, URL, root->children, NULL((void*)0));
1712 if (!found) {
1713 xmlRngPErr(ctxt, node, XML_RNGP_START_MISSING,
1714 "xmlRelaxNG: include %s has a start but not the included grammar\n",
1715 URL, NULL((void*)0));
1716 }
1717 } else if (IS_RELAXNG(cur, "define")((cur != ((void*)0)) && (cur->ns != ((void*)0)) &&
(xmlStrEqual__internal_alias(cur->name, (const xmlChar *)
"define")) && (xmlStrEqual__internal_alias(cur->ns
->href, xmlRelaxNGNs)))
) {
1718 xmlChar *name;
1719
1720 name = xmlGetPropxmlGetProp__internal_alias(cur, BAD_CAST(xmlChar *) "name");
1721 if (name == NULL((void*)0)) {
1722 xmlRngPErr(ctxt, node, XML_RNGP_NAME_MISSING,
1723 "xmlRelaxNG: include %s has define without name\n",
1724 URL, NULL((void*)0));
1725 } else {
1726 int found;
1727
1728 xmlRelaxNGNormExtSpace(name);
1729 found = xmlRelaxNGRemoveRedefine(ctxt, URL,
1730 root->children, name);
1731 if (!found) {
1732 xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_MISSING,
1733 "xmlRelaxNG: include %s has a define %s but not the included grammar\n",
1734 URL, name);
1735 }
1736 xmlFree(name);
1737 }
1738 }
1739 cur = cur->next;
1740 }
1741
1742
1743 return (ret);
1744}
1745
1746/**
1747 * xmlRelaxNGValidErrorPush:
1748 * @ctxt: the validation context
1749 * @err: the error code
1750 * @arg1: the first string argument
1751 * @arg2: the second string argument
1752 * @dup: arg need to be duplicated
1753 *
1754 * Pushes a new error on top of the error stack
1755 *
1756 * Returns 0 in case of error, the index in the stack otherwise
1757 */
1758static int
1759xmlRelaxNGValidErrorPush(xmlRelaxNGValidCtxtPtr ctxt,
1760 xmlRelaxNGValidErr err, const xmlChar * arg1,
1761 const xmlChar * arg2, int dup)
1762{
1763 xmlRelaxNGValidErrorPtr cur;
1764
1765#ifdef DEBUG_ERROR
1766 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
1767 "Pushing error %d at %d on stack\n", err, ctxt->errNr);
1768#endif
1769 if (ctxt->errTab == NULL((void*)0)) {
1770 ctxt->errMax = 8;
1771 ctxt->errNr = 0;
1772 ctxt->errTab =
1773 (xmlRelaxNGValidErrorPtr) xmlMalloc(ctxt->errMax *
1774 sizeof
1775 (xmlRelaxNGValidError));
1776 if (ctxt->errTab == NULL((void*)0)) {
1777 xmlRngVErrMemory(ctxt, "pushing error\n");
1778 return (0);
1779 }
1780 ctxt->err = NULL((void*)0);
1781 }
1782 if (ctxt->errNr >= ctxt->errMax) {
1783 ctxt->errMax *= 2;
1784 ctxt->errTab =
1785 (xmlRelaxNGValidErrorPtr) xmlRealloc(ctxt->errTab,
1786 ctxt->errMax *
1787 sizeof
1788 (xmlRelaxNGValidError));
1789 if (ctxt->errTab == NULL((void*)0)) {
1790 xmlRngVErrMemory(ctxt, "pushing error\n");
1791 return (0);
1792 }
1793 ctxt->err = &ctxt->errTab[ctxt->errNr - 1];
1794 }
1795 if ((ctxt->err != NULL((void*)0)) && (ctxt->state != NULL((void*)0)) &&
1796 (ctxt->err->node == ctxt->state->node) && (ctxt->err->err == err))
1797 return (ctxt->errNr);
1798 cur = &ctxt->errTab[ctxt->errNr];
1799 cur->err = err;
1800 if (dup) {
1801 cur->arg1 = xmlStrdupxmlStrdup__internal_alias(arg1);
1802 cur->arg2 = xmlStrdupxmlStrdup__internal_alias(arg2);
1803 cur->flags = ERROR_IS_DUP1;
1804 } else {
1805 cur->arg1 = arg1;
1806 cur->arg2 = arg2;
1807 cur->flags = 0;
1808 }
1809 if (ctxt->state != NULL((void*)0)) {
1810 cur->node = ctxt->state->node;
1811 cur->seq = ctxt->state->seq;
1812 } else {
1813 cur->node = NULL((void*)0);
1814 cur->seq = NULL((void*)0);
1815 }
1816 ctxt->err = cur;
1817 return (ctxt->errNr++);
1818}
1819
1820/**
1821 * xmlRelaxNGValidErrorPop:
1822 * @ctxt: the validation context
1823 *
1824 * Pops the top error from the error stack
1825 */
1826static void
1827xmlRelaxNGValidErrorPop(xmlRelaxNGValidCtxtPtr ctxt)
1828{
1829 xmlRelaxNGValidErrorPtr cur;
1830
1831 if (ctxt->errNr <= 0) {
1832 ctxt->err = NULL((void*)0);
1833 return;
1834 }
1835 ctxt->errNr--;
1836 if (ctxt->errNr > 0)
1837 ctxt->err = &ctxt->errTab[ctxt->errNr - 1];
1838 else
1839 ctxt->err = NULL((void*)0);
1840 cur = &ctxt->errTab[ctxt->errNr];
1841 if (cur->flags & ERROR_IS_DUP1) {
1842 if (cur->arg1 != NULL((void*)0))
1843 xmlFree((xmlChar *) cur->arg1);
1844 cur->arg1 = NULL((void*)0);
1845 if (cur->arg2 != NULL((void*)0))
1846 xmlFree((xmlChar *) cur->arg2);
1847 cur->arg2 = NULL((void*)0);
1848 cur->flags = 0;
1849 }
1850}
1851
1852/**
1853 * xmlRelaxNGDocumentPush:
1854 * @ctxt: the parser context
1855 * @value: the element doc
1856 *
1857 * Pushes a new doc on top of the doc stack
1858 *
1859 * Returns 0 in case of error, the index in the stack otherwise
1860 */
1861static int
1862xmlRelaxNGDocumentPush(xmlRelaxNGParserCtxtPtr ctxt,
1863 xmlRelaxNGDocumentPtr value)
1864{
1865 if (ctxt->docTab == NULL((void*)0)) {
1866 ctxt->docMax = 4;
1867 ctxt->docNr = 0;
1868 ctxt->docTab =
1869 (xmlRelaxNGDocumentPtr *) xmlMalloc(ctxt->docMax *
1870 sizeof(ctxt->docTab[0]));
1871 if (ctxt->docTab == NULL((void*)0)) {
1872 xmlRngPErrMemory(ctxt, "adding document\n");
1873 return (0);
1874 }
1875 }
1876 if (ctxt->docNr >= ctxt->docMax) {
1877 ctxt->docMax *= 2;
1878 ctxt->docTab =
1879 (xmlRelaxNGDocumentPtr *) xmlRealloc(ctxt->docTab,
1880 ctxt->docMax *
1881 sizeof(ctxt->docTab[0]));
1882 if (ctxt->docTab == NULL((void*)0)) {
1883 xmlRngPErrMemory(ctxt, "adding document\n");
1884 return (0);
1885 }
1886 }
1887 ctxt->docTab[ctxt->docNr] = value;
1888 ctxt->doc = value;
1889 return (ctxt->docNr++);
1890}
1891
1892/**
1893 * xmlRelaxNGDocumentPop:
1894 * @ctxt: the parser context
1895 *
1896 * Pops the top doc from the doc stack
1897 *
1898 * Returns the doc just removed
1899 */
1900static xmlRelaxNGDocumentPtr
1901xmlRelaxNGDocumentPop(xmlRelaxNGParserCtxtPtr ctxt)
1902{
1903 xmlRelaxNGDocumentPtr ret;
1904
1905 if (ctxt->docNr <= 0)
1906 return (NULL((void*)0));
1907 ctxt->docNr--;
1908 if (ctxt->docNr > 0)
1909 ctxt->doc = ctxt->docTab[ctxt->docNr - 1];
1910 else
1911 ctxt->doc = NULL((void*)0);
1912 ret = ctxt->docTab[ctxt->docNr];
1913 ctxt->docTab[ctxt->docNr] = NULL((void*)0);
1914 return (ret);
1915}
1916
1917/**
1918 * xmlRelaxNGLoadExternalRef:
1919 * @ctxt: the parser context
1920 * @URL: the normalized URL
1921 * @ns: the inherited ns if any
1922 *
1923 * First lookup if the document is already loaded into the parser context,
1924 * check against recursion. If not found the resource is loaded and
1925 * the content is preprocessed before being returned back to the caller.
1926 *
1927 * Returns the xmlRelaxNGDocumentPtr or NULL in case of error
1928 */
1929static xmlRelaxNGDocumentPtr
1930xmlRelaxNGLoadExternalRef(xmlRelaxNGParserCtxtPtr ctxt,
1931 const xmlChar * URL, const xmlChar * ns)
1932{
1933 xmlRelaxNGDocumentPtr ret = NULL((void*)0);
1934 xmlDocPtr doc;
1935 xmlNodePtr root;
1936 int i;
1937
1938 /*
1939 * check against recursion in the stack
1940 */
1941 for (i = 0; i < ctxt->docNr; i++) {
1942 if (xmlStrEqualxmlStrEqual__internal_alias(ctxt->docTab[i]->href, URL)) {
1943 xmlRngPErr(ctxt, NULL((void*)0), XML_RNGP_EXTERNALREF_RECURSE,
1944 "Detected an externalRef recursion for %s\n", URL,
1945 NULL((void*)0));
1946 return (NULL((void*)0));
1947 }
1948 }
1949
1950 /*
1951 * load the document
1952 */
1953 doc = xmlReadFilexmlReadFile__internal_alias((const char *) URL,NULL((void*)0),0);
1954 if (doc == NULL((void*)0)) {
1955 xmlRngPErr(ctxt, NULL((void*)0), XML_RNGP_PARSE_ERROR,
1956 "xmlRelaxNG: could not load %s\n", URL, NULL((void*)0));
1957 return (NULL((void*)0));
1958 }
1959
1960 /*
1961 * Allocate the document structures and register it first.
1962 */
1963 ret = (xmlRelaxNGDocumentPtr) xmlMalloc(sizeof(xmlRelaxNGDocument));
1964 if (ret == NULL((void*)0)) {
1965 xmlRngPErr(ctxt, (xmlNodePtr) doc, XML_ERR_NO_MEMORY,
1966 "xmlRelaxNG: allocate memory for doc %s\n", URL, NULL((void*)0));
1967 xmlFreeDocxmlFreeDoc__internal_alias(doc);
1968 return (NULL((void*)0));
1969 }
1970 memset(ret, 0, sizeof(xmlRelaxNGDocument));
1971 ret->doc = doc;
1972 ret->href = xmlStrdupxmlStrdup__internal_alias(URL);
1973 ret->next = ctxt->documents;
1974 ret->externalRef = 1;
1975 ctxt->documents = ret;
1976
1977 /*
1978 * transmit the ns if needed
1979 */
1980 if (ns != NULL((void*)0)) {
1981 root = xmlDocGetRootElementxmlDocGetRootElement__internal_alias(doc);
1982 if (root != NULL((void*)0)) {
1983 if (xmlHasPropxmlHasProp__internal_alias(root, BAD_CAST(xmlChar *) "ns") == NULL((void*)0)) {
1984 xmlSetPropxmlSetProp__internal_alias(root, BAD_CAST(xmlChar *) "ns", ns);
1985 }
1986 }
1987 }
1988
1989 /*
1990 * push it on the stack and register it in the hash table
1991 */
1992 xmlRelaxNGDocumentPush(ctxt, ret);
1993
1994 /*
1995 * Some preprocessing of the document content
1996 */
1997 doc = xmlRelaxNGCleanupDoc(ctxt, doc);
1998 if (doc == NULL((void*)0)) {
1999 ctxt->doc = NULL((void*)0);
2000 return (NULL((void*)0));
2001 }
2002
2003 xmlRelaxNGDocumentPop(ctxt);
2004
2005 return (ret);
2006}
2007
2008/************************************************************************
2009 * *
2010 * Error functions *
2011 * *
2012 ************************************************************************/
2013
2014#define VALID_ERR(a)xmlRelaxNGAddValidError(ctxt, a, ((void*)0), ((void*)0), 0); xmlRelaxNGAddValidError(ctxt, a, NULL((void*)0), NULL((void*)0), 0);
2015#define VALID_ERR2(a, b)xmlRelaxNGAddValidError(ctxt, a, b, ((void*)0), 0); xmlRelaxNGAddValidError(ctxt, a, b, NULL((void*)0), 0);
2016#define VALID_ERR3(a, b, c)xmlRelaxNGAddValidError(ctxt, a, b, c, 0); xmlRelaxNGAddValidError(ctxt, a, b, c, 0);
2017#define VALID_ERR2P(a, b)xmlRelaxNGAddValidError(ctxt, a, b, ((void*)0), 1); xmlRelaxNGAddValidError(ctxt, a, b, NULL((void*)0), 1);
2018#define VALID_ERR3P(a, b, c)xmlRelaxNGAddValidError(ctxt, a, b, c, 1); xmlRelaxNGAddValidError(ctxt, a, b, c, 1);
2019
2020static const char *
2021xmlRelaxNGDefName(xmlRelaxNGDefinePtr def)
2022{
2023 if (def == NULL((void*)0))
2024 return ("none");
2025 switch (def->type) {
2026 case XML_RELAXNG_EMPTY:
2027 return ("empty");
2028 case XML_RELAXNG_NOT_ALLOWED:
2029 return ("notAllowed");
2030 case XML_RELAXNG_EXCEPT:
2031 return ("except");
2032 case XML_RELAXNG_TEXT:
2033 return ("text");
2034 case XML_RELAXNG_ELEMENT:
2035 return ("element");
2036 case XML_RELAXNG_DATATYPE:
2037 return ("datatype");
2038 case XML_RELAXNG_VALUE:
2039 return ("value");
2040 case XML_RELAXNG_LIST:
2041 return ("list");
2042 case XML_RELAXNG_ATTRIBUTE:
2043 return ("attribute");
2044 case XML_RELAXNG_DEF:
2045 return ("def");
2046 case XML_RELAXNG_REF:
2047 return ("ref");
2048 case XML_RELAXNG_EXTERNALREF:
2049 return ("externalRef");
2050 case XML_RELAXNG_PARENTREF:
2051 return ("parentRef");
2052 case XML_RELAXNG_OPTIONAL:
2053 return ("optional");
2054 case XML_RELAXNG_ZEROORMORE:
2055 return ("zeroOrMore");
2056 case XML_RELAXNG_ONEORMORE:
2057 return ("oneOrMore");
2058 case XML_RELAXNG_CHOICE:
2059 return ("choice");
2060 case XML_RELAXNG_GROUP:
2061 return ("group");
2062 case XML_RELAXNG_INTERLEAVE:
2063 return ("interleave");
2064 case XML_RELAXNG_START:
2065 return ("start");
2066 case XML_RELAXNG_NOOP:
2067 return ("noop");
2068 case XML_RELAXNG_PARAM:
2069 return ("param");
2070 }
2071 return ("unknown");
2072}
2073
2074/**
2075 * xmlRelaxNGGetErrorString:
2076 * @err: the error code
2077 * @arg1: the first string argument
2078 * @arg2: the second string argument
2079 *
2080 * computes a formatted error string for the given error code and args
2081 *
2082 * Returns the error string, it must be deallocated by the caller
2083 */
2084static xmlChar *
2085xmlRelaxNGGetErrorString(xmlRelaxNGValidErr err, const xmlChar * arg1,
2086 const xmlChar * arg2)
2087{
2088 char msg[1000];
2089
2090 if (arg1 == NULL((void*)0))
2091 arg1 = BAD_CAST(xmlChar *) "";
2092 if (arg2 == NULL((void*)0))
2093 arg2 = BAD_CAST(xmlChar *) "";
2094
2095 msg[0] = 0;
2096 switch (err) {
2097 case XML_RELAXNG_OK:
2098 return (NULL((void*)0));
2099 case XML_RELAXNG_ERR_MEMORY:
2100 return (xmlCharStrdupxmlCharStrdup__internal_alias("out of memory\n"));
2101 case XML_RELAXNG_ERR_TYPE:
2102 snprintf(msg, 1000, "failed to validate type %s\n", arg1);
2103 break;
2104 case XML_RELAXNG_ERR_TYPEVAL:
2105 snprintf(msg, 1000, "Type %s doesn't allow value '%s'\n", arg1,
2106 arg2);
2107 break;
2108 case XML_RELAXNG_ERR_DUPID:
2109 snprintf(msg, 1000, "ID %s redefined\n", arg1);
2110 break;
2111 case XML_RELAXNG_ERR_TYPECMP:
2112 snprintf(msg, 1000, "failed to compare type %s\n", arg1);
2113 break;
2114 case XML_RELAXNG_ERR_NOSTATE:
2115 return (xmlCharStrdupxmlCharStrdup__internal_alias("Internal error: no state\n"));
2116 case XML_RELAXNG_ERR_NODEFINE:
2117 return (xmlCharStrdupxmlCharStrdup__internal_alias("Internal error: no define\n"));
2118 case XML_RELAXNG_ERR_INTERNAL:
2119 snprintf(msg, 1000, "Internal error: %s\n", arg1);
2120 break;
2121 case XML_RELAXNG_ERR_LISTEXTRA:
2122 snprintf(msg, 1000, "Extra data in list: %s\n", arg1);
2123 break;
2124 case XML_RELAXNG_ERR_INTERNODATA:
2125 return (xmlCharStrdupxmlCharStrdup__internal_alias
2126 ("Internal: interleave block has no data\n"));
2127 case XML_RELAXNG_ERR_INTERSEQ:
2128 return (xmlCharStrdupxmlCharStrdup__internal_alias("Invalid sequence in interleave\n"));
2129 case XML_RELAXNG_ERR_INTEREXTRA:
2130 snprintf(msg, 1000, "Extra element %s in interleave\n", arg1);
2131 break;
2132 case XML_RELAXNG_ERR_ELEMNAME:
2133 snprintf(msg, 1000, "Expecting element %s, got %s\n", arg1,
2134 arg2);
2135 break;
2136 case XML_RELAXNG_ERR_ELEMNONS:
2137 snprintf(msg, 1000, "Expecting a namespace for element %s\n",
2138 arg1);
2139 break;
2140 case XML_RELAXNG_ERR_ELEMWRONGNS:
2141 snprintf(msg, 1000,
2142 "Element %s has wrong namespace: expecting %s\n", arg1,
2143 arg2);
2144 break;
2145 case XML_RELAXNG_ERR_ELEMWRONG:
2146 snprintf(msg, 1000, "Did not expect element %s there\n", arg1);
2147 break;
2148 case XML_RELAXNG_ERR_TEXTWRONG:
2149 snprintf(msg, 1000,
2150 "Did not expect text in element %s content\n", arg1);
2151 break;
2152 case XML_RELAXNG_ERR_ELEMEXTRANS:
2153 snprintf(msg, 1000, "Expecting no namespace for element %s\n",
2154 arg1);
2155 break;
2156 case XML_RELAXNG_ERR_ELEMNOTEMPTY:
2157 snprintf(msg, 1000, "Expecting element %s to be empty\n", arg1);
2158 break;
2159 case XML_RELAXNG_ERR_NOELEM:
2160 snprintf(msg, 1000, "Expecting an element %s, got nothing\n",
2161 arg1);
2162 break;
2163 case XML_RELAXNG_ERR_NOTELEM:
2164 return (xmlCharStrdupxmlCharStrdup__internal_alias("Expecting an element got text\n"));
2165 case XML_RELAXNG_ERR_ATTRVALID:
2166 snprintf(msg, 1000, "Element %s failed to validate attributes\n",
2167 arg1);
2168 break;
2169 case XML_RELAXNG_ERR_CONTENTVALID:
2170 snprintf(msg, 1000, "Element %s failed to validate content\n",
2171 arg1);
2172 break;
2173 case XML_RELAXNG_ERR_EXTRACONTENT:
2174 snprintf(msg, 1000, "Element %s has extra content: %s\n",
2175 arg1, arg2);
2176 break;
2177 case XML_RELAXNG_ERR_INVALIDATTR:
2178 snprintf(msg, 1000, "Invalid attribute %s for element %s\n",
2179 arg1, arg2);
2180 break;
2181 case XML_RELAXNG_ERR_LACKDATA:
2182 snprintf(msg, 1000, "Datatype element %s contains no data\n",
2183 arg1);
2184 break;
2185 case XML_RELAXNG_ERR_DATAELEM:
2186 snprintf(msg, 1000, "Datatype element %s has child elements\n",
2187 arg1);
2188 break;
2189 case XML_RELAXNG_ERR_VALELEM:
2190 snprintf(msg, 1000, "Value element %s has child elements\n",
2191 arg1);
2192 break;
2193 case XML_RELAXNG_ERR_LISTELEM:
2194 snprintf(msg, 1000, "List element %s has child elements\n",
2195 arg1);
2196 break;
2197 case XML_RELAXNG_ERR_DATATYPE:
2198 snprintf(msg, 1000, "Error validating datatype %s\n", arg1);
2199 break;
2200 case XML_RELAXNG_ERR_VALUE:
2201 snprintf(msg, 1000, "Error validating value %s\n", arg1);
2202 break;
2203 case XML_RELAXNG_ERR_LIST:
2204 return (xmlCharStrdupxmlCharStrdup__internal_alias("Error validating list\n"));
2205 case XML_RELAXNG_ERR_NOGRAMMAR:
2206 return (xmlCharStrdupxmlCharStrdup__internal_alias("No top grammar defined\n"));
2207 case XML_RELAXNG_ERR_EXTRADATA:
2208 return (xmlCharStrdupxmlCharStrdup__internal_alias("Extra data in the document\n"));
2209 default:
2210 return (xmlCharStrdupxmlCharStrdup__internal_alias("Unknown error !\n"));
2211 }
2212 if (msg[0] == 0) {
2213 snprintf(msg, 1000, "Unknown error code %d\n", err);
2214 }
2215 msg[1000 - 1] = 0;
2216 return (xmlStrdupxmlStrdup__internal_alias((xmlChar *) msg));
2217}
2218
2219/**
2220 * xmlRelaxNGShowValidError:
2221 * @ctxt: the validation context
2222 * @err: the error number
2223 * @node: the node
2224 * @child: the node child generating the problem.
2225 * @arg1: the first argument
2226 * @arg2: the second argument
2227 *
2228 * Show a validation error.
2229 */
2230static void
2231xmlRelaxNGShowValidError(xmlRelaxNGValidCtxtPtr ctxt,
2232 xmlRelaxNGValidErr err, xmlNodePtr node,
2233 xmlNodePtr child, const xmlChar * arg1,
2234 const xmlChar * arg2)
2235{
2236 xmlChar *msg;
2237
2238 if (ctxt->flags & FLAGS_NOERROR8)
2239 return;
2240
2241#ifdef DEBUG_ERROR
2242 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())), "Show error %d\n", err);
2243#endif
2244 msg = xmlRelaxNGGetErrorString(err, arg1, arg2);
2245 if (msg == NULL((void*)0))
2246 return;
2247
2248 if (ctxt->errNo == XML_RELAXNG_OK)
2249 ctxt->errNo = err;
2250 xmlRngVErr(ctxt, (child == NULL((void*)0) ? node : child), err,
2251 (const char *) msg, arg1, arg2);
2252 xmlFree(msg);
2253}
2254
2255/**
2256 * xmlRelaxNGPopErrors:
2257 * @ctxt: the validation context
2258 * @level: the error level in the stack
2259 *
2260 * pop and discard all errors until the given level is reached
2261 */
2262static void
2263xmlRelaxNGPopErrors(xmlRelaxNGValidCtxtPtr ctxt, int level)
2264{
2265 int i;
2266 xmlRelaxNGValidErrorPtr err;
2267
2268#ifdef DEBUG_ERROR
2269 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
2270 "Pop errors till level %d\n", level);
2271#endif
2272 for (i = level; i < ctxt->errNr; i++) {
2273 err = &ctxt->errTab[i];
2274 if (err->flags & ERROR_IS_DUP1) {
2275 if (err->arg1 != NULL((void*)0))
2276 xmlFree((xmlChar *) err->arg1);
2277 err->arg1 = NULL((void*)0);
2278 if (err->arg2 != NULL((void*)0))
2279 xmlFree((xmlChar *) err->arg2);
2280 err->arg2 = NULL((void*)0);
2281 err->flags = 0;
2282 }
2283 }
2284 ctxt->errNr = level;
2285 if (ctxt->errNr <= 0)
2286 ctxt->err = NULL((void*)0);
2287}
2288
2289/**
2290 * xmlRelaxNGDumpValidError:
2291 * @ctxt: the validation context
2292 *
2293 * Show all validation error over a given index.
2294 */
2295static void
2296xmlRelaxNGDumpValidError(xmlRelaxNGValidCtxtPtr ctxt)
2297{
2298 int i, j, k;
2299 xmlRelaxNGValidErrorPtr err, dup;
2300
2301#ifdef DEBUG_ERROR
2302 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
2303 "Dumping error stack %d errors\n", ctxt->errNr);
2304#endif
2305 for (i = 0, k = 0; i < ctxt->errNr; i++) {
2306 err = &ctxt->errTab[i];
2307 if (k < MAX_ERROR5) {
2308 for (j = 0; j < i; j++) {
2309 dup = &ctxt->errTab[j];
2310 if ((err->err == dup->err) && (err->node == dup->node) &&
2311 (xmlStrEqualxmlStrEqual__internal_alias(err->arg1, dup->arg1)) &&
2312 (xmlStrEqualxmlStrEqual__internal_alias(err->arg2, dup->arg2))) {
2313 goto skip;
2314 }
2315 }
2316 xmlRelaxNGShowValidError(ctxt, err->err, err->node, err->seq,
2317 err->arg1, err->arg2);
2318 k++;
2319 }
2320 skip:
2321 if (err->flags & ERROR_IS_DUP1) {
2322 if (err->arg1 != NULL((void*)0))
2323 xmlFree((xmlChar *) err->arg1);
2324 err->arg1 = NULL((void*)0);
2325 if (err->arg2 != NULL((void*)0))
2326 xmlFree((xmlChar *) err->arg2);
2327 err->arg2 = NULL((void*)0);
2328 err->flags = 0;
2329 }
2330 }
2331 ctxt->errNr = 0;
2332}
2333
2334/**
2335 * xmlRelaxNGAddValidError:
2336 * @ctxt: the validation context
2337 * @err: the error number
2338 * @arg1: the first argument
2339 * @arg2: the second argument
2340 * @dup: need to dup the args
2341 *
2342 * Register a validation error, either generating it if it's sure
2343 * or stacking it for later handling if unsure.
2344 */
2345static void
2346xmlRelaxNGAddValidError(xmlRelaxNGValidCtxtPtr ctxt,
2347 xmlRelaxNGValidErr err, const xmlChar * arg1,
2348 const xmlChar * arg2, int dup)
2349{
2350 if (ctxt == NULL((void*)0))
2351 return;
2352 if (ctxt->flags & FLAGS_NOERROR8)
2353 return;
2354
2355#ifdef DEBUG_ERROR
2356 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())), "Adding error %d\n", err);
2357#endif
2358 /*
2359 * generate the error directly
2360 */
2361 if (((ctxt->flags & FLAGS_IGNORABLE1) == 0) ||
2362 (ctxt->flags & FLAGS_NEGATIVE2)) {
2363 xmlNodePtr node, seq;
2364
2365 /*
2366 * Flush first any stacked error which might be the
2367 * real cause of the problem.
2368 */
2369 if (ctxt->errNr != 0)
2370 xmlRelaxNGDumpValidError(ctxt);
2371 if (ctxt->state != NULL((void*)0)) {
2372 node = ctxt->state->node;
2373 seq = ctxt->state->seq;
2374 } else {
2375 node = seq = NULL((void*)0);
2376 }
2377 if ((node == NULL((void*)0)) && (seq == NULL((void*)0))) {
2378 node = ctxt->pnode;
2379 }
2380 xmlRelaxNGShowValidError(ctxt, err, node, seq, arg1, arg2);
2381 }
2382 /*
2383 * Stack the error for later processing if needed
2384 */
2385 else {
2386 xmlRelaxNGValidErrorPush(ctxt, err, arg1, arg2, dup);
2387 }
2388}
2389
2390
2391/************************************************************************
2392 * *
2393 * Type library hooks *
2394 * *
2395 ************************************************************************/
2396static xmlChar *xmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt,
2397 const xmlChar * str);
2398
2399/**
2400 * xmlRelaxNGSchemaTypeHave:
2401 * @data: data needed for the library
2402 * @type: the type name
2403 *
2404 * Check if the given type is provided by
2405 * the W3C XMLSchema Datatype library.
2406 *
2407 * Returns 1 if yes, 0 if no and -1 in case of error.
2408 */
2409static int
2410xmlRelaxNGSchemaTypeHave(void *data ATTRIBUTE_UNUSED__attribute__((unused)), const xmlChar * type)
2411{
2412 xmlSchemaTypePtr typ;
2413
2414 if (type == NULL((void*)0))
2415 return (-1);
2416 typ = xmlSchemaGetPredefinedTypexmlSchemaGetPredefinedType__internal_alias(type,
2417 BAD_CAST(xmlChar *)
2418 "http://www.w3.org/2001/XMLSchema");
2419 if (typ == NULL((void*)0))
2420 return (0);
2421 return (1);
2422}
2423
2424/**
2425 * xmlRelaxNGSchemaTypeCheck:
2426 * @data: data needed for the library
2427 * @type: the type name
2428 * @value: the value to check
2429 * @node: the node
2430 *
2431 * Check if the given type and value are validated by
2432 * the W3C XMLSchema Datatype library.
2433 *
2434 * Returns 1 if yes, 0 if no and -1 in case of error.
2435 */
2436static int
2437xmlRelaxNGSchemaTypeCheck(void *data ATTRIBUTE_UNUSED__attribute__((unused)),
2438 const xmlChar * type,
2439 const xmlChar * value,
2440 void **result, xmlNodePtr node)
2441{
2442 xmlSchemaTypePtr typ;
2443 int ret;
2444
2445 if ((type == NULL((void*)0)) || (value == NULL((void*)0)))
2446 return (-1);
2447 typ = xmlSchemaGetPredefinedTypexmlSchemaGetPredefinedType__internal_alias(type,
2448 BAD_CAST(xmlChar *)
2449 "http://www.w3.org/2001/XMLSchema");
2450 if (typ == NULL((void*)0))
2451 return (-1);
2452 ret = xmlSchemaValPredefTypeNodexmlSchemaValPredefTypeNode__internal_alias(typ, value,
2453 (xmlSchemaValPtr *) result, node);
2454 if (ret == 2) /* special ID error code */
2455 return (2);
2456 if (ret == 0)
2457 return (1);
2458 if (ret > 0)
2459 return (0);
2460 return (-1);
2461}
2462
2463/**
2464 * xmlRelaxNGSchemaFacetCheck:
2465 * @data: data needed for the library
2466 * @type: the type name
2467 * @facet: the facet name
2468 * @val: the facet value
2469 * @strval: the string value
2470 * @value: the value to check
2471 *
2472 * Function provided by a type library to check a value facet
2473 *
2474 * Returns 1 if yes, 0 if no and -1 in case of error.
2475 */
2476static int
2477xmlRelaxNGSchemaFacetCheck(void *data ATTRIBUTE_UNUSED__attribute__((unused)),
2478 const xmlChar * type, const xmlChar * facetname,
2479 const xmlChar * val, const xmlChar * strval,
2480 void *value)
2481{
2482 xmlSchemaFacetPtr facet;
2483 xmlSchemaTypePtr typ;
2484 int ret;
2485
2486 if ((type == NULL((void*)0)) || (strval == NULL((void*)0)))
2487 return (-1);
2488 typ = xmlSchemaGetPredefinedTypexmlSchemaGetPredefinedType__internal_alias(type,
2489 BAD_CAST(xmlChar *)
2490 "http://www.w3.org/2001/XMLSchema");
2491 if (typ == NULL((void*)0))
2492 return (-1);
2493
2494 facet = xmlSchemaNewFacetxmlSchemaNewFacet__internal_alias();
2495 if (facet == NULL((void*)0))
2496 return (-1);
2497
2498 if (xmlStrEqualxmlStrEqual__internal_alias(facetname, BAD_CAST(xmlChar *) "minInclusive")) {
2499 facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
2500 } else if (xmlStrEqualxmlStrEqual__internal_alias(facetname, BAD_CAST(xmlChar *) "minExclusive")) {
2501 facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
2502 } else if (xmlStrEqualxmlStrEqual__internal_alias(facetname, BAD_CAST(xmlChar *) "maxInclusive")) {
2503 facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
2504 } else if (xmlStrEqualxmlStrEqual__internal_alias(facetname, BAD_CAST(xmlChar *) "maxExclusive")) {
2505 facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
2506 } else if (xmlStrEqualxmlStrEqual__internal_alias(facetname, BAD_CAST(xmlChar *) "totalDigits")) {
2507 facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
2508 } else if (xmlStrEqualxmlStrEqual__internal_alias(facetname, BAD_CAST(xmlChar *) "fractionDigits")) {
2509 facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
2510 } else if (xmlStrEqualxmlStrEqual__internal_alias(facetname, BAD_CAST(xmlChar *) "pattern")) {
2511 facet->type = XML_SCHEMA_FACET_PATTERN;
2512 } else if (xmlStrEqualxmlStrEqual__internal_alias(facetname, BAD_CAST(xmlChar *) "enumeration")) {
2513 facet->type = XML_SCHEMA_FACET_ENUMERATION;
2514 } else if (xmlStrEqualxmlStrEqual__internal_alias(facetname, BAD_CAST(xmlChar *) "whiteSpace")) {
2515 facet->type = XML_SCHEMA_FACET_WHITESPACE;
2516 } else if (xmlStrEqualxmlStrEqual__internal_alias(facetname, BAD_CAST(xmlChar *) "length")) {
2517 facet->type = XML_SCHEMA_FACET_LENGTH;
2518 } else if (xmlStrEqualxmlStrEqual__internal_alias(facetname, BAD_CAST(xmlChar *) "maxLength")) {
2519 facet->type = XML_SCHEMA_FACET_MAXLENGTH;
2520 } else if (xmlStrEqualxmlStrEqual__internal_alias(facetname, BAD_CAST(xmlChar *) "minLength")) {
2521 facet->type = XML_SCHEMA_FACET_MINLENGTH;
2522 } else {
2523 xmlSchemaFreeFacetxmlSchemaFreeFacet__internal_alias(facet);
2524 return (-1);
2525 }
2526 facet->value = val;
2527 ret = xmlSchemaCheckFacetxmlSchemaCheckFacet__internal_alias(facet, typ, NULL((void*)0), type);
2528 if (ret != 0) {
2529 xmlSchemaFreeFacetxmlSchemaFreeFacet__internal_alias(facet);
2530 return (-1);
2531 }
2532 ret = xmlSchemaValidateFacetxmlSchemaValidateFacet__internal_alias(typ, facet, strval, value);
2533 xmlSchemaFreeFacetxmlSchemaFreeFacet__internal_alias(facet);
2534 if (ret != 0)
2535 return (-1);
2536 return (0);
2537}
2538
2539/**
2540 * xmlRelaxNGSchemaFreeValue:
2541 * @data: data needed for the library
2542 * @value: the value to free
2543 *
2544 * Function provided by a type library to free a Schemas value
2545 *
2546 * Returns 1 if yes, 0 if no and -1 in case of error.
2547 */
2548static void
2549xmlRelaxNGSchemaFreeValue(void *data ATTRIBUTE_UNUSED__attribute__((unused)), void *value)
2550{
2551 xmlSchemaFreeValuexmlSchemaFreeValue__internal_alias(value);
2552}
2553
2554/**
2555 * xmlRelaxNGSchemaTypeCompare:
2556 * @data: data needed for the library
2557 * @type: the type name
2558 * @value1: the first value
2559 * @value2: the second value
2560 *
2561 * Compare two values for equality accordingly a type from the W3C XMLSchema
2562 * Datatype library.
2563 *
2564 * Returns 1 if equal, 0 if no and -1 in case of error.
2565 */
2566static int
2567xmlRelaxNGSchemaTypeCompare(void *data ATTRIBUTE_UNUSED__attribute__((unused)),
2568 const xmlChar * type,
2569 const xmlChar * value1,
2570 xmlNodePtr ctxt1,
2571 void *comp1,
2572 const xmlChar * value2, xmlNodePtr ctxt2)
2573{
2574 int ret;
2575 xmlSchemaTypePtr typ;
2576 xmlSchemaValPtr res1 = NULL((void*)0), res2 = NULL((void*)0);
2577
2578 if ((type == NULL((void*)0)) || (value1 == NULL((void*)0)) || (value2 == NULL((void*)0)))
2579 return (-1);
2580 typ = xmlSchemaGetPredefinedTypexmlSchemaGetPredefinedType__internal_alias(type,
2581 BAD_CAST(xmlChar *)
2582 "http://www.w3.org/2001/XMLSchema");
2583 if (typ == NULL((void*)0))
2584 return (-1);
2585 if (comp1 == NULL((void*)0)) {
2586 ret = xmlSchemaValPredefTypeNodexmlSchemaValPredefTypeNode__internal_alias(typ, value1, &res1, ctxt1);
2587 if (ret != 0)
2588 return (-1);
2589 if (res1 == NULL((void*)0))
2590 return (-1);
2591 } else {
2592 res1 = (xmlSchemaValPtr) comp1;
2593 }
2594 ret = xmlSchemaValPredefTypeNodexmlSchemaValPredefTypeNode__internal_alias(typ, value2, &res2, ctxt2);
2595 if (ret != 0) {
2596 if ((comp1 == NULL((void*)0)) && (res1 != NULL((void*)0)))
2597 xmlSchemaFreeValuexmlSchemaFreeValue__internal_alias(res1);
2598 return (-1);
2599 }
2600 if (res1 == NULL((void*)0)) {
2601 return (-1);
2602 }
2603 ret = xmlSchemaCompareValuesxmlSchemaCompareValues__internal_alias(res1, res2);
2604 if (res1 != (xmlSchemaValPtr) comp1)
2605 xmlSchemaFreeValuexmlSchemaFreeValue__internal_alias(res1);
2606 xmlSchemaFreeValuexmlSchemaFreeValue__internal_alias(res2);
2607 if (ret == -2)
2608 return (-1);
2609 if (ret == 0)
2610 return (1);
2611 return (0);
2612}
2613
2614/**
2615 * xmlRelaxNGDefaultTypeHave:
2616 * @data: data needed for the library
2617 * @type: the type name
2618 *
2619 * Check if the given type is provided by
2620 * the default datatype library.
2621 *
2622 * Returns 1 if yes, 0 if no and -1 in case of error.
2623 */
2624static int
2625xmlRelaxNGDefaultTypeHave(void *data ATTRIBUTE_UNUSED__attribute__((unused)),
2626 const xmlChar * type)
2627{
2628 if (type == NULL((void*)0))
2629 return (-1);
2630 if (xmlStrEqualxmlStrEqual__internal_alias(type, BAD_CAST(xmlChar *) "string"))
2631 return (1);
2632 if (xmlStrEqualxmlStrEqual__internal_alias(type, BAD_CAST(xmlChar *) "token"))
2633 return (1);
2634 return (0);
2635}
2636
2637/**
2638 * xmlRelaxNGDefaultTypeCheck:
2639 * @data: data needed for the library
2640 * @type: the type name
2641 * @value: the value to check
2642 * @node: the node
2643 *
2644 * Check if the given type and value are validated by
2645 * the default datatype library.
2646 *
2647 * Returns 1 if yes, 0 if no and -1 in case of error.
2648 */
2649static int
2650xmlRelaxNGDefaultTypeCheck(void *data ATTRIBUTE_UNUSED__attribute__((unused)),
2651 const xmlChar * type ATTRIBUTE_UNUSED__attribute__((unused)),
2652 const xmlChar * value ATTRIBUTE_UNUSED__attribute__((unused)),
2653 void **result ATTRIBUTE_UNUSED__attribute__((unused)),
2654 xmlNodePtr node ATTRIBUTE_UNUSED__attribute__((unused)))
2655{
2656 if (value == NULL((void*)0))
2657 return (-1);
2658 if (xmlStrEqualxmlStrEqual__internal_alias(type, BAD_CAST(xmlChar *) "string"))
2659 return (1);
2660 if (xmlStrEqualxmlStrEqual__internal_alias(type, BAD_CAST(xmlChar *) "token")) {
2661 return (1);
2662 }
2663
2664 return (0);
2665}
2666
2667/**
2668 * xmlRelaxNGDefaultTypeCompare:
2669 * @data: data needed for the library
2670 * @type: the type name
2671 * @value1: the first value
2672 * @value2: the second value
2673 *
2674 * Compare two values accordingly a type from the default
2675 * datatype library.
2676 *
2677 * Returns 1 if yes, 0 if no and -1 in case of error.
2678 */
2679static int
2680xmlRelaxNGDefaultTypeCompare(void *data ATTRIBUTE_UNUSED__attribute__((unused)),
2681 const xmlChar * type,
2682 const xmlChar * value1,
2683 xmlNodePtr ctxt1 ATTRIBUTE_UNUSED__attribute__((unused)),
2684 void *comp1 ATTRIBUTE_UNUSED__attribute__((unused)),
2685 const xmlChar * value2,
2686 xmlNodePtr ctxt2 ATTRIBUTE_UNUSED__attribute__((unused)))
2687{
2688 int ret = -1;
2689
2690 if (xmlStrEqualxmlStrEqual__internal_alias(type, BAD_CAST(xmlChar *) "string")) {
2691 ret = xmlStrEqualxmlStrEqual__internal_alias(value1, value2);
2692 } else if (xmlStrEqualxmlStrEqual__internal_alias(type, BAD_CAST(xmlChar *) "token")) {
2693 if (!xmlStrEqualxmlStrEqual__internal_alias(value1, value2)) {
2694 xmlChar *nval, *nvalue;
2695
2696 /*
2697 * TODO: trivial optimizations are possible by
2698 * computing at compile-time
2699 */
2700 nval = xmlRelaxNGNormalize(NULL((void*)0), value1);
2701 nvalue = xmlRelaxNGNormalize(NULL((void*)0), value2);
2702
2703 if ((nval == NULL((void*)0)) || (nvalue == NULL((void*)0)))
2704 ret = -1;
2705 else if (xmlStrEqualxmlStrEqual__internal_alias(nval, nvalue))
2706 ret = 1;
2707 else
2708 ret = 0;
2709 if (nval != NULL((void*)0))
2710 xmlFree(nval);
2711 if (nvalue != NULL((void*)0))
2712 xmlFree(nvalue);
2713 } else
2714 ret = 1;
2715 }
2716 return (ret);
2717}
2718
2719static int xmlRelaxNGTypeInitialized = 0;
2720static xmlHashTablePtr xmlRelaxNGRegisteredTypes = NULL((void*)0);
2721
2722/**
2723 * xmlRelaxNGFreeTypeLibrary:
2724 * @lib: the type library structure
2725 * @namespace: the URI bound to the library
2726 *
2727 * Free the structure associated to the type library
2728 */
2729static void
2730xmlRelaxNGFreeTypeLibrary(xmlRelaxNGTypeLibraryPtr lib,
2731 const xmlChar * namespace ATTRIBUTE_UNUSED__attribute__((unused)))
2732{
2733 if (lib == NULL((void*)0))
2734 return;
2735 if (lib->namespace != NULL((void*)0))
2736 xmlFree((xmlChar *) lib->namespace);
2737 xmlFree(lib);
2738}
2739
2740/**
2741 * xmlRelaxNGRegisterTypeLibrary:
2742 * @namespace: the URI bound to the library
2743 * @data: data associated to the library
2744 * @have: the provide function
2745 * @check: the checking function
2746 * @comp: the comparison function
2747 *
2748 * Register a new type library
2749 *
2750 * Returns 0 in case of success and -1 in case of error.
2751 */
2752static int
2753xmlRelaxNGRegisterTypeLibrary(const xmlChar * namespace, void *data,
2754 xmlRelaxNGTypeHave have,
2755 xmlRelaxNGTypeCheck check,
2756 xmlRelaxNGTypeCompare comp,
2757 xmlRelaxNGFacetCheck facet,
2758 xmlRelaxNGTypeFree freef)
2759{
2760 xmlRelaxNGTypeLibraryPtr lib;
2761 int ret;
2762
2763 if ((xmlRelaxNGRegisteredTypes == NULL((void*)0)) || (namespace == NULL((void*)0)) ||
2764 (check == NULL((void*)0)) || (comp == NULL((void*)0)))
2765 return (-1);
2766 if (xmlHashLookupxmlHashLookup__internal_alias(xmlRelaxNGRegisteredTypes, namespace) != NULL((void*)0)) {
2767 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
2768 "Relax-NG types library '%s' already registered\n",
2769 namespace);
2770 return (-1);
2771 }
2772 lib =
2773 (xmlRelaxNGTypeLibraryPtr)
2774 xmlMalloc(sizeof(xmlRelaxNGTypeLibrary));
2775 if (lib == NULL((void*)0)) {
2776 xmlRngVErrMemory(NULL((void*)0), "adding types library\n");
2777 return (-1);
2778 }
2779 memset(lib, 0, sizeof(xmlRelaxNGTypeLibrary));
2780 lib->namespace = xmlStrdupxmlStrdup__internal_alias(namespace);
2781 lib->data = data;
2782 lib->have = have;
2783 lib->comp = comp;
2784 lib->check = check;
2785 lib->facet = facet;
2786 lib->freef = freef;
2787 ret = xmlHashAddEntryxmlHashAddEntry__internal_alias(xmlRelaxNGRegisteredTypes, namespace, lib);
2788 if (ret < 0) {
2789 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
2790 "Relax-NG types library failed to register '%s'\n",
2791 namespace);
2792 xmlRelaxNGFreeTypeLibrary(lib, namespace);
2793 return (-1);
2794 }
2795 return (0);
2796}
2797
2798/**
2799 * xmlRelaxNGInitTypes:
2800 *
2801 * Initilize the default type libraries.
2802 *
2803 * Returns 0 in case of success and -1 in case of error.
2804 */
2805int
2806xmlRelaxNGInitTypes(void)
2807{
2808 if (xmlRelaxNGTypeInitialized != 0)
2809 return (0);
2810 xmlRelaxNGRegisteredTypes = xmlHashCreatexmlHashCreate__internal_alias(10);
2811 if (xmlRelaxNGRegisteredTypes == NULL((void*)0)) {
2812 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
2813 "Failed to allocate sh table for Relax-NG types\n");
2814 return (-1);
2815 }
2816 xmlRelaxNGRegisterTypeLibrary(BAD_CAST(xmlChar *)
2817 "http://www.w3.org/2001/XMLSchema-datatypes",
2818 NULL((void*)0), xmlRelaxNGSchemaTypeHave,
2819 xmlRelaxNGSchemaTypeCheck,
2820 xmlRelaxNGSchemaTypeCompare,
2821 xmlRelaxNGSchemaFacetCheck,
2822 xmlRelaxNGSchemaFreeValue);
2823 xmlRelaxNGRegisterTypeLibrary(xmlRelaxNGNs, NULL((void*)0),
2824 xmlRelaxNGDefaultTypeHave,
2825 xmlRelaxNGDefaultTypeCheck,
2826 xmlRelaxNGDefaultTypeCompare, NULL((void*)0),
2827 NULL((void*)0));
2828 xmlRelaxNGTypeInitialized = 1;
2829 return (0);
2830}
2831
2832/**
2833 * xmlRelaxNGCleanupTypes:
2834 *
2835 * Cleanup the default Schemas type library associated to RelaxNG
2836 */
2837void
2838xmlRelaxNGCleanupTypes(void)
2839{
2840 xmlSchemaCleanupTypesxmlSchemaCleanupTypes__internal_alias();
2841 if (xmlRelaxNGTypeInitialized == 0)
2842 return;
2843 xmlHashFreexmlHashFree__internal_alias(xmlRelaxNGRegisteredTypes, (xmlHashDeallocator)
2844 xmlRelaxNGFreeTypeLibrary);
2845 xmlRelaxNGTypeInitialized = 0;
2846}
2847
2848/************************************************************************
2849 * *
2850 * Compiling element content into regexp *
2851 * *
2852 * Sometime the element content can be compiled into a pure regexp, *
2853 * This allows a faster execution and streamability at that level *
2854 * *
2855 ************************************************************************/
2856
2857/* from automata.c but not exported */
2858void xmlAutomataSetFlags(xmlAutomataPtr am, int flags);
2859
2860
2861static int xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt,
2862 xmlRelaxNGDefinePtr def);
2863
2864/**
2865 * xmlRelaxNGIsCompileable:
2866 * @define: the definition to check
2867 *
2868 * Check if a definition is nullable.
2869 *
2870 * Returns 1 if yes, 0 if no and -1 in case of error
2871 */
2872static int
2873xmlRelaxNGIsCompileable(xmlRelaxNGDefinePtr def)
2874{
2875 int ret = -1;
2876
2877 if (def == NULL((void*)0)) {
2878 return (-1);
2879 }
2880 if ((def->type != XML_RELAXNG_ELEMENT) &&
2881 (def->dflags & IS_COMPILABLE(1 << 6)))
2882 return (1);
2883 if ((def->type != XML_RELAXNG_ELEMENT) &&
2884 (def->dflags & IS_NOT_COMPILABLE(1 << 7)))
2885 return (0);
2886 switch (def->type) {
2887 case XML_RELAXNG_NOOP:
2888 ret = xmlRelaxNGIsCompileable(def->content);
2889 break;
2890 case XML_RELAXNG_TEXT:
2891 case XML_RELAXNG_EMPTY:
2892 ret = 1;
2893 break;
2894 case XML_RELAXNG_ELEMENT:
2895 /*
2896 * Check if the element content is compileable
2897 */
2898 if (((def->dflags & IS_NOT_COMPILABLE(1 << 7)) == 0) &&
2899 ((def->dflags & IS_COMPILABLE(1 << 6)) == 0)) {
2900 xmlRelaxNGDefinePtr list;
2901
2902 list = def->content;
2903 while (list != NULL((void*)0)) {
2904 ret = xmlRelaxNGIsCompileable(list);
2905 if (ret != 1)
2906 break;
2907 list = list->next;
2908 }
2909 /*
2910 * Because the routine is recursive, we must guard against
2911 * discovering both COMPILABLE and NOT_COMPILABLE
2912 */
2913 if (ret == 0) {
2914 def->dflags &= ~IS_COMPILABLE(1 << 6);
2915 def->dflags |= IS_NOT_COMPILABLE(1 << 7);
2916 }
2917 if ((ret == 1) && !(def->dflags &= IS_NOT_COMPILABLE(1 << 7)))
2918 def->dflags |= IS_COMPILABLE(1 << 6);
2919#ifdef DEBUG_COMPILE
2920 if (ret == 1) {
2921 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
2922 "element content for %s is compilable\n",
2923 def->name);
2924 } else if (ret == 0) {
2925 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
2926 "element content for %s is not compilable\n",
2927 def->name);
2928 } else {
2929 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
2930 "Problem in RelaxNGIsCompileable for element %s\n",
2931 def->name);
2932 }
2933#endif
2934 }
2935 /*
2936 * All elements return a compileable status unless they
2937 * are generic like anyName
2938 */
2939 if ((def->nameClass != NULL((void*)0)) || (def->name == NULL((void*)0)))
2940 ret = 0;
2941 else
2942 ret = 1;
2943 return (ret);
2944 case XML_RELAXNG_REF:
2945 case XML_RELAXNG_EXTERNALREF:
2946 case XML_RELAXNG_PARENTREF:
2947 if (def->depth == -20) {
2948 return (1);
2949 } else {
2950 xmlRelaxNGDefinePtr list;
2951
2952 def->depth = -20;
2953 list = def->content;
2954 while (list != NULL((void*)0)) {
2955 ret = xmlRelaxNGIsCompileable(list);
2956 if (ret != 1)
2957 break;
2958 list = list->next;
2959 }
2960 }
2961 break;
2962 case XML_RELAXNG_START:
2963 case XML_RELAXNG_OPTIONAL:
2964 case XML_RELAXNG_ZEROORMORE:
2965 case XML_RELAXNG_ONEORMORE:
2966 case XML_RELAXNG_CHOICE:
2967 case XML_RELAXNG_GROUP:
2968 case XML_RELAXNG_DEF:{
2969 xmlRelaxNGDefinePtr list;
2970
2971 list = def->content;
2972 while (list != NULL((void*)0)) {
2973 ret = xmlRelaxNGIsCompileable(list);
2974 if (ret != 1)
2975 break;
2976 list = list->next;
2977 }
2978 break;
2979 }
2980 case XML_RELAXNG_EXCEPT:
2981 case XML_RELAXNG_ATTRIBUTE:
2982 case XML_RELAXNG_INTERLEAVE:
2983 case XML_RELAXNG_DATATYPE:
2984 case XML_RELAXNG_LIST:
2985 case XML_RELAXNG_PARAM:
2986 case XML_RELAXNG_VALUE:
2987 case XML_RELAXNG_NOT_ALLOWED:
2988 ret = 0;
2989 break;
2990 }
2991 if (ret == 0)
2992 def->dflags |= IS_NOT_COMPILABLE(1 << 7);
2993 if (ret == 1)
2994 def->dflags |= IS_COMPILABLE(1 << 6);
2995#ifdef DEBUG_COMPILE
2996 if (ret == 1) {
2997 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
2998 "RelaxNGIsCompileable %s : true\n",
2999 xmlRelaxNGDefName(def));
3000 } else if (ret == 0) {
3001 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
3002 "RelaxNGIsCompileable %s : false\n",
3003 xmlRelaxNGDefName(def));
3004 } else {
3005 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
3006 "Problem in RelaxNGIsCompileable %s\n",
3007 xmlRelaxNGDefName(def));
3008 }
3009#endif
3010 return (ret);
3011}
3012
3013/**
3014 * xmlRelaxNGCompile:
3015 * ctxt: the RelaxNG parser context
3016 * @define: the definition tree to compile
3017 *
3018 * Compile the set of definitions, it works recursively, till the
3019 * element boundaries, where it tries to compile the content if possible
3020 *
3021 * Returns 0 if success and -1 in case of error
3022 */
3023static int
3024xmlRelaxNGCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
3025{
3026 int ret = 0;
3027 xmlRelaxNGDefinePtr list;
3028
3029 if ((ctxt == NULL((void*)0)) || (def == NULL((void*)0)))
3030 return (-1);
3031
3032 switch (def->type) {
3033 case XML_RELAXNG_START:
3034 if ((xmlRelaxNGIsCompileable(def) == 1) && (def->depth != -25)) {
3035 xmlAutomataPtr oldam = ctxt->am;
3036 xmlAutomataStatePtr oldstate = ctxt->state;
3037
3038 def->depth = -25;
3039
3040 list = def->content;
3041 ctxt->am = xmlNewAutomataxmlNewAutomata__internal_alias();
3042 if (ctxt->am == NULL((void*)0))
3043 return (-1);
3044
3045 /*
3046 * assume identical strings but not same pointer are different
3047 * atoms, needed for non-determinism detection
3048 * That way if 2 elements with the same name are in a choice
3049 * branch the automata is found non-deterministic and
3050 * we fallback to the normal validation which does the right
3051 * thing of exploring both choices.
3052 */
3053 xmlAutomataSetFlags(ctxt->am, 1);
3054
3055 ctxt->state = xmlAutomataGetInitStatexmlAutomataGetInitState__internal_alias(ctxt->am);
3056 while (list != NULL((void*)0)) {
3057 xmlRelaxNGCompile(ctxt, list);
3058 list = list->next;
3059 }
3060 xmlAutomataSetFinalStatexmlAutomataSetFinalState__internal_alias(ctxt->am, ctxt->state);
3061 def->contModel = xmlAutomataCompilexmlAutomataCompile__internal_alias(ctxt->am);
3062 xmlRegexpIsDeterministxmlRegexpIsDeterminist__internal_alias(def->contModel);
3063
3064 xmlFreeAutomataxmlFreeAutomata__internal_alias(ctxt->am);
3065 ctxt->state = oldstate;
3066 ctxt->am = oldam;
3067 }
3068 break;
3069 case XML_RELAXNG_ELEMENT:
3070 if ((ctxt->am != NULL((void*)0)) && (def->name != NULL((void*)0))) {
3071 ctxt->state = xmlAutomataNewTransition2xmlAutomataNewTransition2__internal_alias(ctxt->am,
3072 ctxt->state, NULL((void*)0),
3073 def->name, def->ns,
3074 def);
3075 }
3076 if ((def->dflags & IS_COMPILABLE(1 << 6)) && (def->depth != -25)) {
3077 xmlAutomataPtr oldam = ctxt->am;
3078 xmlAutomataStatePtr oldstate = ctxt->state;
3079
3080 def->depth = -25;
3081
3082 list = def->content;
3083 ctxt->am = xmlNewAutomataxmlNewAutomata__internal_alias();
3084 if (ctxt->am == NULL((void*)0))
3085 return (-1);
3086 xmlAutomataSetFlags(ctxt->am, 1);
3087 ctxt->state = xmlAutomataGetInitStatexmlAutomataGetInitState__internal_alias(ctxt->am);
3088 while (list != NULL((void*)0)) {
3089 xmlRelaxNGCompile(ctxt, list);
3090 list = list->next;
3091 }
3092 xmlAutomataSetFinalStatexmlAutomataSetFinalState__internal_alias(ctxt->am, ctxt->state);
3093 def->contModel = xmlAutomataCompilexmlAutomataCompile__internal_alias(ctxt->am);
3094 if (!xmlRegexpIsDeterministxmlRegexpIsDeterminist__internal_alias(def->contModel)) {
3095#ifdef DEBUG_COMPILE
3096 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
3097 "Content model not determinist %s\n",
3098 def->name);
3099#endif
3100 /*
3101 * we can only use the automata if it is determinist
3102 */
3103 xmlRegFreeRegexpxmlRegFreeRegexp__internal_alias(def->contModel);
3104 def->contModel = NULL((void*)0);
3105 }
3106 xmlFreeAutomataxmlFreeAutomata__internal_alias(ctxt->am);
3107 ctxt->state = oldstate;
3108 ctxt->am = oldam;
3109 } else {
3110 xmlAutomataPtr oldam = ctxt->am;
3111
3112 /*
3113 * we can't build the content model for this element content
3114 * but it still might be possible to build it for some of its
3115 * children, recurse.
3116 */
3117 ret = xmlRelaxNGTryCompile(ctxt, def);
3118 ctxt->am = oldam;
3119 }
3120 break;
3121 case XML_RELAXNG_NOOP:
3122 ret = xmlRelaxNGCompile(ctxt, def->content);
3123 break;
3124 case XML_RELAXNG_OPTIONAL:{
3125 xmlAutomataStatePtr oldstate = ctxt->state;
3126
3127 list = def->content;
3128 while (list != NULL((void*)0)) {
3129 xmlRelaxNGCompile(ctxt, list);
3130 list = list->next;
3131 }
3132 xmlAutomataNewEpsilonxmlAutomataNewEpsilon__internal_alias(ctxt->am, oldstate, ctxt->state);
3133 break;
3134 }
3135 case XML_RELAXNG_ZEROORMORE:{
3136 xmlAutomataStatePtr oldstate;
3137
3138 ctxt->state =
3139 xmlAutomataNewEpsilonxmlAutomataNewEpsilon__internal_alias(ctxt->am, ctxt->state, NULL((void*)0));
3140 oldstate = ctxt->state;
3141 list = def->content;
3142 while (list != NULL((void*)0)) {
3143 xmlRelaxNGCompile(ctxt, list);
3144 list = list->next;
3145 }
3146 xmlAutomataNewEpsilonxmlAutomataNewEpsilon__internal_alias(ctxt->am, ctxt->state, oldstate);
3147 ctxt->state =
3148 xmlAutomataNewEpsilonxmlAutomataNewEpsilon__internal_alias(ctxt->am, oldstate, NULL((void*)0));
3149 break;
3150 }
3151 case XML_RELAXNG_ONEORMORE:{
3152 xmlAutomataStatePtr oldstate;
3153
3154 list = def->content;
3155 while (list != NULL((void*)0)) {
3156 xmlRelaxNGCompile(ctxt, list);
3157 list = list->next;
3158 }
3159 oldstate = ctxt->state;
3160 list = def->content;
3161 while (list != NULL((void*)0)) {
3162 xmlRelaxNGCompile(ctxt, list);
3163 list = list->next;
3164 }
3165 xmlAutomataNewEpsilonxmlAutomataNewEpsilon__internal_alias(ctxt->am, ctxt->state, oldstate);
3166 ctxt->state =
3167 xmlAutomataNewEpsilonxmlAutomataNewEpsilon__internal_alias(ctxt->am, oldstate, NULL((void*)0));
3168 break;
3169 }
3170 case XML_RELAXNG_CHOICE:{
3171 xmlAutomataStatePtr target = NULL((void*)0);
3172 xmlAutomataStatePtr oldstate = ctxt->state;
3173
3174 list = def->content;
3175 while (list != NULL((void*)0)) {
3176 ctxt->state = oldstate;
3177 ret = xmlRelaxNGCompile(ctxt, list);
3178 if (ret != 0)
3179 break;
3180 if (target == NULL((void*)0))
3181 target = ctxt->state;
3182 else {
3183 xmlAutomataNewEpsilonxmlAutomataNewEpsilon__internal_alias(ctxt->am, ctxt->state,
3184 target);
3185 }
3186 list = list->next;
3187 }
3188 ctxt->state = target;
3189
3190 break;
3191 }
3192 case XML_RELAXNG_REF:
3193 case XML_RELAXNG_EXTERNALREF:
3194 case XML_RELAXNG_PARENTREF:
3195 case XML_RELAXNG_GROUP:
3196 case XML_RELAXNG_DEF:
3197 list = def->content;
3198 while (list != NULL((void*)0)) {
3199 ret = xmlRelaxNGCompile(ctxt, list);
3200 if (ret != 0)
3201 break;
3202 list = list->next;
3203 }
3204 break;
3205 case XML_RELAXNG_TEXT:{
3206 xmlAutomataStatePtr oldstate;
3207
3208 ctxt->state =
3209 xmlAutomataNewEpsilonxmlAutomataNewEpsilon__internal_alias(ctxt->am, ctxt->state, NULL((void*)0));
3210 oldstate = ctxt->state;
3211 xmlRelaxNGCompile(ctxt, def->content);
3212 xmlAutomataNewTransitionxmlAutomataNewTransition__internal_alias(ctxt->am, ctxt->state,
3213 ctxt->state, BAD_CAST(xmlChar *) "#text",
3214 NULL((void*)0));
3215 ctxt->state =
3216 xmlAutomataNewEpsilonxmlAutomataNewEpsilon__internal_alias(ctxt->am, oldstate, NULL((void*)0));
3217 break;
3218 }
3219 case XML_RELAXNG_EMPTY:
3220 ctxt->state =
3221 xmlAutomataNewEpsilonxmlAutomataNewEpsilon__internal_alias(ctxt->am, ctxt->state, NULL((void*)0));
3222 break;
3223 case XML_RELAXNG_EXCEPT:
3224 case XML_RELAXNG_ATTRIBUTE:
3225 case XML_RELAXNG_INTERLEAVE:
3226 case XML_RELAXNG_NOT_ALLOWED:
3227 case XML_RELAXNG_DATATYPE:
3228 case XML_RELAXNG_LIST:
3229 case XML_RELAXNG_PARAM:
3230 case XML_RELAXNG_VALUE:
3231 /* This should not happen and generate an internal error */
3232 fprintf(stderrstderr, "RNG internal error trying to compile %s\n",
3233 xmlRelaxNGDefName(def));
3234 break;
3235 }
3236 return (ret);
3237}
3238
3239/**
3240 * xmlRelaxNGTryCompile:
3241 * ctxt: the RelaxNG parser context
3242 * @define: the definition tree to compile
3243 *
3244 * Try to compile the set of definitions, it works recursively,
3245 * possibly ignoring parts which cannot be compiled.
3246 *
3247 * Returns 0 if success and -1 in case of error
3248 */
3249static int
3250xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
3251{
3252 int ret = 0;
3253 xmlRelaxNGDefinePtr list;
3254
3255 if ((ctxt == NULL((void*)0)) || (def == NULL((void*)0)))
3256 return (-1);
3257
3258 if ((def->type == XML_RELAXNG_START) ||
3259 (def->type == XML_RELAXNG_ELEMENT)) {
3260 ret = xmlRelaxNGIsCompileable(def);
3261 if ((def->dflags & IS_COMPILABLE(1 << 6)) && (def->depth != -25)) {
3262 ctxt->am = NULL((void*)0);
3263 ret = xmlRelaxNGCompile(ctxt, def);
3264#ifdef DEBUG_PROGRESSIVE
3265 if (ret == 0) {
3266 if (def->type == XML_RELAXNG_START)
3267 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
3268 "compiled the start\n");
3269 else
3270 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
3271 "compiled element %s\n", def->name);
3272 } else {
3273 if (def->type == XML_RELAXNG_START)
3274 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
3275 "failed to compile the start\n");
3276 else
3277 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
3278 "failed to compile element %s\n",
3279 def->name);
3280 }
3281#endif
3282 return (ret);
3283 }
3284 }
3285 switch (def->type) {
3286 case XML_RELAXNG_NOOP:
3287 ret = xmlRelaxNGTryCompile(ctxt, def->content);
3288 break;
3289 case XML_RELAXNG_TEXT:
3290 case XML_RELAXNG_DATATYPE:
3291 case XML_RELAXNG_LIST:
3292 case XML_RELAXNG_PARAM:
3293 case XML_RELAXNG_VALUE:
3294 case XML_RELAXNG_EMPTY:
3295 case XML_RELAXNG_ELEMENT:
3296 ret = 0;
3297 break;
3298 case XML_RELAXNG_OPTIONAL:
3299 case XML_RELAXNG_ZEROORMORE:
3300 case XML_RELAXNG_ONEORMORE:
3301 case XML_RELAXNG_CHOICE:
3302 case XML_RELAXNG_GROUP:
3303 case XML_RELAXNG_DEF:
3304 case XML_RELAXNG_START:
3305 case XML_RELAXNG_REF:
3306 case XML_RELAXNG_EXTERNALREF:
3307 case XML_RELAXNG_PARENTREF:
3308 list = def->content;
3309 while (list != NULL((void*)0)) {
3310 ret = xmlRelaxNGTryCompile(ctxt, list);
3311 if (ret != 0)
3312 break;
3313 list = list->next;
3314 }
3315 break;
3316 case XML_RELAXNG_EXCEPT:
3317 case XML_RELAXNG_ATTRIBUTE:
3318 case XML_RELAXNG_INTERLEAVE:
3319 case XML_RELAXNG_NOT_ALLOWED:
3320 ret = 0;
3321 break;
3322 }
3323 return (ret);
3324}
3325
3326/************************************************************************
3327 * *
3328 * Parsing functions *
3329 * *
3330 ************************************************************************/
3331
3332static xmlRelaxNGDefinePtr xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr
3333 ctxt, xmlNodePtr node);
3334static xmlRelaxNGDefinePtr xmlRelaxNGParseElement(xmlRelaxNGParserCtxtPtr
3335 ctxt, xmlNodePtr node);
3336static xmlRelaxNGDefinePtr xmlRelaxNGParsePatterns(xmlRelaxNGParserCtxtPtr
3337 ctxt, xmlNodePtr nodes,
3338 int group);
3339static xmlRelaxNGDefinePtr xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr
3340 ctxt, xmlNodePtr node);
3341static xmlRelaxNGPtr xmlRelaxNGParseDocument(xmlRelaxNGParserCtxtPtr ctxt,
3342 xmlNodePtr node);
3343static int xmlRelaxNGParseGrammarContent(xmlRelaxNGParserCtxtPtr ctxt,
3344 xmlNodePtr nodes);
3345static xmlRelaxNGDefinePtr xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr
3346 ctxt, xmlNodePtr node,
3347 xmlRelaxNGDefinePtr
3348 def);
3349static xmlRelaxNGGrammarPtr xmlRelaxNGParseGrammar(xmlRelaxNGParserCtxtPtr
3350 ctxt, xmlNodePtr nodes);
3351static int xmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,
3352 xmlRelaxNGDefinePtr define,
3353 xmlNodePtr elem);
3354
3355
3356#define IS_BLANK_NODE(n)(xmlRelaxNGIsBlank((n)->content)) (xmlRelaxNGIsBlank((n)->content))
3357
3358/**
3359 * xmlRelaxNGIsNullable:
3360 * @define: the definition to verify
3361 *
3362 * Check if a definition is nullable.
3363 *
3364 * Returns 1 if yes, 0 if no and -1 in case of error
3365 */
3366static int
3367xmlRelaxNGIsNullable(xmlRelaxNGDefinePtr define)
3368{
3369 int ret;
3370
3371 if (define == NULL((void*)0))
3372 return (-1);
3373
3374 if (define->dflags & IS_NULLABLE(1 << 0))
3375 return (1);
3376 if (define->dflags & IS_NOT_NULLABLE(1 << 1))
3377 return (0);
3378 switch (define->type) {
3379 case XML_RELAXNG_EMPTY:
3380 case XML_RELAXNG_TEXT:
3381 ret = 1;
3382 break;
3383 case XML_RELAXNG_NOOP:
3384 case XML_RELAXNG_DEF:
3385 case XML_RELAXNG_REF:
3386 case XML_RELAXNG_EXTERNALREF:
3387 case XML_RELAXNG_PARENTREF:
3388 case XML_RELAXNG_ONEORMORE:
3389 ret = xmlRelaxNGIsNullable(define->content);
3390 break;
3391 case XML_RELAXNG_EXCEPT:
3392 case XML_RELAXNG_NOT_ALLOWED:
3393 case XML_RELAXNG_ELEMENT:
3394 case XML_RELAXNG_DATATYPE:
3395 case XML_RELAXNG_PARAM:
3396 case XML_RELAXNG_VALUE:
3397 case XML_RELAXNG_LIST:
3398 case XML_RELAXNG_ATTRIBUTE:
3399 ret = 0;
3400 break;
3401 case XML_RELAXNG_CHOICE:{
3402 xmlRelaxNGDefinePtr list = define->content;
3403
3404 while (list != NULL((void*)0)) {
3405 ret = xmlRelaxNGIsNullable(list);
3406 if (ret != 0)
3407 goto done;
3408 list = list->next;
3409 }
3410 ret = 0;
3411 break;
3412 }
3413 case XML_RELAXNG_START:
3414 case XML_RELAXNG_INTERLEAVE:
3415 case XML_RELAXNG_GROUP:{
3416 xmlRelaxNGDefinePtr list = define->content;
3417
3418 while (list != NULL((void*)0)) {
3419 ret = xmlRelaxNGIsNullable(list);
3420 if (ret != 1)
3421 goto done;
3422 list = list->next;
3423 }
3424 return (1);
3425 }
3426 default:
3427 return (-1);
3428 }
3429 done:
3430 if (ret == 0)
3431 define->dflags |= IS_NOT_NULLABLE(1 << 1);
3432 if (ret == 1)
3433 define->dflags |= IS_NULLABLE(1 << 0);
3434 return (ret);
3435}
3436
3437/**
3438 * xmlRelaxNGIsBlank:
3439 * @str: a string
3440 *
3441 * Check if a string is ignorable c.f. 4.2. Whitespace
3442 *
3443 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
3444 */
3445static int
3446xmlRelaxNGIsBlank(xmlChar * str)
3447{
3448 if (str == NULL((void*)0))
3449 return (1);
3450 while (*str != 0) {
3451 if (!(IS_BLANK_CH(*str)(((*str) == 0x20) || ((0x9 <= (*str)) && ((*str) <=
0xa)) || ((*str) == 0xd))
))
3452 return (0);
3453 str++;
3454 }
3455 return (1);
3456}
3457
3458/**
3459 * xmlRelaxNGGetDataTypeLibrary:
3460 * @ctxt: a Relax-NG parser context
3461 * @node: the current data or value element
3462 *
3463 * Applies algorithm from 4.3. datatypeLibrary attribute
3464 *
3465 * Returns the datatypeLibary value or NULL if not found
3466 */
3467static xmlChar *
3468xmlRelaxNGGetDataTypeLibrary(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED__attribute__((unused)),
3469 xmlNodePtr node)
3470{
3471 xmlChar *ret, *escape;
3472
3473 if ((IS_RELAXNG(node, "data")((node != ((void*)0)) && (node->ns != ((void*)0)) &&
(xmlStrEqual__internal_alias(node->name, (const xmlChar *
) "data")) && (xmlStrEqual__internal_alias(node->ns
->href, xmlRelaxNGNs)))
) || (IS_RELAXNG(node, "value")((node != ((void*)0)) && (node->ns != ((void*)0)) &&
(xmlStrEqual__internal_alias(node->name, (const xmlChar *
) "value")) && (xmlStrEqual__internal_alias(node->
ns->href, xmlRelaxNGNs)))
)) {
3474 ret = xmlGetPropxmlGetProp__internal_alias(node, BAD_CAST(xmlChar *) "datatypeLibrary");
3475 if (ret != NULL((void*)0)) {
3476 if (ret[0] == 0) {
3477 xmlFree(ret);
3478 return (NULL((void*)0));
3479 }
3480 escape = xmlURIEscapeStrxmlURIEscapeStr__internal_alias(ret, BAD_CAST(xmlChar *) ":/#?");
3481 if (escape == NULL((void*)0)) {
3482 return (ret);
3483 }
3484 xmlFree(ret);
3485 return (escape);
3486 }
3487 }
3488 node = node->parent;
3489 while ((node != NULL((void*)0)) && (node->type == XML_ELEMENT_NODE)) {
3490 ret = xmlGetPropxmlGetProp__internal_alias(node, BAD_CAST(xmlChar *) "datatypeLibrary");
3491 if (ret != NULL((void*)0)) {
3492 if (ret[0] == 0) {
3493 xmlFree(ret);
3494 return (NULL((void*)0));
3495 }
3496 escape = xmlURIEscapeStrxmlURIEscapeStr__internal_alias(ret, BAD_CAST(xmlChar *) ":/#?");
3497 if (escape == NULL((void*)0)) {
3498 return (ret);
3499 }
3500 xmlFree(ret);
3501 return (escape);
3502 }
3503 node = node->parent;
3504 }
3505 return (NULL((void*)0));
3506}
3507
3508/**
3509 * xmlRelaxNGParseValue:
3510 * @ctxt: a Relax-NG parser context
3511 * @node: the data node.
3512 *
3513 * parse the content of a RelaxNG value node.
3514 *
3515 * Returns the definition pointer or NULL in case of error
3516 */
3517static xmlRelaxNGDefinePtr
3518xmlRelaxNGParseValue(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
3519{
3520 xmlRelaxNGDefinePtr def = NULL((void*)0);
3521 xmlRelaxNGTypeLibraryPtr lib = NULL((void*)0);
3522 xmlChar *type;
3523 xmlChar *library;
3524 int success = 0;
3525
3526 def = xmlRelaxNGNewDefine(ctxt, node);
3527 if (def == NULL((void*)0))
3528 return (NULL((void*)0));
3529 def->type = XML_RELAXNG_VALUE;
3530
3531 type = xmlGetPropxmlGetProp__internal_alias(node, BAD_CAST(xmlChar *) "type");
3532 if (type != NULL((void*)0)) {
3533 xmlRelaxNGNormExtSpace(type);
3534 if (xmlValidateNCNamexmlValidateNCName__internal_alias(type, 0)) {
3535 xmlRngPErr(ctxt, node, XML_RNGP_TYPE_VALUE,
3536 "value type '%s' is not an NCName\n", type, NULL((void*)0));
3537 }
3538 library = xmlRelaxNGGetDataTypeLibrary(ctxt, node);
3539 if (library == NULL((void*)0))
3540 library =
3541 xmlStrdupxmlStrdup__internal_alias(BAD_CAST(xmlChar *) "http://relaxng.org/ns/structure/1.0");
3542
3543 def->name = type;
3544 def->ns = library;
3545
3546 lib = (xmlRelaxNGTypeLibraryPtr)
3547 xmlHashLookupxmlHashLookup__internal_alias(xmlRelaxNGRegisteredTypes, library);
3548 if (lib == NULL((void*)0)) {
3549 xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_TYPE_LIB,
3550 "Use of unregistered type library '%s'\n", library,
3551 NULL((void*)0));
3552 def->data = NULL((void*)0);
3553 } else {
3554 def->data = lib;
3555 if (lib->have == NULL((void*)0)) {
3556 xmlRngPErr(ctxt, node, XML_RNGP_ERROR_TYPE_LIB,
3557 "Internal error with type library '%s': no 'have'\n",
3558 library, NULL((void*)0));
3559 } else {
3560 success = lib->have(lib->data, def->name);
3561 if (success != 1) {
3562 xmlRngPErr(ctxt, node, XML_RNGP_TYPE_NOT_FOUND,
3563 "Error type '%s' is not exported by type library '%s'\n",
3564 def->name, library);
3565 }
3566 }
3567 }
3568 }
3569 if (node->children == NULL((void*)0)) {
3570 def->value = xmlStrdupxmlStrdup__internal_alias(BAD_CAST(xmlChar *) "");
3571 } else if (((node->children->type != XML_TEXT_NODE) &&
3572 (node->children->type != XML_CDATA_SECTION_NODE)) ||
3573 (node->children->next != NULL((void*)0))) {
3574 xmlRngPErr(ctxt, node, XML_RNGP_TEXT_EXPECTED,
3575 "Expecting a single text value for <value>content\n",
3576 NULL((void*)0), NULL((void*)0));
3577 } else if (def != NULL((void*)0)) {
3578 def->value = xmlNodeGetContentxmlNodeGetContent__internal_alias(node);
3579 if (def->value == NULL((void*)0)) {
3580 xmlRngPErr(ctxt, node, XML_RNGP_VALUE_NO_CONTENT,
3581 "Element <value> has no content\n", NULL((void*)0), NULL((void*)0));
3582 } else if ((lib != NULL((void*)0)) && (lib->check != NULL((void*)0)) && (success == 1)) {
3583 void *val = NULL((void*)0);
3584
3585 success =
3586 lib->check(lib->data, def->name, def->value, &val, node);
3587 if (success != 1) {
3588 xmlRngPErr(ctxt, node, XML_RNGP_INVALID_VALUE,
3589 "Value '%s' is not acceptable for type '%s'\n",
3590 def->value, def->name);
3591 } else {
3592 if (val != NULL((void*)0))
3593 def->attrs = val;
3594 }
3595 }
3596 }
3597 return (def);
3598}
3599
3600/**
3601 * xmlRelaxNGParseData:
3602 * @ctxt: a Relax-NG parser context
3603 * @node: the data node.
3604 *
3605 * parse the content of a RelaxNG data node.
3606 *
3607 * Returns the definition pointer or NULL in case of error
3608 */
3609static xmlRelaxNGDefinePtr
3610xmlRelaxNGParseData(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
3611{
3612 xmlRelaxNGDefinePtr def = NULL((void*)0), except;
3613 xmlRelaxNGDefinePtr param, lastparam = NULL((void*)0);
3614 xmlRelaxNGTypeLibraryPtr lib;
3615 xmlChar *type;
3616 xmlChar *library;
3617 xmlNodePtr content;
3618 int tmp;
3619
3620 type = xmlGetPropxmlGetProp__internal_alias(node, BAD_CAST(xmlChar *) "type");
3621 if (type == NULL((void*)0)) {
3622 xmlRngPErr(ctxt, node, XML_RNGP_TYPE_MISSING, "data has no type\n", NULL((void*)0),
3623 NULL((void*)0));
3624 return (NULL((void*)0));
3625 }
3626 xmlRelaxNGNormExtSpace(type);
3627 if (xmlValidateNCNamexmlValidateNCName__internal_alias(type, 0)) {
3628 xmlRngPErr(ctxt, node, XML_RNGP_TYPE_VALUE,
3629 "data type '%s' is not an NCName\n", type, NULL((void*)0));
3630 }
3631 library = xmlRelaxNGGetDataTypeLibrary(ctxt, node);
3632 if (library == NULL((void*)0))
3633 library =
3634 xmlStrdupxmlStrdup__internal_alias(BAD_CAST(xmlChar *) "http://relaxng.org/ns/structure/1.0");
3635
3636 def = xmlRelaxNGNewDefine(ctxt, node);
3637 if (def == NULL((void*)0)) {
3638 xmlFree(type);
3639 return (NULL((void*)0));
3640 }
3641 def->type = XML_RELAXNG_DATATYPE;
3642 def->name = type;
3643 def->ns = library;
3644
3645 lib = (xmlRelaxNGTypeLibraryPtr)
3646 xmlHashLookupxmlHashLookup__internal_alias(xmlRelaxNGRegisteredTypes, library);
3647 if (lib == NULL((void*)0)) {
3648 xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_TYPE_LIB,
3649 "Use of unregistered type library '%s'\n", library,
3650 NULL((void*)0));
3651 def->data = NULL((void*)0);
3652 } else {
3653 def->data = lib;
3654 if (lib->have == NULL((void*)0)) {
3655 xmlRngPErr(ctxt, node, XML_RNGP_ERROR_TYPE_LIB,
3656 "Internal error with type library '%s': no 'have'\n",
3657 library, NULL((void*)0));
3658 } else {
3659 tmp = lib->have(lib->data, def->name);
3660 if (tmp != 1) {
3661 xmlRngPErr(ctxt, node, XML_RNGP_TYPE_NOT_FOUND,
3662 "Error type '%s' is not exported by type library '%s'\n",
3663 def->name, library);
3664 } else
3665 if ((xmlStrEqualxmlStrEqual__internal_alias
3666 (library,
3667 BAD_CAST(xmlChar *)
3668 "http://www.w3.org/2001/XMLSchema-datatypes"))
3669 && ((xmlStrEqualxmlStrEqual__internal_alias(def->name, BAD_CAST(xmlChar *) "IDREF"))
3670 || (xmlStrEqualxmlStrEqual__internal_alias(def->name, BAD_CAST(xmlChar *) "IDREFS")))) {
3671 ctxt->idref = 1;
3672 }
3673 }
3674 }
3675 content = node->children;
3676
3677 /*
3678 * Handle optional params
3679 */
3680 while (content != NULL((void*)0)) {
3681 if (!xmlStrEqualxmlStrEqual__internal_alias(content->name, BAD_CAST(xmlChar *) "param"))
3682 break;
3683 if (xmlStrEqualxmlStrEqual__internal_alias(library,
3684 BAD_CAST(xmlChar *) "http://relaxng.org/ns/structure/1.0")) {
3685 xmlRngPErr(ctxt, node, XML_RNGP_PARAM_FORBIDDEN,
3686 "Type library '%s' does not allow type parameters\n",
3687 library, NULL((void*)0));
3688 content = content->next;
3689 while ((content != NULL((void*)0)) &&
3690 (xmlStrEqualxmlStrEqual__internal_alias(content->name, BAD_CAST(xmlChar *) "param")))
3691 content = content->next;
3692 } else {
3693 param = xmlRelaxNGNewDefine(ctxt, node);
3694 if (param != NULL((void*)0)) {
3695 param->type = XML_RELAXNG_PARAM;
3696 param->name = xmlGetPropxmlGetProp__internal_alias(content, BAD_CAST(xmlChar *) "name");
3697 if (param->name == NULL((void*)0)) {
3698 xmlRngPErr(ctxt, node, XML_RNGP_PARAM_NAME_MISSING,
3699 "param has no name\n", NULL((void*)0), NULL((void*)0));
3700 }
3701 param->value = xmlNodeGetContentxmlNodeGetContent__internal_alias(content);
3702 if (lastparam == NULL((void*)0)) {
3703 def->attrs = lastparam = param;
3704 } else {
3705 lastparam->next = param;
3706 lastparam = param;
3707 }
3708 if (lib != NULL((void*)0)) {
3709 }
3710 }
3711 content = content->next;
3712 }
3713 }
3714 /*
3715 * Handle optional except
3716 */
3717 if ((content != NULL((void*)0))
3718 && (xmlStrEqualxmlStrEqual__internal_alias(content->name, BAD_CAST(xmlChar *) "except"))) {
3719 xmlNodePtr child;
3720 xmlRelaxNGDefinePtr tmp2, last = NULL((void*)0);
3721
3722 except = xmlRelaxNGNewDefine(ctxt, node);
3723 if (except == NULL((void*)0)) {
3724 return (def);
3725 }
3726 except->type = XML_RELAXNG_EXCEPT;
3727 child = content->children;
3728 def->content = except;
3729 if (child == NULL((void*)0)) {
3730 xmlRngPErr(ctxt, content, XML_RNGP_EXCEPT_NO_CONTENT,
3731 "except has no content\n", NULL((void*)0), NULL((void*)0));
3732 }
3733 while (child != NULL((void*)0)) {
3734 tmp2 = xmlRelaxNGParsePattern(ctxt, child);
3735 if (tmp2 != NULL((void*)0)) {
3736 if (last == NULL((void*)0)) {
3737 except->content = last = tmp2;
3738 } else {
3739 last->next = tmp2;
3740 last = tmp2;
3741 }
3742 }
3743 child = child->next;
3744 }
3745 content = content->next;
3746 }
3747 /*
3748 * Check there is no unhandled data
3749 */
3750 if (content != NULL((void*)0)) {
3751 xmlRngPErr(ctxt, content, XML_RNGP_DATA_CONTENT,
3752 "Element data has unexpected content %s\n",
3753 content->name, NULL((void*)0));
3754 }
3755
3756 return (def);
3757}
3758
3759static const xmlChar *invalidName = BAD_CAST(xmlChar *) "\1";
3760
3761/**
3762 * xmlRelaxNGCompareNameClasses:
3763 * @defs1: the first element/attribute defs
3764 * @defs2: the second element/attribute defs
3765 * @name: the restriction on the name
3766 * @ns: the restriction on the namespace
3767 *
3768 * Compare the 2 lists of element definitions. The comparison is
3769 * that if both lists do not accept the same QNames, it returns 1
3770 * If the 2 lists can accept the same QName the comparison returns 0
3771 *
3772 * Returns 1 disttinct, 0 if equal
3773 */
3774static int
3775xmlRelaxNGCompareNameClasses(xmlRelaxNGDefinePtr def1,
3776 xmlRelaxNGDefinePtr def2)
3777{
3778 int ret = 1;
3779 xmlNode node;
3780 xmlNs ns;
3781 xmlRelaxNGValidCtxt ctxt;
3782
3783 memset(&ctxt, 0, sizeof(xmlRelaxNGValidCtxt));
3784
3785 ctxt.flags = FLAGS_IGNORABLE1 | FLAGS_NOERROR8;
3786
3787 if ((def1->type == XML_RELAXNG_ELEMENT) ||
3788 (def1->type == XML_RELAXNG_ATTRIBUTE)) {
3789 if (def2->type == XML_RELAXNG_TEXT)
3790 return (1);
3791 if (def1->name != NULL((void*)0)) {
3792 node.name = def1->name;
3793 } else {
3794 node.name = invalidName;
3795 }
3796 if (def1->ns != NULL((void*)0)) {
3797 if (def1->ns[0] == 0) {
3798 node.ns = NULL((void*)0);
3799 } else {
3800 node.ns = &ns;
3801 ns.href = def1->ns;
3802 }
3803 } else {
3804 node.ns = NULL((void*)0);
3805 }
3806 if (xmlRelaxNGElementMatch(&ctxt, def2, &node)) {
3807 if (def1->nameClass != NULL((void*)0)) {
3808 ret = xmlRelaxNGCompareNameClasses(def1->nameClass, def2);
3809 } else {
3810 ret = 0;
3811 }
3812 } else {
3813 ret = 1;
3814 }
3815 } else if (def1->type == XML_RELAXNG_TEXT) {
3816 if (def2->type == XML_RELAXNG_TEXT)
3817 return (0);
3818 return (1);
3819 } else if (def1->type == XML_RELAXNG_EXCEPT) {
3820 TODO(*(__xmlGenericError__internal_alias()))((*(__xmlGenericErrorContext__internal_alias
())), "Unimplemented block at %s:%d\n", "relaxng.c", 3820);
ret = 0;
3821 } else {
3822 TODO(*(__xmlGenericError__internal_alias()))((*(__xmlGenericErrorContext__internal_alias
())), "Unimplemented block at %s:%d\n", "relaxng.c", 3822);
ret = 0;
3823 }
3824 if (ret == 0)
3825 return (ret);
3826 if ((def2->type == XML_RELAXNG_ELEMENT) ||
3827 (def2->type == XML_RELAXNG_ATTRIBUTE)) {
3828 if (def2->name != NULL((void*)0)) {
3829 node.name = def2->name;
3830 } else {
3831 node.name = invalidName;
3832 }
3833 node.ns = &ns;
3834 if (def2->ns != NULL((void*)0)) {
3835 if (def2->ns[0] == 0) {
3836 node.ns = NULL((void*)0);
3837 } else {
3838 ns.href = def2->ns;
3839 }
3840 } else {
3841 ns.href = invalidName;
3842 }
3843 if (xmlRelaxNGElementMatch(&ctxt, def1, &node)) {
3844 if (def2->nameClass != NULL((void*)0)) {
3845 ret = xmlRelaxNGCompareNameClasses(def2->nameClass, def1);
3846 } else {
3847 ret = 0;
3848 }
3849 } else {
3850 ret = 1;
3851 }
3852 } else {
3853 TODO(*(__xmlGenericError__internal_alias()))((*(__xmlGenericErrorContext__internal_alias
())), "Unimplemented block at %s:%d\n", "relaxng.c", 3853);
ret = 0;
3854 }
3855
3856 return (ret);
3857}
3858
3859/**
3860 * xmlRel