ReactOS 0.4.15-dev-8219-ge8b88cf
xmlschemas.c
Go to the documentation of this file.
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 * - Eliminated 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
48/* To avoid EBCDIC trouble when parsing on zOS */
49#if defined(__MVS__)
50#pragma convert("ISO8859-1")
51#endif
52
53#define IN_LIBXML
54#include "libxml.h"
55
56#ifdef LIBXML_SCHEMAS_ENABLED
57
58#include <string.h>
59#include <libxml/xmlmemory.h>
60#include <libxml/parser.h>
62#include <libxml/hash.h>
63#include <libxml/uri.h>
64#include <libxml/xmlschemas.h>
67#include <libxml/xmlautomata.h>
68#include <libxml/xmlregexp.h>
69#include <libxml/dict.h>
70#include <libxml/encoding.h>
71#include <libxml/xmlIO.h>
72#ifdef LIBXML_PATTERN_ENABLED
73#include <libxml/pattern.h>
74#endif
75#ifdef LIBXML_READER_ENABLED
76#include <libxml/xmlreader.h>
77#endif
78
79/* #define DEBUG 1 */
80
81/* #define DEBUG_CONTENT 1 */
82
83/* #define DEBUG_TYPE 1 */
84
85/* #define DEBUG_CONTENT_REGEXP 1 */
86
87/* #define DEBUG_AUTOMATA 1 */
88
89/* #define DEBUG_IDC */
90
91/* #define DEBUG_IDC_NODE_TABLE */
92
93/* #define WXS_ELEM_DECL_CONS_ENABLED */
94
95#ifdef DEBUG_IDC
96 #ifndef DEBUG_IDC_NODE_TABLE
97 #define DEBUG_IDC_NODE_TABLE
98 #endif
99#endif
100
101/* #define ENABLE_PARTICLE_RESTRICTION 1 */
102
103#define ENABLE_REDEFINE
104
105/* #define ENABLE_NAMED_LOCALS */
106
107/* #define ENABLE_IDC_NODE_TABLES_TEST */
108
109#define DUMP_CONTENT_MODEL
110
111#ifdef LIBXML_READER_ENABLED
112/* #define XML_SCHEMA_READER_ENABLED */
113#endif
114
115#define UNBOUNDED (1 << 30)
116#define TODO \
117 xmlGenericError(xmlGenericErrorContext, \
118 "Unimplemented block at %s:%d\n", \
119 __FILE__, __LINE__);
120
121#define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
122
123/*
124 * The XML Schemas namespaces
125 */
126static const xmlChar *xmlSchemaNs = (const xmlChar *)
127 "http://www.w3.org/2001/XMLSchema";
128
129static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
130 "http://www.w3.org/2001/XMLSchema-instance";
131
132static const xmlChar *xmlNamespaceNs = (const xmlChar *)
133 "http://www.w3.org/2000/xmlns/";
134
135/*
136* Come casting macros.
137*/
138#define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
139#define PCTXT_CAST (xmlSchemaParserCtxtPtr)
140#define VCTXT_CAST (xmlSchemaValidCtxtPtr)
141#define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
142#define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
143#define WXS_PTC_CAST (xmlSchemaParticlePtr)
144#define WXS_TYPE_CAST (xmlSchemaTypePtr)
145#define WXS_ELEM_CAST (xmlSchemaElementPtr)
146#define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
147#define WXS_ATTR_CAST (xmlSchemaAttributePtr)
148#define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
149#define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
150#define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
151#define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
152#define WXS_IDC_CAST (xmlSchemaIDCPtr)
153#define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
154#define WXS_LIST_CAST (xmlSchemaItemListPtr)
155
156/*
157* Macros to query common properties of components.
158*/
159#define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
160
161#define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
162/*
163* Macros for element declarations.
164*/
165#define WXS_ELEM_TYPEDEF(e) (e)->subtypes
166
167#define WXS_SUBST_HEAD(item) (item)->refDecl
168/*
169* Macros for attribute declarations.
170*/
171#define WXS_ATTR_TYPEDEF(a) (a)->subtypes
172/*
173* Macros for attribute uses.
174*/
175#define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl
176
177#define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
178
179#define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
180
181#define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
182/*
183* Macros for attribute groups.
184*/
185#define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
186#define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
187/*
188* Macros for particles.
189*/
190#define WXS_PARTICLE(p) WXS_PTC_CAST (p)
191
192#define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
193
194#define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
195
196#define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
197/*
198* Macros for model groups definitions.
199*/
200#define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
201/*
202* Macros for model groups.
203*/
204#define WXS_IS_MODEL_GROUP(i) \
205 (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
206 ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
207 ((i)->type == XML_SCHEMA_TYPE_ALL))
208
209#define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
210/*
211* Macros for schema buckets.
212*/
213#define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
214 ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
215
216#define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
217 ((t) == XML_SCHEMA_SCHEMA_IMPORT))
218
219#define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
220
221#define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
222/*
223* Macros for complex/simple types.
224*/
225#define WXS_IS_ANYTYPE(i) \
226 (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
227 ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
228
229#define WXS_IS_COMPLEX(i) \
230 (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
231 ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
232
233#define WXS_IS_SIMPLE(item) \
234 ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
235 ((item->type == XML_SCHEMA_TYPE_BASIC) && \
236 (item->builtInType != XML_SCHEMAS_ANYTYPE)))
237
238#define WXS_IS_ANY_SIMPLE_TYPE(i) \
239 (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
240 ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
241
242#define WXS_IS_RESTRICTION(t) \
243 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
244
245#define WXS_IS_EXTENSION(t) \
246 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
247
248#define WXS_IS_TYPE_NOT_FIXED(i) \
249 (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
250 (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
251
252#define WXS_IS_TYPE_NOT_FIXED_1(item) \
253 (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
254 (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
255
256#define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
257
258#define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
259/*
260* Macros for exclusively for complex types.
261*/
262#define WXS_HAS_COMPLEX_CONTENT(item) \
263 ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
264 (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
265 (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
266
267#define WXS_HAS_SIMPLE_CONTENT(item) \
268 ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
269 (item->contentType == XML_SCHEMA_CONTENT_BASIC))
270
271#define WXS_HAS_MIXED_CONTENT(item) \
272 (item->contentType == XML_SCHEMA_CONTENT_MIXED)
273
274#define WXS_EMPTIABLE(t) \
275 (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
276
277#define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
278
279#define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
280
281#define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
282/*
283* Macros for exclusively for simple types.
284*/
285#define WXS_LIST_ITEMTYPE(t) (t)->subtypes
286
287#define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
288
289#define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
290
291#define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
292/*
293* Misc parser context macros.
294*/
295#define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
296
297#define WXS_HAS_BUCKETS(ctx) \
298( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
299(WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
300
301#define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
302
303#define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
304
305#define WXS_SCHEMA(ctx) (ctx)->schema
306
307#define WXS_ADD_LOCAL(ctx, item) \
308 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
309
310#define WXS_ADD_GLOBAL(ctx, item) \
311 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
312
313#define WXS_ADD_PENDING(ctx, item) \
314 xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
315/*
316* xmlSchemaItemList macros.
317*/
318#define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
319/*
320* Misc macros.
321*/
322#define IS_SCHEMA(node, type) \
323 ((node != NULL) && (node->ns != NULL) && \
324 (xmlStrEqual(node->name, (const xmlChar *) type)) && \
325 (xmlStrEqual(node->ns->href, xmlSchemaNs)))
326
327#define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
328
329/*
330* Since we put the default/fixed values into the dict, we can
331* use pointer comparison for those values.
332* REMOVED: (xmlStrEqual((v1), (v2)))
333*/
334#define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
335
336#define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
337
338#define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
339
340#define HFAILURE if (res == -1) goto exit_failure;
341
342#define HERROR if (res != 0) goto exit_error;
343
344#define HSTOP(ctx) if ((ctx)->stop) goto exit;
345/*
346* Some flags used for various schema constraints.
347*/
348#define SUBSET_RESTRICTION 1<<0
349#define SUBSET_EXTENSION 1<<1
350#define SUBSET_SUBSTITUTION 1<<2
351#define SUBSET_LIST 1<<3
352#define SUBSET_UNION 1<<4
353
354typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
355typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
356
357typedef struct _xmlSchemaItemList xmlSchemaItemList;
358typedef xmlSchemaItemList *xmlSchemaItemListPtr;
359struct _xmlSchemaItemList {
360 void **items; /* used for dynamic addition of schemata */
361 int nbItems; /* used for dynamic addition of schemata */
362 int sizeItems; /* used for dynamic addition of schemata */
363};
364
365#define XML_SCHEMA_CTXT_PARSER 1
366#define XML_SCHEMA_CTXT_VALIDATOR 2
367
368typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
369typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
370struct _xmlSchemaAbstractCtxt {
371 int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
372 void *dummy; /* Fix alignment issues */
373};
374
375typedef struct _xmlSchemaBucket xmlSchemaBucket;
376typedef xmlSchemaBucket *xmlSchemaBucketPtr;
377
378#define XML_SCHEMA_SCHEMA_MAIN 0
379#define XML_SCHEMA_SCHEMA_IMPORT 1
380#define XML_SCHEMA_SCHEMA_INCLUDE 2
381#define XML_SCHEMA_SCHEMA_REDEFINE 3
382
388typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
389typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
390struct _xmlSchemaSchemaRelation {
391 xmlSchemaSchemaRelationPtr next;
392 int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
393 const xmlChar *importNamespace;
394 xmlSchemaBucketPtr bucket;
395};
396
397#define XML_SCHEMA_BUCKET_MARKED 1<<0
398#define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
399
400struct _xmlSchemaBucket {
401 int type;
402 int flags;
403 const xmlChar *schemaLocation;
404 const xmlChar *origTargetNamespace;
405 const xmlChar *targetNamespace;
406 xmlDocPtr doc;
407 xmlSchemaSchemaRelationPtr relations;
408 int located;
409 int parsed;
410 int imported;
411 int preserveDoc;
412 xmlSchemaItemListPtr globals; /* Global components. */
413 xmlSchemaItemListPtr locals; /* Local components. */
414};
415
424typedef struct _xmlSchemaImport xmlSchemaImport;
425typedef xmlSchemaImport *xmlSchemaImportPtr;
426struct _xmlSchemaImport {
427 int type; /* Main OR import OR include. */
428 int flags;
429 const xmlChar *schemaLocation; /* The URI of the schema document. */
430 /* For chameleon includes, @origTargetNamespace will be NULL */
431 const xmlChar *origTargetNamespace;
432 /*
433 * For chameleon includes, @targetNamespace will be the
434 * targetNamespace of the including schema.
435 */
436 const xmlChar *targetNamespace;
437 xmlDocPtr doc; /* The schema node-tree. */
438 /* @relations will hold any included/imported/redefined schemas. */
439 xmlSchemaSchemaRelationPtr relations;
440 int located;
441 int parsed;
442 int imported;
443 int preserveDoc;
444 xmlSchemaItemListPtr globals;
445 xmlSchemaItemListPtr locals;
446 /* The imported schema. */
447 xmlSchemaPtr schema;
448};
449
450/*
451* (extends xmlSchemaBucket)
452*/
453typedef struct _xmlSchemaInclude xmlSchemaInclude;
454typedef xmlSchemaInclude *xmlSchemaIncludePtr;
455struct _xmlSchemaInclude {
456 int type;
457 int flags;
458 const xmlChar *schemaLocation;
459 const xmlChar *origTargetNamespace;
460 const xmlChar *targetNamespace;
461 xmlDocPtr doc;
462 xmlSchemaSchemaRelationPtr relations;
463 int located;
464 int parsed;
465 int imported;
466 int preserveDoc;
467 xmlSchemaItemListPtr globals; /* Global components. */
468 xmlSchemaItemListPtr locals; /* Local components. */
469
470 /* The owning main or import schema bucket. */
471 xmlSchemaImportPtr ownerImport;
472};
473
479typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
480typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
481struct _xmlSchemaBasicItem {
482 xmlSchemaTypeType type;
483 void *dummy; /* Fix alignment issues */
484};
485
492typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
493typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
494struct _xmlSchemaAnnotItem {
495 xmlSchemaTypeType type;
496 xmlSchemaAnnotPtr annot;
497};
498
505typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
506typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
507struct _xmlSchemaTreeItem {
508 xmlSchemaTypeType type;
509 xmlSchemaAnnotPtr annot;
510 xmlSchemaTreeItemPtr next;
511 xmlSchemaTreeItemPtr children;
512};
513
514
515#define XML_SCHEMA_ATTR_USE_FIXED 1<<0
522typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
523typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
524struct _xmlSchemaAttributeUse {
525 xmlSchemaTypeType type;
526 xmlSchemaAnnotPtr annot;
527 xmlSchemaAttributeUsePtr next; /* The next attr. use. */
528 /*
529 * The attr. decl. OR a QName-ref. to an attr. decl. OR
530 * a QName-ref. to an attribute group definition.
531 */
532 xmlSchemaAttributePtr attrDecl;
533
534 int flags;
536 int occurs; /* required, optional */
537 const xmlChar * defValue;
538 xmlSchemaValPtr defVal;
539};
540
547typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
548typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
549struct _xmlSchemaAttributeUseProhib {
550 xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
552 const xmlChar *name;
553 const xmlChar *targetNamespace;
554 int isRef;
555};
556
560typedef struct _xmlSchemaRedef xmlSchemaRedef;
561typedef xmlSchemaRedef *xmlSchemaRedefPtr;
562struct _xmlSchemaRedef {
563 xmlSchemaRedefPtr next;
564 xmlSchemaBasicItemPtr item; /* The redefining component. */
565 xmlSchemaBasicItemPtr reference; /* The referencing component. */
566 xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
567 const xmlChar *refName; /* The name of the to-be-redefined component. */
568 const xmlChar *refTargetNs; /* The target namespace of the
569 to-be-redefined comp. */
570 xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
571};
572
576typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
577typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
578struct _xmlSchemaConstructionCtxt {
579 xmlSchemaPtr mainSchema; /* The main schema. */
580 xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
581 xmlDictPtr dict;
582 xmlSchemaItemListPtr buckets; /* List of schema buckets. */
583 /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
584 xmlSchemaBucketPtr bucket; /* The current schema bucket */
585 xmlSchemaItemListPtr pending; /* All Components of all schemas that
586 need to be fixed. */
587 xmlHashTablePtr substGroups;
588 xmlSchemaRedefPtr redefs;
589 xmlSchemaRedefPtr lastRedef;
590};
591
592#define XML_SCHEMAS_PARSE_ERROR 1
593#define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
594
595struct _xmlSchemaParserCtxt {
596 int type;
597 void *errCtxt; /* user specific error context */
598 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
599 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
600 int err;
601 int nberrors;
603
604 xmlSchemaConstructionCtxtPtr constructor;
605 int ownsConstructor; /* TODO: Move this to parser *flags*. */
606
607 /* xmlSchemaPtr topschema; */
608 /* xmlHashTablePtr namespaces; */
609
610 xmlSchemaPtr schema; /* The main schema in use */
611 int counter;
612
613 const xmlChar *URL;
614 xmlDocPtr doc;
615 int preserve; /* Whether the doc should be freed */
616
617 const char *buffer;
618 int size;
619
620 /*
621 * Used to build complex element content models
622 */
623 xmlAutomataPtr am;
624 xmlAutomataStatePtr start;
625 xmlAutomataStatePtr end;
626 xmlAutomataStatePtr state;
627
628 xmlDictPtr dict; /* dictionary for interned string names */
629 xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
630 int options;
631 xmlSchemaValidCtxtPtr vctxt;
632 int isS4S;
633 int isRedefine;
634 int xsiAssemble;
635 int stop; /* If the parser should stop; i.e. a critical error. */
636 const xmlChar *targetNamespace;
637 xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
638
639 xmlSchemaRedefPtr redef; /* Used for redefinitions. */
640 int redefCounter; /* Used for redefinitions. */
641 xmlSchemaItemListPtr attrProhibs;
642};
643
650typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
651typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
652struct _xmlSchemaQNameRef {
653 xmlSchemaTypeType type;
654 xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
655 xmlSchemaTypeType itemType;
656 const xmlChar *name;
657 const xmlChar *targetNamespace;
659};
660
667typedef struct _xmlSchemaParticle xmlSchemaParticle;
668typedef xmlSchemaParticle *xmlSchemaParticlePtr;
669struct _xmlSchemaParticle {
670 xmlSchemaTypeType type;
671 xmlSchemaAnnotPtr annot;
672 xmlSchemaTreeItemPtr next; /* next particle */
673 xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
674 a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
675 etc.) */
676 int minOccurs;
677 int maxOccurs;
679};
680
687typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
688typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
689struct _xmlSchemaModelGroup {
690 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
691 xmlSchemaAnnotPtr annot;
692 xmlSchemaTreeItemPtr next; /* not used */
693 xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
695};
696
697#define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
698#define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
705typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
706typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
707struct _xmlSchemaModelGroupDef {
708 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
709 xmlSchemaAnnotPtr annot;
710 xmlSchemaTreeItemPtr next; /* not used */
711 xmlSchemaTreeItemPtr children; /* the "model group" */
712 const xmlChar *name;
713 const xmlChar *targetNamespace;
715 int flags;
716};
717
718typedef struct _xmlSchemaIDC xmlSchemaIDC;
719typedef xmlSchemaIDC *xmlSchemaIDCPtr;
720
727typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
728typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
729struct _xmlSchemaIDCSelect {
730 xmlSchemaIDCSelectPtr next;
731 xmlSchemaIDCPtr idc;
732 int index; /* an index position if significant for IDC key-sequences */
733 const xmlChar *xpath; /* the XPath expression */
734 void *xpathComp; /* the compiled XPath expression */
735};
736
744struct _xmlSchemaIDC {
745 xmlSchemaTypeType type;
746 xmlSchemaAnnotPtr annot;
747 xmlSchemaIDCPtr next;
749 const xmlChar *name;
750 const xmlChar *targetNamespace;
751 xmlSchemaIDCSelectPtr selector;
752 xmlSchemaIDCSelectPtr fields;
753 int nbFields;
754 xmlSchemaQNameRefPtr ref;
755};
756
762typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
763typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
764struct _xmlSchemaIDCAug {
765 xmlSchemaIDCAugPtr next; /* next in a list */
766 xmlSchemaIDCPtr def; /* the IDC definition */
767 int keyrefDepth; /* the lowest tree level to which IDC
768 tables need to be bubbled upwards */
769};
770
776typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
777typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
778struct _xmlSchemaPSVIIDCKey {
779 xmlSchemaTypePtr type;
780 xmlSchemaValPtr val;
781};
782
788typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
789typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
790struct _xmlSchemaPSVIIDCNode {
792 xmlSchemaPSVIIDCKeyPtr *keys;
793 int nodeLine;
794 int nodeQNameID;
795
796};
797
803typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
804typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
805struct _xmlSchemaPSVIIDCBinding {
806 xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
807 xmlSchemaIDCPtr definition; /* the IDC definition */
808 xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
809 int nbNodes; /* number of entries in the node table */
810 int sizeNodes; /* size of the node table */
811 xmlSchemaItemListPtr dupls;
812};
813
814
815#define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
816#define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
817
818#define XPATH_STATE_OBJ_MATCHES -2
819#define XPATH_STATE_OBJ_BLOCKED -3
820
821typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
822typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
823
829typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
830typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
831struct _xmlSchemaIDCStateObj {
832 int type;
833 xmlSchemaIDCStateObjPtr next; /* next if in a list */
834 int depth; /* depth of creation */
835 int *history; /* list of (depth, state-id) tuples */
836 int nbHistory;
837 int sizeHistory;
838 xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
839 matcher */
840 xmlSchemaIDCSelectPtr sel;
841 void *xpathCtxt;
842};
843
844#define IDC_MATCHER 0
845
851struct _xmlSchemaIDCMatcher {
852 int type;
853 int depth; /* the tree depth at creation time */
854 xmlSchemaIDCMatcherPtr next; /* next in the list */
855 xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
856 xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
857 int idcType;
858 xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
859 elements */
860 int sizeKeySeqs;
861 xmlSchemaItemListPtr targets; /* list of target-node
862 (xmlSchemaPSVIIDCNodePtr) entries */
863 xmlHashTablePtr htab;
864};
865
866/*
867* Element info flags.
868*/
869#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0
870#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
871#define XML_SCHEMA_ELEM_INFO_NILLED 1<<2
872#define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3
873
874#define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4
875#define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5
876#define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6
877
878#define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7
879#define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8
880#define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9
881#define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10
882
888struct _xmlSchemaNodeInfo {
889 int nodeType;
891 int nodeLine;
892 const xmlChar *localName;
893 const xmlChar *nsName;
894 const xmlChar *value;
895 xmlSchemaValPtr val; /* the pre-computed value if any */
896 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
897
898 int flags; /* combination of node info flags */
899
900 int valNeeded;
901 int normVal;
902
903 xmlSchemaElementPtr decl; /* the element/attribute declaration */
904 int depth;
905 xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
906 for the scope element*/
907 xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
908 element */
909 xmlRegExecCtxtPtr regexCtxt;
910
911 const xmlChar **nsBindings; /* Namespace bindings on this element */
912 int nbNsBindings;
913 int sizeNsBindings;
914
915 int hasKeyrefs;
916 int appliedXPath; /* Indicates that an XPath has been applied. */
917};
918
919#define XML_SCHEMAS_ATTR_UNKNOWN 1
920#define XML_SCHEMAS_ATTR_ASSESSED 2
921#define XML_SCHEMAS_ATTR_PROHIBITED 3
922#define XML_SCHEMAS_ATTR_ERR_MISSING 4
923#define XML_SCHEMAS_ATTR_INVALID_VALUE 5
924#define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
925#define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
926#define XML_SCHEMAS_ATTR_DEFAULT 8
927#define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
928#define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
929#define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
930#define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
931#define XML_SCHEMAS_ATTR_WILD_SKIP 13
932#define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
933#define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
934#define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
935#define XML_SCHEMAS_ATTR_META 17
936/*
937* @metaType values of xmlSchemaAttrInfo.
938*/
939#define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
940#define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
941#define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
942#define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
943#define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
944
945typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
946typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
947struct _xmlSchemaAttrInfo {
948 int nodeType;
950 int nodeLine;
951 const xmlChar *localName;
952 const xmlChar *nsName;
953 const xmlChar *value;
954 xmlSchemaValPtr val; /* the pre-computed value if any */
955 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
956 int flags; /* combination of node info flags */
957
958 xmlSchemaAttributePtr decl; /* the attribute declaration */
959 xmlSchemaAttributeUsePtr use; /* the attribute use */
960 int state;
961 int metaType;
962 const xmlChar *vcValue; /* the value constraint value */
963 xmlSchemaNodeInfoPtr parent;
964};
965
966
967#define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
973struct _xmlSchemaValidCtxt {
974 int type;
975 void *errCtxt; /* user specific data block */
976 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
977 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
979
980 xmlSchemaPtr schema; /* The schema in use */
981 xmlDocPtr doc;
983 xmlCharEncoding enc;
985 xmlParserCtxtPtr parserCtxt;
986 void *user_data; /* TODO: What is this for? */
987 char *filename;
988
989 int err;
990 int nberrors;
991
994 /* xmlSchemaTypePtr type; */
995
996 xmlRegExecCtxtPtr regexp;
997 xmlSchemaValPtr value;
998
999 int valueWS;
1000 int options;
1001 xmlNodePtr validationRoot;
1002 xmlSchemaParserCtxtPtr pctxt;
1003 int xsiAssemble;
1004
1005 int depth;
1006 xmlSchemaNodeInfoPtr *elemInfos; /* array of element information */
1007 int sizeElemInfos;
1008 xmlSchemaNodeInfoPtr inode; /* the current element information */
1009
1010 xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC information */
1011
1012 xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
1013 xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
1014 xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
1015
1016 xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
1017 int nbIdcNodes;
1018 int sizeIdcNodes;
1019
1020 xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
1021 int nbIdcKeys;
1022 int sizeIdcKeys;
1023
1024 int flags;
1025
1026 xmlDictPtr dict;
1027
1028#ifdef LIBXML_READER_ENABLED
1029 xmlTextReaderPtr reader;
1030#endif
1031
1032 xmlSchemaAttrInfoPtr *attrInfos;
1033 int nbAttrInfos;
1034 int sizeAttrInfos;
1035
1036 int skipDepth;
1037 xmlSchemaItemListPtr nodeQNames;
1038 int hasKeyrefs;
1039 int createIDCNodeTables;
1040 int psviExposeIDCNodeTables;
1041
1042 /* Locator for error reporting in streaming mode */
1043 xmlSchemaValidityLocatorFunc locFunc;
1044 void *locCtxt;
1045};
1046
1052typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
1053typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
1054struct _xmlSchemaSubstGroup {
1055 xmlSchemaElementPtr head;
1056 xmlSchemaItemListPtr members;
1057};
1058
1064typedef struct _xmlIDCHashEntry xmlIDCHashEntry;
1065typedef xmlIDCHashEntry *xmlIDCHashEntryPtr;
1066struct _xmlIDCHashEntry {
1067 xmlIDCHashEntryPtr next; /* next item with same hash */
1068 int index; /* index into associated item list */
1069};
1070
1071/************************************************************************
1072 * *
1073 * Some predeclarations *
1074 * *
1075 ************************************************************************/
1076
1077static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
1078 xmlSchemaPtr schema,
1080static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
1081 xmlSchemaPtr schema,
1083static int
1084xmlSchemaTypeFixup(xmlSchemaTypePtr type,
1085 xmlSchemaAbstractCtxtPtr ctxt);
1086static const xmlChar *
1087xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
1088static int
1089xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1091static int
1092xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
1093 xmlSchemaParserCtxtPtr ctxt);
1094static void
1095xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
1096static xmlSchemaWhitespaceValueType
1097xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
1098static xmlSchemaTreeItemPtr
1099xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1100 xmlNodePtr node, xmlSchemaTypeType type,
1101 int withParticle);
1102static const xmlChar *
1103xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
1104static xmlSchemaTypeLinkPtr
1105xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
1106static void
1107xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
1108 const char *funcName,
1109 const char *message) LIBXML_ATTR_FORMAT(3,0);
1110static int
1111xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
1112 xmlSchemaTypePtr type,
1113 xmlSchemaTypePtr baseType,
1114 int subset);
1115static void
1116xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
1117 xmlSchemaParserCtxtPtr ctxt);
1118static void
1119xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
1120static xmlSchemaQNameRefPtr
1121xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
1122 xmlSchemaPtr schema,
1124
1125/************************************************************************
1126 * *
1127 * Helper functions *
1128 * *
1129 ************************************************************************/
1130
1137static const xmlChar *
1138xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
1139{
1140 switch (type) {
1141 case XML_SCHEMA_TYPE_BASIC:
1142 return(BAD_CAST "simple type definition");
1143 case XML_SCHEMA_TYPE_SIMPLE:
1144 return(BAD_CAST "simple type definition");
1145 case XML_SCHEMA_TYPE_COMPLEX:
1146 return(BAD_CAST "complex type definition");
1147 case XML_SCHEMA_TYPE_ELEMENT:
1148 return(BAD_CAST "element declaration");
1149 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1150 return(BAD_CAST "attribute use");
1151 case XML_SCHEMA_TYPE_ATTRIBUTE:
1152 return(BAD_CAST "attribute declaration");
1153 case XML_SCHEMA_TYPE_GROUP:
1154 return(BAD_CAST "model group definition");
1155 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1156 return(BAD_CAST "attribute group definition");
1157 case XML_SCHEMA_TYPE_NOTATION:
1158 return(BAD_CAST "notation declaration");
1159 case XML_SCHEMA_TYPE_SEQUENCE:
1160 return(BAD_CAST "model group (sequence)");
1161 case XML_SCHEMA_TYPE_CHOICE:
1162 return(BAD_CAST "model group (choice)");
1163 case XML_SCHEMA_TYPE_ALL:
1164 return(BAD_CAST "model group (all)");
1165 case XML_SCHEMA_TYPE_PARTICLE:
1166 return(BAD_CAST "particle");
1167 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1168 return(BAD_CAST "unique identity-constraint");
1169 /* return(BAD_CAST "IDC (unique)"); */
1170 case XML_SCHEMA_TYPE_IDC_KEY:
1171 return(BAD_CAST "key identity-constraint");
1172 /* return(BAD_CAST "IDC (key)"); */
1173 case XML_SCHEMA_TYPE_IDC_KEYREF:
1174 return(BAD_CAST "keyref identity-constraint");
1175 /* return(BAD_CAST "IDC (keyref)"); */
1176 case XML_SCHEMA_TYPE_ANY:
1177 return(BAD_CAST "wildcard (any)");
1178 case XML_SCHEMA_EXTRA_QNAMEREF:
1179 return(BAD_CAST "[helper component] QName reference");
1180 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
1181 return(BAD_CAST "[helper component] attribute use prohibition");
1182 default:
1183 return(BAD_CAST "Not a schema component");
1184 }
1185}
1186
1193static const xmlChar *
1194xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
1195{
1196 switch (item->type) {
1197 case XML_SCHEMA_TYPE_BASIC:
1198 if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
1199 return(BAD_CAST "complex type definition");
1200 else
1201 return(BAD_CAST "simple type definition");
1202 default:
1203 return(xmlSchemaItemTypeToStr(item->type));
1204 }
1205}
1206
1217static xmlNodePtr
1218xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
1219{
1220 switch (item->type) {
1221 case XML_SCHEMA_TYPE_ELEMENT:
1222 return (((xmlSchemaElementPtr) item)->node);
1223 case XML_SCHEMA_TYPE_ATTRIBUTE:
1224 return (((xmlSchemaAttributePtr) item)->node);
1225 case XML_SCHEMA_TYPE_COMPLEX:
1226 case XML_SCHEMA_TYPE_SIMPLE:
1227 return (((xmlSchemaTypePtr) item)->node);
1228 case XML_SCHEMA_TYPE_ANY:
1229 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1230 return (((xmlSchemaWildcardPtr) item)->node);
1231 case XML_SCHEMA_TYPE_PARTICLE:
1232 return (((xmlSchemaParticlePtr) item)->node);
1233 case XML_SCHEMA_TYPE_SEQUENCE:
1234 case XML_SCHEMA_TYPE_CHOICE:
1235 case XML_SCHEMA_TYPE_ALL:
1236 return (((xmlSchemaModelGroupPtr) item)->node);
1237 case XML_SCHEMA_TYPE_GROUP:
1238 return (((xmlSchemaModelGroupDefPtr) item)->node);
1239 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1240 return (((xmlSchemaAttributeGroupPtr) item)->node);
1241 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1242 case XML_SCHEMA_TYPE_IDC_KEY:
1243 case XML_SCHEMA_TYPE_IDC_KEYREF:
1244 return (((xmlSchemaIDCPtr) item)->node);
1245 case XML_SCHEMA_EXTRA_QNAMEREF:
1246 return(((xmlSchemaQNameRefPtr) item)->node);
1247 /* TODO: What to do with NOTATIONs?
1248 case XML_SCHEMA_TYPE_NOTATION:
1249 return (((xmlSchemaNotationPtr) item)->node);
1250 */
1251 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1252 return (((xmlSchemaAttributeUsePtr) item)->node);
1253 default:
1254 return (NULL);
1255 }
1256}
1257
1258#if 0
1265static xmlSchemaBasicItemPtr
1266xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
1267{
1268 switch (item->type) {
1269 case XML_SCHEMA_TYPE_ELEMENT:
1270 return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
1271 case XML_SCHEMA_TYPE_ATTRIBUTE:
1272 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
1273 case XML_SCHEMA_TYPE_COMPLEX:
1274 case XML_SCHEMA_TYPE_SIMPLE:
1275 return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
1276 case XML_SCHEMA_TYPE_ANY:
1277 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1278 return (NULL);
1279 case XML_SCHEMA_TYPE_PARTICLE:
1280 return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
1281 case XML_SCHEMA_TYPE_SEQUENCE:
1282 case XML_SCHEMA_TYPE_CHOICE:
1283 case XML_SCHEMA_TYPE_ALL:
1284 return (NULL);
1285 case XML_SCHEMA_TYPE_GROUP:
1286 return (NULL);
1287 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1288 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
1289 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1290 case XML_SCHEMA_TYPE_IDC_KEY:
1291 case XML_SCHEMA_TYPE_IDC_KEYREF:
1292 return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
1293 default:
1294 return (NULL);
1295 }
1296}
1297#endif
1298
1299
1312static const xmlChar*
1313xmlSchemaFormatQName(xmlChar **buf,
1314 const xmlChar *namespaceName,
1315 const xmlChar *localName)
1316{
1317 FREE_AND_NULL(*buf)
1318 if (namespaceName != NULL) {
1319 *buf = xmlStrdup(BAD_CAST "{");
1320 *buf = xmlStrcat(*buf, namespaceName);
1321 *buf = xmlStrcat(*buf, BAD_CAST "}");
1322 }
1323 if (localName != NULL) {
1324 if (namespaceName == NULL)
1325 return(localName);
1326 *buf = xmlStrcat(*buf, localName);
1327 } else {
1328 *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
1329 }
1330 return ((const xmlChar *) *buf);
1331}
1332
1333static const xmlChar*
1334xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
1335{
1336 if (ns != NULL)
1337 return (xmlSchemaFormatQName(buf, ns->href, localName));
1338 else
1339 return (xmlSchemaFormatQName(buf, NULL, localName));
1340}
1341
1342static const xmlChar *
1343xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
1344{
1345 if (item == NULL) {
1346 return (NULL);
1347 }
1348 switch (item->type) {
1349 case XML_SCHEMA_TYPE_ELEMENT:
1350 return (((xmlSchemaElementPtr) item)->name);
1351 case XML_SCHEMA_TYPE_ATTRIBUTE:
1352 return (((xmlSchemaAttributePtr) item)->name);
1353 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1354 return (((xmlSchemaAttributeGroupPtr) item)->name);
1355 case XML_SCHEMA_TYPE_BASIC:
1356 case XML_SCHEMA_TYPE_SIMPLE:
1357 case XML_SCHEMA_TYPE_COMPLEX:
1358 return (((xmlSchemaTypePtr) item)->name);
1359 case XML_SCHEMA_TYPE_GROUP:
1360 return (((xmlSchemaModelGroupDefPtr) item)->name);
1361 case XML_SCHEMA_TYPE_IDC_KEY:
1362 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1363 case XML_SCHEMA_TYPE_IDC_KEYREF:
1364 return (((xmlSchemaIDCPtr) item)->name);
1365 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1366 if (WXS_ATTRUSE_DECL(item) != NULL) {
1367 return(xmlSchemaGetComponentName(
1368 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1369 } else
1370 return(NULL);
1371 case XML_SCHEMA_EXTRA_QNAMEREF:
1372 return (((xmlSchemaQNameRefPtr) item)->name);
1373 case XML_SCHEMA_TYPE_NOTATION:
1374 return (((xmlSchemaNotationPtr) item)->name);
1375 default:
1376 /*
1377 * Other components cannot have names.
1378 */
1379 break;
1380 }
1381 return (NULL);
1382}
1383
1384#define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
1385#define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
1386/*
1387static const xmlChar *
1388xmlSchemaGetQNameRefName(void *ref)
1389{
1390 return(((xmlSchemaQNameRefPtr) ref)->name);
1391}
1392
1393static const xmlChar *
1394xmlSchemaGetQNameRefTargetNs(void *ref)
1395{
1396 return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
1397}
1398*/
1399
1400static const xmlChar *
1401xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
1402{
1403 if (item == NULL) {
1404 return (NULL);
1405 }
1406 switch (item->type) {
1407 case XML_SCHEMA_TYPE_ELEMENT:
1408 return (((xmlSchemaElementPtr) item)->targetNamespace);
1409 case XML_SCHEMA_TYPE_ATTRIBUTE:
1410 return (((xmlSchemaAttributePtr) item)->targetNamespace);
1411 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1412 return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
1413 case XML_SCHEMA_TYPE_BASIC:
1414 return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
1415 case XML_SCHEMA_TYPE_SIMPLE:
1416 case XML_SCHEMA_TYPE_COMPLEX:
1417 return (((xmlSchemaTypePtr) item)->targetNamespace);
1418 case XML_SCHEMA_TYPE_GROUP:
1419 return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
1420 case XML_SCHEMA_TYPE_IDC_KEY:
1421 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1422 case XML_SCHEMA_TYPE_IDC_KEYREF:
1423 return (((xmlSchemaIDCPtr) item)->targetNamespace);
1424 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1425 if (WXS_ATTRUSE_DECL(item) != NULL) {
1426 return(xmlSchemaGetComponentTargetNs(
1427 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1428 }
1429 /* TODO: Will returning NULL break something? */
1430 break;
1431 case XML_SCHEMA_EXTRA_QNAMEREF:
1432 return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
1433 case XML_SCHEMA_TYPE_NOTATION:
1434 return (((xmlSchemaNotationPtr) item)->targetNamespace);
1435 default:
1436 /*
1437 * Other components cannot have names.
1438 */
1439 break;
1440 }
1441 return (NULL);
1442}
1443
1444static const xmlChar*
1445xmlSchemaGetComponentQName(xmlChar **buf,
1446 void *item)
1447{
1448 return (xmlSchemaFormatQName(buf,
1449 xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
1450 xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
1451}
1452
1453static const xmlChar*
1454xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
1455{
1456 xmlChar *str = NULL;
1457
1458 *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
1459 *buf = xmlStrcat(*buf, BAD_CAST " '");
1460 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
1461 (xmlSchemaBasicItemPtr) item));
1462 *buf = xmlStrcat(*buf, BAD_CAST "'");
1463 FREE_AND_NULL(str);
1464 return(*buf);
1465}
1466
1467static const xmlChar*
1468xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
1469{
1470 return(xmlSchemaGetComponentDesignation(buf, idc));
1471}
1472
1480static const xmlChar *
1481xmlSchemaWildcardPCToString(int pc)
1482{
1483 switch (pc) {
1484 case XML_SCHEMAS_ANY_SKIP:
1485 return (BAD_CAST "skip");
1486 case XML_SCHEMAS_ANY_LAX:
1487 return (BAD_CAST "lax");
1488 case XML_SCHEMAS_ANY_STRICT:
1489 return (BAD_CAST "strict");
1490 default:
1491 return (BAD_CAST "invalid process contents");
1492 }
1493}
1494
1508static int
1509xmlSchemaGetCanonValueWhtspExt_1(xmlSchemaValPtr val,
1510 xmlSchemaWhitespaceValueType ws,
1511 xmlChar **retValue,
1512 int for_hash)
1513{
1514 int list;
1515 xmlSchemaValType valType;
1516 const xmlChar *value, *value2 = NULL;
1517
1518
1519 if ((retValue == NULL) || (val == NULL))
1520 return (-1);
1521 list = xmlSchemaValueGetNext(val) ? 1 : 0;
1522 *retValue = NULL;
1523 do {
1524 value = NULL;
1525 valType = xmlSchemaGetValType(val);
1526 switch (valType) {
1527 case XML_SCHEMAS_STRING:
1528 case XML_SCHEMAS_NORMSTRING:
1529 case XML_SCHEMAS_ANYSIMPLETYPE:
1530 value = xmlSchemaValueGetAsString(val);
1531 if (value != NULL) {
1532 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
1533 value2 = xmlSchemaCollapseString(value);
1534 else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
1535 value2 = xmlSchemaWhiteSpaceReplace(value);
1536 if (value2 != NULL)
1537 value = value2;
1538 }
1539 break;
1540 default:
1541 if (xmlSchemaGetCanonValue(val, &value2) == -1) {
1542 if (value2 != NULL)
1543 xmlFree((xmlChar *) value2);
1544 goto internal_error;
1545 }
1546 if (for_hash && valType == XML_SCHEMAS_DECIMAL) {
1547 /* We can mostly use the canonical value for hashing,
1548 except in the case of decimal. There the canonical
1549 representation requires a trailing '.0' even for
1550 non-fractional numbers, but for the derived integer
1551 types it forbids any decimal point. Nevertheless they
1552 compare equal if the value is equal. We need to generate
1553 the same hash value for this to work, and it's easiest
1554 to just cut off the useless '.0' suffix for the
1555 decimal type. */
1556 int len = xmlStrlen(value2);
1557 if (len > 2 && value2[len-1] == '0' && value2[len-2] == '.')
1558 ((xmlChar*)value2)[len-2] = 0;
1559 }
1560 value = value2;
1561 }
1562 if (*retValue == NULL)
1563 if (value == NULL) {
1564 if (! list)
1565 *retValue = xmlStrdup(BAD_CAST "");
1566 } else
1567 *retValue = xmlStrdup(value);
1568 else if (value != NULL) {
1569 /* List. */
1570 *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
1571 *retValue = xmlStrcat((xmlChar *) *retValue, value);
1572 }
1573 FREE_AND_NULL(value2)
1574 val = xmlSchemaValueGetNext(val);
1575 } while (val != NULL);
1576
1577 return (0);
1578internal_error:
1579 if (*retValue != NULL)
1580 xmlFree((xmlChar *) (*retValue));
1581 if (value2 != NULL)
1582 xmlFree((xmlChar *) value2);
1583 return (-1);
1584}
1585
1586static int
1587xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
1588 xmlSchemaWhitespaceValueType ws,
1589 xmlChar **retValue)
1590{
1591 return xmlSchemaGetCanonValueWhtspExt_1(val, ws, retValue, 0);
1592}
1593
1594static int
1595xmlSchemaGetCanonValueHash(xmlSchemaValPtr val,
1596 xmlChar **retValue)
1597{
1598 return xmlSchemaGetCanonValueWhtspExt_1(val, XML_SCHEMA_WHITESPACE_COLLAPSE,
1599 retValue, 1);
1600}
1601
1628static xmlChar*
1629xmlSchemaFormatItemForReport(xmlChar **buf,
1630 const xmlChar *itemDes,
1631 xmlSchemaBasicItemPtr item,
1632 xmlNodePtr itemNode)
1633{
1634 xmlChar *str = NULL;
1635 int named = 1;
1636
1637 if (*buf != NULL) {
1638 xmlFree(*buf);
1639 *buf = NULL;
1640 }
1641
1642 if (itemDes != NULL) {
1643 *buf = xmlStrdup(itemDes);
1644 } else if (item != NULL) {
1645 switch (item->type) {
1646 case XML_SCHEMA_TYPE_BASIC: {
1647 xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1648
1649 if (WXS_IS_ATOMIC(type))
1650 *buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
1651 else if (WXS_IS_LIST(type))
1652 *buf = xmlStrdup(BAD_CAST "list type 'xs:");
1653 else if (WXS_IS_UNION(type))
1654 *buf = xmlStrdup(BAD_CAST "union type 'xs:");
1655 else
1656 *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
1657 *buf = xmlStrcat(*buf, type->name);
1658 *buf = xmlStrcat(*buf, BAD_CAST "'");
1659 }
1660 break;
1661 case XML_SCHEMA_TYPE_SIMPLE: {
1662 xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1663
1664 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1665 *buf = xmlStrdup(BAD_CAST"");
1666 } else {
1667 *buf = xmlStrdup(BAD_CAST "local ");
1668 }
1669 if (WXS_IS_ATOMIC(type))
1670 *buf = xmlStrcat(*buf, BAD_CAST "atomic type");
1671 else if (WXS_IS_LIST(type))
1672 *buf = xmlStrcat(*buf, BAD_CAST "list type");
1673 else if (WXS_IS_UNION(type))
1674 *buf = xmlStrcat(*buf, BAD_CAST "union type");
1675 else
1676 *buf = xmlStrcat(*buf, BAD_CAST "simple type");
1677 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1678 *buf = xmlStrcat(*buf, BAD_CAST " '");
1679 *buf = xmlStrcat(*buf, type->name);
1680 *buf = xmlStrcat(*buf, BAD_CAST "'");
1681 }
1682 }
1683 break;
1684 case XML_SCHEMA_TYPE_COMPLEX: {
1685 xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1686
1687 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
1688 *buf = xmlStrdup(BAD_CAST "");
1689 else
1690 *buf = xmlStrdup(BAD_CAST "local ");
1691 *buf = xmlStrcat(*buf, BAD_CAST "complex type");
1692 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1693 *buf = xmlStrcat(*buf, BAD_CAST " '");
1694 *buf = xmlStrcat(*buf, type->name);
1695 *buf = xmlStrcat(*buf, BAD_CAST "'");
1696 }
1697 }
1698 break;
1699 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
1700 xmlSchemaAttributeUsePtr ause;
1701
1702 ause = WXS_ATTR_USE_CAST item;
1703 *buf = xmlStrdup(BAD_CAST "attribute use ");
1704 if (WXS_ATTRUSE_DECL(ause) != NULL) {
1705 *buf = xmlStrcat(*buf, BAD_CAST "'");
1706 *buf = xmlStrcat(*buf,
1707 xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
1708 FREE_AND_NULL(str)
1709 *buf = xmlStrcat(*buf, BAD_CAST "'");
1710 } else {
1711 *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
1712 }
1713 }
1714 break;
1715 case XML_SCHEMA_TYPE_ATTRIBUTE: {
1716 xmlSchemaAttributePtr attr;
1717
1718 attr = (xmlSchemaAttributePtr) item;
1719 *buf = xmlStrdup(BAD_CAST "attribute decl.");
1720 *buf = xmlStrcat(*buf, BAD_CAST " '");
1721 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1722 attr->targetNamespace, attr->name));
1723 FREE_AND_NULL(str)
1724 *buf = xmlStrcat(*buf, BAD_CAST "'");
1725 }
1726 break;
1727 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1728 xmlSchemaGetComponentDesignation(buf, item);
1729 break;
1730 case XML_SCHEMA_TYPE_ELEMENT: {
1731 xmlSchemaElementPtr elem;
1732
1733 elem = (xmlSchemaElementPtr) item;
1734 *buf = xmlStrdup(BAD_CAST "element decl.");
1735 *buf = xmlStrcat(*buf, BAD_CAST " '");
1736 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1737 elem->targetNamespace, elem->name));
1738 *buf = xmlStrcat(*buf, BAD_CAST "'");
1739 }
1740 break;
1741 case XML_SCHEMA_TYPE_IDC_UNIQUE:
1742 case XML_SCHEMA_TYPE_IDC_KEY:
1743 case XML_SCHEMA_TYPE_IDC_KEYREF:
1744 if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
1745 *buf = xmlStrdup(BAD_CAST "unique '");
1746 else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
1747 *buf = xmlStrdup(BAD_CAST "key '");
1748 else
1749 *buf = xmlStrdup(BAD_CAST "keyRef '");
1750 *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
1751 *buf = xmlStrcat(*buf, BAD_CAST "'");
1752 break;
1753 case XML_SCHEMA_TYPE_ANY:
1754 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1755 *buf = xmlStrdup(xmlSchemaWildcardPCToString(
1756 ((xmlSchemaWildcardPtr) item)->processContents));
1757 *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
1758 break;
1759 case XML_SCHEMA_FACET_MININCLUSIVE:
1760 case XML_SCHEMA_FACET_MINEXCLUSIVE:
1761 case XML_SCHEMA_FACET_MAXINCLUSIVE:
1762 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
1763 case XML_SCHEMA_FACET_TOTALDIGITS:
1764 case XML_SCHEMA_FACET_FRACTIONDIGITS:
1765 case XML_SCHEMA_FACET_PATTERN:
1766 case XML_SCHEMA_FACET_ENUMERATION:
1767 case XML_SCHEMA_FACET_WHITESPACE:
1768 case XML_SCHEMA_FACET_LENGTH:
1769 case XML_SCHEMA_FACET_MAXLENGTH:
1770 case XML_SCHEMA_FACET_MINLENGTH:
1771 *buf = xmlStrdup(BAD_CAST "facet '");
1772 *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
1773 *buf = xmlStrcat(*buf, BAD_CAST "'");
1774 break;
1775 case XML_SCHEMA_TYPE_GROUP: {
1776 *buf = xmlStrdup(BAD_CAST "model group def.");
1777 *buf = xmlStrcat(*buf, BAD_CAST " '");
1778 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1779 *buf = xmlStrcat(*buf, BAD_CAST "'");
1780 FREE_AND_NULL(str)
1781 }
1782 break;
1783 case XML_SCHEMA_TYPE_SEQUENCE:
1784 case XML_SCHEMA_TYPE_CHOICE:
1785 case XML_SCHEMA_TYPE_ALL:
1786 case XML_SCHEMA_TYPE_PARTICLE:
1787 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1788 break;
1789 case XML_SCHEMA_TYPE_NOTATION: {
1790 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1791 *buf = xmlStrcat(*buf, BAD_CAST " '");
1792 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1793 *buf = xmlStrcat(*buf, BAD_CAST "'");
1794 FREE_AND_NULL(str);
1795 }
1796 /* Falls through. */
1797 default:
1798 named = 0;
1799 }
1800 } else
1801 named = 0;
1802
1803 if ((named == 0) && (itemNode != NULL)) {
1805
1806 if (itemNode->type == XML_ATTRIBUTE_NODE)
1807 elem = itemNode->parent;
1808 else
1809 elem = itemNode;
1810 *buf = xmlStrdup(BAD_CAST "Element '");
1811 if (elem->ns != NULL) {
1812 *buf = xmlStrcat(*buf,
1813 xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
1814 FREE_AND_NULL(str)
1815 } else
1816 *buf = xmlStrcat(*buf, elem->name);
1817 *buf = xmlStrcat(*buf, BAD_CAST "'");
1818
1819 }
1820 if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
1821 *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
1822 if (itemNode->ns != NULL) {
1823 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1824 itemNode->ns->href, itemNode->name));
1825 FREE_AND_NULL(str)
1826 } else
1827 *buf = xmlStrcat(*buf, itemNode->name);
1828 *buf = xmlStrcat(*buf, BAD_CAST "'");
1829 }
1830 FREE_AND_NULL(str)
1831
1832 return (xmlEscapeFormatString(buf));
1833}
1834
1844static const xmlChar *
1845xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
1846 xmlChar **buf, xmlSchemaTypePtr type)
1847{
1848 xmlSchemaFacetPtr facet;
1849 xmlSchemaWhitespaceValueType ws;
1850 xmlChar *value = NULL;
1851 int res, found = 0;
1852
1853 if (*buf != NULL)
1854 xmlFree(*buf);
1855 *buf = NULL;
1856
1857 do {
1858 /*
1859 * Use the whitespace type of the base type.
1860 */
1861 ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
1862 for (facet = type->facets; facet != NULL; facet = facet->next) {
1863 if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
1864 continue;
1865 found = 1;
1866 res = xmlSchemaGetCanonValueWhtspExt(facet->val,
1867 ws, &value);
1868 if (res == -1) {
1869 xmlSchemaInternalErr(actxt,
1870 "xmlSchemaFormatFacetEnumSet",
1871 "compute the canonical lexical representation");
1872 if (*buf != NULL)
1873 xmlFree(*buf);
1874 *buf = NULL;
1875 return (NULL);
1876 }
1877 if (*buf == NULL)
1878 *buf = xmlStrdup(BAD_CAST "'");
1879 else
1880 *buf = xmlStrcat(*buf, BAD_CAST ", '");
1882 *buf = xmlStrcat(*buf, BAD_CAST "'");
1883 if (value != NULL) {
1884 xmlFree((xmlChar *)value);
1885 value = NULL;
1886 }
1887 }
1888 /*
1889 * The enumeration facet of a type restricts the enumeration
1890 * facet of the ancestor type; i.e., such restricted enumerations
1891 * do not belong to the set of the given type. Thus we break
1892 * on the first found enumeration.
1893 */
1894 if (found)
1895 break;
1896 type = type->baseType;
1897 } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
1898
1899 return ((const xmlChar *) *buf);
1900}
1901
1902/************************************************************************
1903 * *
1904 * Error functions *
1905 * *
1906 ************************************************************************/
1907
1908#if 0
1909static void
1910xmlSchemaErrMemory(const char *msg)
1911{
1912 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
1913 msg);
1914}
1915#endif
1916
1917static void
1918xmlSchemaPSimpleErr(const char *msg)
1919{
1920 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
1921 msg);
1922}
1923
1931static void
1932xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
1933 const char *extra, xmlNodePtr node)
1934{
1935 if (ctxt != NULL)
1936 ctxt->nberrors++;
1937 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
1938 extra);
1939}
1940
1952static void LIBXML_ATTR_FORMAT(4,0)
1953xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
1954 const char *msg, const xmlChar * str1, const xmlChar * str2)
1955{
1956 xmlGenericErrorFunc channel = NULL;
1957 xmlStructuredErrorFunc schannel = NULL;
1958 void *data = NULL;
1959
1960 if (ctxt != NULL) {
1961 ctxt->nberrors++;
1962 ctxt->err = error;
1963 channel = ctxt->error;
1964 data = ctxt->errCtxt;
1965 schannel = ctxt->serror;
1966 }
1967 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
1969 (const char *) str1, (const char *) str2, NULL, 0, 0,
1970 msg, str1, str2);
1971}
1972
1985static void LIBXML_ATTR_FORMAT(5,0)
1986xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
1987 xmlNodePtr child, int error,
1988 const char *msg, const xmlChar * str1, const xmlChar * str2)
1989{
1990 if (child != NULL)
1991 xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
1992 else
1993 xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
1994}
1995
1996
2014static void LIBXML_ATTR_FORMAT(7,0)
2015xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
2016 const xmlChar * strData1, const xmlChar * strData2,
2017 const xmlChar * strData3, const char *msg, const xmlChar * str1,
2018 const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
2019 const xmlChar * str5)
2020{
2021
2022 xmlGenericErrorFunc channel = NULL;
2023 xmlStructuredErrorFunc schannel = NULL;
2024 void *data = NULL;
2025
2026 if (ctxt != NULL) {
2027 ctxt->nberrors++;
2028 ctxt->err = error;
2029 channel = ctxt->error;
2030 data = ctxt->errCtxt;
2031 schannel = ctxt->serror;
2032 }
2033 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
2035 (const char *) strData1, (const char *) strData2,
2036 (const char *) strData3, 0, 0, msg, str1, str2,
2037 str3, str4, str5);
2038}
2039
2040/************************************************************************
2041 * *
2042 * Allround error functions *
2043 * *
2044 ************************************************************************/
2045
2053static void
2054xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
2055 const char *extra, xmlNodePtr node)
2056{
2057 if (ctxt != NULL) {
2058 ctxt->nberrors++;
2059 ctxt->err = XML_SCHEMAV_INTERNAL;
2060 }
2061 __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
2062 extra);
2063}
2064
2065static void LIBXML_ATTR_FORMAT(2,0)
2066xmlSchemaPSimpleInternalErr(xmlNodePtr node,
2067 const char *msg, const xmlChar *str)
2068{
2069 __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
2070 msg, (const char *) str);
2071}
2072
2073#define WXS_ERROR_TYPE_ERROR 1
2074#define WXS_ERROR_TYPE_WARNING 2
2090static void LIBXML_ATTR_FORMAT(6,0)
2091xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
2092 xmlErrorLevel errorLevel,
2093 int error, xmlNodePtr node, int line, const char *msg,
2094 const xmlChar *str1, const xmlChar *str2,
2095 const xmlChar *str3, const xmlChar *str4)
2096{
2097 xmlStructuredErrorFunc schannel = NULL;
2098 xmlGenericErrorFunc channel = NULL;
2099 void *data = NULL;
2100
2101 if (ctxt != NULL) {
2102 if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2103 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
2104 const char *file = NULL;
2105 int col = 0;
2106 if (errorLevel != XML_ERR_WARNING) {
2107 vctxt->nberrors++;
2108 vctxt->err = error;
2109 channel = vctxt->error;
2110 } else {
2111 channel = vctxt->warning;
2112 }
2113 schannel = vctxt->serror;
2114 data = vctxt->errCtxt;
2115
2116 /*
2117 * Error node. If we specify a line number, then
2118 * do not channel any node to the error function.
2119 */
2120 if (line == 0) {
2121 if ((node == NULL) &&
2122 (vctxt->depth >= 0) &&
2123 (vctxt->inode != NULL)) {
2124 node = vctxt->inode->node;
2125 }
2126 /*
2127 * Get filename and line if no node-tree.
2128 */
2129 if ((node == NULL) &&
2130 (vctxt->parserCtxt != NULL) &&
2131 (vctxt->parserCtxt->input != NULL)) {
2132 file = vctxt->parserCtxt->input->filename;
2133 line = vctxt->parserCtxt->input->line;
2134 col = vctxt->parserCtxt->input->col;
2135 }
2136 } else {
2137 /*
2138 * Override the given node's (if any) position
2139 * and channel only the given line number.
2140 */
2141 node = NULL;
2142 /*
2143 * Get filename.
2144 */
2145 if (vctxt->doc != NULL)
2146 file = (const char *) vctxt->doc->URL;
2147 else if ((vctxt->parserCtxt != NULL) &&
2148 (vctxt->parserCtxt->input != NULL))
2149 file = vctxt->parserCtxt->input->filename;
2150 }
2151 if (vctxt->locFunc != NULL) {
2152 if ((file == NULL) || (line == 0)) {
2153 unsigned long l;
2154 const char *f;
2155 vctxt->locFunc(vctxt->locCtxt, &f, &l);
2156 if (file == NULL)
2157 file = f;
2158 if (line == 0)
2159 line = (int) l;
2160 }
2161 }
2162 if ((file == NULL) && (vctxt->filename != NULL))
2163 file = vctxt->filename;
2164
2165 __xmlRaiseError(schannel, channel, data, ctxt,
2167 error, errorLevel, file, line,
2168 (const char *) str1, (const char *) str2,
2169 (const char *) str3, 0, col, msg, str1, str2, str3, str4);
2170
2171 } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
2172 xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
2173 if (errorLevel != XML_ERR_WARNING) {
2174 pctxt->nberrors++;
2175 pctxt->err = error;
2176 channel = pctxt->error;
2177 } else {
2178 channel = pctxt->warning;
2179 }
2180 schannel = pctxt->serror;
2181 data = pctxt->errCtxt;
2182 __xmlRaiseError(schannel, channel, data, ctxt,
2184 errorLevel, NULL, 0,
2185 (const char *) str1, (const char *) str2,
2186 (const char *) str3, 0, 0, msg, str1, str2, str3, str4);
2187 } else {
2188 TODO
2189 }
2190 }
2191}
2192
2205static void LIBXML_ATTR_FORMAT(4,0)
2206xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
2207 int error, xmlNodePtr node, const char *msg,
2208 const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
2209{
2210 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2211 msg, str1, str2, str3, NULL);
2212}
2213
2214static void LIBXML_ATTR_FORMAT(4,0)
2215xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
2216 int error, xmlNodePtr node, const char *msg,
2217 const xmlChar *str1, const xmlChar *str2,
2218 const xmlChar *str3, const xmlChar *str4)
2219{
2220 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2221 msg, str1, str2, str3, str4);
2222}
2223
2224static void LIBXML_ATTR_FORMAT(4,0)
2225xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
2226 int error, xmlNodePtr node, const char *msg,
2227 const xmlChar *str1, const xmlChar *str2)
2228{
2229 xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
2230}
2231
2232static xmlChar *
2233xmlSchemaFormatNodeForError(xmlChar ** msg,
2234 xmlSchemaAbstractCtxtPtr actxt,
2236{
2237 xmlChar *str = NULL;
2238
2239 *msg = NULL;
2240 if ((node != NULL) &&
2241 (node->type != XML_ELEMENT_NODE) &&
2242 (node->type != XML_ATTRIBUTE_NODE))
2243 {
2244 /*
2245 * Don't try to format other nodes than element and
2246 * attribute nodes.
2247 * Play safe and return an empty string.
2248 */
2249 *msg = xmlStrdup(BAD_CAST "");
2250 return(*msg);
2251 }
2252 if (node != NULL) {
2253 /*
2254 * Work on tree nodes.
2255 */
2256 if (node->type == XML_ATTRIBUTE_NODE) {
2257 xmlNodePtr elem = node->parent;
2258
2259 *msg = xmlStrdup(BAD_CAST "Element '");
2260 if (elem->ns != NULL)
2261 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2262 elem->ns->href, elem->name));
2263 else
2264 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2265 NULL, elem->name));
2266 FREE_AND_NULL(str);
2267 *msg = xmlStrcat(*msg, BAD_CAST "', ");
2268 *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2269 } else {
2270 *msg = xmlStrdup(BAD_CAST "Element '");
2271 }
2272 if (node->ns != NULL)
2273 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2274 node->ns->href, node->name));
2275 else
2276 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2277 NULL, node->name));
2278 FREE_AND_NULL(str);
2279 *msg = xmlStrcat(*msg, BAD_CAST "': ");
2280 } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2281 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
2282 /*
2283 * Work on node infos.
2284 */
2285 if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
2286 xmlSchemaNodeInfoPtr ielem =
2287 vctxt->elemInfos[vctxt->depth];
2288
2289 *msg = xmlStrdup(BAD_CAST "Element '");
2290 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2291 ielem->nsName, ielem->localName));
2292 FREE_AND_NULL(str);
2293 *msg = xmlStrcat(*msg, BAD_CAST "', ");
2294 *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2295 } else {
2296 *msg = xmlStrdup(BAD_CAST "Element '");
2297 }
2298 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2299 vctxt->inode->nsName, vctxt->inode->localName));
2300 FREE_AND_NULL(str);
2301 *msg = xmlStrcat(*msg, BAD_CAST "': ");
2302 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
2303 /*
2304 * Hmm, no node while parsing?
2305 * Return an empty string, in case NULL will break something.
2306 */
2307 *msg = xmlStrdup(BAD_CAST "");
2308 } else {
2309 TODO
2310 return (NULL);
2311 }
2312
2313 /*
2314 * xmlSchemaFormatItemForReport() also returns an escaped format
2315 * string, so do this before calling it below (in the future).
2316 */
2318
2319 /*
2320 * VAL TODO: The output of the given schema component is currently
2321 * disabled.
2322 */
2323#if 0
2324 if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
2325 *msg = xmlStrcat(*msg, BAD_CAST " [");
2326 *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
2327 NULL, type, NULL, 0));
2328 FREE_AND_NULL(str)
2329 *msg = xmlStrcat(*msg, BAD_CAST "]");
2330 }
2331#endif
2332 return (*msg);
2333}
2334
2335static void LIBXML_ATTR_FORMAT(3,0)
2336xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
2337 const char *funcName,
2338 const char *message,
2339 const xmlChar *str1,
2340 const xmlChar *str2)
2341{
2342 xmlChar *msg = NULL;
2343
2344 if (actxt == NULL)
2345 return;
2346 msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
2348 msg = xmlStrcat(msg, BAD_CAST ".\n");
2349
2350 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
2351 xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
2352 (const char *) msg, (const xmlChar *) funcName, str1, str2);
2353 else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
2354 xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
2355 (const char *) msg, (const xmlChar *) funcName, str1, str2);
2356
2357 FREE_AND_NULL(msg)
2358}
2359
2360static void LIBXML_ATTR_FORMAT(3,0)
2361xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
2362 const char *funcName,
2363 const char *message)
2364{
2365 xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
2366}
2367
2368#if 0
2369static void LIBXML_ATTR_FORMAT(3,0)
2370xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
2371 const char *funcName,
2372 const char *message,
2373 const xmlChar *str1,
2374 const xmlChar *str2)
2375{
2376 xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
2377 str1, str2);
2378}
2379#endif
2380
2381static void LIBXML_ATTR_FORMAT(5,0)
2382xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
2385 xmlSchemaBasicItemPtr item,
2386 const char *message,
2387 const xmlChar *str1, const xmlChar *str2,
2388 const xmlChar *str3, const xmlChar *str4)
2389{
2390 xmlChar *msg = NULL;
2391
2392 if ((node == NULL) && (item != NULL) &&
2393 (actxt->type == XML_SCHEMA_CTXT_PARSER)) {
2394 node = WXS_ITEM_NODE(item);
2395 xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
2396 msg = xmlStrcat(msg, BAD_CAST ": ");
2397 } else
2398 xmlSchemaFormatNodeForError(&msg, actxt, node);
2399 msg = xmlStrcat(msg, (const xmlChar *) message);
2400 msg = xmlStrcat(msg, BAD_CAST ".\n");
2401 xmlSchemaErr4(actxt, error, node,
2402 (const char *) msg, str1, str2, str3, str4);
2403 FREE_AND_NULL(msg)
2404}
2405
2406static void LIBXML_ATTR_FORMAT(5,0)
2407xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
2410 xmlSchemaBasicItemPtr item,
2411 const char *message,
2412 const xmlChar *str1,
2413 const xmlChar *str2)
2414{
2415 xmlSchemaCustomErr4(actxt, error, node, item,
2416 message, str1, str2, NULL, NULL);
2417}
2418
2419
2420
2421static void LIBXML_ATTR_FORMAT(5,0)
2422xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
2425 xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2426 const char *message,
2427 const xmlChar *str1,
2428 const xmlChar *str2,
2429 const xmlChar *str3)
2430{
2431 xmlChar *msg = NULL;
2432
2433 xmlSchemaFormatNodeForError(&msg, actxt, node);
2434 msg = xmlStrcat(msg, (const xmlChar *) message);
2435 msg = xmlStrcat(msg, BAD_CAST ".\n");
2436
2437 /* URGENT TODO: Set the error code to something sane. */
2438 xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
2439 (const char *) msg, str1, str2, str3, NULL);
2440
2441 FREE_AND_NULL(msg)
2442}
2443
2444
2445
2446static void LIBXML_ATTR_FORMAT(5,0)
2447xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
2449 xmlSchemaPSVIIDCNodePtr idcNode,
2450 xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2451 const char *message,
2452 const xmlChar *str1,
2453 const xmlChar *str2)
2454{
2455 xmlChar *msg = NULL, *qname = NULL;
2456
2457 msg = xmlStrdup(BAD_CAST "Element '%s': ");
2458 msg = xmlStrcat(msg, (const xmlChar *) message);
2459 msg = xmlStrcat(msg, BAD_CAST ".\n");
2460 xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
2461 error, NULL, idcNode->nodeLine, (const char *) msg,
2462 xmlSchemaFormatQName(&qname,
2463 vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
2464 vctxt->nodeQNames->items[idcNode->nodeQNameID]),
2465 str1, str2, NULL);
2466 FREE_AND_NULL(qname);
2467 FREE_AND_NULL(msg);
2468}
2469
2470static int
2471xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
2473{
2474 if (node != NULL)
2475 return (node->type);
2476 if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
2477 (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
2478 return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
2479 return (-1);
2480}
2481
2482static int
2483xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
2484{
2485 switch (item->type) {
2486 case XML_SCHEMA_TYPE_COMPLEX:
2487 case XML_SCHEMA_TYPE_SIMPLE:
2488 if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
2489 return(1);
2490 break;
2491 case XML_SCHEMA_TYPE_GROUP:
2492 return (1);
2493 case XML_SCHEMA_TYPE_ELEMENT:
2494 if ( ((xmlSchemaElementPtr) item)->flags &
2495 XML_SCHEMAS_ELEM_GLOBAL)
2496 return(1);
2497 break;
2498 case XML_SCHEMA_TYPE_ATTRIBUTE:
2499 if ( ((xmlSchemaAttributePtr) item)->flags &
2500 XML_SCHEMAS_ATTR_GLOBAL)
2501 return(1);
2502 break;
2503 /* Note that attribute groups are always global. */
2504 default:
2505 return(1);
2506 }
2507 return (0);
2508}
2509
2510static void
2511xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2514 const xmlChar *value,
2515 xmlSchemaTypePtr type,
2516 int displayValue)
2517{
2518 xmlChar *msg = NULL;
2519
2520 xmlSchemaFormatNodeForError(&msg, actxt, node);
2521
2522 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2524 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
2525 else
2526 msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
2527 "value of ");
2528
2529 if (! xmlSchemaIsGlobalItem(type))
2530 msg = xmlStrcat(msg, BAD_CAST "the local ");
2531 else
2532 msg = xmlStrcat(msg, BAD_CAST "the ");
2533
2534 if (WXS_IS_ATOMIC(type))
2535 msg = xmlStrcat(msg, BAD_CAST "atomic type");
2536 else if (WXS_IS_LIST(type))
2537 msg = xmlStrcat(msg, BAD_CAST "list type");
2538 else if (WXS_IS_UNION(type))
2539 msg = xmlStrcat(msg, BAD_CAST "union type");
2540
2541 if (xmlSchemaIsGlobalItem(type)) {
2542 xmlChar *str = NULL;
2543 msg = xmlStrcat(msg, BAD_CAST " '");
2544 if (type->builtInType != 0) {
2545 msg = xmlStrcat(msg, BAD_CAST "xs:");
2546 str = xmlStrdup(type->name);
2547 } else {
2548 const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
2549 if (!str)
2550 str = xmlStrdup(qName);
2551 }
2553 msg = xmlStrcat(msg, BAD_CAST "'");
2554 FREE_AND_NULL(str);
2555 }
2556 msg = xmlStrcat(msg, BAD_CAST ".\n");
2557 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2559 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2560 else
2561 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2562 FREE_AND_NULL(msg)
2563}
2564
2565static const xmlChar *
2566xmlSchemaFormatErrorNodeQName(xmlChar ** str,
2567 xmlSchemaNodeInfoPtr ni,
2569{
2570 if (node != NULL) {
2571 if (node->ns != NULL)
2572 return (xmlSchemaFormatQName(str, node->ns->href, node->name));
2573 else
2574 return (xmlSchemaFormatQName(str, NULL, node->name));
2575 } else if (ni != NULL)
2576 return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
2577 return (NULL);
2578}
2579
2580static void
2581xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
2583 xmlSchemaAttrInfoPtr ni,
2585{
2586 xmlChar *msg = NULL, *str = NULL;
2587
2588 xmlSchemaFormatNodeForError(&msg, actxt, node);
2589 msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
2590 xmlSchemaErr(actxt, error, node, (const char *) msg,
2591 xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
2592 NULL);
2593 FREE_AND_NULL(str)
2594 FREE_AND_NULL(msg)
2595}
2596
2597static void LIBXML_ATTR_FORMAT(5,0)
2598xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2601 xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2602 const char *message,
2603 int nbval,
2604 int nbneg,
2605 xmlChar **values)
2606{
2607 xmlChar *str = NULL, *msg = NULL;
2608 xmlChar *localName, *nsName;
2609 const xmlChar *cur, *end;
2610 int i;
2611
2612 xmlSchemaFormatNodeForError(&msg, actxt, node);
2613 msg = xmlStrcat(msg, (const xmlChar *) message);
2614 msg = xmlStrcat(msg, BAD_CAST ".");
2615 /*
2616 * Note that is does not make sense to report that we have a
2617 * wildcard here, since the wildcard might be unfolded into
2618 * multiple transitions.
2619 */
2620 if (nbval + nbneg > 0) {
2621 if (nbval + nbneg > 1) {
2622 str = xmlStrdup(BAD_CAST " Expected is one of ( ");
2623 } else
2624 str = xmlStrdup(BAD_CAST " Expected is ( ");
2625 nsName = NULL;
2626
2627 for (i = 0; i < nbval + nbneg; i++) {
2628 cur = values[i];
2629 if (cur == NULL)
2630 continue;
2631 if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
2632 (cur[3] == ' ')) {
2633 cur += 4;
2634 str = xmlStrcat(str, BAD_CAST "##other");
2635 }
2636 /*
2637 * Get the local name.
2638 */
2639 localName = NULL;
2640
2641 end = cur;
2642 if (*end == '*') {
2643 localName = xmlStrdup(BAD_CAST "*");
2644 end++;
2645 } else {
2646 while ((*end != 0) && (*end != '|'))
2647 end++;
2648 localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
2649 }
2650 if (*end != 0) {
2651 end++;
2652 /*
2653 * Skip "*|*" if they come with negated expressions, since
2654 * they represent the same negated wildcard.
2655 */
2656 if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
2657 /*
2658 * Get the namespace name.
2659 */
2660 cur = end;
2661 if (*end == '*') {
2662 nsName = xmlStrdup(BAD_CAST "{*}");
2663 } else {
2664 while (*end != 0)
2665 end++;
2666
2667 if (i >= nbval)
2668 nsName = xmlStrdup(BAD_CAST "{##other:");
2669 else
2670 nsName = xmlStrdup(BAD_CAST "{");
2671
2672 nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
2673 nsName = xmlStrcat(nsName, BAD_CAST "}");
2674 }
2675 str = xmlStrcat(str, BAD_CAST nsName);
2676 FREE_AND_NULL(nsName)
2677 } else {
2678 FREE_AND_NULL(localName);
2679 continue;
2680 }
2681 }
2682 str = xmlStrcat(str, BAD_CAST localName);
2683 FREE_AND_NULL(localName);
2684
2685 if (i < nbval + nbneg -1)
2686 str = xmlStrcat(str, BAD_CAST ", ");
2687 }
2688 str = xmlStrcat(str, BAD_CAST " ).\n");
2690 FREE_AND_NULL(str)
2691 } else
2692 msg = xmlStrcat(msg, BAD_CAST "\n");
2693 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2694 xmlFree(msg);
2695}
2696
2697static void LIBXML_ATTR_FORMAT(8,0)
2698xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
2702 unsigned long length,
2703 xmlSchemaTypePtr type,
2704 xmlSchemaFacetPtr facet,
2705 const char *message,
2706 const xmlChar *str1,
2707 const xmlChar *str2)
2708{
2709 xmlChar *str = NULL, *msg = NULL;
2710 xmlSchemaTypeType facetType;
2711 int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
2712
2713 xmlSchemaFormatNodeForError(&msg, actxt, node);
2715 facetType = XML_SCHEMA_FACET_ENUMERATION;
2716 /*
2717 * If enumerations are validated, one must not expect the
2718 * facet to be given.
2719 */
2720 } else
2721 facetType = facet->type;
2722 msg = xmlStrcat(msg, BAD_CAST "[");
2723 msg = xmlStrcat(msg, BAD_CAST "facet '");
2724 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
2725 msg = xmlStrcat(msg, BAD_CAST "'] ");
2726 if (message == NULL) {
2727 /*
2728 * Use a default message.
2729 */
2730 if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
2731 (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
2732 (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
2733
2734 char len[25], actLen[25];
2735
2736 /* FIXME, TODO: What is the max expected string length of the
2737 * this value?
2738 */
2739 if (nodeType == XML_ATTRIBUTE_NODE)
2740 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
2741 else
2742 msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
2743
2744 snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
2745 snprintf(actLen, 24, "%lu", length);
2746
2747 if (facetType == XML_SCHEMA_FACET_LENGTH)
2748 msg = xmlStrcat(msg,
2749 BAD_CAST "this differs from the allowed length of '%s'.\n");
2750 else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
2751 msg = xmlStrcat(msg,
2752 BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
2753 else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
2754 msg = xmlStrcat(msg,
2755 BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
2756
2757 if (nodeType == XML_ATTRIBUTE_NODE)
2758 xmlSchemaErr3(actxt, error, node, (const char *) msg,
2759 value, (const xmlChar *) actLen, (const xmlChar *) len);
2760 else
2761 xmlSchemaErr(actxt, error, node, (const char *) msg,
2762 (const xmlChar *) actLen, (const xmlChar *) len);
2763
2764 } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
2765 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
2766 "of the set {%s}.\n");
2767 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2768 xmlSchemaFormatFacetEnumSet(actxt, &str, type));
2769 } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
2770 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
2771 "by the pattern '%s'.\n");
2772 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2773 facet->value);
2774 } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
2775 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
2776 "minimum value allowed ('%s').\n");
2777 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2778 facet->value);
2779 } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
2780 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
2781 "maximum value allowed ('%s').\n");
2782 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2783 facet->value);
2784 } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
2785 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
2786 "'%s'.\n");
2787 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2788 facet->value);
2789 } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
2790 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
2791 "'%s'.\n");
2792 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2793 facet->value);
2794 } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
2795 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
2796 "digits than are allowed ('%s').\n");
2797 xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2798 facet->value);
2799 } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
2800 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
2801 "digits than are allowed ('%s').\n");
2802 xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2803 facet->value);
2804 } else if (nodeType == XML_ATTRIBUTE_NODE) {
2805 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
2806 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2807 } else {
2808 msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
2809 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2810 }
2811 } else {
2812 msg = xmlStrcat(msg, (const xmlChar *) message);
2813 msg = xmlStrcat(msg, BAD_CAST ".\n");
2814 xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
2815 }
2816 FREE_AND_NULL(str)
2817 xmlFree(msg);
2818}
2819
2820#define VERROR(err, type, msg) \
2821 xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
2822
2823#define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
2824
2825#define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
2826#define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
2827
2828#define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
2829
2830
2841static void
2842xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
2844 xmlSchemaBasicItemPtr ownerItem,
2845 xmlNodePtr ownerElem,
2846 const char *name,
2847 const char *message)
2848{
2849 xmlChar *des = NULL;
2850
2851 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2852
2853 if (message != NULL)
2854 xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
2855 else
2856 xmlSchemaPErr(ctxt, ownerElem, error,
2857 "%s: The attribute '%s' is required but missing.\n",
2859 FREE_AND_NULL(des);
2860}
2861
2862
2877static void
2878xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
2880 xmlSchemaBasicItemPtr ownerItem,
2881 xmlNodePtr ownerElem,
2882 const char *name,
2883 const xmlChar *refName,
2884 const xmlChar *refURI,
2885 xmlSchemaTypeType refType,
2886 const char *refTypeStr)
2887{
2888 xmlChar *des = NULL, *strA = NULL;
2889
2890 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2891 if (refTypeStr == NULL)
2892 refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
2893 xmlSchemaPErrExt(ctxt, ownerElem, error,
2894 NULL, NULL, NULL,
2895 "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
2896 "%s.\n", BAD_CAST des, BAD_CAST name,
2897 xmlSchemaFormatQName(&strA, refURI, refName),
2898 BAD_CAST refTypeStr, NULL);
2899 FREE_AND_NULL(des)
2900 FREE_AND_NULL(strA)
2901}
2902
2913static void
2914xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
2916 xmlChar **ownerDes,
2917 xmlSchemaBasicItemPtr ownerItem,
2919 const char *msg)
2920{
2921 xmlChar *des = NULL;
2922
2923 if (ownerDes == NULL)
2924 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
2925 else if (*ownerDes == NULL) {
2926 xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
2927 des = *ownerDes;
2928 } else
2929 des = *ownerDes;
2930 if (attr == NULL) {
2931 xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
2932 "%s, attribute '%s': %s.\n",
2933 BAD_CAST des, (const xmlChar *) "Unknown",
2934 (const xmlChar *) msg, NULL, NULL);
2935 } else {
2936 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
2937 "%s, attribute '%s': %s.\n",
2938 BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
2939 }
2940 if (ownerDes == NULL)
2941 FREE_AND_NULL(des);
2942}
2943
2953static void
2954xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
2956 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
2958{
2959 xmlChar *strA = NULL, *strB = NULL;
2960
2961 xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
2962 xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
2963 "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
2964 xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
2965 NULL, NULL);
2966 FREE_AND_NULL(strA);
2967 FREE_AND_NULL(strB);
2968}
2969
2984static void LIBXML_ATTR_FORMAT(5,0)
2985xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
2987 xmlSchemaBasicItemPtr item,
2988 xmlNodePtr itemElem,
2989 const char *message,
2990 const xmlChar *str1,
2991 const xmlChar *str2,
2992 const xmlChar *str3)
2993{
2994 xmlChar *des = NULL, *msg = NULL;
2995
2996 xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
2997 msg = xmlStrdup(BAD_CAST "%s: ");
2998 msg = xmlStrcat(msg, (const xmlChar *) message);
2999 msg = xmlStrcat(msg, BAD_CAST ".\n");
3000 if ((itemElem == NULL) && (item != NULL))
3001 itemElem = WXS_ITEM_NODE(item);
3002 xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
3003 (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
3004 FREE_AND_NULL(des);
3005 FREE_AND_NULL(msg);
3006}
3007
3020static void LIBXML_ATTR_FORMAT(5,0)
3021xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
3023 xmlSchemaBasicItemPtr item,
3024 xmlNodePtr itemElem,
3025 const char *message,
3026 const xmlChar *str1)
3027{
3028 xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
3029 str1, NULL, NULL);
3030}
3031
3045static void LIBXML_ATTR_FORMAT(6,0)
3046xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
3049 xmlSchemaBasicItemPtr ownerItem,
3050 const xmlSchemaAttributeUsePtr attruse,
3051 const char *message,
3052 const xmlChar *str1, const xmlChar *str2,
3053 const xmlChar *str3,const xmlChar *str4)
3054{
3055 xmlChar *str = NULL, *msg = NULL;
3056
3057 xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
3058 msg = xmlStrcat(msg, BAD_CAST ", ");
3059 msg = xmlStrcat(msg,
3060 BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
3061 WXS_BASIC_CAST attruse, NULL));
3062 FREE_AND_NULL(str);
3063 msg = xmlStrcat(msg, BAD_CAST ": ");
3064 msg = xmlStrcat(msg, (const xmlChar *) message);
3065 msg = xmlStrcat(msg, BAD_CAST ".\n");
3066 xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
3067 (const char *) msg, str1, str2, str3, str4);
3068 xmlFree(msg);
3069}
3070
3081static void
3082xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
3084 xmlSchemaTypePtr type,
3085 xmlSchemaTypePtr baseType,
3086 xmlSchemaFacetPtr facet)
3087{
3088 xmlChar *des = NULL, *strT = NULL;
3089
3090 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
3091 xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
3092 "%s: The facet '%s' is not allowed on types derived from the "
3093 "type %s.\n",
3094 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
3095 xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
3096 NULL, NULL);
3097 FREE_AND_NULL(des);
3098 FREE_AND_NULL(strT);
3099}
3100
3111static void
3112xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
3114 xmlSchemaTypePtr type,
3115 xmlSchemaFacetPtr facet)
3116{
3117 xmlChar *des = NULL;
3118
3119 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
3120 type->node);
3121 xmlSchemaPErr(ctxt, type->node, error,
3122 "%s: The facet '%s' is not allowed.\n",
3123 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
3124 FREE_AND_NULL(des);
3125}
3126
3137static void
3138xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
3140 xmlSchemaBasicItemPtr ownerItem,
3142 const char *name1,
3143 const char *name2)
3144{
3145 xmlChar *des = NULL;
3146
3147 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
3148 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
3149 "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
3151 FREE_AND_NULL(des);
3152}
3153
3166static void LIBXML_ATTR_FORMAT(8,0)
3167xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
3169 xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
3171 xmlSchemaTypePtr type,
3172 const char *expected,
3174 const char *message,
3175 const xmlChar *str1,
3176 const xmlChar *str2)
3177{
3178 xmlChar *msg = NULL;
3179
3180 xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
3181 if (message == NULL) {
3182 /*
3183 * Use default messages.
3184 */
3185 if (type != NULL) {
3186 if (node->type == XML_ATTRIBUTE_NODE)
3187 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
3188 else
3189 msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
3190 "valid value of ");
3191 if (! xmlSchemaIsGlobalItem(type))
3192 msg = xmlStrcat(msg, BAD_CAST "the local ");
3193 else
3194 msg = xmlStrcat(msg, BAD_CAST "the ");
3195
3196 if (WXS_IS_ATOMIC(type))
3197 msg = xmlStrcat(msg, BAD_CAST "atomic type");
3198 else if (WXS_IS_LIST(type))
3199 msg = xmlStrcat(msg, BAD_CAST "list type");
3200 else if (WXS_IS_UNION(type))
3201 msg = xmlStrcat(msg, BAD_CAST "union type");
3202
3203 if (xmlSchemaIsGlobalItem(type)) {
3204 xmlChar *str = NULL;
3205 msg = xmlStrcat(msg, BAD_CAST " '");
3206 if (type->builtInType != 0) {
3207 msg = xmlStrcat(msg, BAD_CAST "xs:");
3208 str = xmlStrdup(type->name);
3209 } else {
3210 const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
3211 if (!str)
3212 str = xmlStrdup(qName);
3213 }
3215 msg = xmlStrcat(msg, BAD_CAST "'.");
3216 FREE_AND_NULL(str);
3217 }
3218 } else {
3219 if (node->type == XML_ATTRIBUTE_NODE)
3220 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
3221 else
3222 msg = xmlStrcat(msg, BAD_CAST "The character content is not "
3223 "valid.");
3224 }
3225 if (expected) {
3226 xmlChar *expectedEscaped = xmlCharStrdup(expected);
3227 msg = xmlStrcat(msg, BAD_CAST " Expected is '");
3228 msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
3229 FREE_AND_NULL(expectedEscaped);
3230 msg = xmlStrcat(msg, BAD_CAST "'.\n");
3231 } else
3232 msg = xmlStrcat(msg, BAD_CAST "\n");
3233 if (node->type == XML_ATTRIBUTE_NODE)
3234 xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
3235 else
3236 xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
3237 } else {
3239 msg = xmlStrcat(msg, BAD_CAST ".\n");
3240 xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
3241 (const char*) msg, str1, str2, NULL, NULL, NULL);
3242 }
3243 /* Cleanup. */
3244 FREE_AND_NULL(msg)
3245}
3246
3259static void
3260xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
3262 xmlSchemaBasicItemPtr ownerItem,
3263 xmlNodePtr ownerElem,
3265 const char *message,
3266 const char *content)
3267{
3268 xmlChar *des = NULL;
3269
3270 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
3271 if (message != NULL)
3272 xmlSchemaPErr2(ctxt, ownerElem, child, error,
3273 "%s: %s.\n",
3275 else {
3276 if (content != NULL) {
3277 xmlSchemaPErr2(ctxt, ownerElem, child, error,
3278 "%s: The content is not valid. Expected is %s.\n",
3280 } else {
3281 xmlSchemaPErr2(ctxt, ownerElem, child, error,
3282 "%s: The content is not valid.\n",
3283 BAD_CAST des, NULL);
3284 }
3285 }
3286 FREE_AND_NULL(des)
3287}
3288
3289/************************************************************************
3290 * *
3291 * Streamable error functions *
3292 * *
3293 ************************************************************************/
3294
3295
3296
3297
3298/************************************************************************
3299 * *
3300 * Validation helper functions *
3301 * *
3302 ************************************************************************/
3303
3304
3305/************************************************************************
3306 * *
3307 * Allocation functions *
3308 * *
3309 ************************************************************************/
3310
3319static xmlSchemaPtr
3320xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
3321{
3322 xmlSchemaPtr ret;
3323
3324 ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
3325 if (ret == NULL) {
3326 xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
3327 return (NULL);
3328 }
3329 memset(ret, 0, sizeof(xmlSchema));
3330 ret->dict = ctxt->dict;
3331 xmlDictReference(ret->dict);
3332
3333 return (ret);
3334}
3335
3343xmlSchemaFacetPtr
3344xmlSchemaNewFacet(void)
3345{
3346 xmlSchemaFacetPtr ret;
3347
3348 ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
3349 if (ret == NULL) {
3350 return (NULL);
3351 }
3352 memset(ret, 0, sizeof(xmlSchemaFacet));
3353
3354 return (ret);
3355}
3356
3366static xmlSchemaAnnotPtr
3367xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
3368{
3369 xmlSchemaAnnotPtr ret;
3370
3371 ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
3372 if (ret == NULL) {
3373 xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
3374 return (NULL);
3375 }
3376 memset(ret, 0, sizeof(xmlSchemaAnnot));
3377 ret->content = node;
3378 return (ret);
3379}
3380
3381static xmlSchemaItemListPtr
3382xmlSchemaItemListCreate(void)
3383{
3384 xmlSchemaItemListPtr ret;
3385
3386 ret = xmlMalloc(sizeof(xmlSchemaItemList));
3387 if (ret == NULL) {
3388 xmlSchemaPErrMemory(NULL,
3389 "allocating an item list structure", NULL);
3390 return (NULL);
3391 }
3392 memset(ret, 0, sizeof(xmlSchemaItemList));
3393 return (ret);
3394}
3395
3396static void
3397xmlSchemaItemListClear(xmlSchemaItemListPtr list)
3398{
3399 if (list->items != NULL) {
3400 xmlFree(list->items);
3401 list->items = NULL;
3402 }
3403 list->nbItems = 0;
3404 list->sizeItems = 0;
3405}
3406
3407static int
3408xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
3409{
3410 if (list->items == NULL) {
3411 list->items = (void **) xmlMalloc(
3412 20 * sizeof(void *));
3413 if (list->items == NULL) {
3414 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3415 return(-1);
3416 }
3417 list->sizeItems = 20;
3418 } else if (list->sizeItems <= list->nbItems) {
3419 list->sizeItems *= 2;
3420 list->items = (void **) xmlRealloc(list->items,
3421 list->sizeItems * sizeof(void *));
3422 if (list->items == NULL) {
3423 xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3424 list->sizeItems = 0;
3425 return(-1);
3426 }
3427 }
3428 list->items[list->nbItems++] = item;
3429 return(0);
3430}
3431
3432static int
3433xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
3434 int initialSize,
3435 void *item)
3436{
3437 if (list->items == NULL) {
3438 if (initialSize <= 0)
3439 initialSize = 1;
3440 list->items = (void **) xmlMalloc(
3441 initialSize * sizeof(void *));
3442 if (list->items == NULL) {
3443 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3444 return(-1);
3445 }
3446 list->sizeItems = initialSize;
3447 } else if (list->sizeItems <= list->nbItems) {
3448 list->sizeItems *= 2;
3449 list->items = (void **) xmlRealloc(list->items,
3450 list->sizeItems * sizeof(void *));
3451 if (list->items == NULL) {
3452 xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3453 list->sizeItems = 0;
3454 return(-1);
3455 }
3456 }
3457 list->items[list->nbItems++] = item;
3458 return(0);
3459}
3460
3461static int
3462xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
3463{
3464 if (list->items == NULL) {
3465 list->items = (void **) xmlMalloc(
3466 20 * sizeof(void *));
3467 if (list->items == NULL) {
3468 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3469 return(-1);
3470 }
3471 list->sizeItems = 20;
3472 } else if (list->sizeItems <= list->nbItems) {
3473 list->sizeItems *= 2;
3474 list->items = (void **) xmlRealloc(list->items,
3475 list->sizeItems * sizeof(void *));
3476 if (list->items == NULL) {
3477 xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3478 list->sizeItems = 0;
3479 return(-1);
3480 }
3481 }
3482 /*
3483 * Just append if the index is greater/equal than the item count.
3484 */
3485 if (idx >= list->nbItems) {
3486 list->items[list->nbItems++] = item;
3487 } else {
3488 int i;
3489 for (i = list->nbItems; i > idx; i--)
3490 list->items[i] = list->items[i-1];
3491 list->items[idx] = item;
3492 list->nbItems++;
3493 }
3494 return(0);
3495}
3496
3497#if 0 /* enable if ever needed */
3498static int
3499xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
3500 int initialSize,
3501 void *item,
3502 int idx)
3503{
3504 if (list->items == NULL) {
3505 if (initialSize <= 0)
3506 initialSize = 1;
3507 list->items = (void **) xmlMalloc(
3508 initialSize * sizeof(void *));
3509 if (list->items == NULL) {
3510 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3511 return(-1);
3512 }
3513 list->sizeItems = initialSize;
3514 } else if (list->sizeItems <= list->nbItems) {
3515 list->sizeItems *= 2;
3516 list->items = (void **) xmlRealloc(list->items,
3517 list->sizeItems * sizeof(void *));
3518 if (list->items == NULL) {
3519 xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3520 list->sizeItems = 0;
3521 return(-1);
3522 }
3523 }
3524 /*
3525 * Just append if the index is greater/equal than the item count.
3526 */
3527 if (idx >= list->nbItems) {
3528 list->items[list->nbItems++] = item;
3529 } else {
3530 int i;
3531 for (i = list->nbItems; i > idx; i--)
3532 list->items[i] = list->items[i-1];
3533 list->items[idx] = item;
3534 list->nbItems++;
3535 }
3536 return(0);
3537}
3538#endif
3539
3540static int
3541xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
3542{
3543 int i;
3544 if ((list->items == NULL) || (idx >= list->nbItems)) {
3545 xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
3546 "index error.\n");
3547 return(-1);
3548 }
3549
3550 if (list->nbItems == 1) {
3551 /* TODO: Really free the list? */
3552 xmlFree(list->items);
3553 list->items = NULL;
3554 list->nbItems = 0;
3555 list->sizeItems = 0;
3556 } else if (list->nbItems -1 == idx) {
3557 list->nbItems--;
3558 } else {
3559 for (i = idx; i < list->nbItems -1; i++)
3560 list->items[i] = list->items[i+1];
3561 list->nbItems--;
3562 }
3563 return(0);
3564}
3565
3572static void
3573xmlSchemaItemListFree(xmlSchemaItemListPtr list)
3574{
3575 if (list == NULL)
3576 return;
3577 if (list->items != NULL)
3578 xmlFree(list->items);
3579 xmlFree(list);
3580}
3581
3582static void
3583xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
3584{
3585 if (bucket == NULL)
3586 return;
3587 if (bucket->globals != NULL) {
3588 xmlSchemaComponentListFree(bucket->globals);
3589 xmlSchemaItemListFree(bucket->globals);
3590 }
3591 if (bucket->locals != NULL) {
3592 xmlSchemaComponentListFree(bucket->locals);
3593 xmlSchemaItemListFree(bucket->locals);
3594 }
3595 if (bucket->relations != NULL) {
3596 xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
3597 do {
3598 prev = cur;
3599 cur = cur->next;
3600 xmlFree(prev);
3601 } while (cur != NULL);
3602 }
3603 if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
3604 xmlFreeDoc(bucket->doc);
3605 }
3606 if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
3607 if (WXS_IMPBUCKET(bucket)->schema != NULL)
3608 xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
3609 }
3610 xmlFree(bucket);
3611}
3612
3613static void
3614xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED)
3615{
3616 xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket);
3617}
3618
3619static xmlSchemaBucketPtr
3620xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
3621 int type, const xmlChar *targetNamespace)
3622{
3623 xmlSchemaBucketPtr ret;
3624 int size;
3625 xmlSchemaPtr mainSchema;
3626
3627 if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
3628 PERROR_INT("xmlSchemaBucketCreate",
3629 "no main schema on constructor");
3630 return(NULL);
3631 }
3632 mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
3633 /* Create the schema bucket. */
3634 if (WXS_IS_BUCKET_INCREDEF(type))
3635 size = sizeof(xmlSchemaInclude);
3636 else
3637 size = sizeof(xmlSchemaImport);
3638 ret = (xmlSchemaBucketPtr) xmlMalloc(size);
3639 if (ret == NULL) {
3640 xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
3641 return(NULL);
3642 }
3643 memset(ret, 0, size);
3644 ret->targetNamespace = targetNamespace;
3645 ret->type = type;
3646 ret->globals = xmlSchemaItemListCreate();
3647 if (ret->globals == NULL) {
3648 xmlFree(ret);
3649 return(NULL);
3650 }
3651 ret->locals = xmlSchemaItemListCreate();
3652 if (ret->locals == NULL) {
3653 xmlFree(ret);
3654 return(NULL);
3655 }
3656 /*
3657 * The following will assure that only the first bucket is marked as
3658 * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
3659 * For each following import buckets an xmlSchema will be created.
3660 * An xmlSchema will be created for every distinct targetNamespace.
3661 * We assign the targetNamespace to the schemata here.
3662 */
3663 if (! WXS_HAS_BUCKETS(pctxt)) {
3664 if (WXS_IS_BUCKET_INCREDEF(type)) {
3665 PERROR_INT("xmlSchemaBucketCreate",
3666 "first bucket but it's an include or redefine");
3667 xmlSchemaBucketFree(ret);
3668 return(NULL);
3669 }
3670 /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
3671 ret->type = XML_SCHEMA_SCHEMA_MAIN;
3672 /* Point to the *main* schema. */
3673 WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
3674 WXS_IMPBUCKET(ret)->schema = mainSchema;
3675 /*
3676 * Ensure that the main schema gets a targetNamespace.
3677 */
3678 mainSchema->targetNamespace = targetNamespace;
3679 } else {
3680 if (type == XML_SCHEMA_SCHEMA_MAIN) {
3681 PERROR_INT("xmlSchemaBucketCreate",
3682 "main bucket but it's not the first one");
3683 xmlSchemaBucketFree(ret);
3684 return(NULL);
3685 } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
3686 /*
3687 * Create a schema for imports and assign the
3688 * targetNamespace.
3689 */
3690 WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
3691 if (WXS_IMPBUCKET(ret)->schema == NULL) {
3692 xmlSchemaBucketFree(ret);
3693 return(NULL);
3694 }
3695 WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
3696 }
3697 }
3698 if (WXS_IS_BUCKET_IMPMAIN(type)) {
3699 int res;
3700 /*
3701 * Imports go into the "schemasImports" slot of the main *schema*.
3702 * Note that we create an import entry for the main schema as well; i.e.,
3703 * even if there's only one schema, we'll get an import.
3704 */
3705 if (mainSchema->schemasImports == NULL) {
3706 mainSchema->schemasImports = xmlHashCreateDict(5,
3707 WXS_CONSTRUCTOR(pctxt)->dict);
3708 if (mainSchema->schemasImports == NULL) {
3709 xmlSchemaBucketFree(ret);
3710 return(NULL);
3711 }
3712 }
3713 if (targetNamespace == NULL)
3714 res = xmlHashAddEntry(mainSchema->schemasImports,
3715 XML_SCHEMAS_NO_NAMESPACE, ret);
3716 else
3717 res = xmlHashAddEntry(mainSchema->schemasImports,
3718 targetNamespace, ret);
3719 if (res != 0) {
3720 PERROR_INT("xmlSchemaBucketCreate",
3721 "failed to add the schema bucket to the hash");
3722 xmlSchemaBucketFree(ret);
3723 return(NULL);
3724 }
3725 } else {
3726 /* Set the @ownerImport of an include bucket. */
3727 if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
3728 WXS_INCBUCKET(ret)->ownerImport =
3729 WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
3730 else
3731 WXS_INCBUCKET(ret)->ownerImport =
3732 WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
3733
3734 /* Includes got into the "includes" slot of the *main* schema. */
3735 if (mainSchema->includes == NULL) {
3736 mainSchema->includes = xmlSchemaItemListCreate();
3737 if (mainSchema->includes == NULL) {
3738 xmlSchemaBucketFree(ret);
3739 return(NULL);
3740 }
3741 }
3742 xmlSchemaItemListAdd(mainSchema->includes, ret);
3743 }
3744 /*
3745 * Add to list of all buckets; this is used for lookup
3746 * during schema construction time only.
3747 */
3748 if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
3749 return(NULL);
3750 return(ret);
3751}
3752
3753static int
3754xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
3755{
3756 if (*list == NULL) {
3757 *list = xmlSchemaItemListCreate();
3758 if (*list == NULL)
3759 return(-1);
3760 }
3761 xmlSchemaItemListAddSize(*list, initialSize, item);
3762 return(0);
3763}
3764
3771static void
3772xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
3773{
3774 if (annot == NULL)
3775 return;
3776 if (annot->next == NULL) {
3777 xmlFree(annot);
3778 } else {
3779 xmlSchemaAnnotPtr prev;
3780
3781 do {
3782 prev = annot;
3783 annot = annot->next;
3784 xmlFree(prev);
3785 } while (annot != NULL);
3786 }
3787}
3788
3795static void
3796xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
3797{
3798 if (nota == NULL)
3799 return;
3800 xmlFree(nota);
3801}
3802
3809static void
3810xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
3811{
3812 if (attr == NULL)
3813 return;
3814 if (attr->annot != NULL)
3815 xmlSchemaFreeAnnot(attr->annot);
3816 if (attr->defVal != NULL)
3817 xmlSchemaFreeValue(attr->defVal);
3818 xmlFree(attr);
3819}
3820
3827static void
3828xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
3829{
3830 if (use == NULL)
3831 return;
3832 if (use->annot != NULL)
3833 xmlSchemaFreeAnnot(use->annot);
3834 if (use->defVal != NULL)
3835 xmlSchemaFreeValue(use->defVal);
3836 xmlFree(use);
3837}
3838
3845static void
3846xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
3847{
3848 if (prohib == NULL)
3849 return;
3850 xmlFree(prohib);
3851}
3852
3859static void
3860xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
3861{
3862 xmlSchemaWildcardNsPtr next;
3863
3864 while (set != NULL) {
3865 next = set->next;
3866 xmlFree(set);
3867 set = next;
3868 }
3869}
3870
3877void
3878xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
3879{
3880 if (wildcard == NULL)
3881 return;
3882 if (wildcard->annot != NULL)
3883 xmlSchemaFreeAnnot(wildcard->annot);
3884 if (wildcard->nsSet != NULL)
3885 xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
3886 if (wildcard->negNsSet != NULL)
3887 xmlFree(wildcard->negNsSet);
3888 xmlFree(wildcard);
3889}
3890
3897static void
3898xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
3899{
3900 if (attrGr == NULL)
3901 return;
3902 if (attrGr->annot != NULL)
3903 xmlSchemaFreeAnnot(attrGr->annot);
3904 if (attrGr->attrUses != NULL)
3905 xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
3906 xmlFree(attrGr);
3907}
3908
3915static void
3916xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
3917{
3918 xmlFree(item);
3919}
3920
3927static void
3928xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
3929{
3930 xmlSchemaTypeLinkPtr next;
3931
3932 while (link != NULL) {
3933 next = link->next;
3934 xmlFree(link);
3935 link = next;
3936 }
3937}
3938
3939static void
3940xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
3941{
3942 xmlSchemaIDCStateObjPtr next;
3943 while (sto != NULL) {
3944 next = sto->next;
3945 if (sto->history != NULL)
3946 xmlFree(sto->history);
3947 if (sto->xpathCtxt != NULL)
3948 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
3949 xmlFree(sto);
3950 sto = next;
3951 }
3952}
3953
3960static void
3961xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
3962{
3963 xmlSchemaIDCSelectPtr cur, prev;
3964
3965 if (idcDef == NULL)
3966 return;
3967 if (idcDef->annot != NULL)
3968 xmlSchemaFreeAnnot(idcDef->annot);
3969 /* Selector */
3970 if (idcDef->selector != NULL) {
3971 if (idcDef->selector->xpathComp != NULL)
3972 xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
3973 xmlFree(idcDef->selector);
3974 }
3975 /* Fields */
3976 if (idcDef->fields != NULL) {
3977 cur = idcDef->fields;
3978 do {
3979 prev = cur;
3980 cur = cur->next;
3981 if (prev->xpathComp != NULL)
3982 xmlFreePattern((xmlPatternPtr) prev->xpathComp);
3983 xmlFree(prev);
3984 } while (cur != NULL);
3985 }
3986 xmlFree(idcDef);
3987}
3988
3995static void
3996xmlSchemaFreeElement(xmlSchemaElementPtr elem)
3997{
3998 if (elem == NULL)
3999 return;
4000 if (elem->annot != NULL)
4001 xmlSchemaFreeAnnot(elem->annot);
4002 if (elem->contModel != NULL)
4003 xmlRegFreeRegexp(elem->contModel);
4004 if (elem->defVal != NULL)
4005 xmlSchemaFreeValue(elem->defVal);
4006 xmlFree(elem);
4007}
4008
4015void
4016xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
4017{
4018 if (facet == NULL)
4019 return;
4020 if (facet->val != NULL)
4021 xmlSchemaFreeValue(facet->val);
4022 if (facet->regexp != NULL)
4023 xmlRegFreeRegexp(facet->regexp);
4024 if (facet->annot != NULL)
4025 xmlSchemaFreeAnnot(facet->annot);
4026 xmlFree(facet);
4027}
4028
4035void
4036xmlSchemaFreeType(xmlSchemaTypePtr type)
4037{
4038 if (type == NULL)
4039 return;
4040 if (type->annot != NULL)
4041 xmlSchemaFreeAnnot(type->annot);
4042 if (type->facets != NULL) {
4043 xmlSchemaFacetPtr facet, next;
4044
4045 facet = type->facets;
4046 while (facet != NULL) {
4047 next = facet->next;
4048 xmlSchemaFreeFacet(facet);
4049 facet = next;
4050 }
4051 }
4052 if (type->attrUses != NULL)
4053 xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
4054 if (type->memberTypes != NULL)
4055 xmlSchemaFreeTypeLinkList(type->memberTypes);
4056 if (type->facetSet != NULL) {
4057 xmlSchemaFacetLinkPtr next, link;
4058
4059 link = type->facetSet;
4060 do {
4061 next = link->next;
4062 xmlFree(link);
4063 link = next;
4064 } while (link != NULL);
4065 }
4066 if (type->contModel != NULL)
4067 xmlRegFreeRegexp(type->contModel);
4068 xmlFree(type);
4069}
4070
4077static void
4078xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
4079{
4080 if (item->annot != NULL)
4081 xmlSchemaFreeAnnot(item->annot);
4082 xmlFree(item);
4083}
4084
4091static void
4092xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
4093{
4094 if (item->annot != NULL)
4095 xmlSchemaFreeAnnot(item->annot);
4096 xmlFree(item);
4097}
4098
4099static void
4100xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
4101{
4102 if ((list == NULL) || (list->nbItems == 0))
4103 return;
4104 {
4105 xmlSchemaTreeItemPtr item;
4106 xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
4107 int i;
4108
4109 for (i = 0; i < list->nbItems; i++) {
4110 item = items[i];
4111 if (item == NULL)
4112 continue;
4113 switch (item->type) {
4114 case XML_SCHEMA_TYPE_SIMPLE:
4115 case XML_SCHEMA_TYPE_COMPLEX:
4116 xmlSchemaFreeType((xmlSchemaTypePtr) item);
4117 break;
4118 case XML_SCHEMA_TYPE_ATTRIBUTE:
4119 xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
4120 break;
4121 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
4122 xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
4123 break;
4124 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
4125 xmlSchemaFreeAttributeUseProhib(
4126 (xmlSchemaAttributeUseProhibPtr) item);
4127 break;
4128 case XML_SCHEMA_TYPE_ELEMENT:
4129 xmlSchemaFreeElement((xmlSchemaElementPtr) item);
4130 break;
4131 case XML_SCHEMA_TYPE_PARTICLE:
4132 if (item->annot != NULL)
4133 xmlSchemaFreeAnnot(item->annot);
4134 xmlFree(item);
4135 break;
4136 case XML_SCHEMA_TYPE_SEQUENCE:
4137 case XML_SCHEMA_TYPE_CHOICE:
4138 case XML_SCHEMA_TYPE_ALL:
4139 xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
4140 break;
4141 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
4142 xmlSchemaFreeAttributeGroup(
4143 (xmlSchemaAttributeGroupPtr) item);
4144 break;
4145 case XML_SCHEMA_TYPE_GROUP:
4146 xmlSchemaFreeModelGroupDef(
4147 (xmlSchemaModelGroupDefPtr) item);
4148 break;
4149 case XML_SCHEMA_TYPE_ANY:
4150 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
4151 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
4152 break;
4153 case XML_SCHEMA_TYPE_IDC_KEY:
4154 case XML_SCHEMA_TYPE_IDC_UNIQUE:
4155 case XML_SCHEMA_TYPE_IDC_KEYREF:
4156 xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
4157 break;
4158 case XML_SCHEMA_TYPE_NOTATION:
4159 xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
4160 break;
4161 case XML_SCHEMA_EXTRA_QNAMEREF:
4162 xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
4163 break;
4164 default: {
4165 /* TODO: This should never be hit. */
4166 xmlSchemaPSimpleInternalErr(NULL,
4167 "Internal error: xmlSchemaComponentListFree, "
4168 "unexpected component type '%s'\n",
4169 (const xmlChar *) WXS_ITEM_TYPE_NAME(item));
4170 }
4171 break;
4172 }
4173 }
4174 list->nbItems = 0;
4175 }
4176}
4177
4184void
4185xmlSchemaFree(xmlSchemaPtr schema)
4186{
4187 if (schema == NULL)
4188 return;
4189 /* @volatiles is not used anymore :-/ */
4190 if (schema->volatiles != NULL)
4191 TODO
4192 /*
4193 * Note that those slots are not responsible for freeing
4194 * schema components anymore; this will now be done by
4195 * the schema buckets.
4196 */
4197 if (schema->notaDecl != NULL)
4198 xmlHashFree(schema->notaDecl, NULL);
4199 if (schema->attrDecl != NULL)
4200 xmlHashFree(schema->attrDecl, NULL);
4201 if (schema->attrgrpDecl != NULL)
4202 xmlHashFree(schema->attrgrpDecl, NULL);
4203 if (schema->elemDecl != NULL)
4204 xmlHashFree(schema->elemDecl, NULL);
4205 if (schema->typeDecl != NULL)
4206 xmlHashFree(schema->typeDecl, NULL);
4207 if (schema->groupDecl != NULL)
4208 xmlHashFree(schema->groupDecl, NULL);
4209 if (schema->idcDef != NULL)
4210 xmlHashFree(schema->idcDef, NULL);
4211
4212 if (schema->schemasImports != NULL)
4213 xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry);
4214 if (schema->includes != NULL) {
4215 xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
4216 int i;
4217 for (i = 0; i < list->nbItems; i++) {
4218 xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
4219 }
4220 xmlSchemaItemListFree(list);
4221 }
4222 if (schema->annot != NULL)
4223 xmlSchemaFreeAnnot(schema->annot);
4224 /* Never free the doc here, since this will be done by the buckets. */
4225
4226 xmlDictFree(schema->dict);
4227 xmlFree(schema);
4228}
4229
4230/************************************************************************
4231 * *
4232 * Debug functions *
4233 * *
4234 ************************************************************************/
4235
4236#ifdef LIBXML_OUTPUT_ENABLED
4237
4238static void
4239xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
4240
4248static void
4249xmlSchemaElementDump(void *payload, void *data,
4251 const xmlChar * namespace ATTRIBUTE_UNUSED,
4253{
4254 xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload;
4255 FILE *output = (FILE *) data;
4256 if (elem == NULL)
4257 return;
4258
4259
4260 fprintf(output, "Element");
4261 if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
4262 fprintf(output, " (global)");
4263 fprintf(output, ": '%s' ", elem->name);
4264 if (namespace != NULL)
4265 fprintf(output, "ns '%s'", namespace);
4266 fprintf(output, "\n");
4267#if 0
4268 if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
4269 fprintf(output, " min %d ", elem->minOccurs);
4270 if (elem->maxOccurs >= UNBOUNDED)
4271 fprintf(output, "max: unbounded\n");
4272 else if (elem->maxOccurs != 1)
4273 fprintf(output, "max: %d\n", elem->maxOccurs);
4274 else
4275 fprintf(output, "\n");
4276 }
4277#endif
4278 /*
4279 * Misc other properties.
4280 */
4281 if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
4282 (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
4283 (elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
4284 (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
4285 fprintf(output, " props: ");
4286 if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
4287 fprintf(output, "[fixed] ");
4288 if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
4289 fprintf(output, "[default] ");
4290 if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
4291 fprintf(output, "[abstract] ");
4292 if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
4293 fprintf(output, "[nillable] ");
4294 fprintf(output, "\n");
4295 }
4296 /*
4297 * Default/fixed value.
4298 */
4299 if (elem->value != NULL)
4300 fprintf(output, " value: '%s'\n", elem->value);
4301 /*
4302 * Type.
4303 */
4304 if (elem->namedType != NULL) {
4305 fprintf(output, " type: '%s' ", elem->namedType);
4306 if (elem->namedTypeNs != NULL)
4307 fprintf(output, "ns '%s'\n", elem->namedTypeNs);
4308 else
4309 fprintf(output, "\n");
4310 } else if (elem->subtypes != NULL) {
4311 /*
4312 * Dump local types.
4313 */
4314 xmlSchemaTypeDump(elem->subtypes, output);
4315 }
4316 /*
4317 * Substitution group.
4318 */
4319 if (elem->substGroup != NULL) {
4320 fprintf(output, " substitutionGroup: '%s' ", elem->substGroup);
4321 if (elem->substGroupNs != NULL)
4322 fprintf(output, "ns '%s'\n", elem->substGroupNs);
4323 else
4324 fprintf(output, "\n");
4325 }
4326}
4327
4335static void
4336xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
4337{
4339
4340 if (annot == NULL)
4341 return;
4342
4343 content = xmlNodeGetContent(annot->content);
4344 if (content != NULL) {
4345 fprintf(output, " Annot: %s\n", content);
4347 } else
4348 fprintf(output, " Annot: empty\n");
4349}
4350
4359static void
4360xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
4361{
4362 xmlChar *str = NULL;
4363 xmlSchemaTreeItemPtr term;
4364 char shift[100];
4365 int i;
4366
4367 if (particle == NULL)
4368 return;
4369 for (i = 0;((i < depth) && (i < 25));i++)
4370 shift[2 * i] = shift[2 * i + 1] = ' ';
4371 shift[2 * i] = shift[2 * i + 1] = 0;
4372 fprintf(output, "%s", shift);
4373 if (particle->children == NULL) {
4374 fprintf(output, "MISSING particle term\n");
4375 return;
4376 }
4377 term = particle->children;
4378 if (term == NULL) {
4379 fprintf(output, "(NULL)");
4380 } else {
4381 switch (term->type) {
4382 case XML_SCHEMA_TYPE_ELEMENT:
4383 fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
4384 ((xmlSchemaElementPtr)term)->targetNamespace,
4385 ((xmlSchemaElementPtr)term)->name));
4386 FREE_AND_NULL(str);
4387 break;
4388 case XML_SCHEMA_TYPE_SEQUENCE:
4389 fprintf(output, "SEQUENCE");
4390 break;
4391 case XML_SCHEMA_TYPE_CHOICE:
4392 fprintf(output, "CHOICE");
4393 break;
4394 case XML_SCHEMA_TYPE_ALL:
4395 fprintf(output, "ALL");
4396 break;
4397 case XML_SCHEMA_TYPE_ANY:
4398 fprintf(output, "ANY");
4399 break;
4400 default:
4401 fprintf(output, "UNKNOWN\n");
4402 return;
4403 }
4404 }
4405 if (particle->minOccurs != 1)
4406 fprintf(output, " min: %d", particle->minOccurs);
4407 if (particle->maxOccurs >= UNBOUNDED)
4408 fprintf(output, " max: unbounded");
4409 else if (particle->maxOccurs != 1)
4410 fprintf(output, " max: %d", particle->maxOccurs);
4411 fprintf(output, "\n");
4412 if (term &&
4413 ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
4414 (term->type == XML_SCHEMA_TYPE_CHOICE) ||
4415 (term->type == XML_SCHEMA_TYPE_ALL)) &&
4416 (term->children != NULL)) {
4417 xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
4418 output, depth +1);
4419 }
4420 if (particle->next != NULL)
4421 xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
4422 output, depth);
4423}
4424
4432static void
4433xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
4434{
4435 xmlSchemaAttributeUsePtr use;
4436 xmlSchemaAttributeUseProhibPtr prohib;
4437 xmlSchemaQNameRefPtr ref;
4438 const xmlChar *name, *tns;
4439 xmlChar *str = NULL;
4440 int i;
4441
4442 if ((uses == NULL) || (uses->nbItems == 0))
4443 return;
4444
4445 fprintf(output, " attributes:\n");
4446 for (i = 0; i < uses->nbItems; i++) {
4447 use = uses->items[i];
4448 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
4449 fprintf(output, " [prohibition] ");
4450 prohib = (xmlSchemaAttributeUseProhibPtr) use;
4451 name = prohib->name;
4452 tns = prohib->targetNamespace;
4453 } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
4454 fprintf(output, " [reference] ");
4455 ref = (xmlSchemaQNameRefPtr) use;
4456 name = ref->name;
4457 tns = ref->targetNamespace;
4458 } else {
4459 fprintf(output, " [use] ");
4460 name = WXS_ATTRUSE_DECL_NAME(use);
4461 tns = WXS_ATTRUSE_DECL_TNS(use);
4462 }
4463 fprintf(output, "'%s'\n",
4464 (const char *) xmlSchemaFormatQName(&str, tns, name));
4465 FREE_AND_NULL(str);
4466 }
4467}
4468
4476static void
4477xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
4478{
4479 if (type == NULL) {
4480 fprintf(output, "Type: NULL\n");
4481 return;
4482 }
4483 fprintf(output, "Type: ");
4484 if (type->name != NULL)
4485 fprintf(output, "'%s' ", type->name);
4486 else
4487 fprintf(output, "(no name) ");
4488 if (type->targetNamespace != NULL)
4489 fprintf(output, "ns '%s' ", type->targetNamespace);
4490 switch (type->type) {
4491 case XML_SCHEMA_TYPE_BASIC:
4492 fprintf(output, "[basic] ");
4493 break;
4494 case XML_SCHEMA_TYPE_SIMPLE:
4495 fprintf(output, "[simple] ");
4496 break;
4497 case XML_SCHEMA_TYPE_COMPLEX:
4498 fprintf(output, "[complex] ");
4499 break;
4500 case XML_SCHEMA_TYPE_SEQUENCE:
4501 fprintf(output, "[sequence] ");
4502 break;
4503 case XML_SCHEMA_TYPE_CHOICE:
4504 fprintf(output, "[choice] ");
4505 break;
4506 case XML_SCHEMA_TYPE_ALL:
4507 fprintf(output, "[all] ");
4508 break;
4509 case XML_SCHEMA_TYPE_UR:
4510 fprintf(output, "[ur] ");
4511 break;
4512 case XML_SCHEMA_TYPE_RESTRICTION:
4513 fprintf(output, "[restriction] ");
4514 break;
4515 case XML_SCHEMA_TYPE_EXTENSION:
4516 fprintf(output, "[extension] ");
4517 break;
4518 default:
4519 fprintf(output, "[unknown type %d] ", type->type);
4520 break;
4521 }
4522 fprintf(output, "content: ");
4523 switch (type->contentType) {
4524 case XML_SCHEMA_CONTENT_UNKNOWN:
4525 fprintf(output, "[unknown] ");
4526 break;
4527 case XML_SCHEMA_CONTENT_EMPTY:
4528 fprintf(output, "[empty] ");
4529 break;
4530 case XML_SCHEMA_CONTENT_ELEMENTS:
4531 fprintf(output, "[element] ");
4532 break;
4533 case XML_SCHEMA_CONTENT_MIXED:
4534 fprintf(output, "[mixed] ");
4535 break;
4536 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
4537 /* not used. */
4538 break;
4539 case XML_SCHEMA_CONTENT_BASIC:
4540 fprintf(output, "[basic] ");
4541 break;
4542 case XML_SCHEMA_CONTENT_SIMPLE:
4543 fprintf(output, "[simple] ");
4544 break;
4545 case XML_SCHEMA_CONTENT_ANY:
4546 fprintf(output, "[any] ");
4547 break;
4548 }
4549 fprintf(output, "\n");
4550 if (type->base != NULL) {
4551 fprintf(output, " base type: '%s'", type->base);
4552 if (type->baseNs != NULL)
4553 fprintf(output, " ns '%s'\n", type->baseNs);
4554 else
4555 fprintf(output, "\n");
4556 }
4557 if (type->attrUses != NULL)
4558 xmlSchemaAttrUsesDump(type->attrUses, output);
4559 if (type->annot != NULL)
4560 xmlSchemaAnnotDump(output, type->annot);
4561#ifdef DUMP_CONTENT_MODEL
4562 if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
4563 (type->subtypes != NULL)) {
4564 xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
4565 output, 1);
4566 }
4567#endif
4568}
4569
4570static void
4571xmlSchemaTypeDumpEntry(void *type, void *output,
4573{
4574 xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output);
4575}
4576
4584void
4585xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
4586{
4587 if (output == NULL)
4588 return;
4589 if (schema == NULL) {
4590 fprintf(output, "Schemas: NULL\n");
4591 return;
4592 }
4593 fprintf(output, "Schemas: ");
4594 if (schema->name != NULL)
4595 fprintf(output, "%s, ", schema->name);
4596 else
4597 fprintf(output, "no name, ");
4598 if (schema->targetNamespace != NULL)
4599 fprintf(output, "%s", (const char *) schema->targetNamespace);
4600 else
4601 fprintf(output, "no target namespace");
4602 fprintf(output, "\n");
4603 if (schema->annot != NULL)
4604 xmlSchemaAnnotDump(output, schema->annot);
4605 xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output);
4606 xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output);
4607}
4608
4609#ifdef DEBUG_IDC_NODE_TABLE
4616static void
4617xmlSchemaDebugDumpIDCTable(FILE * output,
4618 const xmlChar *namespaceName,
4619 const xmlChar *localName,
4620 xmlSchemaPSVIIDCBindingPtr bind)
4621{
4622 xmlChar *str = NULL;
4623 const xmlChar *value;
4624 xmlSchemaPSVIIDCNodePtr tab;
4625 xmlSchemaPSVIIDCKeyPtr key;
4626 int i, j, res;
4627
4628 fprintf(output, "IDC: TABLES on '%s'\n",
4629 xmlSchemaFormatQName(&str, namespaceName, localName));
4630 FREE_AND_NULL(str)
4631
4632 if (bind == NULL)
4633 return;
4634 do {
4635 fprintf(output, "IDC: BINDING '%s' (%d)\n",
4636 xmlSchemaGetComponentQName(&str,
4637 bind->definition), bind->nbNodes);
4638 FREE_AND_NULL(str)
4639 for (i = 0; i < bind->nbNodes; i++) {
4640 tab = bind->nodeTable[i];
4641 fprintf(output, " ( ");
4642 for (j = 0; j < bind->definition->nbFields; j++) {
4643 key = tab->keys[j];
4644 if ((key != NULL) && (key->val != NULL)) {
4645 res = xmlSchemaGetCanonValue(key->val, &value);
4646 if (res >= 0)
4647 fprintf(output, "'%s' ", value);
4648 else
4649 fprintf(output, "CANON-VALUE-FAILED ");
4650 if (res == 0)
4651 FREE_AND_NULL(value)
4652 } else if (key != NULL)
4653 fprintf(output, "(no val), ");
4654 else
4655 fprintf(output, "(key missing), ");
4656 }
4657 fprintf(output, ")\n");
4658 }
4659 if (bind->dupls && bind->dupls->nbItems) {
4660 fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems);
4661 for (i = 0; i < bind->dupls->nbItems; i++) {
4662 tab = bind->dupls->items[i];
4663 fprintf(output, " ( ");
4664 for (j = 0; j < bind->definition->nbFields; j++) {
4665 key = tab->keys[j];
4666 if ((key != NULL) && (key->val != NULL)) {
4667 res = xmlSchemaGetCanonValue(key->val, &value);
4668 if (res >= 0)
4669 fprintf(output, "'%s' ", value);
4670 else
4671 fprintf(output, "CANON-VALUE-FAILED ");
4672 if (res == 0)
4673 FREE_AND_NULL(value)
4674 } else if (key != NULL)
4675 fprintf(output, "(no val), ");
4676 else
4677 fprintf(output, "(key missing), ");
4678 }
4679 fprintf(output, ")\n");
4680 }
4681 }
4682 bind = bind->next;
4683 } while (bind != NULL);
4684}
4685#endif /* DEBUG_IDC */
4686#endif /* LIBXML_OUTPUT_ENABLED */
4687
4688/************************************************************************
4689 * *
4690 * Utilities *
4691 * *
4692 ************************************************************************/
4693
4704static xmlAttrPtr
4705xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
4706{
4707 xmlAttrPtr prop;
4708
4709 if ((node == NULL) || (name == NULL))
4710 return(NULL);
4711 prop = node->properties;
4712 while (prop != NULL) {
4713 if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
4714 return(prop);
4715 prop = prop->next;
4716 }
4717 return (NULL);
4718}
4719
4731static xmlAttrPtr
4732xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
4733{
4734 xmlAttrPtr prop;
4735
4736 if ((node == NULL) || (name == NULL))
4737 return(NULL);
4738 prop = node->properties;
4739 while (prop != NULL) {
4740 if ((prop->ns != NULL) &&
4741 xmlStrEqual(prop->name, BAD_CAST name) &&
4742 xmlStrEqual(prop->ns->href, BAD_CAST uri))
4743 return(prop);
4744 prop = prop->next;
4745 }
4746 return (NULL);
4747}
4748
4749static const xmlChar *
4750xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
4751{
4752 xmlChar *val;
4753 const xmlChar *ret;
4754
4756 if (val == NULL)
4757 val = xmlStrdup((xmlChar *)"");
4758 ret = xmlDictLookup(ctxt->dict, val, -1);
4759 xmlFree(val);
4760 return(ret);
4761}
4762
4763static const xmlChar *
4764xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
4765{
4766 return((const xmlChar*) xmlNodeGetContent(node));
4767}
4768
4779static const xmlChar *
4780xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
4781 const char *name)
4782{
4783 xmlChar *val;
4784 const xmlChar *ret;
4785
4787 if (val == NULL)
4788 return(NULL);
4789 ret = xmlDictLookup(ctxt->dict, val, -1);
4790 xmlFree(val);
4791 return(ret);
4792}
4793
4794/************************************************************************
4795 * *
4796 * Parsing functions *
4797 * *
4798 ************************************************************************/
4799
4800#define WXS_FIND_GLOBAL_ITEM(slot) \
4801 if (xmlStrEqual(nsName, schema->targetNamespace)) { \
4802 ret = xmlHashLookup(schema->slot, name); \
4803 if (ret != NULL) goto exit; \
4804 } \
4805 if (xmlHashSize(schema->schemasImports) > 1) { \
4806 xmlSchemaImportPtr import; \
4807 if (nsName == NULL) \
4808 import = xmlHashLookup(schema->schemasImports, \
4809 XML_SCHEMAS_NO_NAMESPACE); \
4810 else \
4811 import = xmlHashLookup(schema->schemasImports, nsName); \
4812 if (import == NULL) \
4813 goto exit; \
4814 ret = xmlHashLookup(import->schema->slot, name); \
4815 }
4816
4827static xmlSchemaElementPtr
4828xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
4829 const xmlChar * nsName)
4830{
4831 xmlSchemaElementPtr ret = NULL;
4832
4833 if ((name == NULL) || (schema == NULL))
4834 return(NULL);
4835 if (schema != NULL) {
4836 WXS_FIND_GLOBAL_ITEM(elemDecl)
4837 }
4838exit:
4839#ifdef DEBUG
4840 if (ret == NULL) {
4841 if (nsName == NULL)
4842 fprintf(stderr, "Unable to lookup element decl. %s", name);
4843 else
4844 fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
4845 nsName);
4846 }
4847#endif
4848 return (ret);
4849}
4850
4861static xmlSchemaTypePtr
4862xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
4863 const xmlChar * nsName)
4864{
4865 xmlSchemaTypePtr ret = NULL;
4866
4867 if (name == NULL)
4868 return (NULL);
4869 /* First try the built-in types. */
4870 if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
4871 ret = xmlSchemaGetPredefinedType(name, nsName);
4872 if (ret != NULL)
4873 goto exit;
4874 /*
4875 * Note that we try the parsed schemas as well here
4876 * since one might have parsed the S4S, which contain more
4877 * than the built-in types.
4878 * TODO: Can we optimize this?
4879 */
4880 }
4881 if (schema != NULL) {
4882 WXS_FIND_GLOBAL_ITEM(typeDecl)
4883 }
4884exit:
4885
4886#ifdef DEBUG
4887 if (ret == NULL) {
4888 if (nsName == NULL)
4889 fprintf(stderr, "Unable to lookup type %s", name);
4890 else
4891 fprintf(stderr, "Unable to lookup type %s:%s", name,
4892 nsName);
4893 }
4894#endif
4895 return (ret);
4896}
4897
4908static xmlSchemaAttributePtr
4909xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
4910 const xmlChar * nsName)
4911{
4912 xmlSchemaAttributePtr ret = NULL;
4913
4914 if ((name == NULL) || (schema == NULL))
4915 return (NULL);
4916 if (schema != NULL) {
4917 WXS_FIND_GLOBAL_ITEM(attrDecl)
4918 }
4919exit:
4920#ifdef DEBUG
4921 if (ret == NULL) {
4922 if (nsName == NULL)
4923 fprintf(stderr, "Unable to lookup attribute %s", name);
4924 else
4925 fprintf(stderr, "Unable to lookup attribute %s:%s", name,
4926 nsName);
4927 }
4928#endif
4929 return (ret);
4930}
4931
4942static xmlSchemaAttributeGroupPtr
4943xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
4944 const xmlChar * nsName)
4945{
4946 xmlSchemaAttributeGroupPtr ret = NULL;
4947
4948 if ((name == NULL) || (schema == NULL))
4949 return (NULL);
4950 if (schema != NULL) {
4951 WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
4952 }
4953exit:
4954 /* TODO:
4955 if ((ret != NULL) && (ret->redef != NULL)) {
4956 * Return the last redefinition. *
4957 ret = ret->redef;
4958 }
4959 */
4960#ifdef DEBUG
4961 if (ret == NULL) {
4962 if (nsName == NULL)
4963 fprintf(stderr, "Unable to lookup attribute group %s", name);
4964 else
4965 fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
4966 nsName);
4967 }
4968#endif
4969 return (ret);
4970}
4971
4982static xmlSchemaModelGroupDefPtr
4983xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
4984 const xmlChar * nsName)
4985{
4986 xmlSchemaModelGroupDefPtr ret = NULL;
4987
4988 if ((name == NULL) || (schema == NULL))
4989 return (NULL);
4990 if (schema != NULL) {
4991 WXS_FIND_GLOBAL_ITEM(groupDecl)
4992 }
4993exit:
4994
4995#ifdef DEBUG
4996 if (ret == NULL) {
4997 if (nsName == NULL)
4998 fprintf(stderr, "Unable to lookup group %s", name);
4999 else
5000 fprintf(stderr, "Unable to lookup group %s:%s", name,
5001 nsName);
5002 }
5003#endif
5004 return (ret);
5005}
5006
5007static xmlSchemaNotationPtr
5008xmlSchemaGetNotation(xmlSchemaPtr schema,
5009 const xmlChar *name,
5010 const xmlChar *nsName)
5011{
5012 xmlSchemaNotationPtr ret = NULL;
5013
5014 if ((name == NULL) || (schema == NULL))
5015 return (NULL);
5016 if (schema != NULL) {
5017 WXS_FIND_GLOBAL_ITEM(notaDecl)
5018 }
5019exit:
5020 return (ret);
5021}
5022
5023static xmlSchemaIDCPtr
5024xmlSchemaGetIDC(xmlSchemaPtr schema,
5025 const xmlChar *name,
5026 const xmlChar *nsName)
5027{
5028 xmlSchemaIDCPtr ret = NULL;
5029
5030 if ((name == NULL) || (schema == NULL))
5031 return (NULL);
5032 if (schema != NULL) {
5033 WXS_FIND_GLOBAL_ITEM(idcDef)
5034 }
5035exit:
5036 return (ret);
5037}
5038
5049static xmlSchemaBasicItemPtr
5050xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
5051 xmlSchemaTypeType itemType,
5052 const xmlChar *name,
5053 const xmlChar *targetNs)
5054{
5055 switch (itemType) {
5056 case XML_SCHEMA_TYPE_GROUP:
5057 return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
5058 name, targetNs));
5059 case XML_SCHEMA_TYPE_ELEMENT:
5060 return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
5061 name, targetNs));
5062 default:
5063 TODO
5064 return (NULL);
5065 }
5066}
5067
5068/************************************************************************
5069 * *
5070 * Parsing functions *
5071 * *
5072 ************************************************************************/
5073
5074#define IS_BLANK_NODE(n) \
5075 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
5076
5086static int
5087xmlSchemaIsBlank(xmlChar * str, int len)
5088{
5089 if (str == NULL)
5090 return (1);
5091 if (len < 0) {
5092 while (*str != 0) {
5093 if (!(IS_BLANK_CH(*str)))
5094 return (0);
5095 str++;
5096 }
5097 } else while ((*str != 0) && (len != 0)) {
5098 if (!(IS_BLANK_CH(*str)))
5099 return (0);
5100 str++;
5101 len--;
5102 }
5103
5104 return (1);
5105}
5106
5107#define WXS_COMP_NAME(c, t) ((t) (c))->name
5108#define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
5109/*
5110* xmlSchemaFindRedefCompInGraph:
5111* ATTENTION TODO: This uses pointer comp. for strings.
5112*/
5113static xmlSchemaBasicItemPtr
5114xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
5115 xmlSchemaTypeType type,
5116 const xmlChar *name,
5117 const xmlChar *nsName)
5118{
5119 xmlSchemaBasicItemPtr ret;
5120 int i;
5121
5122 if ((bucket == NULL) || (name == NULL))
5123 return(NULL);
5124 if ((bucket->globals == NULL) ||
5125 (bucket->globals->nbItems == 0))
5126 goto subschemas;
5127 /*
5128 * Search in global components.
5129 */
5130 for (i = 0; i < bucket->globals->nbItems; i++) {
5131 ret = bucket->globals->items[i];
5132 if (ret->type == type) {
5133 switch (type) {
5134 case XML_SCHEMA_TYPE_COMPLEX:
5135 case XML_SCHEMA_TYPE_SIMPLE:
5136 if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
5137 (WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
5138 nsName))
5139 {
5140 return(ret);
5141 }
5142 break;
5143 case XML_SCHEMA_TYPE_GROUP:
5144 if ((WXS_COMP_NAME(ret,
5145 xmlSchemaModelGroupDefPtr) == name) &&
5146 (WXS_COMP_TNS(ret,
5147 xmlSchemaModelGroupDefPtr) == nsName))
5148 {
5149 return(ret);
5150 }
5151 break;
5152 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
5153 if ((WXS_COMP_NAME(ret,
5154 xmlSchemaAttributeGroupPtr) == name) &&
5155 (WXS_COMP_TNS(ret,
5156 xmlSchemaAttributeGroupPtr) == nsName))
5157 {
5158 return(ret);
5159 }
5160 break;
5161 default:
5162 /* Should not be hit. */
5163 return(NULL);
5164 }
5165 }
5166 }
5167subschemas:
5168 /*
5169 * Process imported/included schemas.
5170 */
5171 if (bucket->relations != NULL) {
5172 xmlSchemaSchemaRelationPtr rel = bucket->relations;
5173
5174 /*
5175 * TODO: Marking the bucket will not avoid multiple searches
5176 * in the same schema, but avoids at least circularity.
5177 */
5178 bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
5179 do {
5180 if ((rel->bucket != NULL) &&
5181 ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
5182 ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
5183 type, name, nsName);
5184 if (ret != NULL)
5185 return(ret);
5186 }
5187 rel = rel->next;
5188 } while (rel != NULL);
5189 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
5190 }
5191 return(NULL);
5192}
5193
5205static xmlSchemaNotationPtr
5206xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5207 const xmlChar *name, const xmlChar *nsName,
5209{
5210 xmlSchemaNotationPtr ret = NULL;
5211
5212 if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5213 return (NULL);
5214
5215 ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
5216 if (ret == NULL) {
5217 xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
5218 return (NULL);
5219 }
5220 memset(ret, 0, sizeof(xmlSchemaNotation));
5221 ret->type = XML_SCHEMA_TYPE_NOTATION;
5222 ret->name = name;
5223 ret->targetNamespace = nsName;
5224 /* TODO: do we need the node to be set?
5225 * ret->node = node;*/
5226 WXS_ADD_GLOBAL(ctxt, ret);
5227 return (ret);
5228}
5229
5242static xmlSchemaAttributePtr
5243xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5244 const xmlChar * name, const xmlChar * nsName,
5245 xmlNodePtr node, int topLevel)
5246{
5247 xmlSchemaAttributePtr ret = NULL;
5248
5249 if ((ctxt == NULL) || (schema == NULL))
5250 return (NULL);
5251
5252 ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
5253 if (ret == NULL) {
5254 xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
5255 return (NULL);
5256 }
5257 memset(ret, 0, sizeof(xmlSchemaAttribute));
5258 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
5259 ret->node = node;
5260 ret->name = name;
5261 ret->targetNamespace = nsName;
5262
5263 if (topLevel)
5264 WXS_ADD_GLOBAL(ctxt, ret);
5265 else
5266 WXS_ADD_LOCAL(ctxt, ret);
5267 WXS_ADD_PENDING(ctxt, ret);
5268 return (ret);
5269}
5270
5283static xmlSchemaAttributeUsePtr
5284xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
5286{
5287 xmlSchemaAttributeUsePtr ret = NULL;
5288
5289 if (pctxt == NULL)
5290 return (NULL);
5291
5292 ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
5293 if (ret == NULL) {
5294 xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
5295 return (NULL);
5296 }
5297 memset(ret, 0, sizeof(xmlSchemaAttributeUse));
5298 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
5299 ret->node = node;
5300
5301 WXS_ADD_LOCAL(pctxt, ret);
5302 return (ret);
5303}
5304
5305/*
5306* xmlSchemaAddRedef:
5307*
5308* Adds a redefinition information. This is used at a later stage to:
5309* resolve references to the redefined components and to check constraints.
5310*/
5311static xmlSchemaRedefPtr
5312xmlSchemaAddRedef(xml