1/*
2 * schemas.c : implementation of the XML Schema handling and
3 *             schema validity checking
4 *
5 * See Copyright for the status of this software.
6 *
7 * Daniel Veillard <veillard@redhat.com>
8 */
9
10/*
11 * TODO:
12 *   - when types are redefined in includes, check that all
13 *     types in the redef list are equal
14 *     -> need a type equality operation.
15 *   - if we don't intend to use the schema for schemas, we
16 *     need to validate all schema attributes (ref, type, name)
17 *     against their types.
18 *   - Eliminate item creation for: ??
19 *
20 * URGENT TODO:
21 *   - For xsi-driven schema acquisition, augment the IDCs after every
22 *     acquisition episode (xmlSchemaAugmentIDC).
23 *
24 * NOTES:
25 *   - Elimated item creation for: <restriction>, <extension>,
26 *     <simpleContent>, <complexContent>, <list>, <union>
27 *
28 * PROBLEMS:
29 *   - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
30 *     IDC XPath expression and chameleon includes: the targetNamespace is changed, so
31 *     XPath will have trouble to resolve to this namespace, since not known.
32 *
33 *
34 * CONSTRAINTS:
35 *
36 * Schema Component Constraint:
37 *   All Group Limited (cos-all-limited)
38 *   Status: complete
39 *   (1.2)
40 *     In xmlSchemaGroupDefReferenceTermFixup() and
41 *   (2)
42 *     In xmlSchemaParseModelGroup()
43 *     TODO: Actually this should go to component-level checks,
44 *     but is done here due to performance. Move it to an other layer
45 *     is schema construction via an API is implemented.
46 */
47#define IN_LIBXML
48#include "libxml.h"
49
50#ifdef LIBXML_SCHEMAS_ENABLED
51
52#include <string.h>
53#include <libxml/xmlmemory.h>
54#include <libxml/parser.h>
55#include <libxml/parserInternals.h>
56#include <libxml/hash.h>
57#include <libxml/uri.h>
58#include <libxml/xmlschemas.h>
59#include <libxml/schemasInternals.h>
60#include <libxml/xmlschemastypes.h>
61#include <libxml/xmlautomata.h>
62#include <libxml/xmlregexp.h>
63#include <libxml/dict.h>
64#include <libxml/encoding.h>
65#include <libxml/xmlIO.h>
66#ifdef LIBXML_PATTERN_ENABLED
67#include <libxml/pattern.h>
68#endif
69#ifdef LIBXML_READER_ENABLED
70#include <libxml/xmlreader.h>
71#endif
72
73/* #define DEBUG 1 */
74
75/* #define DEBUG_CONTENT 1 */
76
77/* #define DEBUG_TYPE 1 */
78
79/* #define DEBUG_CONTENT_REGEXP 1 */
80
81/* #define DEBUG_AUTOMATA 1 */
82
83/* #define DEBUG_IDC */
84
85/* #define DEBUG_IDC_NODE_TABLE */
86
87/* #define WXS_ELEM_DECL_CONS_ENABLED */
88
89#ifdef DEBUG_IDC
90 #ifndef DEBUG_IDC_NODE_TABLE
91  #define DEBUG_IDC_NODE_TABLE
92 #endif
93#endif
94
95/* #define ENABLE_PARTICLE_RESTRICTION 1 */
96
97#define ENABLE_REDEFINE
98
99/* #define ENABLE_NAMED_LOCALS */
100
101/* #define ENABLE_IDC_NODE_TABLES_TEST */
102
103#define DUMP_CONTENT_MODEL
104
105#ifdef LIBXML_READER_ENABLED
106/* #define XML_SCHEMA_READER_ENABLED */
107#endif
108
109#define UNBOUNDED (1 << 30)
110#define TODO								\
111    xmlGenericError(xmlGenericErrorContext,				\
112	    "Unimplemented block at %s:%d\n",				\
113            __FILE__, __LINE__);
114
115#define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
116
117/*
118 * The XML Schemas namespaces
119 */
120static const xmlChar *xmlSchemaNs = (const xmlChar *)
121    "http://www.w3.org/2001/XMLSchema";
122
123static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
124    "http://www.w3.org/2001/XMLSchema-instance";
125
126static const xmlChar *xmlNamespaceNs = (const xmlChar *)
127    "http://www.w3.org/2000/xmlns/";
128
129/*
130* Come casting macros.
131*/
132#define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
133#define PCTXT_CAST (xmlSchemaParserCtxtPtr)
134#define VCTXT_CAST (xmlSchemaValidCtxtPtr)
135#define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
136#define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
137#define WXS_PTC_CAST (xmlSchemaParticlePtr)
138#define WXS_TYPE_CAST (xmlSchemaTypePtr)
139#define WXS_ELEM_CAST (xmlSchemaElementPtr)
140#define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
141#define WXS_ATTR_CAST (xmlSchemaAttributePtr)
142#define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
143#define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
144#define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
145#define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
146#define WXS_IDC_CAST (xmlSchemaIDCPtr)
147#define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
148#define WXS_LIST_CAST (xmlSchemaItemListPtr)
149
150/*
151* Macros to query common properties of components.
152*/
153#define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
154
155#define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
156/*
157* Macros for element declarations.
158*/
159#define WXS_ELEM_TYPEDEF(e) (e)->subtypes
160
161#define WXS_SUBST_HEAD(item) (item)->refDecl
162/*
163* Macros for attribute declarations.
164*/
165#define WXS_ATTR_TYPEDEF(a) (a)->subtypes
166/*
167* Macros for attribute uses.
168*/
169#define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl
170
171#define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
172
173#define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
174
175#define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
176/*
177* Macros for attribute groups.
178*/
179#define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
180#define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
181/*
182* Macros for particles.
183*/
184#define WXS_PARTICLE(p) WXS_PTC_CAST (p)
185
186#define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
187
188#define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
189
190#define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
191/*
192* Macros for model groups definitions.
193*/
194#define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
195/*
196* Macros for model groups.
197*/
198#define WXS_IS_MODEL_GROUP(i) \
199    (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
200     ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
201     ((i)->type == XML_SCHEMA_TYPE_ALL))
202
203#define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
204/*
205* Macros for schema buckets.
206*/
207#define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
208    ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
209
210#define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
211    ((t) == XML_SCHEMA_SCHEMA_IMPORT))
212
213#define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
214
215#define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
216/*
217* Macros for complex/simple types.
218*/
219#define WXS_IS_ANYTYPE(i) \
220     (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
221      ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
222
223#define WXS_IS_COMPLEX(i) \
224    (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
225     ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
226
227#define WXS_IS_SIMPLE(item) \
228    ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
229     ((item->type == XML_SCHEMA_TYPE_BASIC) && \
230      (item->builtInType != XML_SCHEMAS_ANYTYPE)))
231
232#define WXS_IS_ANY_SIMPLE_TYPE(i) \
233    (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
234      ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
235
236#define WXS_IS_RESTRICTION(t) \
237    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
238
239#define WXS_IS_EXTENSION(t) \
240    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
241
242#define WXS_IS_TYPE_NOT_FIXED(i) \
243    (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
244     (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
245
246#define WXS_IS_TYPE_NOT_FIXED_1(item) \
247    (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
248     (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
249
250#define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
251
252#define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
253/*
254* Macros for exclusively for complex types.
255*/
256#define WXS_HAS_COMPLEX_CONTENT(item) \
257    ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
258     (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
259     (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
260
261#define WXS_HAS_SIMPLE_CONTENT(item) \
262    ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
263     (item->contentType == XML_SCHEMA_CONTENT_BASIC))
264
265#define WXS_HAS_MIXED_CONTENT(item) \
266    (item->contentType == XML_SCHEMA_CONTENT_MIXED)
267
268#define WXS_EMPTIABLE(t) \
269    (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
270
271#define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
272
273#define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
274
275#define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
276/*
277* Macros for exclusively for simple types.
278*/
279#define WXS_LIST_ITEMTYPE(t) (t)->subtypes
280
281#define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
282
283#define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
284
285#define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
286/*
287* Misc parser context macros.
288*/
289#define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
290
291#define WXS_HAS_BUCKETS(ctx) \
292( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
293(WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
294
295#define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
296
297#define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
298
299#define WXS_SCHEMA(ctx) (ctx)->schema
300
301#define WXS_ADD_LOCAL(ctx, item) \
302    xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
303
304#define WXS_ADD_GLOBAL(ctx, item) \
305    xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
306
307#define WXS_ADD_PENDING(ctx, item) \
308    xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
309/*
310* xmlSchemaItemList macros.
311*/
312#define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
313/*
314* Misc macros.
315*/
316#define IS_SCHEMA(node, type) \
317   ((node != NULL) && (node->ns != NULL) && \
318    (xmlStrEqual(node->name, (const xmlChar *) type)) && \
319    (xmlStrEqual(node->ns->href, xmlSchemaNs)))
320
321#define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
322
323/*
324* Since we put the default/fixed values into the dict, we can
325* use pointer comparison for those values.
326* REMOVED: (xmlStrEqual((v1), (v2)))
327*/
328#define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
329
330#define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
331
332#define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
333
334#define HFAILURE if (res == -1) goto exit_failure;
335
336#define HERROR if (res != 0) goto exit_error;
337
338#define HSTOP(ctx) if ((ctx)->stop) goto exit;
339/*
340* Some flags used for various schema constraints.
341*/
342#define SUBSET_RESTRICTION  1<<0
343#define SUBSET_EXTENSION    1<<1
344#define SUBSET_SUBSTITUTION 1<<2
345#define SUBSET_LIST         1<<3
346#define SUBSET_UNION        1<<4
347
348typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
349typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
350
351typedef struct _xmlSchemaItemList xmlSchemaItemList;
352typedef xmlSchemaItemList *xmlSchemaItemListPtr;
353struct _xmlSchemaItemList {
354    void **items;  /* used for dynamic addition of schemata */
355    int nbItems; /* used for dynamic addition of schemata */
356    int sizeItems; /* used for dynamic addition of schemata */
357};
358
359#define XML_SCHEMA_CTXT_PARSER 1
360#define XML_SCHEMA_CTXT_VALIDATOR 2
361
362typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
363typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
364struct _xmlSchemaAbstractCtxt {
365    int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
366};
367
368typedef struct _xmlSchemaBucket xmlSchemaBucket;
369typedef xmlSchemaBucket *xmlSchemaBucketPtr;
370
371#define XML_SCHEMA_SCHEMA_MAIN 0
372#define XML_SCHEMA_SCHEMA_IMPORT 1
373#define XML_SCHEMA_SCHEMA_INCLUDE 2
374#define XML_SCHEMA_SCHEMA_REDEFINE 3
375
376/**
377 * xmlSchemaSchemaRelation:
378 *
379 * Used to create a graph of schema relationships.
380 */
381typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
382typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
383struct _xmlSchemaSchemaRelation {
384    xmlSchemaSchemaRelationPtr next;
385    int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
386    const xmlChar *importNamespace;
387    xmlSchemaBucketPtr bucket;
388};
389
390#define XML_SCHEMA_BUCKET_MARKED 1<<0
391#define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
392
393struct _xmlSchemaBucket {
394    int type;
395    int flags;
396    const xmlChar *schemaLocation;
397    const xmlChar *origTargetNamespace;
398    const xmlChar *targetNamespace;
399    xmlDocPtr doc;
400    xmlSchemaSchemaRelationPtr relations;
401    int located;
402    int parsed;
403    int imported;
404    int preserveDoc;
405    xmlSchemaItemListPtr globals; /* Global components. */
406    xmlSchemaItemListPtr locals; /* Local components. */
407};
408
409/**
410 * xmlSchemaImport:
411 * (extends xmlSchemaBucket)
412 *
413 * Reflects a schema. Holds some information
414 * about the schema and its toplevel components. Duplicate
415 * toplevel components are not checked at this level.
416 */
417typedef struct _xmlSchemaImport xmlSchemaImport;
418typedef xmlSchemaImport *xmlSchemaImportPtr;
419struct _xmlSchemaImport {
420    int type; /* Main OR import OR include. */
421    int flags;
422    const xmlChar *schemaLocation; /* The URI of the schema document. */
423    /* For chameleon includes, @origTargetNamespace will be NULL */
424    const xmlChar *origTargetNamespace;
425    /*
426    * For chameleon includes, @targetNamespace will be the
427    * targetNamespace of the including schema.
428    */
429    const xmlChar *targetNamespace;
430    xmlDocPtr doc; /* The schema node-tree. */
431    /* @relations will hold any included/imported/redefined schemas. */
432    xmlSchemaSchemaRelationPtr relations;
433    int located;
434    int parsed;
435    int imported;
436    int preserveDoc;
437    xmlSchemaItemListPtr globals;
438    xmlSchemaItemListPtr locals;
439    /* The imported schema. */
440    xmlSchemaPtr schema;
441};
442
443/*
444* (extends xmlSchemaBucket)
445*/
446typedef struct _xmlSchemaInclude xmlSchemaInclude;
447typedef xmlSchemaInclude *xmlSchemaIncludePtr;
448struct _xmlSchemaInclude {
449    int type;
450    int flags;
451    const xmlChar *schemaLocation;
452    const xmlChar *origTargetNamespace;
453    const xmlChar *targetNamespace;
454    xmlDocPtr doc;
455    xmlSchemaSchemaRelationPtr relations;
456    int located;
457    int parsed;
458    int imported;
459    int preserveDoc;
460    xmlSchemaItemListPtr globals; /* Global components. */
461    xmlSchemaItemListPtr locals; /* Local components. */
462
463    /* The owning main or import schema bucket. */
464    xmlSchemaImportPtr ownerImport;
465};
466
467/**
468 * xmlSchemaBasicItem:
469 *
470 * The abstract base type for schema components.
471 */
472typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
473typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
474struct _xmlSchemaBasicItem {
475    xmlSchemaTypeType type;
476};
477
478/**
479 * xmlSchemaAnnotItem:
480 *
481 * The abstract base type for annotated schema components.
482 * (Extends xmlSchemaBasicItem)
483 */
484typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
485typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
486struct _xmlSchemaAnnotItem {
487    xmlSchemaTypeType type;
488    xmlSchemaAnnotPtr annot;
489};
490
491/**
492 * xmlSchemaTreeItem:
493 *
494 * The abstract base type for tree-like structured schema components.
495 * (Extends xmlSchemaAnnotItem)
496 */
497typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
498typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
499struct _xmlSchemaTreeItem {
500    xmlSchemaTypeType type;
501    xmlSchemaAnnotPtr annot;
502    xmlSchemaTreeItemPtr next;
503    xmlSchemaTreeItemPtr children;
504};
505
506
507#define XML_SCHEMA_ATTR_USE_FIXED 1<<0
508/**
509 * xmlSchemaAttributeUsePtr:
510 *
511 * The abstract base type for tree-like structured schema components.
512 * (Extends xmlSchemaTreeItem)
513 */
514typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
515typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
516struct _xmlSchemaAttributeUse {
517    xmlSchemaTypeType type;
518    xmlSchemaAnnotPtr annot;
519    xmlSchemaAttributeUsePtr next; /* The next attr. use. */
520    /*
521    * The attr. decl. OR a QName-ref. to an attr. decl. OR
522    * a QName-ref. to an attribute group definition.
523    */
524    xmlSchemaAttributePtr attrDecl;
525
526    int flags;
527    xmlNodePtr node;
528    int occurs; /* required, optional */
529    const xmlChar * defValue;
530    xmlSchemaValPtr defVal;
531};
532
533/**
534 * xmlSchemaAttributeUseProhibPtr:
535 *
536 * A helper component to reflect attribute prohibitions.
537 * (Extends xmlSchemaBasicItem)
538 */
539typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
540typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
541struct _xmlSchemaAttributeUseProhib {
542    xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
543    xmlNodePtr node;
544    const xmlChar *name;
545    const xmlChar *targetNamespace;
546    int isRef;
547};
548
549/**
550 * xmlSchemaRedef:
551 */
552typedef struct _xmlSchemaRedef xmlSchemaRedef;
553typedef xmlSchemaRedef *xmlSchemaRedefPtr;
554struct _xmlSchemaRedef {
555    xmlSchemaRedefPtr next;
556    xmlSchemaBasicItemPtr item; /* The redefining component. */
557    xmlSchemaBasicItemPtr reference; /* The referencing component. */
558    xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
559    const xmlChar *refName; /* The name of the to-be-redefined component. */
560    const xmlChar *refTargetNs; /* The target namespace of the
561                                   to-be-redefined comp. */
562    xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
563};
564
565/**
566 * xmlSchemaConstructionCtxt:
567 */
568typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
569typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
570struct _xmlSchemaConstructionCtxt {
571    xmlSchemaPtr mainSchema; /* The main schema. */
572    xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
573    xmlDictPtr dict;
574    xmlSchemaItemListPtr buckets; /* List of schema buckets. */
575    /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
576    xmlSchemaBucketPtr bucket; /* The current schema bucket */
577    xmlSchemaItemListPtr pending; /* All Components of all schemas that
578                                     need to be fixed. */
579    xmlHashTablePtr substGroups;
580    xmlSchemaRedefPtr redefs;
581    xmlSchemaRedefPtr lastRedef;
582};
583
584#define XML_SCHEMAS_PARSE_ERROR		1
585#define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
586
587struct _xmlSchemaParserCtxt {
588    int type;
589    void *errCtxt;             /* user specific error context */
590    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
591    xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
592    int err;
593    int nberrors;
594    xmlStructuredErrorFunc serror;
595
596    xmlSchemaConstructionCtxtPtr constructor;
597    int ownsConstructor; /* TODO: Move this to parser *flags*. */
598
599    /* xmlSchemaPtr topschema;	*/
600    /* xmlHashTablePtr namespaces;  */
601
602    xmlSchemaPtr schema;        /* The main schema in use */
603    int counter;
604
605    const xmlChar *URL;
606    xmlDocPtr doc;
607    int preserve;		/* Whether the doc should be freed  */
608
609    const char *buffer;
610    int size;
611
612    /*
613     * Used to build complex element content models
614     */
615    xmlAutomataPtr am;
616    xmlAutomataStatePtr start;
617    xmlAutomataStatePtr end;
618    xmlAutomataStatePtr state;
619
620    xmlDictPtr dict;		/* dictionnary for interned string names */
621    xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
622    int options;
623    xmlSchemaValidCtxtPtr vctxt;
624    int isS4S;
625    int isRedefine;
626    int xsiAssemble;
627    int stop; /* If the parser should stop; i.e. a critical error. */
628    const xmlChar *targetNamespace;
629    xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
630
631    xmlSchemaRedefPtr redef; /* Used for redefinitions. */
632    int redefCounter; /* Used for redefinitions. */
633    xmlSchemaItemListPtr attrProhibs;
634};
635
636/**
637 * xmlSchemaQNameRef:
638 *
639 * A component reference item (not a schema component)
640 * (Extends xmlSchemaBasicItem)
641 */
642typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
643typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
644struct _xmlSchemaQNameRef {
645    xmlSchemaTypeType type;
646    xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
647    xmlSchemaTypeType itemType;
648    const xmlChar *name;
649    const xmlChar *targetNamespace;
650    xmlNodePtr node;
651};
652
653/**
654 * xmlSchemaParticle:
655 *
656 * A particle component.
657 * (Extends xmlSchemaTreeItem)
658 */
659typedef struct _xmlSchemaParticle xmlSchemaParticle;
660typedef xmlSchemaParticle *xmlSchemaParticlePtr;
661struct _xmlSchemaParticle {
662    xmlSchemaTypeType type;
663    xmlSchemaAnnotPtr annot;
664    xmlSchemaTreeItemPtr next; /* next particle */
665    xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
666	a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
667        etc.) */
668    int minOccurs;
669    int maxOccurs;
670    xmlNodePtr node;
671};
672
673/**
674 * xmlSchemaModelGroup:
675 *
676 * A model group component.
677 * (Extends xmlSchemaTreeItem)
678 */
679typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
680typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
681struct _xmlSchemaModelGroup {
682    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
683    xmlSchemaAnnotPtr annot;
684    xmlSchemaTreeItemPtr next; /* not used */
685    xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
686    xmlNodePtr node;
687};
688
689#define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
690#define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
691/**
692 * xmlSchemaModelGroupDef:
693 *
694 * A model group definition component.
695 * (Extends xmlSchemaTreeItem)
696 */
697typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
698typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
699struct _xmlSchemaModelGroupDef {
700    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
701    xmlSchemaAnnotPtr annot;
702    xmlSchemaTreeItemPtr next; /* not used */
703    xmlSchemaTreeItemPtr children; /* the "model group" */
704    const xmlChar *name;
705    const xmlChar *targetNamespace;
706    xmlNodePtr node;
707    int flags;
708};
709
710typedef struct _xmlSchemaIDC xmlSchemaIDC;
711typedef xmlSchemaIDC *xmlSchemaIDCPtr;
712
713/**
714 * xmlSchemaIDCSelect:
715 *
716 * The identity-constraint "field" and "selector" item, holding the
717 * XPath expression.
718 */
719typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
720typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
721struct _xmlSchemaIDCSelect {
722    xmlSchemaIDCSelectPtr next;
723    xmlSchemaIDCPtr idc;
724    int index; /* an index position if significant for IDC key-sequences */
725    const xmlChar *xpath; /* the XPath expression */
726    void *xpathComp; /* the compiled XPath expression */
727};
728
729/**
730 * xmlSchemaIDC:
731 *
732 * The identity-constraint definition component.
733 * (Extends xmlSchemaAnnotItem)
734 */
735
736struct _xmlSchemaIDC {
737    xmlSchemaTypeType type;
738    xmlSchemaAnnotPtr annot;
739    xmlSchemaIDCPtr next;
740    xmlNodePtr node;
741    const xmlChar *name;
742    const xmlChar *targetNamespace;
743    xmlSchemaIDCSelectPtr selector;
744    xmlSchemaIDCSelectPtr fields;
745    int nbFields;
746    xmlSchemaQNameRefPtr ref;
747};
748
749/**
750 * xmlSchemaIDCAug:
751 *
752 * The augmented IDC information used for validation.
753 */
754typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
755typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
756struct _xmlSchemaIDCAug {
757    xmlSchemaIDCAugPtr next; /* next in a list */
758    xmlSchemaIDCPtr def; /* the IDC definition */
759    int keyrefDepth; /* the lowest tree level to which IDC
760                        tables need to be bubbled upwards */
761};
762
763/**
764 * xmlSchemaPSVIIDCKeySequence:
765 *
766 * The key sequence of a node table item.
767 */
768typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
769typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
770struct _xmlSchemaPSVIIDCKey {
771    xmlSchemaTypePtr type;
772    xmlSchemaValPtr val;
773};
774
775/**
776 * xmlSchemaPSVIIDCNode:
777 *
778 * The node table item of a node table.
779 */
780typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
781typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
782struct _xmlSchemaPSVIIDCNode {
783    xmlNodePtr node;
784    xmlSchemaPSVIIDCKeyPtr *keys;
785    int nodeLine;
786    int nodeQNameID;
787
788};
789
790/**
791 * xmlSchemaPSVIIDCBinding:
792 *
793 * The identity-constraint binding item of the [identity-constraint table].
794 */
795typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
796typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
797struct _xmlSchemaPSVIIDCBinding {
798    xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
799    xmlSchemaIDCPtr definition; /* the IDC definition */
800    xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
801    int nbNodes; /* number of entries in the node table */
802    int sizeNodes; /* size of the node table */
803    xmlSchemaItemListPtr dupls;
804};
805
806
807#define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
808#define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
809
810#define XPATH_STATE_OBJ_MATCHES -2
811#define XPATH_STATE_OBJ_BLOCKED -3
812
813typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
814typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
815
816/**
817 * xmlSchemaIDCStateObj:
818 *
819 * The state object used to evaluate XPath expressions.
820 */
821typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
822typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
823struct _xmlSchemaIDCStateObj {
824    int type;
825    xmlSchemaIDCStateObjPtr next; /* next if in a list */
826    int depth; /* depth of creation */
827    int *history; /* list of (depth, state-id) tuples */
828    int nbHistory;
829    int sizeHistory;
830    xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
831                                       matcher */
832    xmlSchemaIDCSelectPtr sel;
833    void *xpathCtxt;
834};
835
836#define IDC_MATCHER 0
837
838/**
839 * xmlSchemaIDCMatcher:
840 *
841 * Used to evaluate IDC selectors (and fields).
842 */
843struct _xmlSchemaIDCMatcher {
844    int type;
845    int depth; /* the tree depth at creation time */
846    xmlSchemaIDCMatcherPtr next; /* next in the list */
847    xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
848    xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
849    int idcType;
850    xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
851                                         elements */
852    int sizeKeySeqs;
853    xmlSchemaItemListPtr targets; /* list of target-node
854                                     (xmlSchemaPSVIIDCNodePtr) entries */
855};
856
857/*
858* Element info flags.
859*/
860#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES  1<<0
861#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
862#define XML_SCHEMA_ELEM_INFO_NILLED	       1<<2
863#define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE	       1<<3
864
865#define XML_SCHEMA_NODE_INFO_VALUE_NEEDED      1<<4
866#define XML_SCHEMA_ELEM_INFO_EMPTY             1<<5
867#define XML_SCHEMA_ELEM_INFO_HAS_CONTENT       1<<6
868
869#define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT  1<<7
870#define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT  1<<8
871#define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED  1<<9
872#define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE  1<<10
873
874/**
875 * xmlSchemaNodeInfo:
876 *
877 * Holds information of an element node.
878 */
879struct _xmlSchemaNodeInfo {
880    int nodeType;
881    xmlNodePtr node;
882    int nodeLine;
883    const xmlChar *localName;
884    const xmlChar *nsName;
885    const xmlChar *value;
886    xmlSchemaValPtr val; /* the pre-computed value if any */
887    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
888
889    int flags; /* combination of node info flags */
890
891    int valNeeded;
892    int normVal;
893
894    xmlSchemaElementPtr decl; /* the element/attribute declaration */
895    int depth;
896    xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
897                                            for the scope element*/
898    xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
899                                           element */
900    xmlRegExecCtxtPtr regexCtxt;
901
902    const xmlChar **nsBindings; /* Namespace bindings on this element */
903    int nbNsBindings;
904    int sizeNsBindings;
905
906    int hasKeyrefs;
907    int appliedXPath; /* Indicates that an XPath has been applied. */
908};
909
910#define XML_SCHEMAS_ATTR_UNKNOWN 1
911#define XML_SCHEMAS_ATTR_ASSESSED 2
912#define XML_SCHEMAS_ATTR_PROHIBITED 3
913#define XML_SCHEMAS_ATTR_ERR_MISSING 4
914#define XML_SCHEMAS_ATTR_INVALID_VALUE 5
915#define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
916#define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
917#define XML_SCHEMAS_ATTR_DEFAULT 8
918#define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
919#define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
920#define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
921#define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
922#define XML_SCHEMAS_ATTR_WILD_SKIP 13
923#define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
924#define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
925#define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
926#define XML_SCHEMAS_ATTR_META 17
927/*
928* @metaType values of xmlSchemaAttrInfo.
929*/
930#define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
931#define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
932#define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
933#define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
934#define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
935
936typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
937typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
938struct _xmlSchemaAttrInfo {
939    int nodeType;
940    xmlNodePtr node;
941    int nodeLine;
942    const xmlChar *localName;
943    const xmlChar *nsName;
944    const xmlChar *value;
945    xmlSchemaValPtr val; /* the pre-computed value if any */
946    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
947    int flags; /* combination of node info flags */
948
949    xmlSchemaAttributePtr decl; /* the attribute declaration */
950    xmlSchemaAttributeUsePtr use;  /* the attribute use */
951    int state;
952    int metaType;
953    const xmlChar *vcValue; /* the value constraint value */
954    xmlSchemaNodeInfoPtr parent;
955};
956
957
958#define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
959/**
960 * xmlSchemaValidCtxt:
961 *
962 * A Schemas validation context
963 */
964struct _xmlSchemaValidCtxt {
965    int type;
966    void *errCtxt;             /* user specific data block */
967    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
968    xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
969    xmlStructuredErrorFunc serror;
970
971    xmlSchemaPtr schema;        /* The schema in use */
972    xmlDocPtr doc;
973    xmlParserInputBufferPtr input;
974    xmlCharEncoding enc;
975    xmlSAXHandlerPtr sax;
976    xmlParserCtxtPtr parserCtxt;
977    void *user_data; /* TODO: What is this for? */
978    char *filename;
979
980    int err;
981    int nberrors;
982
983    xmlNodePtr node;
984    xmlNodePtr cur;
985    /* xmlSchemaTypePtr type; */
986
987    xmlRegExecCtxtPtr regexp;
988    xmlSchemaValPtr value;
989
990    int valueWS;
991    int options;
992    xmlNodePtr validationRoot;
993    xmlSchemaParserCtxtPtr pctxt;
994    int xsiAssemble;
995
996    int depth;
997    xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */
998    int sizeElemInfos;
999    xmlSchemaNodeInfoPtr inode; /* the current element information */
1000
1001    xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */
1002
1003    xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
1004    xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
1005    xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
1006
1007    xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
1008    int nbIdcNodes;
1009    int sizeIdcNodes;
1010
1011    xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
1012    int nbIdcKeys;
1013    int sizeIdcKeys;
1014
1015    int flags;
1016
1017    xmlDictPtr dict;
1018
1019#ifdef LIBXML_READER_ENABLED
1020    xmlTextReaderPtr reader;
1021#endif
1022
1023    xmlSchemaAttrInfoPtr *attrInfos;
1024    int nbAttrInfos;
1025    int sizeAttrInfos;
1026
1027    int skipDepth;
1028    xmlSchemaItemListPtr nodeQNames;
1029    int hasKeyrefs;
1030    int createIDCNodeTables;
1031    int psviExposeIDCNodeTables;
1032
1033    /* Locator for error reporting in streaming mode */
1034    xmlSchemaValidityLocatorFunc locFunc;
1035    void *locCtxt;
1036};
1037
1038/**
1039 * xmlSchemaSubstGroup:
1040 *
1041 *
1042 */
1043typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
1044typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
1045struct _xmlSchemaSubstGroup {
1046    xmlSchemaElementPtr head;
1047    xmlSchemaItemListPtr members;
1048};
1049
1050/************************************************************************
1051 *									*
1052 *			Some predeclarations				*
1053 *									*
1054 ************************************************************************/
1055
1056static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
1057                                 xmlSchemaPtr schema,
1058                                 xmlNodePtr node);
1059static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
1060                                 xmlSchemaPtr schema,
1061                                 xmlNodePtr node);
1062static int
1063xmlSchemaTypeFixup(xmlSchemaTypePtr type,
1064                   xmlSchemaAbstractCtxtPtr ctxt);
1065static const xmlChar *
1066xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
1067static int
1068xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1069                     xmlNodePtr node);
1070static int
1071xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
1072                       xmlSchemaParserCtxtPtr ctxt);
1073static void
1074xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
1075static xmlSchemaWhitespaceValueType
1076xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
1077static xmlSchemaTreeItemPtr
1078xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1079			 xmlNodePtr node, xmlSchemaTypeType type,
1080			 int withParticle);
1081static const xmlChar *
1082xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
1083static xmlSchemaTypeLinkPtr
1084xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
1085static void
1086xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
1087		     const char *funcName,
1088		     const char *message);
1089static int
1090xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
1091			     xmlSchemaTypePtr type,
1092			     xmlSchemaTypePtr baseType,
1093			     int subset);
1094static void
1095xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
1096				   xmlSchemaParserCtxtPtr ctxt);
1097static void
1098xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
1099static xmlSchemaQNameRefPtr
1100xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
1101				xmlSchemaPtr schema,
1102				xmlNodePtr node);
1103
1104/************************************************************************
1105 *									*
1106 *			Helper functions			        *
1107 *									*
1108 ************************************************************************/
1109
1110/**
1111 * xmlSchemaItemTypeToStr:
1112 * @type: the type of the schema item
1113 *
1114 * Returns the component name of a schema item.
1115 */
1116static const xmlChar *
1117xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
1118{
1119    switch (type) {
1120	case XML_SCHEMA_TYPE_BASIC:
1121	    return(BAD_CAST "simple type definition");
1122	case XML_SCHEMA_TYPE_SIMPLE:
1123	    return(BAD_CAST "simple type definition");
1124	case XML_SCHEMA_TYPE_COMPLEX:
1125	    return(BAD_CAST "complex type definition");
1126	case XML_SCHEMA_TYPE_ELEMENT:
1127	    return(BAD_CAST "element declaration");
1128	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1129	    return(BAD_CAST "attribute use");
1130	case XML_SCHEMA_TYPE_ATTRIBUTE:
1131	    return(BAD_CAST "attribute declaration");
1132	case XML_SCHEMA_TYPE_GROUP:
1133	    return(BAD_CAST "model group definition");
1134	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1135	    return(BAD_CAST "attribute group definition");
1136	case XML_SCHEMA_TYPE_NOTATION:
1137	    return(BAD_CAST "notation declaration");
1138	case XML_SCHEMA_TYPE_SEQUENCE:
1139	    return(BAD_CAST "model group (sequence)");
1140	case XML_SCHEMA_TYPE_CHOICE:
1141	    return(BAD_CAST "model group (choice)");
1142	case XML_SCHEMA_TYPE_ALL:
1143	    return(BAD_CAST "model group (all)");
1144	case XML_SCHEMA_TYPE_PARTICLE:
1145	    return(BAD_CAST "particle");
1146	case XML_SCHEMA_TYPE_IDC_UNIQUE:
1147	    return(BAD_CAST "unique identity-constraint");
1148	    /* return(BAD_CAST "IDC (unique)"); */
1149	case XML_SCHEMA_TYPE_IDC_KEY:
1150	    return(BAD_CAST "key identity-constraint");
1151	    /* return(BAD_CAST "IDC (key)"); */
1152	case XML_SCHEMA_TYPE_IDC_KEYREF:
1153	    return(BAD_CAST "keyref identity-constraint");
1154	    /* return(BAD_CAST "IDC (keyref)"); */
1155	case XML_SCHEMA_TYPE_ANY:
1156	    return(BAD_CAST "wildcard (any)");
1157	case XML_SCHEMA_EXTRA_QNAMEREF:
1158	    return(BAD_CAST "[helper component] QName reference");
1159	case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
1160	    return(BAD_CAST "[helper component] attribute use prohibition");
1161	default:
1162	    return(BAD_CAST "Not a schema component");
1163    }
1164}
1165
1166/**
1167 * xmlSchemaGetComponentTypeStr:
1168 * @type: the type of the schema item
1169 *
1170 * Returns the component name of a schema item.
1171 */
1172static const xmlChar *
1173xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
1174{
1175    switch (item->type) {
1176	case XML_SCHEMA_TYPE_BASIC:
1177	    if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
1178		return(BAD_CAST "complex type definition");
1179	    else
1180		return(BAD_CAST "simple type definition");
1181	default:
1182	    return(xmlSchemaItemTypeToStr(item->type));
1183    }
1184}
1185
1186/**
1187 * xmlSchemaGetComponentNode:
1188 * @item: a schema component
1189 *
1190 * Returns node associated with the schema component.
1191 * NOTE that such a node need not be available; plus, a component's
1192 * node need not to reflect the component directly, since there is no
1193 * one-to-one relationship between the XML Schema representation and
1194 * the component representation.
1195 */
1196static xmlNodePtr
1197xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
1198{
1199    switch (item->type) {
1200	case XML_SCHEMA_TYPE_ELEMENT:
1201	    return (((xmlSchemaElementPtr) item)->node);
1202	case XML_SCHEMA_TYPE_ATTRIBUTE:
1203	    return (((xmlSchemaAttributePtr) item)->node);
1204	case XML_SCHEMA_TYPE_COMPLEX:
1205	case XML_SCHEMA_TYPE_SIMPLE:
1206	    return (((xmlSchemaTypePtr) item)->node);
1207	case XML_SCHEMA_TYPE_ANY:
1208	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1209	    return (((xmlSchemaWildcardPtr) item)->node);
1210	case XML_SCHEMA_TYPE_PARTICLE:
1211	    return (((xmlSchemaParticlePtr) item)->node);
1212	case XML_SCHEMA_TYPE_SEQUENCE:
1213	case XML_SCHEMA_TYPE_CHOICE:
1214	case XML_SCHEMA_TYPE_ALL:
1215	    return (((xmlSchemaModelGroupPtr) item)->node);
1216	case XML_SCHEMA_TYPE_GROUP:
1217	    return (((xmlSchemaModelGroupDefPtr) item)->node);
1218	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1219	    return (((xmlSchemaAttributeGroupPtr) item)->node);
1220	case XML_SCHEMA_TYPE_IDC_UNIQUE:
1221	case XML_SCHEMA_TYPE_IDC_KEY:
1222	case XML_SCHEMA_TYPE_IDC_KEYREF:
1223	    return (((xmlSchemaIDCPtr) item)->node);
1224	case XML_SCHEMA_EXTRA_QNAMEREF:
1225	    return(((xmlSchemaQNameRefPtr) item)->node);
1226	/* TODO: What to do with NOTATIONs?
1227	case XML_SCHEMA_TYPE_NOTATION:
1228	    return (((xmlSchemaNotationPtr) item)->node);
1229	*/
1230	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1231	    return (((xmlSchemaAttributeUsePtr) item)->node);
1232	default:
1233	    return (NULL);
1234    }
1235}
1236
1237#if 0
1238/**
1239 * xmlSchemaGetNextComponent:
1240 * @item: a schema component
1241 *
1242 * Returns the next sibling of the schema component.
1243 */
1244static xmlSchemaBasicItemPtr
1245xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
1246{
1247    switch (item->type) {
1248	case XML_SCHEMA_TYPE_ELEMENT:
1249	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
1250	case XML_SCHEMA_TYPE_ATTRIBUTE:
1251	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
1252	case XML_SCHEMA_TYPE_COMPLEX:
1253	case XML_SCHEMA_TYPE_SIMPLE:
1254	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
1255	case XML_SCHEMA_TYPE_ANY:
1256	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1257	    return (NULL);
1258	case XML_SCHEMA_TYPE_PARTICLE:
1259	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
1260	case XML_SCHEMA_TYPE_SEQUENCE:
1261	case XML_SCHEMA_TYPE_CHOICE:
1262	case XML_SCHEMA_TYPE_ALL:
1263	    return (NULL);
1264	case XML_SCHEMA_TYPE_GROUP:
1265	    return (NULL);
1266	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1267	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
1268	case XML_SCHEMA_TYPE_IDC_UNIQUE:
1269	case XML_SCHEMA_TYPE_IDC_KEY:
1270	case XML_SCHEMA_TYPE_IDC_KEYREF:
1271	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
1272	default:
1273	    return (NULL);
1274    }
1275}
1276#endif
1277
1278
1279/**
1280 * xmlSchemaFormatQName:
1281 * @buf: the string buffer
1282 * @namespaceName:  the namespace name
1283 * @localName: the local name
1284 *
1285 * Returns the given QName in the format "{namespaceName}localName" or
1286 * just "localName" if @namespaceName is NULL.
1287 *
1288 * Returns the localName if @namespaceName is NULL, a formatted
1289 * string otherwise.
1290 */
1291static const xmlChar*
1292xmlSchemaFormatQName(xmlChar **buf,
1293		     const xmlChar *namespaceName,
1294		     const xmlChar *localName)
1295{
1296    FREE_AND_NULL(*buf)
1297    if (namespaceName != NULL) {
1298	*buf = xmlStrdup(BAD_CAST "{");
1299	*buf = xmlStrcat(*buf, namespaceName);
1300	*buf = xmlStrcat(*buf, BAD_CAST "}");
1301    }
1302    if (localName != NULL) {
1303	if (namespaceName == NULL)
1304	    return(localName);
1305	*buf = xmlStrcat(*buf, localName);
1306    } else {
1307	*buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
1308    }
1309    return ((const xmlChar *) *buf);
1310}
1311
1312static const xmlChar*
1313xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
1314{
1315    if (ns != NULL)
1316	return (xmlSchemaFormatQName(buf, ns->href, localName));
1317    else
1318	return (xmlSchemaFormatQName(buf, NULL, localName));
1319}
1320
1321static const xmlChar *
1322xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
1323{
1324    switch (item->type) {
1325	case XML_SCHEMA_TYPE_ELEMENT:
1326	    return (((xmlSchemaElementPtr) item)->name);
1327	case XML_SCHEMA_TYPE_ATTRIBUTE:
1328	    return (((xmlSchemaAttributePtr) item)->name);
1329	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1330	    return (((xmlSchemaAttributeGroupPtr) item)->name);
1331	case XML_SCHEMA_TYPE_BASIC:
1332	case XML_SCHEMA_TYPE_SIMPLE:
1333	case XML_SCHEMA_TYPE_COMPLEX:
1334	    return (((xmlSchemaTypePtr) item)->name);
1335	case XML_SCHEMA_TYPE_GROUP:
1336	    return (((xmlSchemaModelGroupDefPtr) item)->name);
1337	case XML_SCHEMA_TYPE_IDC_KEY:
1338	case XML_SCHEMA_TYPE_IDC_UNIQUE:
1339	case XML_SCHEMA_TYPE_IDC_KEYREF:
1340	    return (((xmlSchemaIDCPtr) item)->name);
1341	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1342	    if (WXS_ATTRUSE_DECL(item) != NULL) {
1343		return(xmlSchemaGetComponentName(
1344		    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1345	    } else
1346		return(NULL);
1347	case XML_SCHEMA_EXTRA_QNAMEREF:
1348	    return (((xmlSchemaQNameRefPtr) item)->name);
1349	case XML_SCHEMA_TYPE_NOTATION:
1350	    return (((xmlSchemaNotationPtr) item)->name);
1351	default:
1352	    /*
1353	    * Other components cannot have names.
1354	    */
1355	    break;
1356    }
1357    return (NULL);
1358}
1359
1360#define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
1361#define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
1362/*
1363static const xmlChar *
1364xmlSchemaGetQNameRefName(void *ref)
1365{
1366    return(((xmlSchemaQNameRefPtr) ref)->name);
1367}
1368
1369static const xmlChar *
1370xmlSchemaGetQNameRefTargetNs(void *ref)
1371{
1372    return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
1373}
1374*/
1375
1376static const xmlChar *
1377xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
1378{
1379    switch (item->type) {
1380	case XML_SCHEMA_TYPE_ELEMENT:
1381	    return (((xmlSchemaElementPtr) item)->targetNamespace);
1382	case XML_SCHEMA_TYPE_ATTRIBUTE:
1383	    return (((xmlSchemaAttributePtr) item)->targetNamespace);
1384	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1385	    return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
1386	case XML_SCHEMA_TYPE_BASIC:
1387	    return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
1388	case XML_SCHEMA_TYPE_SIMPLE:
1389	case XML_SCHEMA_TYPE_COMPLEX:
1390	    return (((xmlSchemaTypePtr) item)->targetNamespace);
1391	case XML_SCHEMA_TYPE_GROUP:
1392	    return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
1393	case XML_SCHEMA_TYPE_IDC_KEY:
1394	case XML_SCHEMA_TYPE_IDC_UNIQUE:
1395	case XML_SCHEMA_TYPE_IDC_KEYREF:
1396	    return (((xmlSchemaIDCPtr) item)->targetNamespace);
1397	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1398	    if (WXS_ATTRUSE_DECL(item) != NULL) {
1399		return(xmlSchemaGetComponentTargetNs(
1400		    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1401	    }
1402	    /* TODO: Will returning NULL break something? */
1403	    break;
1404	case XML_SCHEMA_EXTRA_QNAMEREF:
1405	    return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
1406	case XML_SCHEMA_TYPE_NOTATION:
1407	    return (((xmlSchemaNotationPtr) item)->targetNamespace);
1408	default:
1409	    /*
1410	    * Other components cannot have names.
1411	    */
1412	    break;
1413    }
1414    return (NULL);
1415}
1416
1417static const xmlChar*
1418xmlSchemaGetComponentQName(xmlChar **buf,
1419			   void *item)
1420{
1421    return (xmlSchemaFormatQName(buf,
1422	xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
1423	xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
1424}
1425
1426static const xmlChar*
1427xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
1428{
1429    xmlChar *str = NULL;
1430
1431    *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
1432    *buf = xmlStrcat(*buf, BAD_CAST " '");
1433    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
1434	(xmlSchemaBasicItemPtr) item));
1435    *buf = xmlStrcat(*buf, BAD_CAST "'");
1436    FREE_AND_NULL(str);
1437    return(*buf);
1438}
1439
1440static const xmlChar*
1441xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
1442{
1443    return(xmlSchemaGetComponentDesignation(buf, idc));
1444}
1445
1446/**
1447 * xmlSchemaWildcardPCToString:
1448 * @pc: the type of processContents
1449 *
1450 * Returns a string representation of the type of
1451 * processContents.
1452 */
1453static const xmlChar *
1454xmlSchemaWildcardPCToString(int pc)
1455{
1456    switch (pc) {
1457	case XML_SCHEMAS_ANY_SKIP:
1458	    return (BAD_CAST "skip");
1459	case XML_SCHEMAS_ANY_LAX:
1460	    return (BAD_CAST "lax");
1461	case XML_SCHEMAS_ANY_STRICT:
1462	    return (BAD_CAST "strict");
1463	default:
1464	    return (BAD_CAST "invalid process contents");
1465    }
1466}
1467
1468/**
1469 * xmlSchemaGetCanonValueWhtspExt:
1470 * @val: the precomputed value
1471 * @retValue: the returned value
1472 * @ws: the whitespace type of the value
1473 *
1474 * Get a the cononical representation of the value.
1475 * The caller has to free the returned retValue.
1476 *
1477 * Returns 0 if the value could be built and -1 in case of
1478 *         API errors or if the value type is not supported yet.
1479 */
1480static int
1481xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
1482			       xmlSchemaWhitespaceValueType ws,
1483			       xmlChar **retValue)
1484{
1485    int list;
1486    xmlSchemaValType valType;
1487    const xmlChar *value, *value2 = NULL;
1488
1489
1490    if ((retValue == NULL) || (val == NULL))
1491	return (-1);
1492    list = xmlSchemaValueGetNext(val) ? 1 : 0;
1493    *retValue = NULL;
1494    do {
1495	value = NULL;
1496	valType = xmlSchemaGetValType(val);
1497	switch (valType) {
1498	    case XML_SCHEMAS_STRING:
1499	    case XML_SCHEMAS_NORMSTRING:
1500	    case XML_SCHEMAS_ANYSIMPLETYPE:
1501		value = xmlSchemaValueGetAsString(val);
1502		if (value != NULL) {
1503		    if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
1504			value2 = xmlSchemaCollapseString(value);
1505		    else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
1506			value2 = xmlSchemaWhiteSpaceReplace(value);
1507		    if (value2 != NULL)
1508			value = value2;
1509		}
1510		break;
1511	    default:
1512		if (xmlSchemaGetCanonValue(val, &value2) == -1) {
1513		    if (value2 != NULL)
1514			xmlFree((xmlChar *) value2);
1515		    goto internal_error;
1516		}
1517		value = value2;
1518	}
1519	if (*retValue == NULL)
1520	    if (value == NULL) {
1521		if (! list)
1522		    *retValue = xmlStrdup(BAD_CAST "");
1523	    } else
1524		*retValue = xmlStrdup(value);
1525	else if (value != NULL) {
1526	    /* List. */
1527	    *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
1528	    *retValue = xmlStrcat((xmlChar *) *retValue, value);
1529	}
1530	FREE_AND_NULL(value2)
1531	val = xmlSchemaValueGetNext(val);
1532    } while (val != NULL);
1533
1534    return (0);
1535internal_error:
1536    if (*retValue != NULL)
1537	xmlFree((xmlChar *) (*retValue));
1538    if (value2 != NULL)
1539	xmlFree((xmlChar *) value2);
1540    return (-1);
1541}
1542
1543/**
1544 * xmlSchemaFormatItemForReport:
1545 * @buf: the string buffer
1546 * @itemDes: the designation of the item
1547 * @itemName: the name of the item
1548 * @item: the item as an object
1549 * @itemNode: the node of the item
1550 * @local: the local name
1551 * @parsing: if the function is used during the parse
1552 *
1553 * Returns a representation of the given item used
1554 * for error reports.
1555 *
1556 * The following order is used to build the resulting
1557 * designation if the arguments are not NULL:
1558 * 1a. If itemDes not NULL -> itemDes
1559 * 1b. If (itemDes not NULL) and (itemName not NULL)
1560 *     -> itemDes + itemName
1561 * 2. If the preceding was NULL and (item not NULL) -> item
1562 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
1563 *
1564 * If the itemNode is an attribute node, the name of the attribute
1565 * will be appended to the result.
1566 *
1567 * Returns the formatted string and sets @buf to the resulting value.
1568 */
1569static xmlChar*
1570xmlSchemaFormatItemForReport(xmlChar **buf,
1571		     const xmlChar *itemDes,
1572		     xmlSchemaBasicItemPtr item,
1573		     xmlNodePtr itemNode)
1574{
1575    xmlChar *str = NULL;
1576    int named = 1;
1577
1578    if (*buf != NULL) {
1579	xmlFree(*buf);
1580	*buf = NULL;
1581    }
1582
1583    if (itemDes != NULL) {
1584	*buf = xmlStrdup(itemDes);
1585    } else if (item != NULL) {
1586	switch (item->type) {
1587	case XML_SCHEMA_TYPE_BASIC: {
1588	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1589
1590	    if (WXS_IS_ATOMIC(type))
1591		*buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
1592	    else if (WXS_IS_LIST(type))
1593		*buf = xmlStrdup(BAD_CAST "list type 'xs:");
1594	    else if (WXS_IS_UNION(type))
1595		*buf = xmlStrdup(BAD_CAST "union type 'xs:");
1596	    else
1597		*buf = xmlStrdup(BAD_CAST "simple type 'xs:");
1598	    *buf = xmlStrcat(*buf, type->name);
1599	    *buf = xmlStrcat(*buf, BAD_CAST "'");
1600	    }
1601	    break;
1602	case XML_SCHEMA_TYPE_SIMPLE: {
1603	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1604
1605	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1606		*buf = xmlStrdup(BAD_CAST"");
1607	    } else {
1608		*buf = xmlStrdup(BAD_CAST "local ");
1609	    }
1610	    if (WXS_IS_ATOMIC(type))
1611		*buf = xmlStrcat(*buf, BAD_CAST "atomic type");
1612	    else if (WXS_IS_LIST(type))
1613		*buf = xmlStrcat(*buf, BAD_CAST "list type");
1614	    else if (WXS_IS_UNION(type))
1615		*buf = xmlStrcat(*buf, BAD_CAST "union type");
1616	    else
1617		*buf = xmlStrcat(*buf, BAD_CAST "simple type");
1618	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1619		*buf = xmlStrcat(*buf, BAD_CAST " '");
1620		*buf = xmlStrcat(*buf, type->name);
1621		*buf = xmlStrcat(*buf, BAD_CAST "'");
1622	    }
1623	    }
1624	    break;
1625	case XML_SCHEMA_TYPE_COMPLEX: {
1626	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1627
1628	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
1629		*buf = xmlStrdup(BAD_CAST "");
1630	    else
1631		*buf = xmlStrdup(BAD_CAST "local ");
1632	    *buf = xmlStrcat(*buf, BAD_CAST "complex type");
1633	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1634		*buf = xmlStrcat(*buf, BAD_CAST " '");
1635		*buf = xmlStrcat(*buf, type->name);
1636		*buf = xmlStrcat(*buf, BAD_CAST "'");
1637	    }
1638	    }
1639	    break;
1640	case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
1641		xmlSchemaAttributeUsePtr ause;
1642
1643		ause = WXS_ATTR_USE_CAST item;
1644		*buf = xmlStrdup(BAD_CAST "attribute use ");
1645		if (WXS_ATTRUSE_DECL(ause) != NULL) {
1646		    *buf = xmlStrcat(*buf, BAD_CAST "'");
1647		    *buf = xmlStrcat(*buf,
1648			xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
1649		    FREE_AND_NULL(str)
1650			*buf = xmlStrcat(*buf, BAD_CAST "'");
1651		} else {
1652		    *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
1653		}
1654	    }
1655	    break;
1656	case XML_SCHEMA_TYPE_ATTRIBUTE: {
1657		xmlSchemaAttributePtr attr;
1658
1659		attr = (xmlSchemaAttributePtr) item;
1660		*buf = xmlStrdup(BAD_CAST "attribute decl.");
1661		*buf = xmlStrcat(*buf, BAD_CAST " '");
1662		*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1663		    attr->targetNamespace, attr->name));
1664		FREE_AND_NULL(str)
1665		    *buf = xmlStrcat(*buf, BAD_CAST "'");
1666	    }
1667	    break;
1668	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1669	    xmlSchemaGetComponentDesignation(buf, item);
1670	    break;
1671	case XML_SCHEMA_TYPE_ELEMENT: {
1672		xmlSchemaElementPtr elem;
1673
1674		elem = (xmlSchemaElementPtr) item;
1675		*buf = xmlStrdup(BAD_CAST "element decl.");
1676		*buf = xmlStrcat(*buf, BAD_CAST " '");
1677		*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1678		    elem->targetNamespace, elem->name));
1679		*buf = xmlStrcat(*buf, BAD_CAST "'");
1680	    }
1681	    break;
1682	case XML_SCHEMA_TYPE_IDC_UNIQUE:
1683	case XML_SCHEMA_TYPE_IDC_KEY:
1684	case XML_SCHEMA_TYPE_IDC_KEYREF:
1685	    if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
1686		*buf = xmlStrdup(BAD_CAST "unique '");
1687	    else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
1688		*buf = xmlStrdup(BAD_CAST "key '");
1689	    else
1690		*buf = xmlStrdup(BAD_CAST "keyRef '");
1691	    *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
1692	    *buf = xmlStrcat(*buf, BAD_CAST "'");
1693	    break;
1694	case XML_SCHEMA_TYPE_ANY:
1695	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1696	    *buf = xmlStrdup(xmlSchemaWildcardPCToString(
1697		    ((xmlSchemaWildcardPtr) item)->processContents));
1698	    *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
1699	    break;
1700	case XML_SCHEMA_FACET_MININCLUSIVE:
1701	case XML_SCHEMA_FACET_MINEXCLUSIVE:
1702	case XML_SCHEMA_FACET_MAXINCLUSIVE:
1703	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
1704	case XML_SCHEMA_FACET_TOTALDIGITS:
1705	case XML_SCHEMA_FACET_FRACTIONDIGITS:
1706	case XML_SCHEMA_FACET_PATTERN:
1707	case XML_SCHEMA_FACET_ENUMERATION:
1708	case XML_SCHEMA_FACET_WHITESPACE:
1709	case XML_SCHEMA_FACET_LENGTH:
1710	case XML_SCHEMA_FACET_MAXLENGTH:
1711	case XML_SCHEMA_FACET_MINLENGTH:
1712	    *buf = xmlStrdup(BAD_CAST "facet '");
1713	    *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
1714	    *buf = xmlStrcat(*buf, BAD_CAST "'");
1715	    break;
1716	case XML_SCHEMA_TYPE_GROUP: {
1717		*buf = xmlStrdup(BAD_CAST "model group def.");
1718		*buf = xmlStrcat(*buf, BAD_CAST " '");
1719		*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1720		*buf = xmlStrcat(*buf, BAD_CAST "'");
1721		FREE_AND_NULL(str)
1722	    }
1723	    break;
1724	case XML_SCHEMA_TYPE_SEQUENCE:
1725	case XML_SCHEMA_TYPE_CHOICE:
1726	case XML_SCHEMA_TYPE_ALL:
1727	case XML_SCHEMA_TYPE_PARTICLE:
1728	    *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1729	    break;
1730	case XML_SCHEMA_TYPE_NOTATION: {
1731		*buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1732		*buf = xmlStrcat(*buf, BAD_CAST " '");
1733		*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1734		*buf = xmlStrcat(*buf, BAD_CAST "'");
1735		FREE_AND_NULL(str);
1736	    }
1737	default:
1738	    named = 0;
1739	}
1740    } else
1741	named = 0;
1742
1743    if ((named == 0) && (itemNode != NULL)) {
1744	xmlNodePtr elem;
1745
1746	if (itemNode->type == XML_ATTRIBUTE_NODE)
1747	    elem = itemNode->parent;
1748	else
1749	    elem = itemNode;
1750	*buf = xmlStrdup(BAD_CAST "Element '");
1751	if (elem->ns != NULL) {
1752	    *buf = xmlStrcat(*buf,
1753		xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
1754	    FREE_AND_NULL(str)
1755	} else
1756	    *buf = xmlStrcat(*buf, elem->name);
1757	*buf = xmlStrcat(*buf, BAD_CAST "'");
1758
1759    }
1760    if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
1761	*buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
1762	if (itemNode->ns != NULL) {
1763	    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1764		itemNode->ns->href, itemNode->name));
1765	    FREE_AND_NULL(str)
1766	} else
1767	    *buf = xmlStrcat(*buf, itemNode->name);
1768	*buf = xmlStrcat(*buf, BAD_CAST "'");
1769    }
1770    FREE_AND_NULL(str)
1771
1772    return (*buf);
1773}
1774
1775/**
1776 * xmlSchemaFormatFacetEnumSet:
1777 * @buf: the string buffer
1778 * @type: the type holding the enumeration facets
1779 *
1780 * Builds a string consisting of all enumeration elements.
1781 *
1782 * Returns a string of all enumeration elements.
1783 */
1784static const xmlChar *
1785xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
1786			    xmlChar **buf, xmlSchemaTypePtr type)
1787{
1788    xmlSchemaFacetPtr facet;
1789    xmlSchemaWhitespaceValueType ws;
1790    xmlChar *value = NULL;
1791    int res, found = 0;
1792
1793    if (*buf != NULL)
1794	xmlFree(*buf);
1795    *buf = NULL;
1796
1797    do {
1798	/*
1799	* Use the whitespace type of the base type.
1800	*/
1801	ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
1802	for (facet = type->facets; facet != NULL; facet = facet->next) {
1803	    if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
1804		continue;
1805	    found = 1;
1806	    res = xmlSchemaGetCanonValueWhtspExt(facet->val,
1807		ws, &value);
1808	    if (res == -1) {
1809		xmlSchemaInternalErr(actxt,
1810		    "xmlSchemaFormatFacetEnumSet",
1811		    "compute the canonical lexical representation");
1812		if (*buf != NULL)
1813		    xmlFree(*buf);
1814		*buf = NULL;
1815		return (NULL);
1816	    }
1817	    if (*buf == NULL)
1818		*buf = xmlStrdup(BAD_CAST "'");
1819	    else
1820		*buf = xmlStrcat(*buf, BAD_CAST ", '");
1821	    *buf = xmlStrcat(*buf, BAD_CAST value);
1822	    *buf = xmlStrcat(*buf, BAD_CAST "'");
1823	    if (value != NULL) {
1824		xmlFree((xmlChar *)value);
1825		value = NULL;
1826	    }
1827	}
1828	/*
1829	* The enumeration facet of a type restricts the enumeration
1830	* facet of the ancestor type; i.e., such restricted enumerations
1831	* do not belong to the set of the given type. Thus we break
1832	* on the first found enumeration.
1833	*/
1834	if (found)
1835	    break;
1836	type = type->baseType;
1837    } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
1838
1839    return ((const xmlChar *) *buf);
1840}
1841
1842/************************************************************************
1843 *									*
1844 *			Error functions				        *
1845 *									*
1846 ************************************************************************/
1847
1848#if 0
1849static void
1850xmlSchemaErrMemory(const char *msg)
1851{
1852    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
1853                     msg);
1854}
1855#endif
1856
1857static void
1858xmlSchemaPSimpleErr(const char *msg)
1859{
1860    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
1861                     msg);
1862}
1863
1864/**
1865 * xmlSchemaPErrMemory:
1866 * @node: a context node
1867 * @extra:  extra informations
1868 *
1869 * Handle an out of memory condition
1870 */
1871static void
1872xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
1873                    const char *extra, xmlNodePtr node)
1874{
1875    if (ctxt != NULL)
1876        ctxt->nberrors++;
1877    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
1878                     extra);
1879}
1880
1881/**
1882 * xmlSchemaPErr:
1883 * @ctxt: the parsing context
1884 * @node: the context node
1885 * @error: the error code
1886 * @msg: the error message
1887 * @str1: extra data
1888 * @str2: extra data
1889 *
1890 * Handle a parser error
1891 */
1892static void
1893xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
1894              const char *msg, const xmlChar * str1, const xmlChar * str2)
1895{
1896    xmlGenericErrorFunc channel = NULL;
1897    xmlStructuredErrorFunc schannel = NULL;
1898    void *data = NULL;
1899
1900    if (ctxt != NULL) {
1901        ctxt->nberrors++;
1902	ctxt->err = error;
1903        channel = ctxt->error;
1904        data = ctxt->errCtxt;
1905	schannel = ctxt->serror;
1906    }
1907    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
1908                    error, XML_ERR_ERROR, NULL, 0,
1909                    (const char *) str1, (const char *) str2, NULL, 0, 0,
1910                    msg, str1, str2);
1911}
1912
1913/**
1914 * xmlSchemaPErr2:
1915 * @ctxt: the parsing context
1916 * @node: the context node
1917 * @node: the current child
1918 * @error: the error code
1919 * @msg: the error message
1920 * @str1: extra data
1921 * @str2: extra data
1922 *
1923 * Handle a parser error
1924 */
1925static void
1926xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
1927               xmlNodePtr child, int error,
1928               const char *msg, const xmlChar * str1, const xmlChar * str2)
1929{
1930    if (child != NULL)
1931        xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
1932    else
1933        xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
1934}
1935
1936
1937/**
1938 * xmlSchemaPErrExt:
1939 * @ctxt: the parsing context
1940 * @node: the context node
1941 * @error: the error code
1942 * @strData1: extra data
1943 * @strData2: extra data
1944 * @strData3: extra data
1945 * @msg: the message
1946 * @str1:  extra parameter for the message display
1947 * @str2:  extra parameter for the message display
1948 * @str3:  extra parameter for the message display
1949 * @str4:  extra parameter for the message display
1950 * @str5:  extra parameter for the message display
1951 *
1952 * Handle a parser error
1953 */
1954static void
1955xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
1956		const xmlChar * strData1, const xmlChar * strData2,
1957		const xmlChar * strData3, const char *msg, const xmlChar * str1,
1958		const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
1959		const xmlChar * str5)
1960{
1961
1962    xmlGenericErrorFunc channel = NULL;
1963    xmlStructuredErrorFunc schannel = NULL;
1964    void *data = NULL;
1965
1966    if (ctxt != NULL) {
1967        ctxt->nberrors++;
1968	ctxt->err = error;
1969        channel = ctxt->error;
1970        data = ctxt->errCtxt;
1971	schannel = ctxt->serror;
1972    }
1973    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
1974                    error, XML_ERR_ERROR, NULL, 0,
1975                    (const char *) strData1, (const char *) strData2,
1976		    (const char *) strData3, 0, 0, msg, str1, str2,
1977		    str3, str4, str5);
1978}
1979
1980/************************************************************************
1981 *									*
1982 *			Allround error functions			*
1983 *									*
1984 ************************************************************************/
1985
1986/**
1987 * xmlSchemaVTypeErrMemory:
1988 * @node: a context node
1989 * @extra:  extra informations
1990 *
1991 * Handle an out of memory condition
1992 */
1993static void
1994xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
1995                    const char *extra, xmlNodePtr node)
1996{
1997    if (ctxt != NULL) {
1998        ctxt->nberrors++;
1999        ctxt->err = XML_SCHEMAV_INTERNAL;
2000    }
2001    __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
2002                     extra);
2003}
2004
2005static void
2006xmlSchemaPSimpleInternalErr(xmlNodePtr node,
2007			    const char *msg, const xmlChar *str)
2008{
2009     __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
2010	 msg, (const char *) str);
2011}
2012
2013#define WXS_ERROR_TYPE_ERROR 1
2014#define WXS_ERROR_TYPE_WARNING 2
2015/**
2016 * xmlSchemaErr3:
2017 * @ctxt: the validation context
2018 * @node: the context node
2019 * @error: the error code
2020 * @msg: the error message
2021 * @str1: extra data
2022 * @str2: extra data
2023 * @str3: extra data
2024 *
2025 * Handle a validation error
2026 */
2027static void
2028xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
2029		  xmlErrorLevel errorLevel,
2030		  int error, xmlNodePtr node, int line, const char *msg,
2031		  const xmlChar *str1, const xmlChar *str2,
2032		  const xmlChar *str3, const xmlChar *str4)
2033{
2034    xmlStructuredErrorFunc schannel = NULL;
2035    xmlGenericErrorFunc channel = NULL;
2036    void *data = NULL;
2037
2038    if (ctxt != NULL) {
2039	if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2040	    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
2041	    const char *file = NULL;
2042	    if (errorLevel != XML_ERR_WARNING) {
2043		vctxt->nberrors++;
2044		vctxt->err = error;
2045		channel = vctxt->error;
2046	    } else {
2047		channel = vctxt->warning;
2048	    }
2049	    schannel = vctxt->serror;
2050	    data = vctxt->errCtxt;
2051
2052	    /*
2053	    * Error node. If we specify a line number, then
2054	    * do not channel any node to the error function.
2055	    */
2056	    if (line == 0) {
2057		if ((node == NULL) &&
2058		    (vctxt->depth >= 0) &&
2059		    (vctxt->inode != NULL)) {
2060		    node = vctxt->inode->node;
2061		}
2062		/*
2063		* Get filename and line if no node-tree.
2064		*/
2065		if ((node == NULL) &&
2066		    (vctxt->parserCtxt != NULL) &&
2067		    (vctxt->parserCtxt->input != NULL)) {
2068		    file = vctxt->parserCtxt->input->filename;
2069		    line = vctxt->parserCtxt->input->line;
2070		}
2071	    } else {
2072		/*
2073		* Override the given node's (if any) position
2074		* and channel only the given line number.
2075		*/
2076		node = NULL;
2077		/*
2078		* Get filename.
2079		*/
2080		if (vctxt->doc != NULL)
2081		    file = (const char *) vctxt->doc->URL;
2082		else if ((vctxt->parserCtxt != NULL) &&
2083		    (vctxt->parserCtxt->input != NULL))
2084		    file = vctxt->parserCtxt->input->filename;
2085	    }
2086	    if (vctxt->locFunc != NULL) {
2087	        if ((file == NULL) || (line == 0)) {
2088		    unsigned long l;
2089		    const char *f;
2090		    vctxt->locFunc(vctxt->locCtxt, &f, &l);
2091		    if (file == NULL)
2092		        file = f;
2093		    if (line == 0)
2094		        line = (int) l;
2095		}
2096	    }
2097	    if ((file == NULL) && (vctxt->filename != NULL))
2098	        file = vctxt->filename;
2099
2100	    __xmlRaiseError(schannel, channel, data, ctxt,
2101		node, XML_FROM_SCHEMASV,
2102		error, errorLevel, file, line,
2103		(const char *) str1, (const char *) str2,
2104		(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
2105
2106	} else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
2107	    xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
2108	    if (errorLevel != XML_ERR_WARNING) {
2109		pctxt->nberrors++;
2110		pctxt->err = error;
2111		channel = pctxt->error;
2112	    } else {
2113		channel = pctxt->warning;
2114	    }
2115	    schannel = pctxt->serror;
2116	    data = pctxt->errCtxt;
2117	    __xmlRaiseError(schannel, channel, data, ctxt,
2118		node, XML_FROM_SCHEMASP, error,
2119		errorLevel, NULL, 0,
2120		(const char *) str1, (const char *) str2,
2121		(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
2122	} else {
2123	    TODO
2124	}
2125    }
2126}
2127
2128/**
2129 * xmlSchemaErr3:
2130 * @ctxt: the validation context
2131 * @node: the context node
2132 * @error: the error code
2133 * @msg: the error message
2134 * @str1: extra data
2135 * @str2: extra data
2136 * @str3: extra data
2137 *
2138 * Handle a validation error
2139 */
2140static void
2141xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
2142	      int error, xmlNodePtr node, const char *msg,
2143	      const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
2144{
2145    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2146	msg, str1, str2, str3, NULL);
2147}
2148
2149static void
2150xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
2151	      int error, xmlNodePtr node, const char *msg,
2152	      const xmlChar *str1, const xmlChar *str2,
2153	      const xmlChar *str3, const xmlChar *str4)
2154{
2155    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2156	msg, str1, str2, str3, str4);
2157}
2158
2159static void
2160xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
2161	     int error, xmlNodePtr node, const char *msg,
2162	     const xmlChar *str1, const xmlChar *str2)
2163{
2164    xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
2165}
2166
2167static xmlChar *
2168xmlSchemaFormatNodeForError(xmlChar ** msg,
2169			    xmlSchemaAbstractCtxtPtr actxt,
2170			    xmlNodePtr node)
2171{
2172    xmlChar *str = NULL;
2173
2174    *msg = NULL;
2175    if ((node != NULL) &&
2176	(node->type != XML_ELEMENT_NODE) &&
2177	(node->type != XML_ATTRIBUTE_NODE))
2178    {
2179	/*
2180	* Don't try to format other nodes than element and
2181	* attribute nodes.
2182	* Play save and return an empty string.
2183	*/
2184	*msg = xmlStrdup(BAD_CAST "");
2185	return(*msg);
2186    }
2187    if (node != NULL) {
2188	/*
2189	* Work on tree nodes.
2190	*/
2191	if (node->type == XML_ATTRIBUTE_NODE) {
2192	    xmlNodePtr elem = node->parent;
2193
2194	    *msg = xmlStrdup(BAD_CAST "Element '");
2195	    if (elem->ns != NULL)
2196		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2197		    elem->ns->href, elem->name));
2198	    else
2199		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2200		    NULL, elem->name));
2201	    FREE_AND_NULL(str);
2202	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
2203	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2204	} else {
2205	    *msg = xmlStrdup(BAD_CAST "Element '");
2206	}
2207	if (node->ns != NULL)
2208	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2209	    node->ns->href, node->name));
2210	else
2211	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2212	    NULL, node->name));
2213	FREE_AND_NULL(str);
2214	*msg = xmlStrcat(*msg, BAD_CAST "': ");
2215    } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2216	xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
2217	/*
2218	* Work on node infos.
2219	*/
2220	if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
2221	    xmlSchemaNodeInfoPtr ielem =
2222		vctxt->elemInfos[vctxt->depth];
2223
2224	    *msg = xmlStrdup(BAD_CAST "Element '");
2225	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2226		ielem->nsName, ielem->localName));
2227	    FREE_AND_NULL(str);
2228	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
2229	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2230	} else {
2231	    *msg = xmlStrdup(BAD_CAST "Element '");
2232	}
2233	*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2234	    vctxt->inode->nsName, vctxt->inode->localName));
2235	FREE_AND_NULL(str);
2236	*msg = xmlStrcat(*msg, BAD_CAST "': ");
2237    } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
2238	/*
2239	* Hmm, no node while parsing?
2240	* Return an empty string, in case NULL will break something.
2241	*/
2242	*msg = xmlStrdup(BAD_CAST "");
2243    } else {
2244	TODO
2245	return (NULL);
2246    }
2247    /*
2248    * VAL TODO: The output of the given schema component is currently
2249    * disabled.
2250    */
2251#if 0
2252    if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
2253	*msg = xmlStrcat(*msg, BAD_CAST " [");
2254	*msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
2255	    NULL, type, NULL, 0));
2256	FREE_AND_NULL(str)
2257	*msg = xmlStrcat(*msg, BAD_CAST "]");
2258    }
2259#endif
2260    return (*msg);
2261}
2262
2263static void
2264xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
2265		     const char *funcName,
2266		     const char *message,
2267		     const xmlChar *str1,
2268		     const xmlChar *str2)
2269{
2270    xmlChar *msg = NULL;
2271
2272    if (actxt == NULL)
2273        return;
2274    msg = xmlStrdup(BAD_CAST "Internal error: ");
2275    msg = xmlStrcat(msg, BAD_CAST funcName);
2276    msg = xmlStrcat(msg, BAD_CAST ", ");
2277    msg = xmlStrcat(msg, BAD_CAST message);
2278    msg = xmlStrcat(msg, BAD_CAST ".\n");
2279
2280    if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
2281	xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL,
2282	    (const char *) msg, str1, str2);
2283
2284    else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
2285	xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL,
2286	    (const char *) msg, str1, str2);
2287
2288    FREE_AND_NULL(msg)
2289}
2290
2291static void
2292xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
2293		     const char *funcName,
2294		     const char *message)
2295{
2296    xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
2297}
2298
2299#if 0
2300static void
2301xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
2302		     const char *funcName,
2303		     const char *message,
2304		     const xmlChar *str1,
2305		     const xmlChar *str2)
2306{
2307    xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
2308	str1, str2);
2309}
2310#endif
2311
2312static void
2313xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
2314		   xmlParserErrors error,
2315		   xmlNodePtr node,
2316		   xmlSchemaBasicItemPtr item,
2317		   const char *message,
2318		   const xmlChar *str1, const xmlChar *str2,
2319		   const xmlChar *str3, const xmlChar *str4)
2320{
2321    xmlChar *msg = NULL;
2322
2323    if ((node == NULL) && (item != NULL) &&
2324	(actxt->type == XML_SCHEMA_CTXT_PARSER)) {
2325	node = WXS_ITEM_NODE(item);
2326	xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
2327	msg = xmlStrcat(msg, BAD_CAST ": ");
2328    } else
2329	xmlSchemaFormatNodeForError(&msg, actxt, node);
2330    msg = xmlStrcat(msg, (const xmlChar *) message);
2331    msg = xmlStrcat(msg, BAD_CAST ".\n");
2332    xmlSchemaErr4(actxt, error, node,
2333	(const char *) msg, str1, str2, str3, str4);
2334    FREE_AND_NULL(msg)
2335}
2336
2337static void
2338xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
2339		   xmlParserErrors error,
2340		   xmlNodePtr node,
2341		   xmlSchemaBasicItemPtr item,
2342		   const char *message,
2343		   const xmlChar *str1,
2344		   const xmlChar *str2)
2345{
2346    xmlSchemaCustomErr4(actxt, error, node, item,
2347	message, str1, str2, NULL, NULL);
2348}
2349
2350
2351
2352static void
2353xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
2354		   xmlParserErrors error,
2355		   xmlNodePtr node,
2356		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2357		   const char *message,
2358		   const xmlChar *str1,
2359		   const xmlChar *str2,
2360		   const xmlChar *str3)
2361{
2362    xmlChar *msg = NULL;
2363
2364    xmlSchemaFormatNodeForError(&msg, actxt, node);
2365    msg = xmlStrcat(msg, (const xmlChar *) message);
2366    msg = xmlStrcat(msg, BAD_CAST ".\n");
2367
2368    /* URGENT TODO: Set the error code to something sane. */
2369    xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
2370	(const char *) msg, str1, str2, str3, NULL);
2371
2372    FREE_AND_NULL(msg)
2373}
2374
2375
2376
2377static void
2378xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
2379		   xmlParserErrors error,
2380		   xmlSchemaPSVIIDCNodePtr idcNode,
2381		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2382		   const char *message,
2383		   const xmlChar *str1,
2384		   const xmlChar *str2)
2385{
2386    xmlChar *msg = NULL, *qname = NULL;
2387
2388    msg = xmlStrdup(BAD_CAST "Element '%s': ");
2389    msg = xmlStrcat(msg, (const xmlChar *) message);
2390    msg = xmlStrcat(msg, BAD_CAST ".\n");
2391    xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
2392	error, NULL, idcNode->nodeLine, (const char *) msg,
2393	xmlSchemaFormatQName(&qname,
2394	    vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
2395	    vctxt->nodeQNames->items[idcNode->nodeQNameID]),
2396	str1, str2, NULL);
2397    FREE_AND_NULL(qname);
2398    FREE_AND_NULL(msg);
2399}
2400
2401static int
2402xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
2403			   xmlNodePtr node)
2404{
2405    if (node != NULL)
2406	return (node->type);
2407    if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
2408	(((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
2409	return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
2410    return (-1);
2411}
2412
2413static int
2414xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
2415{
2416    switch (item->type) {
2417	case XML_SCHEMA_TYPE_COMPLEX:
2418	case XML_SCHEMA_TYPE_SIMPLE:
2419	    if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
2420		return(1);
2421	    break;
2422	case XML_SCHEMA_TYPE_GROUP:
2423	    return (1);
2424	case XML_SCHEMA_TYPE_ELEMENT:
2425	    if ( ((xmlSchemaElementPtr) item)->flags &
2426		XML_SCHEMAS_ELEM_GLOBAL)
2427		return(1);
2428	    break;
2429	case XML_SCHEMA_TYPE_ATTRIBUTE:
2430	    if ( ((xmlSchemaAttributePtr) item)->flags &
2431		XML_SCHEMAS_ATTR_GLOBAL)
2432		return(1);
2433	    break;
2434	/* Note that attribute groups are always global. */
2435	default:
2436	    return(1);
2437    }
2438    return (0);
2439}
2440
2441static void
2442xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2443		       xmlParserErrors error,
2444		       xmlNodePtr node,
2445		       const xmlChar *value,
2446		       xmlSchemaTypePtr type,
2447		       int displayValue)
2448{
2449    xmlChar *msg = NULL;
2450
2451    xmlSchemaFormatNodeForError(&msg, actxt, node);
2452
2453    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2454	    XML_ATTRIBUTE_NODE))
2455	msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
2456    else
2457	msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
2458	    "value of ");
2459
2460    if (! xmlSchemaIsGlobalItem(type))
2461	msg = xmlStrcat(msg, BAD_CAST "the local ");
2462    else
2463	msg = xmlStrcat(msg, BAD_CAST "the ");
2464
2465    if (WXS_IS_ATOMIC(type))
2466	msg = xmlStrcat(msg, BAD_CAST "atomic type");
2467    else if (WXS_IS_LIST(type))
2468	msg = xmlStrcat(msg, BAD_CAST "list type");
2469    else if (WXS_IS_UNION(type))
2470	msg = xmlStrcat(msg, BAD_CAST "union type");
2471
2472    if (xmlSchemaIsGlobalItem(type)) {
2473	xmlChar *str = NULL;
2474	msg = xmlStrcat(msg, BAD_CAST " '");
2475	if (type->builtInType != 0) {
2476	    msg = xmlStrcat(msg, BAD_CAST "xs:");
2477	    msg = xmlStrcat(msg, type->name);
2478	} else
2479	    msg = xmlStrcat(msg,
2480		xmlSchemaFormatQName(&str,
2481		    type->targetNamespace, type->name));
2482	msg = xmlStrcat(msg, BAD_CAST "'");
2483	FREE_AND_NULL(str);
2484    }
2485    msg = xmlStrcat(msg, BAD_CAST ".\n");
2486    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2487	    XML_ATTRIBUTE_NODE))
2488	xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2489    else
2490	xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2491    FREE_AND_NULL(msg)
2492}
2493
2494static const xmlChar *
2495xmlSchemaFormatErrorNodeQName(xmlChar ** str,
2496			      xmlSchemaNodeInfoPtr ni,
2497			      xmlNodePtr node)
2498{
2499    if (node != NULL) {
2500	if (node->ns != NULL)
2501	    return (xmlSchemaFormatQName(str, node->ns->href, node->name));
2502	else
2503	    return (xmlSchemaFormatQName(str, NULL, node->name));
2504    } else if (ni != NULL)
2505	return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
2506    return (NULL);
2507}
2508
2509static void
2510xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
2511			xmlParserErrors error,
2512			xmlSchemaAttrInfoPtr ni,
2513			xmlNodePtr node)
2514{
2515    xmlChar *msg = NULL, *str = NULL;
2516
2517    xmlSchemaFormatNodeForError(&msg, actxt, node);
2518    msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
2519    xmlSchemaErr(actxt, error, node, (const char *) msg,
2520	xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
2521	NULL);
2522    FREE_AND_NULL(str)
2523    FREE_AND_NULL(msg)
2524}
2525
2526static void
2527xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2528		        xmlParserErrors error,
2529		        xmlNodePtr node,
2530			xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2531			const char *message,
2532			int nbval,
2533			int nbneg,
2534			xmlChar **values)
2535{
2536    xmlChar *str = NULL, *msg = NULL;
2537    xmlChar *localName, *nsName;
2538    const xmlChar *cur, *end;
2539    int i;
2540
2541    xmlSchemaFormatNodeForError(&msg, actxt, node);
2542    msg = xmlStrcat(msg, (const xmlChar *) message);
2543    msg = xmlStrcat(msg, BAD_CAST ".");
2544    /*
2545    * Note that is does not make sense to report that we have a
2546    * wildcard here, since the wildcard might be unfolded into
2547    * multiple transitions.
2548    */
2549    if (nbval + nbneg > 0) {
2550	if (nbval + nbneg > 1) {
2551	    str = xmlStrdup(BAD_CAST " Expected is one of ( ");
2552	} else
2553	    str = xmlStrdup(BAD_CAST " Expected is ( ");
2554	nsName = NULL;
2555
2556	for (i = 0; i < nbval + nbneg; i++) {
2557	    cur = values[i];
2558	    if (cur == NULL)
2559	        continue;
2560	    if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
2561	        (cur[3] == ' ')) {
2562		cur += 4;
2563		str = xmlStrcat(str, BAD_CAST "##other");
2564	    }
2565	    /*
2566	    * Get the local name.
2567	    */
2568	    localName = NULL;
2569
2570	    end = cur;
2571	    if (*end == '*') {
2572		localName = xmlStrdup(BAD_CAST "*");
2573		end++;
2574	    } else {
2575		while ((*end != 0) && (*end != '|'))
2576		    end++;
2577		localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
2578	    }
2579	    if (*end != 0) {
2580		end++;
2581		/*
2582		* Skip "*|*" if they come with negated expressions, since
2583		* they represent the same negated wildcard.
2584		*/
2585		if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
2586		    /*
2587		    * Get the namespace name.
2588		    */
2589		    cur = end;
2590		    if (*end == '*') {
2591			nsName = xmlStrdup(BAD_CAST "{*}");
2592		    } else {
2593			while (*end != 0)
2594			    end++;
2595
2596			if (i >= nbval)
2597			    nsName = xmlStrdup(BAD_CAST "{##other:");
2598			else
2599			    nsName = xmlStrdup(BAD_CAST "{");
2600
2601			nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
2602			nsName = xmlStrcat(nsName, BAD_CAST "}");
2603		    }
2604		    str = xmlStrcat(str, BAD_CAST nsName);
2605		    FREE_AND_NULL(nsName)
2606		} else {
2607		    FREE_AND_NULL(localName);
2608		    continue;
2609		}
2610	    }
2611	    str = xmlStrcat(str, BAD_CAST localName);
2612	    FREE_AND_NULL(localName);
2613
2614	    if (i < nbval + nbneg -1)
2615		str = xmlStrcat(str, BAD_CAST ", ");
2616	}
2617	str = xmlStrcat(str, BAD_CAST " ).\n");
2618	msg = xmlStrcat(msg, BAD_CAST str);
2619	FREE_AND_NULL(str)
2620    } else
2621      msg = xmlStrcat(msg, BAD_CAST "\n");
2622    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2623    xmlFree(msg);
2624}
2625
2626static void
2627xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
2628		  xmlParserErrors error,
2629		  xmlNodePtr node,
2630		  const xmlChar *value,
2631		  unsigned long length,
2632		  xmlSchemaTypePtr type,
2633		  xmlSchemaFacetPtr facet,
2634		  const char *message,
2635		  const xmlChar *str1,
2636		  const xmlChar *str2)
2637{
2638    xmlChar *str = NULL, *msg = NULL;
2639    xmlSchemaTypeType facetType;
2640    int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
2641
2642    xmlSchemaFormatNodeForError(&msg, actxt, node);
2643    if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
2644	facetType = XML_SCHEMA_FACET_ENUMERATION;
2645	/*
2646	* If enumerations are validated, one must not expect the
2647	* facet to be given.
2648	*/
2649    } else
2650	facetType = facet->type;
2651    msg = xmlStrcat(msg, BAD_CAST "[");
2652    msg = xmlStrcat(msg, BAD_CAST "facet '");
2653    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
2654    msg = xmlStrcat(msg, BAD_CAST "'] ");
2655    if (message == NULL) {
2656	/*
2657	* Use a default message.
2658	*/
2659	if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
2660	    (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
2661	    (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
2662
2663	    char len[25], actLen[25];
2664
2665	    /* FIXME, TODO: What is the max expected string length of the
2666	    * this value?
2667	    */
2668	    if (nodeType == XML_ATTRIBUTE_NODE)
2669		msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
2670	    else
2671		msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
2672
2673	    snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
2674	    snprintf(actLen, 24, "%lu", length);
2675
2676	    if (facetType == XML_SCHEMA_FACET_LENGTH)
2677		msg = xmlStrcat(msg,
2678		BAD_CAST "this differs from the allowed length of '%s'.\n");
2679	    else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
2680		msg = xmlStrcat(msg,
2681		BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
2682	    else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
2683		msg = xmlStrcat(msg,
2684		BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
2685
2686	    if (nodeType == XML_ATTRIBUTE_NODE)
2687		xmlSchemaErr3(actxt, error, node, (const char *) msg,
2688		    value, (const xmlChar *) actLen, (const xmlChar *) len);
2689	    else
2690		xmlSchemaErr(actxt, error, node, (const char *) msg,
2691		    (const xmlChar *) actLen, (const xmlChar *) len);
2692
2693	} else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
2694	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
2695		"of the set {%s}.\n");
2696	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2697		xmlSchemaFormatFacetEnumSet(actxt, &str, type));
2698	} else if (facetType == XML_SCHEMA_FACET_PATTERN) {
2699	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
2700		"by the pattern '%s'.\n");
2701	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2702		facet->value);
2703	} else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
2704	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
2705		"minimum value allowed ('%s').\n");
2706	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2707		facet->value);
2708	} else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
2709	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
2710		"maximum value allowed ('%s').\n");
2711	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2712		facet->value);
2713	} else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
2714	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
2715		"'%s'.\n");
2716	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2717		facet->value);
2718	} else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
2719	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
2720		"'%s'.\n");
2721	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2722		facet->value);
2723	} else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
2724	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
2725		"digits than are allowed ('%s').\n");
2726	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2727		facet->value);
2728	} else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
2729	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
2730		"digits than are allowed ('%s').\n");
2731	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2732		facet->value);
2733	} else if (nodeType == XML_ATTRIBUTE_NODE) {
2734	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
2735	    xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2736	} else {
2737	    msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
2738	    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2739	}
2740    } else {
2741	msg = xmlStrcat(msg, (const xmlChar *) message);
2742	msg = xmlStrcat(msg, BAD_CAST ".\n");
2743	xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
2744    }
2745    FREE_AND_NULL(str)
2746    xmlFree(msg);
2747}
2748
2749#define VERROR(err, type, msg) \
2750    xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
2751
2752#define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
2753
2754#define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
2755#define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
2756
2757#define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
2758
2759
2760/**
2761 * xmlSchemaPMissingAttrErr:
2762 * @ctxt: the schema validation context
2763 * @ownerDes: the designation of  the owner
2764 * @ownerName: the name of the owner
2765 * @ownerItem: the owner as a schema object
2766 * @ownerElem: the owner as an element node
2767 * @node: the parent element node of the missing attribute node
2768 * @type: the corresponding type of the attribute node
2769 *
2770 * Reports an illegal attribute.
2771 */
2772static void
2773xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
2774			 xmlParserErrors error,
2775			 xmlSchemaBasicItemPtr ownerItem,
2776			 xmlNodePtr ownerElem,
2777			 const char *name,
2778			 const char *message)
2779{
2780    xmlChar *des = NULL;
2781
2782    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2783
2784    if (message != NULL)
2785	xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
2786    else
2787	xmlSchemaPErr(ctxt, ownerElem, error,
2788	    "%s: The attribute '%s' is required but missing.\n",
2789	    BAD_CAST des, BAD_CAST name);
2790    FREE_AND_NULL(des);
2791}
2792
2793
2794/**
2795 * xmlSchemaPResCompAttrErr:
2796 * @ctxt: the schema validation context
2797 * @error: the error code
2798 * @ownerDes: the designation of  the owner
2799 * @ownerItem: the owner as a schema object
2800 * @ownerElem: the owner as an element node
2801 * @name: the name of the attribute holding the QName
2802 * @refName: the referenced local name
2803 * @refURI: the referenced namespace URI
2804 * @message: optional message
2805 *
2806 * Used to report QName attribute values that failed to resolve
2807 * to schema components.
2808 */
2809static void
2810xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
2811			 xmlParserErrors error,
2812			 xmlSchemaBasicItemPtr ownerItem,
2813			 xmlNodePtr ownerElem,
2814			 const char *name,
2815			 const xmlChar *refName,
2816			 const xmlChar *refURI,
2817			 xmlSchemaTypeType refType,
2818			 const char *refTypeStr)
2819{
2820    xmlChar *des = NULL, *strA = NULL;
2821
2822    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2823    if (refTypeStr == NULL)
2824	refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
2825	xmlSchemaPErrExt(ctxt, ownerElem, error,
2826	    NULL, NULL, NULL,
2827	    "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
2828	    "%s.\n", BAD_CAST des, BAD_CAST name,
2829	    xmlSchemaFormatQName(&strA, refURI, refName),
2830	    BAD_CAST refTypeStr, NULL);
2831    FREE_AND_NULL(des)
2832    FREE_AND_NULL(strA)
2833}
2834
2835/**
2836 * xmlSchemaPCustomAttrErr:
2837 * @ctxt: the schema parser context
2838 * @error: the error code
2839 * @ownerDes: the designation of the owner
2840 * @ownerItem: the owner as a schema object
2841 * @attr: the illegal attribute node
2842 *
2843 * Reports an illegal attribute during the parse.
2844 */
2845static void
2846xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
2847			xmlParserErrors error,
2848			xmlChar **ownerDes,
2849			xmlSchemaBasicItemPtr ownerItem,
2850			xmlAttrPtr attr,
2851			const char *msg)
2852{
2853    xmlChar *des = NULL;
2854
2855    if (ownerDes == NULL)
2856	xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
2857    else if (*ownerDes == NULL) {
2858	xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
2859	des = *ownerDes;
2860    } else
2861	des = *ownerDes;
2862    if (attr == NULL) {
2863	xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
2864	    "%s, attribute '%s': %s.\n",
2865	    BAD_CAST des, (const xmlChar *) "Unknown",
2866	    (const xmlChar *) msg, NULL, NULL);
2867    } else {
2868	xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
2869	    "%s, attribute '%s': %s.\n",
2870	    BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
2871    }
2872    if (ownerDes == NULL)
2873	FREE_AND_NULL(des);
2874}
2875
2876/**
2877 * xmlSchemaPIllegalAttrErr:
2878 * @ctxt: the schema parser context
2879 * @error: the error code
2880 * @ownerDes: the designation of the attribute's owner
2881 * @ownerItem: the attribute's owner item
2882 * @attr: the illegal attribute node
2883 *
2884 * Reports an illegal attribute during the parse.
2885 */
2886static void
2887xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
2888			 xmlParserErrors error,
2889			 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
2890			 xmlAttrPtr attr)
2891{
2892    xmlChar *strA = NULL, *strB = NULL;
2893
2894    xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
2895    xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
2896	"%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
2897	xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
2898	NULL, NULL);
2899    FREE_AND_NULL(strA);
2900    FREE_AND_NULL(strB);
2901}
2902
2903/**
2904 * xmlSchemaPCustomErr:
2905 * @ctxt: the schema parser context
2906 * @error: the error code
2907 * @itemDes: the designation of the schema item
2908 * @item: the schema item
2909 * @itemElem: the node of the schema item
2910 * @message: the error message
2911 * @str1: an optional param for the error message
2912 * @str2: an optional param for the error message
2913 * @str3: an optional param for the error message
2914 *
2915 * Reports an error during parsing.
2916 */
2917static void
2918xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
2919		    xmlParserErrors error,
2920		    xmlSchemaBasicItemPtr item,
2921		    xmlNodePtr itemElem,
2922		    const char *message,
2923		    const xmlChar *str1,
2924		    const xmlChar *str2,
2925		    const xmlChar *str3)
2926{
2927    xmlChar *des = NULL, *msg = NULL;
2928
2929    xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
2930    msg = xmlStrdup(BAD_CAST "%s: ");
2931    msg = xmlStrcat(msg, (const xmlChar *) message);
2932    msg = xmlStrcat(msg, BAD_CAST ".\n");
2933    if ((itemElem == NULL) && (item != NULL))
2934	itemElem = WXS_ITEM_NODE(item);
2935    xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
2936	(const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
2937    FREE_AND_NULL(des);
2938    FREE_AND_NULL(msg);
2939}
2940
2941/**
2942 * xmlSchemaPCustomErr:
2943 * @ctxt: the schema parser context
2944 * @error: the error code
2945 * @itemDes: the designation of the schema item
2946 * @item: the schema item
2947 * @itemElem: the node of the schema item
2948 * @message: the error message
2949 * @str1: the optional param for the error message
2950 *
2951 * Reports an error during parsing.
2952 */
2953static void
2954xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
2955		    xmlParserErrors error,
2956		    xmlSchemaBasicItemPtr item,
2957		    xmlNodePtr itemElem,
2958		    const char *message,
2959		    const xmlChar *str1)
2960{
2961    xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
2962	str1, NULL, NULL);
2963}
2964
2965/**
2966 * xmlSchemaPAttrUseErr:
2967 * @ctxt: the schema parser context
2968 * @error: the error code
2969 * @itemDes: the designation of the schema type
2970 * @item: the schema type
2971 * @itemElem: the node of the schema type
2972 * @attr: the invalid schema attribute
2973 * @message: the error message
2974 * @str1: the optional param for the error message
2975 *
2976 * Reports an attribute use error during parsing.
2977 */
2978static void
2979xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
2980		    xmlParserErrors error,
2981		    xmlNodePtr node,
2982		    xmlSchemaBasicItemPtr ownerItem,
2983		    const xmlSchemaAttributeUsePtr attruse,
2984		    const char *message,
2985		    const xmlChar *str1, const xmlChar *str2,
2986		    const xmlChar *str3,const xmlChar *str4)
2987{
2988    xmlChar *str = NULL, *msg = NULL;
2989
2990    xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
2991    msg = xmlStrcat(msg, BAD_CAST ", ");
2992    msg = xmlStrcat(msg,
2993	BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
2994	WXS_BASIC_CAST attruse, NULL));
2995    FREE_AND_NULL(str);
2996    msg = xmlStrcat(msg, BAD_CAST ": ");
2997    msg = xmlStrcat(msg, (const xmlChar *) message);
2998    msg = xmlStrcat(msg, BAD_CAST ".\n");
2999    xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
3000	(const char *) msg, str1, str2, str3, str4);
3001    xmlFree(msg);
3002}
3003
3004/**
3005 * xmlSchemaPIllegalFacetAtomicErr:
3006 * @ctxt: the schema parser context
3007 * @error: the error code
3008 * @type: the schema type
3009 * @baseType: the base type of type
3010 * @facet: the illegal facet
3011 *
3012 * Reports an illegal facet for atomic simple types.
3013 */
3014static void
3015xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
3016			  xmlParserErrors error,
3017			  xmlSchemaTypePtr type,
3018			  xmlSchemaTypePtr baseType,
3019			  xmlSchemaFacetPtr facet)
3020{
3021    xmlChar *des = NULL, *strT = NULL;
3022
3023    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
3024    xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
3025	"%s: The facet '%s' is not allowed on types derived from the "
3026	"type %s.\n",
3027	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
3028	xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
3029	NULL, NULL);
3030    FREE_AND_NULL(des);
3031    FREE_AND_NULL(strT);
3032}
3033
3034/**
3035 * xmlSchemaPIllegalFacetListUnionErr:
3036 * @ctxt: the schema parser context
3037 * @error: the error code
3038 * @itemDes: the designation of the schema item involved
3039 * @item: the schema item involved
3040 * @facet: the illegal facet
3041 *
3042 * Reports an illegal facet for <list> and <union>.
3043 */
3044static void
3045xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
3046			  xmlParserErrors error,
3047			  xmlSchemaTypePtr type,
3048			  xmlSchemaFacetPtr facet)
3049{
3050    xmlChar *des = NULL;
3051
3052    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
3053	type->node);
3054    xmlSchemaPErr(ctxt, type->node, error,
3055	"%s: The facet '%s' is not allowed.\n",
3056	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
3057    FREE_AND_NULL(des);
3058}
3059
3060/**
3061 * xmlSchemaPMutualExclAttrErr:
3062 * @ctxt: the schema validation context
3063 * @error: the error code
3064 * @elemDes: the designation of the parent element node
3065 * @attr: the bad attribute node
3066 * @type: the corresponding type of the attribute node
3067 *
3068 * Reports an illegal attribute.
3069 */
3070static void
3071xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
3072			 xmlParserErrors error,
3073			 xmlSchemaBasicItemPtr ownerItem,
3074			 xmlAttrPtr attr,
3075			 const char *name1,
3076			 const char *name2)
3077{
3078    xmlChar *des = NULL;
3079
3080    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
3081    xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
3082	"%s: The attributes '%s' and '%s' are mutually exclusive.\n",
3083	BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
3084    FREE_AND_NULL(des);
3085}
3086
3087/**
3088 * xmlSchemaPSimpleTypeErr:
3089 * @ctxt:  the schema validation context
3090 * @error: the error code
3091 * @type: the type specifier
3092 * @ownerDes: the designation of the owner
3093 * @ownerItem: the schema object if existent
3094 * @node: the validated node
3095 * @value: the validated value
3096 *
3097 * Reports a simple type validation error.
3098 * TODO: Should this report the value of an element as well?
3099 */
3100static void
3101xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
3102			xmlParserErrors error,
3103			xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
3104			xmlNodePtr node,
3105			xmlSchemaTypePtr type,
3106			const char *expected,
3107			const xmlChar *value,
3108			const char *message,
3109			const xmlChar *str1,
3110			const xmlChar *str2)
3111{
3112    xmlChar *msg = NULL;
3113
3114    xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
3115    if (message == NULL) {
3116	/*
3117	* Use default messages.
3118	*/
3119	if (type != NULL) {
3120	    if (node->type == XML_ATTRIBUTE_NODE)
3121		msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
3122	    else
3123		msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
3124		"valid value of ");
3125	    if (! xmlSchemaIsGlobalItem(type))
3126		msg = xmlStrcat(msg, BAD_CAST "the local ");
3127	    else
3128		msg = xmlStrcat(msg, BAD_CAST "the ");
3129
3130	    if (WXS_IS_ATOMIC(type))
3131		msg = xmlStrcat(msg, BAD_CAST "atomic type");
3132	    else if (WXS_IS_LIST(type))
3133		msg = xmlStrcat(msg, BAD_CAST "list type");
3134	    else if (WXS_IS_UNION(type))
3135		msg = xmlStrcat(msg, BAD_CAST "union type");
3136
3137	    if (xmlSchemaIsGlobalItem(type)) {
3138		xmlChar *str = NULL;
3139		msg = xmlStrcat(msg, BAD_CAST " '");
3140		if (type->builtInType != 0) {
3141		    msg = xmlStrcat(msg, BAD_CAST "xs:");
3142		    msg = xmlStrcat(msg, type->name);
3143		} else
3144		    msg = xmlStrcat(msg,
3145			xmlSchemaFormatQName(&str,
3146			    type->targetNamespace, type->name));
3147		msg = xmlStrcat(msg, BAD_CAST "'.");
3148		FREE_AND_NULL(str);
3149	    }
3150	} else {
3151	    if (node->type == XML_ATTRIBUTE_NODE)
3152		msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
3153	    else
3154		msg = xmlStrcat(msg, BAD_CAST "The character content is not "
3155		"valid.");
3156	}
3157	if (expected) {
3158	    msg = xmlStrcat(msg, BAD_CAST " Expected is '");
3159	    msg = xmlStrcat(msg, BAD_CAST expected);
3160	    msg = xmlStrcat(msg, BAD_CAST "'.\n");
3161	} else
3162	    msg = xmlStrcat(msg, BAD_CAST "\n");
3163	if (node->type == XML_ATTRIBUTE_NODE)
3164	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
3165	else
3166	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
3167    } else {
3168	msg = xmlStrcat(msg, BAD_CAST message);
3169	msg = xmlStrcat(msg, BAD_CAST ".\n");
3170	xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
3171	     (const char*) msg, str1, str2, NULL, NULL, NULL);
3172    }
3173    /* Cleanup. */
3174    FREE_AND_NULL(msg)
3175}
3176
3177/**
3178 * xmlSchemaPContentErr:
3179 * @ctxt: the schema parser context
3180 * @error: the error code
3181 * @onwerDes: the designation of the holder of the content
3182 * @ownerItem: the owner item of the holder of the content
3183 * @ownerElem: the node of the holder of the content
3184 * @child: the invalid child node
3185 * @message: the optional error message
3186 * @content: the optional string describing the correct content
3187 *
3188 * Reports an error concerning the content of a schema element.
3189 */
3190static void
3191xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
3192		     xmlParserErrors error,
3193		     xmlSchemaBasicItemPtr ownerItem,
3194		     xmlNodePtr ownerElem,
3195		     xmlNodePtr child,
3196		     const char *message,
3197		     const char *content)
3198{
3199    xmlChar *des = NULL;
3200
3201    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
3202    if (message != NULL)
3203	xmlSchemaPErr2(ctxt, ownerElem, child, error,
3204	    "%s: %s.\n",
3205	    BAD_CAST des, BAD_CAST message);
3206    else {
3207	if (content != NULL) {
3208	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
3209		"%s: The content is not valid. Expected is %s.\n",
3210		BAD_CAST des, BAD_CAST content);
3211	} else {
3212	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
3213		"%s: The content is not valid.\n",
3214		BAD_CAST des, NULL);
3215	}
3216    }
3217    FREE_AND_NULL(des)
3218}
3219
3220/************************************************************************
3221 *									*
3222 *			Streamable error functions                      *
3223 *									*
3224 ************************************************************************/
3225
3226
3227
3228
3229/************************************************************************
3230 *									*
3231 *			Validation helper functions			*
3232 *									*
3233 ************************************************************************/
3234
3235
3236/************************************************************************
3237 *									*
3238 *			Allocation functions				*
3239 *									*
3240 ************************************************************************/
3241
3242/**
3243 * xmlSchemaNewSchemaForParserCtxt:
3244 * @ctxt:  a schema validation context
3245 *
3246 * Allocate a new Schema structure.
3247 *
3248 * Returns the newly allocated structure or NULL in case or error
3249 */
3250static xmlSchemaPtr
3251xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
3252{
3253    xmlSchemaPtr ret;
3254
3255    ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
3256    if (ret == NULL) {
3257        xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
3258        return (NULL);
3259    }
3260    memset(ret, 0, sizeof(xmlSchema));
3261    ret->dict = ctxt->dict;
3262    xmlDictReference(ret->dict);
3263
3264    return (ret);
3265}
3266
3267/**
3268 * xmlSchemaNewFacet:
3269 *
3270 * Allocate a new Facet structure.
3271 *
3272 * Returns the newly allocated structure or NULL in case or error
3273 */
3274xmlSchemaFacetPtr
3275xmlSchemaNewFacet(void)
3276{
3277    xmlSchemaFacetPtr ret;
3278
3279    ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
3280    if (ret == NULL) {
3281        return (NULL);
3282    }
3283    memset(ret, 0, sizeof(xmlSchemaFacet));
3284
3285    return (ret);
3286}
3287
3288/**
3289 * xmlSchemaNewAnnot:
3290 * @ctxt:  a schema validation context
3291 * @node:  a node
3292 *
3293 * Allocate a new annotation structure.
3294 *
3295 * Returns the newly allocated structure or NULL in case or error
3296 */
3297static xmlSchemaAnnotPtr
3298xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
3299{
3300    xmlSchemaAnnotPtr ret;
3301
3302    ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
3303    if (ret == NULL) {
3304        xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
3305        return (NULL);
3306    }
3307    memset(ret, 0, sizeof(xmlSchemaAnnot));
3308    ret->content = node;
3309    return (ret);
3310}
3311
3312static xmlSchemaItemListPtr
3313xmlSchemaItemListCreate(void)
3314{
3315    xmlSchemaItemListPtr ret;
3316
3317    ret = xmlMalloc(sizeof(xmlSchemaItemList));
3318    if (ret == NULL) {
3319	xmlSchemaPErrMemory(NULL,
3320	    "allocating an item list structure", NULL);
3321	return (NULL);
3322    }
3323    memset(ret, 0, sizeof(xmlSchemaItemList));
3324    return (ret);
3325}
3326
3327static void
3328xmlSchemaItemListClear(xmlSchemaItemListPtr list)
3329{
3330    if (list->items != NULL) {
3331	xmlFree(list->items);
3332	list->items = NULL;
3333    }
3334    list->nbItems = 0;
3335    list->sizeItems = 0;
3336}
3337
3338static int
3339xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
3340{
3341    if (list->items == NULL) {
3342	list->items = (void **) xmlMalloc(
3343	    20 * sizeof(void *));
3344	if (list->items == NULL) {
3345	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3346	    return(-1);
3347	}
3348	list->sizeItems = 20;
3349    } else if (list->sizeItems <= list->nbItems) {
3350	list->sizeItems *= 2;
3351	list->items = (void **) xmlRealloc(list->items,
3352	    list->sizeItems * sizeof(void *));
3353	if (list->items == NULL) {
3354	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3355	    list->sizeItems = 0;
3356	    return(-1);
3357	}
3358    }
3359    list->items[list->nbItems++] = item;
3360    return(0);
3361}
3362
3363static int
3364xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
3365			 int initialSize,
3366			 void *item)
3367{
3368    if (list->items == NULL) {
3369	if (initialSize <= 0)
3370	    initialSize = 1;
3371	list->items = (void **) xmlMalloc(
3372	    initialSize * sizeof(void *));
3373	if (list->items == NULL) {
3374	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3375	    return(-1);
3376	}
3377	list->sizeItems = initialSize;
3378    } else if (list->sizeItems <= list->nbItems) {
3379	list->sizeItems *= 2;
3380	list->items = (void **) xmlRealloc(list->items,
3381	    list->sizeItems * sizeof(void *));
3382	if (list->items == NULL) {
3383	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3384	    list->sizeItems = 0;
3385	    return(-1);
3386	}
3387    }
3388    list->items[list->nbItems++] = item;
3389    return(0);
3390}
3391
3392static int
3393xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
3394{
3395    if (list->items == NULL) {
3396	list->items = (void **) xmlMalloc(
3397	    20 * sizeof(void *));
3398	if (list->items == NULL) {
3399	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3400	    return(-1);
3401	}
3402	list->sizeItems = 20;
3403    } else if (list->sizeItems <= list->nbItems) {
3404	list->sizeItems *= 2;
3405	list->items = (void **) xmlRealloc(list->items,
3406	    list->sizeItems * sizeof(void *));
3407	if (list->items == NULL) {
3408	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3409	    list->sizeItems = 0;
3410	    return(-1);
3411	}
3412    }
3413    /*
3414    * Just append if the index is greater/equal than the item count.
3415    */
3416    if (idx >= list->nbItems) {
3417	list->items[list->nbItems++] = item;
3418    } else {
3419	int i;
3420	for (i = list->nbItems; i > idx; i--)
3421	    list->items[i] = list->items[i-1];
3422	list->items[idx] = item;
3423	list->nbItems++;
3424    }
3425    return(0);
3426}
3427
3428#if 0 /* enable if ever needed */
3429static int
3430xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
3431			    int initialSize,
3432			    void *item,
3433			    int idx)
3434{
3435    if (list->items == NULL) {
3436	if (initialSize <= 0)
3437	    initialSize = 1;
3438	list->items = (void **) xmlMalloc(
3439	    initialSize * sizeof(void *));
3440	if (list->items == NULL) {
3441	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3442	    return(-1);
3443	}
3444	list->sizeItems = initialSize;
3445    } else if (list->sizeItems <= list->nbItems) {
3446	list->sizeItems *= 2;
3447	list->items = (void **) xmlRealloc(list->items,
3448	    list->sizeItems * sizeof(void *));
3449	if (list->items == NULL) {
3450	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3451	    list->sizeItems = 0;
3452	    return(-1);
3453	}
3454    }
3455    /*
3456    * Just append if the index is greater/equal than the item count.
3457    */
3458    if (idx >= list->nbItems) {
3459	list->items[list->nbItems++] = item;
3460    } else {
3461	int i;
3462	for (i = list->nbItems; i > idx; i--)
3463	    list->items[i] = list->items[i-1];
3464	list->items[idx] = item;
3465	list->nbItems++;
3466    }
3467    return(0);
3468}
3469#endif
3470
3471static int
3472xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
3473{
3474    int i;
3475    if ((list->items == NULL) || (idx >= list->nbItems)) {
3476	xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
3477	    "index error.\n");
3478	return(-1);
3479    }
3480
3481    if (list->nbItems == 1) {
3482	/* TODO: Really free the list? */
3483	xmlFree(list->items);
3484	list->items = NULL;
3485	list->nbItems = 0;
3486	list->sizeItems = 0;
3487    } else if (list->nbItems -1 == idx) {
3488	list->nbItems--;
3489    } else {
3490	for (i = idx; i < list->nbItems -1; i++)
3491	    list->items[i] = list->items[i+1];
3492	list->nbItems--;
3493    }
3494    return(0);
3495}
3496
3497/**
3498 * xmlSchemaItemListFree:
3499 * @annot:  a schema type structure
3500 *
3501 * Deallocate a annotation structure
3502 */
3503static void
3504xmlSchemaItemListFree(xmlSchemaItemListPtr list)
3505{
3506    if (list == NULL)
3507	return;
3508    if (list->items != NULL)
3509	xmlFree(list->items);
3510    xmlFree(list);
3511}
3512
3513static void
3514xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
3515{
3516    if (bucket == NULL)
3517	return;
3518    if (bucket->globals != NULL) {
3519	xmlSchemaComponentListFree(bucket->globals);
3520	xmlSchemaItemListFree(bucket->globals);
3521    }
3522    if (bucket->locals != NULL) {
3523	xmlSchemaComponentListFree(bucket->locals);
3524	xmlSchemaItemListFree(bucket->locals);
3525    }
3526    if (bucket->relations != NULL) {
3527	xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
3528	do {
3529	    prev = cur;
3530	    cur = cur->next;
3531	    xmlFree(prev);
3532	} while (cur != NULL);
3533    }
3534    if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
3535	xmlFreeDoc(bucket->doc);
3536    }
3537    if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
3538	if (WXS_IMPBUCKET(bucket)->schema != NULL)
3539	    xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
3540    }
3541    xmlFree(bucket);
3542}
3543
3544static xmlSchemaBucketPtr
3545xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
3546			 int type, const xmlChar *targetNamespace)
3547{
3548    xmlSchemaBucketPtr ret;
3549    int size;
3550    xmlSchemaPtr mainSchema;
3551
3552    if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
3553	PERROR_INT("xmlSchemaBucketCreate",
3554	    "no main schema on constructor");
3555	return(NULL);
3556    }
3557    mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
3558    /* Create the schema bucket. */
3559    if (WXS_IS_BUCKET_INCREDEF(type))
3560	size = sizeof(xmlSchemaInclude);
3561    else
3562	size = sizeof(xmlSchemaImport);
3563    ret = (xmlSchemaBucketPtr) xmlMalloc(size);
3564    if (ret == NULL) {
3565	xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
3566	return(NULL);
3567    }
3568    memset(ret, 0, size);
3569    ret->targetNamespace = targetNamespace;
3570    ret->type = type;
3571    ret->globals = xmlSchemaItemListCreate();
3572    if (ret->globals == NULL) {
3573	xmlFree(ret);
3574	return(NULL);
3575    }
3576    ret->locals = xmlSchemaItemListCreate();
3577    if (ret->locals == NULL) {
3578	xmlFree(ret);
3579	return(NULL);
3580    }
3581    /*
3582    * The following will assure that only the first bucket is marked as
3583    * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
3584    * For each following import buckets an xmlSchema will be created.
3585    * An xmlSchema will be created for every distinct targetNamespace.
3586    * We assign the targetNamespace to the schemata here.
3587    */
3588    if (! WXS_HAS_BUCKETS(pctxt)) {
3589	if (WXS_IS_BUCKET_INCREDEF(type)) {
3590	    PERROR_INT("xmlSchemaBucketCreate",
3591		"first bucket but it's an include or redefine");
3592	    xmlSchemaBucketFree(ret);
3593	    return(NULL);
3594	}
3595	/* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
3596	ret->type = XML_SCHEMA_SCHEMA_MAIN;
3597	/* Point to the *main* schema. */
3598	WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
3599	WXS_IMPBUCKET(ret)->schema = mainSchema;
3600	/*
3601	* Ensure that the main schema gets a targetNamespace.
3602	*/
3603	mainSchema->targetNamespace = targetNamespace;
3604    } else {
3605	if (type == XML_SCHEMA_SCHEMA_MAIN) {
3606	    PERROR_INT("xmlSchemaBucketCreate",
3607		"main bucket but it's not the first one");
3608	    xmlSchemaBucketFree(ret);
3609	    return(NULL);
3610	} else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
3611	    /*
3612	    * Create a schema for imports and assign the
3613	    * targetNamespace.
3614	    */
3615	    WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
3616	    if (WXS_IMPBUCKET(ret)->schema == NULL) {
3617		xmlSchemaBucketFree(ret);
3618		return(NULL);
3619	    }
3620	    WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
3621	}
3622    }
3623    if (WXS_IS_BUCKET_IMPMAIN(type)) {
3624	int res;
3625	/*
3626	* Imports go into the "schemasImports" slot of the main *schema*.
3627	* Note that we create an import entry for the main schema as well; i.e.,
3628	* even if there's only one schema, we'll get an import.
3629	*/
3630	if (mainSchema->schemasImports == NULL) {
3631	    mainSchema->schemasImports = xmlHashCreateDict(5,
3632		WXS_CONSTRUCTOR(pctxt)->dict);
3633	    if (mainSchema->schemasImports == NULL) {
3634		xmlSchemaBucketFree(ret);
3635		return(NULL);
3636	    }
3637	}
3638	if (targetNamespace == NULL)
3639	    res = xmlHashAddEntry(mainSchema->schemasImports,
3640		XML_SCHEMAS_NO_NAMESPACE, ret);
3641	else
3642	    res = xmlHashAddEntry(mainSchema->schemasImports,
3643		targetNamespace, ret);
3644	if (res != 0) {
3645	    PERROR_INT("xmlSchemaBucketCreate",
3646		"failed to add the schema bucket to the hash");
3647	    xmlSchemaBucketFree(ret);
3648	    return(NULL);
3649	}
3650    } else {
3651	/* Set the @ownerImport of an include bucket. */
3652	if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
3653	    WXS_INCBUCKET(ret)->ownerImport =
3654		WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
3655	else
3656	    WXS_INCBUCKET(ret)->ownerImport =
3657		WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
3658
3659	/* Includes got into the "includes" slot of the *main* schema. */
3660	if (mainSchema->includes == NULL) {
3661	    mainSchema->includes = xmlSchemaItemListCreate();
3662	    if (mainSchema->includes == NULL) {
3663		xmlSchemaBucketFree(ret);
3664		return(NULL);
3665	    }
3666	}
3667	xmlSchemaItemListAdd(mainSchema->includes, ret);
3668    }
3669    /*
3670    * Add to list of all buckets; this is used for lookup
3671    * during schema construction time only.
3672    */
3673    if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
3674	return(NULL);
3675    return(ret);
3676}
3677
3678static int
3679xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
3680{
3681    if (*list == NULL) {
3682	*list = xmlSchemaItemListCreate();
3683	if (*list == NULL)
3684	    return(-1);
3685    }
3686    xmlSchemaItemListAddSize(*list, initialSize, item);
3687    return(0);
3688}
3689
3690/**
3691 * xmlSchemaFreeAnnot:
3692 * @annot:  a schema type structure
3693 *
3694 * Deallocate a annotation structure
3695 */
3696static void
3697xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
3698{
3699    if (annot == NULL)
3700        return;
3701    if (annot->next == NULL) {
3702	xmlFree(annot);
3703    } else {
3704	xmlSchemaAnnotPtr prev;
3705
3706	do {
3707	    prev = annot;
3708	    annot = annot->next;
3709	    xmlFree(prev);
3710	} while (annot != NULL);
3711    }
3712}
3713
3714/**
3715 * xmlSchemaFreeNotation:
3716 * @schema:  a schema notation structure
3717 *
3718 * Deallocate a Schema Notation structure.
3719 */
3720static void
3721xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
3722{
3723    if (nota == NULL)
3724        return;
3725    xmlFree(nota);
3726}
3727
3728/**
3729 * xmlSchemaFreeAttribute:
3730 * @attr:  an attribute declaration
3731 *
3732 * Deallocates an attribute declaration structure.
3733 */
3734static void
3735xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
3736{
3737    if (attr == NULL)
3738        return;
3739    if (attr->annot != NULL)
3740	xmlSchemaFreeAnnot(attr->annot);
3741    if (attr->defVal != NULL)
3742	xmlSchemaFreeValue(attr->defVal);
3743    xmlFree(attr);
3744}
3745
3746/**
3747 * xmlSchemaFreeAttributeUse:
3748 * @use:  an attribute use
3749 *
3750 * Deallocates an attribute use structure.
3751 */
3752static void
3753xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
3754{
3755    if (use == NULL)
3756        return;
3757    if (use->annot != NULL)
3758	xmlSchemaFreeAnnot(use->annot);
3759    if (use->defVal != NULL)
3760	xmlSchemaFreeValue(use->defVal);
3761    xmlFree(use);
3762}
3763
3764/**
3765 * xmlSchemaFreeAttributeUseProhib:
3766 * @prohib:  an attribute use prohibition
3767 *
3768 * Deallocates an attribute use structure.
3769 */
3770static void
3771xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
3772{
3773    if (prohib == NULL)
3774        return;
3775    xmlFree(prohib);
3776}
3777
3778/**
3779 * xmlSchemaFreeWildcardNsSet:
3780 * set:  a schema wildcard namespace
3781 *
3782 * Deallocates a list of wildcard constraint structures.
3783 */
3784static void
3785xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
3786{
3787    xmlSchemaWildcardNsPtr next;
3788
3789    while (set != NULL) {
3790	next = set->next;
3791	xmlFree(set);
3792	set = next;
3793    }
3794}
3795
3796/**
3797 * xmlSchemaFreeWildcard:
3798 * @wildcard:  a wildcard structure
3799 *
3800 * Deallocates a wildcard structure.
3801 */
3802void
3803xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
3804{
3805    if (wildcard == NULL)
3806        return;
3807    if (wildcard->annot != NULL)
3808        xmlSchemaFreeAnnot(wildcard->annot);
3809    if (wildcard->nsSet != NULL)
3810	xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
3811    if (wildcard->negNsSet != NULL)
3812	xmlFree(wildcard->negNsSet);
3813    xmlFree(wildcard);
3814}
3815
3816/**
3817 * xmlSchemaFreeAttributeGroup:
3818 * @schema:  a schema attribute group structure
3819 *
3820 * Deallocate a Schema Attribute Group structure.
3821 */
3822static void
3823xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
3824{
3825    if (attrGr == NULL)
3826        return;
3827    if (attrGr->annot != NULL)
3828        xmlSchemaFreeAnnot(attrGr->annot);
3829    if (attrGr->attrUses != NULL)
3830	xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
3831    xmlFree(attrGr);
3832}
3833
3834/**
3835 * xmlSchemaFreeQNameRef:
3836 * @item: a QName reference structure
3837 *
3838 * Deallocatea a QName reference structure.
3839 */
3840static void
3841xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
3842{
3843    xmlFree(item);
3844}
3845
3846/**
3847 * xmlSchemaFreeTypeLinkList:
3848 * @alink: a type link
3849 *
3850 * Deallocate a list of types.
3851 */
3852static void
3853xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
3854{
3855    xmlSchemaTypeLinkPtr next;
3856
3857    while (link != NULL) {
3858	next = link->next;
3859	xmlFree(link);
3860	link = next;
3861    }
3862}
3863
3864static void
3865xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
3866{
3867    xmlSchemaIDCStateObjPtr next;
3868    while (sto != NULL) {
3869	next = sto->next;
3870	if (sto->history != NULL)
3871	    xmlFree(sto->history);
3872	if (sto->xpathCtxt != NULL)
3873	    xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
3874	xmlFree(sto);
3875	sto = next;
3876    }
3877}
3878
3879/**
3880 * xmlSchemaFreeIDC:
3881 * @idc: a identity-constraint definition
3882 *
3883 * Deallocates an identity-constraint definition.
3884 */
3885static void
3886xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
3887{
3888    xmlSchemaIDCSelectPtr cur, prev;
3889
3890    if (idcDef == NULL)
3891	return;
3892    if (idcDef->annot != NULL)
3893        xmlSchemaFreeAnnot(idcDef->annot);
3894    /* Selector */
3895    if (idcDef->selector != NULL) {
3896	if (idcDef->selector->xpathComp != NULL)
3897	    xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
3898	xmlFree(idcDef->selector);
3899    }
3900    /* Fields */
3901    if (idcDef->fields != NULL) {
3902	cur = idcDef->fields;
3903	do {
3904	    prev = cur;
3905	    cur = cur->next;
3906	    if (prev->xpathComp != NULL)
3907		xmlFreePattern((xmlPatternPtr) prev->xpathComp);
3908	    xmlFree(prev);
3909	} while (cur != NULL);
3910    }
3911    xmlFree(idcDef);
3912}
3913
3914/**
3915 * xmlSchemaFreeElement:
3916 * @schema:  a schema element structure
3917 *
3918 * Deallocate a Schema Element structure.
3919 */
3920static void
3921xmlSchemaFreeElement(xmlSchemaElementPtr elem)
3922{
3923    if (elem == NULL)
3924        return;
3925    if (elem->annot != NULL)
3926        xmlSchemaFreeAnnot(elem->annot);
3927    if (elem->contModel != NULL)
3928        xmlRegFreeRegexp(elem->contModel);
3929    if (elem->defVal != NULL)
3930	xmlSchemaFreeValue(elem->defVal);
3931    xmlFree(elem);
3932}
3933
3934/**
3935 * xmlSchemaFreeFacet:
3936 * @facet:  a schema facet structure
3937 *
3938 * Deallocate a Schema Facet structure.
3939 */
3940void
3941xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
3942{
3943    if (facet == NULL)
3944        return;
3945    if (facet->val != NULL)
3946        xmlSchemaFreeValue(facet->val);
3947    if (facet->regexp != NULL)
3948        xmlRegFreeRegexp(facet->regexp);
3949    if (facet->annot != NULL)
3950        xmlSchemaFreeAnnot(facet->annot);
3951    xmlFree(facet);
3952}
3953
3954/**
3955 * xmlSchemaFreeType:
3956 * @type:  a schema type structure
3957 *
3958 * Deallocate a Schema Type structure.
3959 */
3960void
3961xmlSchemaFreeType(xmlSchemaTypePtr type)
3962{
3963    if (type == NULL)
3964        return;
3965    if (type->annot != NULL)
3966        xmlSchemaFreeAnnot(type->annot);
3967    if (type->facets != NULL) {
3968        xmlSchemaFacetPtr facet, next;
3969
3970        facet = type->facets;
3971        while (facet != NULL) {
3972            next = facet->next;
3973            xmlSchemaFreeFacet(facet);
3974            facet = next;
3975        }
3976    }
3977    if (type->attrUses != NULL)
3978	xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
3979    if (type->memberTypes != NULL)
3980	xmlSchemaFreeTypeLinkList(type->memberTypes);
3981    if (type->facetSet != NULL) {
3982	xmlSchemaFacetLinkPtr next, link;
3983
3984	link = type->facetSet;
3985	do {
3986	    next = link->next;
3987	    xmlFree(link);
3988	    link = next;
3989	} while (link != NULL);
3990    }
3991    if (type->contModel != NULL)
3992        xmlRegFreeRegexp(type->contModel);
3993    xmlFree(type);
3994}
3995
3996/**
3997 * xmlSchemaFreeModelGroupDef:
3998 * @item:  a schema model group definition
3999 *
4000 * Deallocates a schema model group definition.
4001 */
4002static void
4003xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
4004{
4005    if (item->annot != NULL)
4006	xmlSchemaFreeAnnot(item->annot);
4007    xmlFree(item);
4008}
4009
4010/**
4011 * xmlSchemaFreeModelGroup:
4012 * @item:  a schema model group
4013 *
4014 * Deallocates a schema model group structure.
4015 */
4016static void
4017xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
4018{
4019    if (item->annot != NULL)
4020	xmlSchemaFreeAnnot(item->annot);
4021    xmlFree(item);
4022}
4023
4024static void
4025xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
4026{
4027    if ((list == NULL) || (list->nbItems == 0))
4028	return;
4029    {
4030	xmlSchemaTreeItemPtr item;
4031	xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
4032	int i;
4033
4034	for (i = 0; i < list->nbItems; i++) {
4035	    item = items[i];
4036	    if (item == NULL)
4037		continue;
4038	    switch (item->type) {
4039		case XML_SCHEMA_TYPE_SIMPLE:
4040		case XML_SCHEMA_TYPE_COMPLEX:
4041		    xmlSchemaFreeType((xmlSchemaTypePtr) item);
4042		    break;
4043		case XML_SCHEMA_TYPE_ATTRIBUTE:
4044		    xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
4045		    break;
4046		case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
4047		    xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
4048		    break;
4049		case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
4050		    xmlSchemaFreeAttributeUseProhib(
4051			(xmlSchemaAttributeUseProhibPtr) item);
4052		    break;
4053		case XML_SCHEMA_TYPE_ELEMENT:
4054		    xmlSchemaFreeElement((xmlSchemaElementPtr) item);
4055		    break;
4056		case XML_SCHEMA_TYPE_PARTICLE:
4057		    if (item->annot != NULL)
4058			xmlSchemaFreeAnnot(item->annot);
4059		    xmlFree(item);
4060		    break;
4061		case XML_SCHEMA_TYPE_SEQUENCE:
4062		case XML_SCHEMA_TYPE_CHOICE:
4063		case XML_SCHEMA_TYPE_ALL:
4064		    xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
4065		    break;
4066		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
4067		    xmlSchemaFreeAttributeGroup(
4068			(xmlSchemaAttributeGroupPtr) item);
4069		    break;
4070		case XML_SCHEMA_TYPE_GROUP:
4071		    xmlSchemaFreeModelGroupDef(
4072			(xmlSchemaModelGroupDefPtr) item);
4073		    break;
4074		case XML_SCHEMA_TYPE_ANY:
4075		case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
4076		    xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
4077		    break;
4078		case XML_SCHEMA_TYPE_IDC_KEY:
4079		case XML_SCHEMA_TYPE_IDC_UNIQUE:
4080		case XML_SCHEMA_TYPE_IDC_KEYREF:
4081		    xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
4082		    break;
4083		case XML_SCHEMA_TYPE_NOTATION:
4084		    xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
4085		    break;
4086		case XML_SCHEMA_EXTRA_QNAMEREF:
4087		    xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
4088		    break;
4089		default: {
4090		    /* TODO: This should never be hit. */
4091		    xmlSchemaPSimpleInternalErr(NULL,
4092			"Internal error: xmlSchemaComponentListFree, "
4093			"unexpected component type '%s'\n",
4094			(const xmlChar *) WXS_ITEM_TYPE_NAME(item));
4095			 }
4096		    break;
4097	    }
4098	}
4099	list->nbItems = 0;
4100    }
4101}
4102
4103/**
4104 * xmlSchemaFree:
4105 * @schema:  a schema structure
4106 *
4107 * Deallocate a Schema structure.
4108 */
4109void
4110xmlSchemaFree(xmlSchemaPtr schema)
4111{
4112    if (schema == NULL)
4113        return;
4114    /* @volatiles is not used anymore :-/ */
4115    if (schema->volatiles != NULL)
4116	TODO
4117    /*
4118    * Note that those slots are not responsible for freeing
4119    * schema components anymore; this will now be done by
4120    * the schema buckets.
4121    */
4122    if (schema->notaDecl != NULL)
4123        xmlHashFree(schema->notaDecl, NULL);
4124    if (schema->attrDecl != NULL)
4125        xmlHashFree(schema->attrDecl, NULL);
4126    if (schema->attrgrpDecl != NULL)
4127        xmlHashFree(schema->attrgrpDecl, NULL);
4128    if (schema->elemDecl != NULL)
4129        xmlHashFree(schema->elemDecl, NULL);
4130    if (schema->typeDecl != NULL)
4131        xmlHashFree(schema->typeDecl, NULL);
4132    if (schema->groupDecl != NULL)
4133        xmlHashFree(schema->groupDecl, NULL);
4134    if (schema->idcDef != NULL)
4135        xmlHashFree(schema->idcDef, NULL);
4136
4137    if (schema->schemasImports != NULL)
4138	xmlHashFree(schema->schemasImports,
4139		    (xmlHashDeallocator) xmlSchemaBucketFree);
4140    if (schema->includes != NULL) {
4141	xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
4142	int i;
4143	for (i = 0; i < list->nbItems; i++) {
4144	    xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
4145	}
4146	xmlSchemaItemListFree(list);
4147    }
4148    if (schema->annot != NULL)
4149        xmlSchemaFreeAnnot(schema->annot);
4150    /* Never free the doc here, since this will be done by the buckets. */
4151
4152    xmlDictFree(schema->dict);
4153    xmlFree(schema);
4154}
4155
4156/************************************************************************
4157 *									*
4158 *			Debug functions					*
4159 *									*
4160 ************************************************************************/
4161
4162#ifdef LIBXML_OUTPUT_ENABLED
4163
4164static void
4165xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
4166
4167/**
4168 * xmlSchemaElementDump:
4169 * @elem:  an element
4170 * @output:  the file output
4171 *
4172 * Dump the element
4173 */
4174static void
4175xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output,
4176                     const xmlChar * name ATTRIBUTE_UNUSED,
4177		     const xmlChar * namespace ATTRIBUTE_UNUSED,
4178                     const xmlChar * context ATTRIBUTE_UNUSED)
4179{
4180    if (elem == NULL)
4181        return;
4182
4183
4184    fprintf(output, "Element");
4185    if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
4186	fprintf(output, " (global)");
4187    fprintf(output, ": '%s' ", elem->name);
4188    if (namespace != NULL)
4189	fprintf(output, "ns '%s'", namespace);
4190    fprintf(output, "\n");
4191#if 0
4192    if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
4193	fprintf(output, "  min %d ", elem->minOccurs);
4194        if (elem->maxOccurs >= UNBOUNDED)
4195            fprintf(output, "max: unbounded\n");
4196        else if (elem->maxOccurs != 1)
4197            fprintf(output, "max: %d\n", elem->maxOccurs);
4198        else
4199            fprintf(output, "\n");
4200    }
4201#endif
4202    /*
4203    * Misc other properties.
4204    */
4205    if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
4206	(elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
4207	(elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
4208	(elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
4209	fprintf(output, "  props: ");
4210	if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
4211	    fprintf(output, "[fixed] ");
4212	if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
4213	    fprintf(output, "[default] ");
4214	if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
4215	    fprintf(output, "[abstract] ");
4216	if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
4217	    fprintf(output, "[nillable] ");
4218	fprintf(output, "\n");
4219    }
4220    /*
4221    * Default/fixed value.
4222    */
4223    if (elem->value != NULL)
4224	fprintf(output, "  value: '%s'\n", elem->value);
4225    /*
4226    * Type.
4227    */
4228    if (elem->namedType != NULL) {
4229	fprintf(output, "  type: '%s' ", elem->namedType);
4230	if (elem->namedTypeNs != NULL)
4231	    fprintf(output, "ns '%s'\n", elem->namedTypeNs);
4232	else
4233	    fprintf(output, "\n");
4234    } else if (elem->subtypes != NULL) {
4235	/*
4236	* Dump local types.
4237	*/
4238	xmlSchemaTypeDump(elem->subtypes, output);
4239    }
4240    /*
4241    * Substitution group.
4242    */
4243    if (elem->substGroup != NULL) {
4244	fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
4245	if (elem->substGroupNs != NULL)
4246	    fprintf(output, "ns '%s'\n", elem->substGroupNs);
4247	else
4248	    fprintf(output, "\n");
4249    }
4250}
4251
4252/**
4253 * xmlSchemaAnnotDump:
4254 * @output:  the file output
4255 * @annot:  a annotation
4256 *
4257 * Dump the annotation
4258 */
4259static void
4260xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
4261{
4262    xmlChar *content;
4263
4264    if (annot == NULL)
4265        return;
4266
4267    content = xmlNodeGetContent(annot->content);
4268    if (content != NULL) {
4269        fprintf(output, "  Annot: %s\n", content);
4270        xmlFree(content);
4271    } else
4272        fprintf(output, "  Annot: empty\n");
4273}
4274
4275/**
4276 * xmlSchemaContentModelDump:
4277 * @particle: the schema particle
4278 * @output: the file output
4279 * @depth: the depth used for intentation
4280 *
4281 * Dump a SchemaType structure
4282 */
4283static void
4284xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
4285{
4286    xmlChar *str = NULL;
4287    xmlSchemaTreeItemPtr term;
4288    char shift[100];
4289    int i;
4290
4291    if (particle == NULL)
4292	return;
4293    for (i = 0;((i < depth) && (i < 25));i++)
4294        shift[2 * i] = shift[2 * i + 1] = ' ';
4295    shift[2 * i] = shift[2 * i + 1] = 0;
4296    fprintf(output, "%s", shift);
4297    if (particle->children == NULL) {
4298	fprintf(output, "MISSING particle term\n");
4299	return;
4300    }
4301    term = particle->children;
4302    if (term == NULL) {
4303	fprintf(output, "(NULL)");
4304    } else {
4305	switch (term->type) {
4306	    case XML_SCHEMA_TYPE_ELEMENT:
4307		fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
4308		    ((xmlSchemaElementPtr)term)->targetNamespace,
4309		    ((xmlSchemaElementPtr)term)->name));
4310		FREE_AND_NULL(str);
4311		break;
4312	    case XML_SCHEMA_TYPE_SEQUENCE:
4313		fprintf(output, "SEQUENCE");
4314		break;
4315	    case XML_SCHEMA_TYPE_CHOICE:
4316		fprintf(output, "CHOICE");
4317		break;
4318	    case XML_SCHEMA_TYPE_ALL:
4319		fprintf(output, "ALL");
4320		break;
4321	    case XML_SCHEMA_TYPE_ANY:
4322		fprintf(output, "ANY");
4323		break;
4324	    default:
4325		fprintf(output, "UNKNOWN\n");
4326		return;
4327	}
4328    }
4329    if (particle->minOccurs != 1)
4330	fprintf(output, " min: %d", particle->minOccurs);
4331    if (particle->maxOccurs >= UNBOUNDED)
4332	fprintf(output, " max: unbounded");
4333    else if (particle->maxOccurs != 1)
4334	fprintf(output, " max: %d", particle->maxOccurs);
4335    fprintf(output, "\n");
4336    if (term &&
4337	((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
4338	 (term->type == XML_SCHEMA_TYPE_CHOICE) ||
4339	 (term->type == XML_SCHEMA_TYPE_ALL)) &&
4340	 (term->children != NULL)) {
4341	xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
4342	    output, depth +1);
4343    }
4344    if (particle->next != NULL)
4345	xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
4346		output, depth);
4347}
4348
4349/**
4350 * xmlSchemaAttrUsesDump:
4351 * @uses:  attribute uses list
4352 * @output:  the file output
4353 *
4354 * Dumps a list of attribute use components.
4355 */
4356static void
4357xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
4358{
4359    xmlSchemaAttributeUsePtr use;
4360    xmlSchemaAttributeUseProhibPtr prohib;
4361    xmlSchemaQNameRefPtr ref;
4362    const xmlChar *name, *tns;
4363    xmlChar *str = NULL;
4364    int i;
4365
4366    if ((uses == NULL) || (uses->nbItems == 0))
4367        return;
4368
4369    fprintf(output, "  attributes:\n");
4370    for (i = 0; i < uses->nbItems; i++) {
4371	use = uses->items[i];
4372	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
4373	    fprintf(output, "  [prohibition] ");
4374	    prohib = (xmlSchemaAttributeUseProhibPtr) use;
4375	    name = prohib->name;
4376	    tns = prohib->targetNamespace;
4377	} else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
4378	    fprintf(output, "  [reference] ");
4379	    ref = (xmlSchemaQNameRefPtr) use;
4380	    name = ref->name;
4381	    tns = ref->targetNamespace;
4382	} else {
4383	    fprintf(output, "  [use] ");
4384	    name = WXS_ATTRUSE_DECL_NAME(use);
4385	    tns = WXS_ATTRUSE_DECL_TNS(use);
4386	}
4387	fprintf(output, "'%s'\n",
4388	    (const char *) xmlSchemaFormatQName(&str, tns, name));
4389	FREE_AND_NULL(str);
4390    }
4391}
4392
4393/**
4394 * xmlSchemaTypeDump:
4395 * @output:  the file output
4396 * @type:  a type structure
4397 *
4398 * Dump a SchemaType structure
4399 */
4400static void
4401xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
4402{
4403    if (type == NULL) {
4404        fprintf(output, "Type: NULL\n");
4405        return;
4406    }
4407    fprintf(output, "Type: ");
4408    if (type->name != NULL)
4409        fprintf(output, "'%s' ", type->name);
4410    else
4411        fprintf(output, "(no name) ");
4412    if (type->targetNamespace != NULL)
4413	fprintf(output, "ns '%s' ", type->targetNamespace);
4414    switch (type->type) {
4415        case XML_SCHEMA_TYPE_BASIC:
4416            fprintf(output, "[basic] ");
4417            break;
4418        case XML_SCHEMA_TYPE_SIMPLE:
4419            fprintf(output, "[simple] ");
4420            break;
4421        case XML_SCHEMA_TYPE_COMPLEX:
4422            fprintf(output, "[complex] ");
4423            break;
4424        case XML_SCHEMA_TYPE_SEQUENCE:
4425            fprintf(output, "[sequence] ");
4426            break;
4427        case XML_SCHEMA_TYPE_CHOICE:
4428            fprintf(output, "[choice] ");
4429            break;
4430        case XML_SCHEMA_TYPE_ALL:
4431            fprintf(output, "[all] ");
4432            break;
4433        case XML_SCHEMA_TYPE_UR:
4434            fprintf(output, "[ur] ");
4435            break;
4436        case XML_SCHEMA_TYPE_RESTRICTION:
4437            fprintf(output, "[restriction] ");
4438            break;
4439        case XML_SCHEMA_TYPE_EXTENSION:
4440            fprintf(output, "[extension] ");
4441            break;
4442        default:
4443            fprintf(output, "[unknown type %d] ", type->type);
4444            break;
4445    }
4446    fprintf(output, "content: ");
4447    switch (type->contentType) {
4448        case XML_SCHEMA_CONTENT_UNKNOWN:
4449            fprintf(output, "[unknown] ");
4450            break;
4451        case XML_SCHEMA_CONTENT_EMPTY:
4452            fprintf(output, "[empty] ");
4453            break;
4454        case XML_SCHEMA_CONTENT_ELEMENTS:
4455            fprintf(output, "[element] ");
4456            break;
4457        case XML_SCHEMA_CONTENT_MIXED:
4458            fprintf(output, "[mixed] ");
4459            break;
4460        case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
4461	/* not used. */
4462            break;
4463        case XML_SCHEMA_CONTENT_BASIC:
4464            fprintf(output, "[basic] ");
4465            break;
4466        case XML_SCHEMA_CONTENT_SIMPLE:
4467            fprintf(output, "[simple] ");
4468            break;
4469        case XML_SCHEMA_CONTENT_ANY:
4470            fprintf(output, "[any] ");
4471            break;
4472    }
4473    fprintf(output, "\n");
4474    if (type->base != NULL) {
4475        fprintf(output, "  base type: '%s'", type->base);
4476	if (type->baseNs != NULL)
4477	    fprintf(output, " ns '%s'\n", type->baseNs);
4478	else
4479	    fprintf(output, "\n");
4480    }
4481    if (type->attrUses != NULL)
4482	xmlSchemaAttrUsesDump(type->attrUses, output);
4483    if (type->annot != NULL)
4484        xmlSchemaAnnotDump(output, type->annot);
4485#ifdef DUMP_CONTENT_MODEL
4486    if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
4487	(type->subtypes != NULL)) {
4488	xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
4489	    output, 1);
4490    }
4491#endif
4492}
4493
4494/**
4495 * xmlSchemaDump:
4496 * @output:  the file output
4497 * @schema:  a schema structure
4498 *
4499 * Dump a Schema structure.
4500 */
4501void
4502xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
4503{
4504    if (output == NULL)
4505        return;
4506    if (schema == NULL) {
4507        fprintf(output, "Schemas: NULL\n");
4508        return;
4509    }
4510    fprintf(output, "Schemas: ");
4511    if (schema->name != NULL)
4512        fprintf(output, "%s, ", schema->name);
4513    else
4514        fprintf(output, "no name, ");
4515    if (schema->targetNamespace != NULL)
4516        fprintf(output, "%s", (const char *) schema->targetNamespace);
4517    else
4518        fprintf(output, "no target namespace");
4519    fprintf(output, "\n");
4520    if (schema->annot != NULL)
4521        xmlSchemaAnnotDump(output, schema->annot);
4522    xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump,
4523                output);
4524    xmlHashScanFull(schema->elemDecl,
4525                    (xmlHashScannerFull) xmlSchemaElementDump, output);
4526}
4527
4528#ifdef DEBUG_IDC_NODE_TABLE
4529/**
4530 * xmlSchemaDebugDumpIDCTable:
4531 * @vctxt: the WXS validation context
4532 *
4533 * Displays the current IDC table for debug purposes.
4534 */
4535static void
4536xmlSchemaDebugDumpIDCTable(FILE * output,
4537			   const xmlChar *namespaceName,
4538			   const xmlChar *localName,
4539			   xmlSchemaPSVIIDCBindingPtr bind)
4540{
4541    xmlChar *str = NULL;
4542    const xmlChar *value;
4543    xmlSchemaPSVIIDCNodePtr tab;
4544    xmlSchemaPSVIIDCKeyPtr key;
4545    int i, j, res;
4546
4547    fprintf(output, "IDC: TABLES on '%s'\n",
4548	xmlSchemaFormatQName(&str, namespaceName, localName));
4549    FREE_AND_NULL(str)
4550
4551    if (bind == NULL)
4552	return;
4553    do {
4554	fprintf(output, "IDC:   BINDING '%s' (%d)\n",
4555	    xmlSchemaGetComponentQName(&str,
4556		bind->definition), bind->nbNodes);
4557	FREE_AND_NULL(str)
4558	for (i = 0; i < bind->nbNodes; i++) {
4559	    tab = bind->nodeTable[i];
4560	    fprintf(output, "         ( ");
4561	    for (j = 0; j < bind->definition->nbFields; j++) {
4562		key = tab->keys[j];
4563		if ((key != NULL) && (key->val != NULL)) {
4564		    res = xmlSchemaGetCanonValue(key->val, &value);
4565		    if (res >= 0)
4566			fprintf(output, "'%s' ", value);
4567		    else
4568			fprintf(output, "CANON-VALUE-FAILED ");
4569		    if (res == 0)
4570			FREE_AND_NULL(value)
4571		} else if (key != NULL)
4572		    fprintf(output, "(no val), ");
4573		else
4574		    fprintf(output, "(key missing), ");
4575	    }
4576	    fprintf(output, ")\n");
4577	}
4578	if (bind->dupls && bind->dupls->nbItems) {
4579	    fprintf(output, "IDC:     dupls (%d):\n", bind->dupls->nbItems);
4580	    for (i = 0; i < bind->dupls->nbItems; i++) {
4581		tab = bind->dupls->items[i];
4582		fprintf(output, "         ( ");
4583		for (j = 0; j < bind->definition->nbFields; j++) {
4584		    key = tab->keys[j];
4585		    if ((key != NULL) && (key->val != NULL)) {
4586			res = xmlSchemaGetCanonValue(key->val, &value);
4587			if (res >= 0)
4588			    fprintf(output, "'%s' ", value);
4589			else
4590			    fprintf(output, "CANON-VALUE-FAILED ");
4591			if (res == 0)
4592			    FREE_AND_NULL(value)
4593		    } else if (key != NULL)
4594		    fprintf(output, "(no val), ");
4595			else
4596			    fprintf(output, "(key missing), ");
4597		}
4598		fprintf(output, ")\n");
4599	    }
4600	}
4601	bind = bind->next;
4602    } while (bind != NULL);
4603}
4604#endif /* DEBUG_IDC */
4605#endif /* LIBXML_OUTPUT_ENABLED */
4606
4607/************************************************************************
4608 *									*
4609 *			Utilities					*
4610 *									*
4611 ************************************************************************/
4612
4613/**
4614 * xmlSchemaGetPropNode:
4615 * @node: the element node
4616 * @name: the name of the attribute
4617 *
4618 * Seeks an attribute with a name of @name in
4619 * no namespace.
4620 *
4621 * Returns the attribute or NULL if not present.
4622 */
4623static xmlAttrPtr
4624xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
4625{
4626    xmlAttrPtr prop;
4627
4628    if ((node == NULL) || (name == NULL))
4629	return(NULL);
4630    prop = node->properties;
4631    while (prop != NULL) {
4632        if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
4633	    return(prop);
4634	prop = prop->next;
4635    }
4636    return (NULL);
4637}
4638
4639/**
4640 * xmlSchemaGetPropNodeNs:
4641 * @node: the element node
4642 * @uri: the uri
4643 * @name: the name of the attribute
4644 *
4645 * Seeks an attribute with a local name of @name and
4646 * a namespace URI of @uri.
4647 *
4648 * Returns the attribute or NULL if not present.
4649 */
4650static xmlAttrPtr
4651xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
4652{
4653    xmlAttrPtr prop;
4654
4655    if ((node == NULL) || (name == NULL))
4656	return(NULL);
4657    prop = node->properties;
4658    while (prop != NULL) {
4659	if ((prop->ns != NULL) &&
4660	    xmlStrEqual(prop->name, BAD_CAST name) &&
4661	    xmlStrEqual(prop->ns->href, BAD_CAST uri))
4662	    return(prop);
4663	prop = prop->next;
4664    }
4665    return (NULL);
4666}
4667
4668static const xmlChar *
4669xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
4670{
4671    xmlChar *val;
4672    const xmlChar *ret;
4673
4674    val = xmlNodeGetContent(node);
4675    if (val == NULL)
4676	val = xmlStrdup((xmlChar *)"");
4677    ret = xmlDictLookup(ctxt->dict, val, -1);
4678    xmlFree(val);
4679    return(ret);
4680}
4681
4682static const xmlChar *
4683xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
4684{
4685    return((const xmlChar*) xmlNodeGetContent(node));
4686}
4687
4688/**
4689 * xmlSchemaGetProp:
4690 * @ctxt: the parser context
4691 * @node: the node
4692 * @name: the property name
4693 *
4694 * Read a attribute value and internalize the string
4695 *
4696 * Returns the string or NULL if not present.
4697 */
4698static const xmlChar *
4699xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
4700                 const char *name)
4701{
4702    xmlChar *val;
4703    const xmlChar *ret;
4704
4705    val = xmlGetNoNsProp(node, BAD_CAST name);
4706    if (val == NULL)
4707        return(NULL);
4708    ret = xmlDictLookup(ctxt->dict, val, -1);
4709    xmlFree(val);
4710    return(ret);
4711}
4712
4713/************************************************************************
4714 *									*
4715 *			Parsing functions				*
4716 *									*
4717 ************************************************************************/
4718
4719#define WXS_FIND_GLOBAL_ITEM(slot)			\
4720    if (xmlStrEqual(nsName, schema->targetNamespace)) { \
4721	ret = xmlHashLookup(schema->slot, name); \
4722	if (ret != NULL) goto exit; \
4723    } \
4724    if (xmlHashSize(schema->schemasImports) > 1) { \
4725	xmlSchemaImportPtr import; \
4726	if (nsName == NULL) \
4727	    import = xmlHashLookup(schema->schemasImports, \
4728		XML_SCHEMAS_NO_NAMESPACE); \
4729	else \
4730	    import = xmlHashLookup(schema->schemasImports, nsName); \
4731	if (import == NULL) \
4732	    goto exit; \
4733	ret = xmlHashLookup(import->schema->slot, name); \
4734    }
4735
4736/**
4737 * xmlSchemaGetElem:
4738 * @schema:  the schema context
4739 * @name:  the element name
4740 * @ns:  the element namespace
4741 *
4742 * Lookup a global element declaration in the schema.
4743 *
4744 * Returns the element declaration or NULL if not found.
4745 */
4746static xmlSchemaElementPtr
4747xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
4748                 const xmlChar * nsName)
4749{
4750    xmlSchemaElementPtr ret = NULL;
4751
4752    if ((name == NULL) || (schema == NULL))
4753        return(NULL);
4754    if (schema != NULL) {
4755	WXS_FIND_GLOBAL_ITEM(elemDecl)
4756    }
4757exit:
4758#ifdef DEBUG
4759    if (ret == NULL) {
4760        if (nsName == NULL)
4761            fprintf(stderr, "Unable to lookup element decl. %s", name);
4762        else
4763            fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
4764                    nsName);
4765    }
4766#endif
4767    return (ret);
4768}
4769
4770/**
4771 * xmlSchemaGetType:
4772 * @schema:  the main schema
4773 * @name:  the type's name
4774 * nsName:  the type's namespace
4775 *
4776 * Lookup a type in the schemas or the predefined types
4777 *
4778 * Returns the group definition or NULL if not found.
4779 */
4780static xmlSchemaTypePtr
4781xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
4782                 const xmlChar * nsName)
4783{
4784    xmlSchemaTypePtr ret = NULL;
4785
4786    if (name == NULL)
4787        return (NULL);
4788    /* First try the built-in types. */
4789    if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
4790	ret = xmlSchemaGetPredefinedType(name, nsName);
4791	if (ret != NULL)
4792	    goto exit;
4793	/*
4794	* Note that we try the parsed schemas as well here
4795	* since one might have parsed the S4S, which contain more
4796	* than the built-in types.
4797	* TODO: Can we optimize this?
4798	*/
4799    }
4800    if (schema != NULL) {
4801	WXS_FIND_GLOBAL_ITEM(typeDecl)
4802    }
4803exit:
4804
4805#ifdef DEBUG
4806    if (ret == NULL) {
4807        if (nsName == NULL)
4808            fprintf(stderr, "Unable to lookup type %s", name);
4809        else
4810            fprintf(stderr, "Unable to lookup type %s:%s", name,
4811                    nsName);
4812    }
4813#endif
4814    return (ret);
4815}
4816
4817/**
4818 * xmlSchemaGetAttributeDecl:
4819 * @schema:  the context of the schema
4820 * @name:  the name of the attribute
4821 * @ns:  the target namespace of the attribute
4822 *
4823 * Lookup a an attribute in the schema or imported schemas
4824 *
4825 * Returns the attribute declaration or NULL if not found.
4826 */
4827static xmlSchemaAttributePtr
4828xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
4829                 const xmlChar * nsName)
4830{
4831    xmlSchemaAttributePtr ret = NULL;
4832
4833    if ((name == NULL) || (schema == NULL))
4834        return (NULL);
4835    if (schema != NULL) {
4836	WXS_FIND_GLOBAL_ITEM(attrDecl)
4837    }
4838exit:
4839#ifdef DEBUG
4840    if (ret == NULL) {
4841        if (nsName == NULL)
4842            fprintf(stderr, "Unable to lookup attribute %s", name);
4843        else
4844            fprintf(stderr, "Unable to lookup attribute %s:%s", name,
4845                    nsName);
4846    }
4847#endif
4848    return (ret);
4849}
4850
4851/**
4852 * xmlSchemaGetAttributeGroup:
4853 * @schema:  the context of the schema
4854 * @name:  the name of the attribute group
4855 * @ns:  the target namespace of the attribute group
4856 *
4857 * Lookup a an attribute group in the schema or imported schemas
4858 *
4859 * Returns the attribute group definition or NULL if not found.
4860 */
4861static xmlSchemaAttributeGroupPtr
4862xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
4863                 const xmlChar * nsName)
4864{
4865    xmlSchemaAttributeGroupPtr ret = NULL;
4866
4867    if ((name == NULL) || (schema == NULL))
4868        return (NULL);
4869    if (schema != NULL) {
4870	WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
4871    }
4872exit:
4873    /* TODO:
4874    if ((ret != NULL) && (ret->redef != NULL)) {
4875	* Return the last redefinition. *
4876	ret = ret->redef;
4877    }
4878    */
4879#ifdef DEBUG
4880    if (ret == NULL) {
4881        if (nsName == NULL)
4882            fprintf(stderr, "Unable to lookup attribute group %s", name);
4883        else
4884            fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
4885                    nsName);
4886    }
4887#endif
4888    return (ret);
4889}
4890
4891/**
4892 * xmlSchemaGetGroup:
4893 * @schema:  the context of the schema
4894 * @name:  the name of the group
4895 * @ns:  the target namespace of the group
4896 *
4897 * Lookup a group in the schema or imported schemas
4898 *
4899 * Returns the group definition or NULL if not found.
4900 */
4901static xmlSchemaModelGroupDefPtr
4902xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
4903                 const xmlChar * nsName)
4904{
4905    xmlSchemaModelGroupDefPtr ret = NULL;
4906
4907    if ((name == NULL) || (schema == NULL))
4908        return (NULL);
4909    if (schema != NULL) {
4910	WXS_FIND_GLOBAL_ITEM(groupDecl)
4911    }
4912exit:
4913
4914#ifdef DEBUG
4915    if (ret == NULL) {
4916        if (nsName == NULL)
4917            fprintf(stderr, "Unable to lookup group %s", name);
4918        else
4919            fprintf(stderr, "Unable to lookup group %s:%s", name,
4920                    nsName);
4921    }
4922#endif
4923    return (ret);
4924}
4925
4926static xmlSchemaNotationPtr
4927xmlSchemaGetNotation(xmlSchemaPtr schema,
4928		     const xmlChar *name,
4929		     const xmlChar *nsName)
4930{
4931    xmlSchemaNotationPtr ret = NULL;
4932
4933    if ((name == NULL) || (schema == NULL))
4934        return (NULL);
4935    if (schema != NULL) {
4936	WXS_FIND_GLOBAL_ITEM(notaDecl)
4937    }
4938exit:
4939    return (ret);
4940}
4941
4942static xmlSchemaIDCPtr
4943xmlSchemaGetIDC(xmlSchemaPtr schema,
4944		const xmlChar *name,
4945		const xmlChar *nsName)
4946{
4947    xmlSchemaIDCPtr ret = NULL;
4948
4949    if ((name == NULL) || (schema == NULL))
4950        return (NULL);
4951    if (schema != NULL) {
4952	WXS_FIND_GLOBAL_ITEM(idcDef)
4953    }
4954exit:
4955    return (ret);
4956}
4957
4958/**
4959 * xmlSchemaGetNamedComponent:
4960 * @schema:  the schema
4961 * @name:  the name of the group
4962 * @ns:  the target namespace of the group
4963 *
4964 * Lookup a group in the schema or imported schemas
4965 *
4966 * Returns the group definition or NULL if not found.
4967 */
4968static xmlSchemaBasicItemPtr
4969xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
4970			   xmlSchemaTypeType itemType,
4971			   const xmlChar *name,
4972			   const xmlChar *targetNs)
4973{
4974    switch (itemType) {
4975	case XML_SCHEMA_TYPE_GROUP:
4976	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
4977		name, targetNs));
4978	case XML_SCHEMA_TYPE_ELEMENT:
4979	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
4980		name, targetNs));
4981	default:
4982	    TODO
4983	    return (NULL);
4984    }
4985}
4986
4987/************************************************************************
4988 *									*
4989 *			Parsing functions				*
4990 *									*
4991 ************************************************************************/
4992
4993#define IS_BLANK_NODE(n)						\
4994    (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
4995
4996/**
4997 * xmlSchemaIsBlank:
4998 * @str:  a string
4999 * @len: the length of the string or -1
5000 *
5001 * Check if a string is ignorable
5002 *
5003 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
5004 */
5005static int
5006xmlSchemaIsBlank(xmlChar * str, int len)
5007{
5008    if (str == NULL)
5009        return (1);
5010    if (len < 0) {
5011	while (*str != 0) {
5012	    if (!(IS_BLANK_CH(*str)))
5013		return (0);
5014	    str++;
5015	}
5016    } else while ((*str != 0) && (len != 0)) {
5017	if (!(IS_BLANK_CH(*str)))
5018	    return (0);
5019	str++;
5020	len--;
5021    }
5022
5023    return (1);
5024}
5025
5026#define WXS_COMP_NAME(c, t) ((t) (c))->name
5027#define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
5028/*
5029* xmlSchemaFindRedefCompInGraph:
5030* ATTENTION TODO: This uses pointer comp. for strings.
5031*/
5032static xmlSchemaBasicItemPtr
5033xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
5034			      xmlSchemaTypeType type,
5035			      const xmlChar *name,
5036			      const xmlChar *nsName)
5037{
5038    xmlSchemaBasicItemPtr ret;
5039    int i;
5040
5041    if ((bucket == NULL) || (name == NULL))
5042	return(NULL);
5043    if ((bucket->globals == NULL) ||
5044	(bucket->globals->nbItems == 0))
5045	goto subschemas;
5046    /*
5047    * Search in global components.
5048    */
5049    for (i = 0; i < bucket->globals->nbItems; i++) {
5050	ret = bucket->globals->items[i];
5051	if (ret->type == type) {
5052	    switch (type) {
5053		case XML_SCHEMA_TYPE_COMPLEX:
5054		case XML_SCHEMA_TYPE_SIMPLE:
5055		    if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
5056			(WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
5057			nsName))
5058		    {
5059			return(ret);
5060		    }
5061		    break;
5062		case XML_SCHEMA_TYPE_GROUP:
5063		    if ((WXS_COMP_NAME(ret,
5064			    xmlSchemaModelGroupDefPtr) == name) &&
5065			(WXS_COMP_TNS(ret,
5066			    xmlSchemaModelGroupDefPtr) == nsName))
5067		    {
5068			return(ret);
5069		    }
5070		    break;
5071		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
5072		    if ((WXS_COMP_NAME(ret,
5073			    xmlSchemaAttributeGroupPtr) == name) &&
5074			(WXS_COMP_TNS(ret,
5075			    xmlSchemaAttributeGroupPtr) == nsName))
5076		    {
5077			return(ret);
5078		    }
5079		    break;
5080		default:
5081		    /* Should not be hit. */
5082		    return(NULL);
5083	    }
5084	}
5085    }
5086subschemas:
5087    /*
5088    * Process imported/included schemas.
5089    */
5090    if (bucket->relations != NULL) {
5091	xmlSchemaSchemaRelationPtr rel = bucket->relations;
5092
5093	/*
5094	* TODO: Marking the bucket will not avoid multiple searches
5095	* in the same schema, but avoids at least circularity.
5096	*/
5097	bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
5098	do {
5099	    if ((rel->bucket != NULL) &&
5100		((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
5101		ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
5102		    type, name, nsName);
5103		if (ret != NULL)
5104		    return(ret);
5105	    }
5106	    rel = rel->next;
5107	} while (rel != NULL);
5108	 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
5109    }
5110    return(NULL);
5111}
5112
5113/**
5114 * xmlSchemaAddNotation:
5115 * @ctxt:  a schema parser context
5116 * @schema:  the schema being built
5117 * @name:  the item name
5118 *
5119 * Add an XML schema annotation declaration
5120 * *WARNING* this interface is highly subject to change
5121 *
5122 * Returns the new struture or NULL in case of error
5123 */
5124static xmlSchemaNotationPtr
5125xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5126                     const xmlChar *name, const xmlChar *nsName,
5127		     xmlNodePtr node ATTRIBUTE_UNUSED)
5128{
5129    xmlSchemaNotationPtr ret = NULL;
5130
5131    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5132        return (NULL);
5133
5134    ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
5135    if (ret == NULL) {
5136        xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
5137        return (NULL);
5138    }
5139    memset(ret, 0, sizeof(xmlSchemaNotation));
5140    ret->type = XML_SCHEMA_TYPE_NOTATION;
5141    ret->name = name;
5142    ret->targetNamespace = nsName;
5143    /* TODO: do we need the node to be set?
5144    * ret->node = node;*/
5145    WXS_ADD_GLOBAL(ctxt, ret);
5146    return (ret);
5147}
5148
5149/**
5150 * xmlSchemaAddAttribute:
5151 * @ctxt:  a schema parser context
5152 * @schema:  the schema being built
5153 * @name:  the item name
5154 * @namespace:  the namespace
5155 *
5156 * Add an XML schema Attrribute declaration
5157 * *WARNING* this interface is highly subject to change
5158 *
5159 * Returns the new struture or NULL in case of error
5160 */
5161static xmlSchemaAttributePtr
5162xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5163                      const xmlChar * name, const xmlChar * nsName,
5164		      xmlNodePtr node, int topLevel)
5165{
5166    xmlSchemaAttributePtr ret = NULL;
5167
5168    if ((ctxt == NULL) || (schema == NULL))
5169        return (NULL);
5170
5171    ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
5172    if (ret == NULL) {
5173        xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
5174        return (NULL);
5175    }
5176    memset(ret, 0, sizeof(xmlSchemaAttribute));
5177    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
5178    ret->node = node;
5179    ret->name = name;
5180    ret->targetNamespace = nsName;
5181
5182    if (topLevel)
5183	WXS_ADD_GLOBAL(ctxt, ret);
5184    else
5185	WXS_ADD_LOCAL(ctxt, ret);
5186    WXS_ADD_PENDING(ctxt, ret);
5187    return (ret);
5188}
5189
5190/**
5191 * xmlSchemaAddAttributeUse:
5192 * @ctxt:  a schema parser context
5193 * @schema:  the schema being built
5194 * @name:  the item name
5195 * @namespace:  the namespace
5196 *
5197 * Add an XML schema Attrribute declaration
5198 * *WARNING* this interface is highly subject to change
5199 *
5200 * Returns the new struture or NULL in case of error
5201 */
5202static xmlSchemaAttributeUsePtr
5203xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
5204			 xmlNodePtr node)
5205{
5206    xmlSchemaAttributeUsePtr ret = NULL;
5207
5208    if (pctxt == NULL)
5209        return (NULL);
5210
5211    ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
5212    if (ret == NULL) {
5213        xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
5214        return (NULL);
5215    }
5216    memset(ret, 0, sizeof(xmlSchemaAttributeUse));
5217    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
5218    ret->node = node;
5219
5220    WXS_ADD_LOCAL(pctxt, ret);
5221    return (ret);
5222}
5223
5224/*
5225* xmlSchemaAddRedef:
5226*
5227* Adds a redefinition information. This is used at a later stage to:
5228* resolve references to the redefined components and to check constraints.
5229*/
5230static xmlSchemaRedefPtr
5231xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
5232		  xmlSchemaBucketPtr targetBucket,
5233		  void *item,
5234		  const xmlChar *refName,
5235		  const xmlChar *refTargetNs)
5236{
5237    xmlSchemaRedefPtr ret;
5238
5239    ret = (xmlSchemaRedefPtr)
5240	xmlMalloc(sizeof(xmlSchemaRedef));
5241    if (ret == NULL) {
5242	xmlSchemaPErrMemory(pctxt,
5243	    "allocating redefinition info", NULL);
5244	return (NULL);
5245    }
5246    memset(ret, 0, sizeof(xmlSchemaRedef));
5247    ret->item = item;
5248    ret->targetBucket = targetBucket;
5249    ret->refName = refName;
5250    ret->refTargetNs = refTargetNs;
5251    if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
5252	WXS_CONSTRUCTOR(pctxt)->redefs = ret;
5253    else
5254	WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
5255    WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
5256
5257    return (ret);
5258}
5259
5260/**
5261 * xmlSchemaAddAttributeGroupDefinition:
5262 * @ctxt:  a schema parser context
5263 * @schema:  the schema being built
5264 * @name:  the item name
5265 * @nsName:  the target namespace
5266 * @node: the corresponding node
5267 *
5268 * Add an XML schema Attrribute Group definition.
5269 *
5270 * Returns the new struture or NULL in case of error
5271 */
5272static xmlSchemaAttributeGroupPtr
5273xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
5274                           xmlSchemaPtr schema ATTRIBUTE_UNUSED,
5275			   const xmlChar *name,
5276			   const xmlChar *nsName,
5277			   xmlNodePtr node)
5278{
5279    xmlSchemaAttributeGroupPtr ret = NULL;
5280
5281    if ((pctxt == NULL) || (name == NULL))
5282        return (NULL);
5283
5284    ret = (xmlSchemaAttributeGroupPtr)
5285        xmlMalloc(sizeof(xmlSchemaAttributeGroup));
5286    if (ret == NULL) {
5287	xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
5288	return (NULL);
5289    }
5290    memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
5291    ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
5292    ret->name = name;
5293    ret->targetNamespace = nsName;
5294    ret->node = node;
5295
5296    /* TODO: Remove the flag. */
5297    ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
5298    if (pctxt->isRedefine) {
5299	pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
5300	    ret, name, nsName);
5301	if (pctxt->redef == NULL) {
5302	    xmlFree(ret);
5303	    return(NULL);
5304	}
5305	pctxt->redefCounter = 0;
5306    }
5307    WXS_ADD_GLOBAL(pctxt, ret);
5308    WXS_ADD_PENDING(pctxt, ret);
5309    return (ret);
5310}
5311
5312/**
5313 * xmlSchemaAddElement:
5314 * @ctxt:  a schema parser context
5315 * @schema:  the schema being built
5316 * @name:  the type name
5317 * @namespace:  the type namespace
5318 *
5319 * Add an XML schema Element declaration
5320 * *WARNING* this interface is highly subject to change
5321 *
5322 * Returns the new struture or NULL in case of error
5323 */
5324static xmlSchemaElementPtr
5325xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
5326                    const xmlChar * name, const xmlChar * nsName,
5327		    xmlNodePtr node, int topLevel)
5328{
5329    xmlSchemaElementPtr ret = NULL;
5330
5331    if ((ctxt == NULL) || (name == NULL))
5332        return (NULL);
5333
5334    ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
5335    if (ret == NULL) {
5336        xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
5337        return (NULL);
5338    }
5339    memset(ret, 0, sizeof(xmlSchemaElement));
5340    ret->type = XML_SCHEMA_TYPE_ELEMENT;
5341    ret->name = name;
5342    ret->targetNamespace = nsName;
5343    ret->node = node;
5344
5345    if (topLevel)
5346	WXS_ADD_GLOBAL(ctxt, ret);
5347    else
5348	WXS_ADD_LOCAL(ctxt, ret);
5349    WXS_ADD_PENDING(ctxt, ret);
5350    return (ret);
5351}
5352
5353/**
5354 * xmlSchemaAddType:
5355 * @ctxt:  a schema parser context
5356 * @schema:  the schema being built
5357 * @name:  the item name
5358 * @namespace:  the namespace
5359 *
5360 * Add an XML schema item
5361 * *WARNING* this interface is highly subject to change
5362 *
5363 * Returns the new struture or NULL in case of error
5364 */
5365static xmlSchemaTypePtr
5366xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5367		 xmlSchemaTypeType type,
5368                 const xmlChar * name, const xmlChar * nsName,
5369		 xmlNodePtr node, int topLevel)
5370{
5371    xmlSchemaTypePtr ret = NULL;
5372
5373    if ((ctxt == NULL) || (schema == NULL))
5374        return (NULL);
5375
5376    ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
5377    if (ret == NULL) {
5378        xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
5379        return (NULL);
5380    }
5381    memset(ret, 0, sizeof(xmlSchemaType));
5382    ret->type = type;
5383    ret->name = name;
5384    ret->targetNamespace = nsName;
5385    ret->node = node;
5386    if (topLevel) {
5387	if (ctxt->isRedefine) {
5388	    ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5389		ret, name, nsName);
5390	    if (ctxt->redef == NULL) {
5391		xmlFree(ret);
5392		return(NULL);
5393	    }
5394	    ctxt->redefCounter = 0;
5395	}
5396	WXS_ADD_GLOBAL(ctxt, ret);
5397    } else
5398	WXS_ADD_LOCAL(ctxt, ret);
5399    WXS_ADD_PENDING(ctxt, ret);
5400    return (ret);
5401}
5402
5403static xmlSchemaQNameRefPtr
5404xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
5405		     xmlSchemaTypeType refType,
5406		     const xmlChar *refName,
5407		     const xmlChar *refNs)
5408{
5409    xmlSchemaQNameRefPtr ret;
5410
5411    ret = (xmlSchemaQNameRefPtr)
5412	xmlMalloc(sizeof(xmlSchemaQNameRef));
5413    if (ret == NULL) {
5414	xmlSchemaPErrMemory(pctxt,
5415	    "allocating QName reference item", NULL);
5416	return (NULL);
5417    }
5418    ret->node = NULL;
5419    ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
5420    ret->name = refName;
5421    ret->targetNamespace = refNs;
5422    ret->item = NULL;
5423    ret->itemType = refType;
5424    /*
5425    * Store the reference item in the schema.
5426    */
5427    WXS_ADD_LOCAL(pctxt, ret);
5428    return (ret);
5429}
5430
5431static xmlSchemaAttributeUseProhibPtr
5432xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
5433{
5434    xmlSchemaAttributeUseProhibPtr ret;
5435
5436    ret = (xmlSchemaAttributeUseProhibPtr)
5437	xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
5438    if (ret == NULL) {
5439	xmlSchemaPErrMemory(pctxt,
5440	    "allocating attribute use prohibition", NULL);
5441	return (NULL);
5442    }
5443    memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
5444    ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
5445    WXS_ADD_LOCAL(pctxt, ret);
5446    return (ret);
5447}
5448
5449
5450/**
5451 * xmlSchemaAddModelGroup:
5452 * @ctxt:  a schema parser context
5453 * @schema:  the schema being built
5454 * @type: the "compositor" type of the model group
5455 * @node: the node in the schema doc
5456 *
5457 * Adds a schema model group
5458 * *WARNING* this interface is highly subject to change
5459 *
5460 * Returns the new struture or NULL in case of error
5461 */
5462static xmlSchemaModelGroupPtr
5463xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
5464		       xmlSchemaPtr schema,
5465		       xmlSchemaTypeType type,
5466		       xmlNodePtr node)
5467{
5468    xmlSchemaModelGroupPtr ret = NULL;
5469
5470    if ((ctxt == NULL) || (schema == NULL))
5471        return (NULL);
5472
5473    ret = (xmlSchemaModelGroupPtr)
5474	xmlMalloc(sizeof(xmlSchemaModelGroup));
5475    if (ret == NULL) {
5476	xmlSchemaPErrMemory(ctxt, "allocating model group component",
5477	    NULL);
5478	return (NULL);
5479    }
5480    memset(ret, 0, sizeof(xmlSchemaModelGroup));
5481    ret->type = type;
5482    ret->node = node;
5483    WXS_ADD_LOCAL(ctxt, ret);
5484    if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
5485	(type == XML_SCHEMA_TYPE_CHOICE))
5486	WXS_ADD_PENDING(ctxt, ret);
5487    return (ret);
5488}
5489
5490
5491/**
5492 * xmlSchemaAddParticle:
5493 * @ctxt:  a schema parser context
5494 * @schema:  the schema being built
5495 * @node: the corresponding node in the schema doc
5496 * @min: the minOccurs
5497 * @max: the maxOccurs
5498 *
5499 * Adds an XML schema particle component.
5500 * *WARNING* this interface is highly subject to change
5501 *
5502 * Returns the new struture or NULL in case of error
5503 */
5504static xmlSchemaParticlePtr
5505xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
5506		     xmlNodePtr node, int min, int max)
5507{
5508    xmlSchemaParticlePtr ret = NULL;
5509    if (ctxt == NULL)
5510        return (NULL);
5511
5512#ifdef DEBUG
5513    fprintf(stderr, "Adding particle component\n");
5514#endif
5515    ret = (xmlSchemaParticlePtr)
5516	xmlMalloc(sizeof(xmlSchemaParticle));
5517    if (ret == NULL) {
5518	xmlSchemaPErrMemory(ctxt, "allocating particle component",
5519	    NULL);
5520	return (NULL);
5521    }
5522    ret->type = XML_SCHEMA_TYPE_PARTICLE;
5523    ret->annot = NULL;
5524    ret->node = node;
5525    ret->minOccurs = min;
5526    ret->maxOccurs = max;
5527    ret->next = NULL;
5528    ret->children = NULL;
5529
5530    WXS_ADD_LOCAL(ctxt, ret);
5531    /*
5532    * Note that addition to pending components will be done locally
5533    * to the specific parsing function, since the most particles
5534    * need not to be fixed up (i.e. the reference to be resolved).
5535    * REMOVED: WXS_ADD_PENDING(ctxt, ret);
5536    */
5537    return (ret);
5538}
5539
5540/**
5541 * xmlSchemaAddModelGroupDefinition:
5542 * @ctxt:  a schema validation context
5543 * @schema:  the schema being built
5544 * @name:  the group name
5545 *
5546 * Add an XML schema Group definition
5547 *
5548 * Returns the new struture or NULL in case of error
5549 */
5550static xmlSchemaModelGroupDefPtr
5551xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
5552				 xmlSchemaPtr schema,
5553				 const xmlChar *name,
5554				 const xmlChar *nsName,
5555				 xmlNodePtr node)
5556{
5557    xmlSchemaModelGroupDefPtr ret = NULL;
5558
5559    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5560        return (NULL);
5561
5562    ret = (xmlSchemaModelGroupDefPtr)
5563	xmlMalloc(sizeof(xmlSchemaModelGroupDef));
5564    if (ret == NULL) {
5565        xmlSchemaPErrMemory(ctxt, "adding group", NULL);
5566        return (NULL);
5567    }
5568    memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
5569    ret->name = name;
5570    ret->type = XML_SCHEMA_TYPE_GROUP;
5571    ret->node = node;
5572    ret->targetNamespace = nsName;
5573
5574    if (ctxt->isRedefine) {
5575	ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5576	    ret, name, nsName);
5577	if (ctxt->redef == NULL) {
5578	    xmlFree(ret);
5579	    return(NULL);
5580	}
5581	ctxt->redefCounter = 0;
5582    }
5583    WXS_ADD_GLOBAL(ctxt, ret);
5584    WXS_ADD_PENDING(ctxt, ret);
5585    return (ret);
5586}
5587
5588/**
5589 * xmlSchemaNewWildcardNs:
5590 * @ctxt:  a schema validation context
5591 *
5592 * Creates a new wildcard namespace constraint.
5593 *
5594 * Returns the new struture or NULL in case of error
5595 */
5596static xmlSchemaWildcardNsPtr
5597xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
5598{
5599    xmlSchemaWildcardNsPtr ret;
5600
5601    ret = (xmlSchemaWildcardNsPtr)
5602	xmlMalloc(sizeof(xmlSchemaWildcardNs));
5603    if (ret == NULL) {
5604	xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
5605	return (NULL);
5606    }
5607    ret->value = NULL;
5608    ret->next = NULL;
5609    return (ret);
5610}
5611
5612static xmlSchemaIDCPtr
5613xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5614                  const xmlChar *name, const xmlChar *nsName,
5615		  int category, xmlNodePtr node)
5616{
5617    xmlSchemaIDCPtr ret = NULL;
5618
5619    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5620        return (NULL);
5621
5622    ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
5623    if (ret == NULL) {
5624        xmlSchemaPErrMemory(ctxt,
5625	    "allocating an identity-constraint definition", NULL);
5626        return (NULL);
5627    }
5628    memset(ret, 0, sizeof(xmlSchemaIDC));
5629    /* The target namespace of the parent element declaration. */
5630    ret->targetNamespace = nsName;
5631    ret->name = name;
5632    ret->type = category;
5633    ret->node = node;
5634
5635    WXS_ADD_GLOBAL(ctxt, ret);
5636    /*
5637    * Only keyrefs need to be fixup up.
5638    */
5639    if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
5640	WXS_ADD_PENDING(ctxt, ret);
5641    return (ret);
5642}
5643
5644/**
5645 * xmlSchemaAddWildcard:
5646 * @ctxt:  a schema validation context
5647 * @schema: a schema
5648 *
5649 * Adds a wildcard.
5650 * It corresponds to a xsd:anyAttribute and xsd:any.
5651 *
5652 * Returns the new struture or NULL in case of error
5653 */
5654static xmlSchemaWildcardPtr
5655xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5656		     xmlSchemaTypeType type, xmlNodePtr node)
5657{
5658    xmlSchemaWildcardPtr ret = NULL;
5659
5660    if ((ctxt == NULL) || (schema == NULL))
5661        return (NULL);
5662
5663    ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
5664    if (ret == NULL) {
5665        xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
5666        return (NULL);
5667    }
5668    memset(ret, 0, sizeof(xmlSchemaWildcard));
5669    ret->type = type;
5670    ret->node = node;
5671    WXS_ADD_LOCAL(ctxt, ret);
5672    return (ret);
5673}
5674
5675static void
5676xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
5677{
5678    if (group == NULL)
5679	return;
5680    if (group->members != NULL)
5681	xmlSchemaItemListFree(group->members);
5682    xmlFree(group);
5683}
5684
5685static xmlSchemaSubstGroupPtr
5686xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
5687		       xmlSchemaElementPtr head)
5688{
5689    xmlSchemaSubstGroupPtr ret;
5690
5691    /* Init subst group hash. */
5692    if (WXS_SUBST_GROUPS(pctxt) == NULL) {
5693	WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
5694	if (WXS_SUBST_GROUPS(pctxt) == NULL)
5695	    return(NULL);
5696    }
5697    /* Create a new substitution group. */
5698    ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
5699    if (ret == NULL) {
5700	xmlSchemaPErrMemory(NULL,
5701	    "allocating a substitution group container", NULL);
5702	return(NULL);
5703    }
5704    memset(ret, 0, sizeof(xmlSchemaSubstGroup));
5705    ret->head = head;
5706    /* Create list of members. */
5707    ret->members = xmlSchemaItemListCreate();
5708    if (ret->members == NULL) {
5709	xmlSchemaSubstGroupFree(ret);
5710	return(NULL);
5711    }
5712    /* Add subst group to hash. */
5713    if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
5714	head->name, head->targetNamespace, ret) != 0) {
5715	PERROR_INT("xmlSchemaSubstGroupAdd",
5716	    "failed to add a new substitution container");
5717	xmlSchemaSubstGroupFree(ret);
5718	return(NULL);
5719    }
5720    return(ret);
5721}
5722
5723static xmlSchemaSubstGroupPtr
5724xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
5725		       xmlSchemaElementPtr head)
5726{
5727    if (WXS_SUBST_GROUPS(pctxt) == NULL)
5728	return(NULL);
5729    return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
5730	head->name, head->targetNamespace));
5731
5732}
5733
5734/**
5735 * xmlSchemaAddElementSubstitutionMember:
5736 * @pctxt:  a schema parser context
5737 * @head:  the head of the substitution group
5738 * @member: the new member of the substitution group
5739 *
5740 * Allocate a new annotation structure.
5741 *
5742 * Returns the newly allocated structure or NULL in case or error
5743 */
5744static int
5745xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
5746				      xmlSchemaElementPtr head,
5747				      xmlSchemaElementPtr member)
5748{
5749    xmlSchemaSubstGroupPtr substGroup = NULL;
5750
5751    if ((pctxt == NULL) || (head == NULL) || (member == NULL))
5752	return (-1);
5753
5754    substGroup = xmlSchemaSubstGroupGet(pctxt, head);
5755    if (substGroup == NULL)
5756	substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
5757    if (substGroup == NULL)
5758	return(-1);
5759    if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
5760	return(-1);
5761    return(0);
5762}
5763
5764/************************************************************************
5765 *									*
5766 *		Utilities for parsing					*
5767 *									*
5768 ************************************************************************/
5769
5770/**
5771 * xmlSchemaPValAttrNodeQNameValue:
5772 * @ctxt:  a schema parser context
5773 * @schema: the schema context
5774 * @ownerDes: the designation of the parent element
5775 * @ownerItem: the parent as a schema object
5776 * @value:  the QName value
5777 * @local: the resulting local part if found, the attribute value otherwise
5778 * @uri:  the resulting namespace URI if found
5779 *
5780 * Extracts the local name and the URI of a QName value and validates it.
5781 * This one is intended to be used on attribute values that
5782 * should resolve to schema components.
5783 *
5784 * Returns 0, in case the QName is valid, a positive error code
5785 * if not valid and -1 if an internal error occurs.
5786 */
5787static int
5788xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
5789				       xmlSchemaPtr schema,
5790				       xmlSchemaBasicItemPtr ownerItem,
5791				       xmlAttrPtr attr,
5792				       const xmlChar *value,
5793				       const xmlChar **uri,
5794				       const xmlChar **local)
5795{
5796    const xmlChar *pref;
5797    xmlNsPtr ns;
5798    int len, ret;
5799
5800    *uri = NULL;
5801    *local = NULL;
5802    ret = xmlValidateQName(value, 1);
5803    if (ret > 0) {
5804	xmlSchemaPSimpleTypeErr(ctxt,
5805	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5806	    ownerItem, (xmlNodePtr) attr,
5807	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
5808	    NULL, value, NULL, NULL, NULL);
5809	*local = value;
5810	return (ctxt->err);
5811    } else if (ret < 0)
5812	return (-1);
5813
5814    if (!strchr((char *) value, ':')) {
5815	ns = xmlSearchNs(attr->doc, attr->parent, NULL);
5816	if (ns)
5817	    *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5818	else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
5819	    /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
5820	    * parser context. */
5821	    /*
5822	    * This one takes care of included schemas with no
5823	    * target namespace.
5824	    */
5825	    *uri = ctxt->targetNamespace;
5826	}
5827	*local = xmlDictLookup(ctxt->dict, value, -1);
5828	return (0);
5829    }
5830    /*
5831    * At this point xmlSplitQName3 has to return a local name.
5832    */
5833    *local = xmlSplitQName3(value, &len);
5834    *local = xmlDictLookup(ctxt->dict, *local, -1);
5835    pref = xmlDictLookup(ctxt->dict, value, len);
5836    ns = xmlSearchNs(attr->doc, attr->parent, pref);
5837    if (ns == NULL) {
5838	xmlSchemaPSimpleTypeErr(ctxt,
5839	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5840	    ownerItem, (xmlNodePtr) attr,
5841	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
5842	    "The value '%s' of simple type 'xs:QName' has no "
5843	    "corresponding namespace declaration in scope", value, NULL);
5844	return (ctxt->err);
5845    } else {
5846        *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5847    }
5848    return (0);
5849}
5850
5851/**
5852 * xmlSchemaPValAttrNodeQName:
5853 * @ctxt:  a schema parser context
5854 * @schema: the schema context
5855 * @ownerDes: the designation of the owner element
5856 * @ownerItem: the owner as a schema object
5857 * @attr:  the attribute node
5858 * @local: the resulting local part if found, the attribute value otherwise
5859 * @uri:  the resulting namespace URI if found
5860 *
5861 * Extracts and validates the QName of an attribute value.
5862 * This one is intended to be used on attribute values that
5863 * should resolve to schema components.
5864 *
5865 * Returns 0, in case the QName is valid, a positive error code
5866 * if not valid and -1 if an internal error occurs.
5867 */
5868static int
5869xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
5870				       xmlSchemaPtr schema,
5871				       xmlSchemaBasicItemPtr ownerItem,
5872				       xmlAttrPtr attr,
5873				       const xmlChar **uri,
5874				       const xmlChar **local)
5875{
5876    const xmlChar *value;
5877
5878    value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5879    return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
5880	ownerItem, attr, value, uri, local));
5881}
5882
5883/**
5884 * xmlSchemaPValAttrQName:
5885 * @ctxt:  a schema parser context
5886 * @schema: the schema context
5887 * @ownerDes: the designation of the parent element
5888 * @ownerItem: the owner as a schema object
5889 * @ownerElem:  the parent node of the attribute
5890 * @name:  the name of the attribute
5891 * @local: the resulting local part if found, the attribute value otherwise
5892 * @uri:  the resulting namespace URI if found
5893 *
5894 * Extracts and validates the QName of an attribute value.
5895 *
5896 * Returns 0, in case the QName is valid, a positive error code
5897 * if not valid and -1 if an internal error occurs.
5898 */
5899static int
5900xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
5901				   xmlSchemaPtr schema,
5902				   xmlSchemaBasicItemPtr ownerItem,
5903				   xmlNodePtr ownerElem,
5904				   const char *name,
5905				   const xmlChar **uri,
5906				   const xmlChar **local)
5907{
5908    xmlAttrPtr attr;
5909
5910    attr = xmlSchemaGetPropNode(ownerElem, name);
5911    if (attr == NULL) {
5912	*local = NULL;
5913	*uri = NULL;
5914	return (0);
5915    }
5916    return (xmlSchemaPValAttrNodeQName(ctxt, schema,
5917	ownerItem, attr, uri, local));
5918}
5919
5920/**
5921 * xmlSchemaPValAttrID:
5922 * @ctxt:  a schema parser context
5923 * @schema: the schema context
5924 * @ownerDes: the designation of the parent element
5925 * @ownerItem: the owner as a schema object
5926 * @ownerElem:  the parent node of the attribute
5927 * @name:  the name of the attribute
5928 *
5929 * Extracts and validates the ID of an attribute value.
5930 *
5931 * Returns 0, in case the ID is valid, a positive error code
5932 * if not valid and -1 if an internal error occurs.
5933 */
5934static int
5935xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
5936{
5937    int ret;
5938    const xmlChar *value;
5939
5940    if (attr == NULL)
5941	return(0);
5942    value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
5943    ret = xmlValidateNCName(value, 1);
5944    if (ret == 0) {
5945	/*
5946	* NOTE: the IDness might have already be declared in the DTD
5947	*/
5948	if (attr->atype != XML_ATTRIBUTE_ID) {
5949	    xmlIDPtr res;
5950	    xmlChar *strip;
5951
5952	    /*
5953	    * TODO: Use xmlSchemaStrip here; it's not exported at this
5954	    * moment.
5955	    */
5956	    strip = xmlSchemaCollapseString(value);
5957	    if (strip != NULL) {
5958		xmlFree((xmlChar *) value);
5959		value = strip;
5960	    }
5961	    res = xmlAddID(NULL, attr->doc, value, attr);
5962	    if (res == NULL) {
5963		ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
5964		xmlSchemaPSimpleTypeErr(ctxt,
5965		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5966		    NULL, (xmlNodePtr) attr,
5967		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
5968		    NULL, NULL, "Duplicate value '%s' of simple "
5969		    "type 'xs:ID'", value, NULL);
5970	    } else
5971		attr->atype = XML_ATTRIBUTE_ID;
5972	}
5973    } else if (ret > 0) {
5974	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
5975	xmlSchemaPSimpleTypeErr(ctxt,
5976	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5977	    NULL, (xmlNodePtr) attr,
5978	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
5979	    NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
5980	    "not a valid 'xs:NCName'",
5981	    value, NULL);
5982    }
5983    if (value != NULL)
5984	xmlFree((xmlChar *)value);
5985
5986    return (ret);
5987}
5988
5989static int
5990xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
5991		    xmlNodePtr ownerElem,
5992		    const xmlChar *name)
5993{
5994    xmlAttrPtr attr;
5995
5996    attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
5997    if (attr == NULL)
5998	return(0);
5999    return(xmlSchemaPValAttrNodeID(ctxt, attr));
6000
6001}
6002
6003/**
6004 * xmlGetMaxOccurs:
6005 * @ctxt:  a schema validation context
6006 * @node:  a subtree containing XML Schema informations
6007 *
6008 * Get the maxOccurs property
6009 *
6010 * Returns the default if not found, or the value
6011 */
6012static int
6013xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
6014		int min, int max, int def, const char *expected)
6015{
6016    const xmlChar *val, *cur;
6017    int ret = 0;
6018    xmlAttrPtr attr;
6019
6020    attr = xmlSchemaGetPropNode(node, "maxOccurs");
6021    if (attr == NULL)
6022	return (def);
6023    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6024
6025    if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
6026	if (max != UNBOUNDED) {
6027	    xmlSchemaPSimpleTypeErr(ctxt,
6028		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6029		/* XML_SCHEMAP_INVALID_MINOCCURS, */
6030		NULL, (xmlNodePtr) attr, NULL, expected,
6031		val, NULL, NULL, NULL);
6032	    return (def);
6033	} else
6034	    return (UNBOUNDED);  /* encoding it with -1 might be another option */
6035    }
6036
6037    cur = val;
6038    while (IS_BLANK_CH(*cur))
6039        cur++;
6040    if (*cur == 0) {
6041        xmlSchemaPSimpleTypeErr(ctxt,
6042	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6043	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
6044	    NULL, (xmlNodePtr) attr, NULL, expected,
6045	    val, NULL, NULL, NULL);
6046	return (def);
6047    }
6048    while ((*cur >= '0') && (*cur <= '9')) {
6049        ret = ret * 10 + (*cur - '0');
6050        cur++;
6051    }
6052    while (IS_BLANK_CH(*cur))
6053        cur++;
6054    /*
6055    * TODO: Restrict the maximal value to Integer.
6056    */
6057    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6058	xmlSchemaPSimpleTypeErr(ctxt,
6059	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6060	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
6061	    NULL, (xmlNodePtr) attr, NULL, expected,
6062	    val, NULL, NULL, NULL);
6063        return (def);
6064    }
6065    return (ret);
6066}
6067
6068/**
6069 * xmlGetMinOccurs:
6070 * @ctxt:  a schema validation context
6071 * @node:  a subtree containing XML Schema informations
6072 *
6073 * Get the minOccurs property
6074 *
6075 * Returns the default if not found, or the value
6076 */
6077static int
6078xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
6079		int min, int max, int def, const char *expected)
6080{
6081    const xmlChar *val, *cur;
6082    int ret = 0;
6083    xmlAttrPtr attr;
6084
6085    attr = xmlSchemaGetPropNode(node, "minOccurs");
6086    if (attr == NULL)
6087	return (def);
6088    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6089    cur = val;
6090    while (IS_BLANK_CH(*cur))
6091        cur++;
6092    if (*cur == 0) {
6093        xmlSchemaPSimpleTypeErr(ctxt,
6094	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6095	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
6096	    NULL, (xmlNodePtr) attr, NULL, expected,
6097	    val, NULL, NULL, NULL);
6098        return (def);
6099    }
6100    while ((*cur >= '0') && (*cur <= '9')) {
6101        ret = ret * 10 + (*cur - '0');
6102        cur++;
6103    }
6104    while (IS_BLANK_CH(*cur))
6105        cur++;
6106    /*
6107    * TODO: Restrict the maximal value to Integer.
6108    */
6109    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6110	xmlSchemaPSimpleTypeErr(ctxt,
6111	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6112	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
6113	    NULL, (xmlNodePtr) attr, NULL, expected,
6114	    val, NULL, NULL, NULL);
6115        return (def);
6116    }
6117    return (ret);
6118}
6119
6120/**
6121 * xmlSchemaPGetBoolNodeValue:
6122 * @ctxt:  a schema validation context
6123 * @ownerDes:  owner designation
6124 * @ownerItem:  the owner as a schema item
6125 * @node: the node holding the value
6126 *
6127 * Converts a boolean string value into 1 or 0.
6128 *
6129 * Returns 0 or 1.
6130 */
6131static int
6132xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
6133			   xmlSchemaBasicItemPtr