Coverage Report

Created: 2023-11-19 06:13

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