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