~ubuntu-branches/ubuntu/wily/opencollada/wily-proposed

« back to all changes in this revision

Viewing changes to Externals/LibXML/xmlschemas.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2015-05-14 17:23:27 UTC
  • Revision ID: package-import@ubuntu.com-20150514172327-f862u8envms01fra
Tags: upstream-0.1.0~20140703.ddf8f47+dfsg1
ImportĀ upstreamĀ versionĀ 0.1.0~20140703.ddf8f47+dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * schemas.c : implementation of the XML Schema handling and
 
3
 *             schema validity checking
 
4
 *
 
5
 * See Copyright for the status of this software.
 
6
 *
 
7
 * Daniel Veillard <veillard@redhat.com>
 
8
 */
 
9
 
 
10
/*
 
11
 * TODO:
 
12
 *   - when types are redefined in includes, check that all
 
13
 *     types in the redef list are equal
 
14
 *     -> need a type equality operation.
 
15
 *   - if we don't intend to use the schema for schemas, we
 
16
 *     need to validate all schema attributes (ref, type, name)
 
17
 *     against their types.
 
18
 *   - Eliminate item creation for: ??
 
19
 *
 
20
 * URGENT TODO:
 
21
 *   - For xsi-driven schema acquisition, augment the IDCs after every
 
22
 *     acquisition episode (xmlSchemaAugmentIDC).
 
23
 *
 
24
 * NOTES:
 
25
 *   - Elimated item creation for: <restriction>, <extension>,
 
26
 *     <simpleContent>, <complexContent>, <list>, <union>
 
27
 *
 
28
 * PROBLEMS:
 
29
 *   - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
 
30
 *     IDC XPath expression and chameleon includes: the targetNamespace is changed, so
 
31
 *     XPath will have trouble to resolve to this namespace, since not known.
 
32
 *
 
33
 *
 
34
 * CONSTRAINTS:
 
35
 *
 
36
 * Schema Component Constraint:
 
37
 *   All Group Limited (cos-all-limited)
 
38
 *   Status: complete
 
39
 *   (1.2)
 
40
 *     In xmlSchemaGroupDefReferenceTermFixup() and
 
41
 *   (2)
 
42
 *     In xmlSchemaParseModelGroup()
 
43
 *     TODO: Actually this should go to component-level checks,
 
44
 *     but is done here due to performance. Move it to an other layer
 
45
 *     is schema construction via an API is implemented.
 
46
 */
 
47
#define IN_LIBXML
 
48
#include "libxml.h"
 
49
 
 
50
#ifdef LIBXML_SCHEMAS_ENABLED
 
51
 
 
52
#include <string.h>
 
53
#include <libxml/xmlmemory.h>
 
54
#include <libxml/parser.h>
 
55
#include <libxml/parserInternals.h>
 
56
#include <libxml/hash.h>
 
57
#include <libxml/uri.h>
 
58
#include <libxml/xmlschemas.h>
 
59
#include <libxml/schemasInternals.h>
 
60
#include <libxml/xmlschemastypes.h>
 
61
#include <libxml/xmlautomata.h>
 
62
#include <libxml/xmlregexp.h>
 
63
#include <libxml/dict.h>
 
64
#include <libxml/encoding.h>
 
65
#include <libxml/xmlIO.h>
 
66
#ifdef LIBXML_PATTERN_ENABLED
 
67
#include <libxml/pattern.h>
 
68
#endif
 
69
#ifdef LIBXML_READER_ENABLED
 
70
#include <libxml/xmlreader.h>
 
71
#endif
 
72
 
 
73
/* #define DEBUG 1 */
 
74
 
 
75
/* #define DEBUG_CONTENT 1 */
 
76
 
 
77
/* #define DEBUG_TYPE 1 */
 
78
 
 
79
/* #define DEBUG_CONTENT_REGEXP 1 */
 
80
 
 
81
/* #define DEBUG_AUTOMATA 1 */
 
82
 
 
83
/* #define DEBUG_IDC */
 
84
 
 
85
/* #define DEBUG_IDC_NODE_TABLE */
 
86
 
 
87
/* #define WXS_ELEM_DECL_CONS_ENABLED */
 
88
 
 
89
#ifdef DEBUG_IDC
 
90
 #ifndef DEBUG_IDC_NODE_TABLE
 
91
  #define DEBUG_IDC_NODE_TABLE
 
92
 #endif
 
93
#endif   
 
94
 
 
95
/* #define ENABLE_PARTICLE_RESTRICTION 1 */
 
96
 
 
97
#define ENABLE_REDEFINE
 
98
 
 
99
/* #define ENABLE_NAMED_LOCALS */
 
100
 
 
101
/* #define ENABLE_IDC_NODE_TABLES_TEST */
 
102
 
 
103
#define DUMP_CONTENT_MODEL
 
104
 
 
105
#ifdef LIBXML_READER_ENABLED
 
106
/* #define XML_SCHEMA_READER_ENABLED */
 
107
#endif
 
108
 
 
109
#define UNBOUNDED (1 << 30)
 
110
#define TODO                                                            \
 
111
    xmlGenericError(xmlGenericErrorContext,                             \
 
112
            "Unimplemented block at %s:%d\n",                           \
 
113
            __FILE__, __LINE__);
 
114
 
 
115
#define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
 
116
 
 
117
/*
 
118
 * The XML Schemas namespaces
 
119
 */
 
120
static const xmlChar *xmlSchemaNs = (const xmlChar *)
 
121
    "http://www.w3.org/2001/XMLSchema";
 
122
 
 
123
static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
 
124
    "http://www.w3.org/2001/XMLSchema-instance";
 
125
 
 
126
static const xmlChar *xmlNamespaceNs = (const xmlChar *)
 
127
    "http://www.w3.org/2000/xmlns/";
 
128
 
 
129
/*
 
130
* Come casting macros.
 
131
*/
 
132
#define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
 
133
#define PCTXT_CAST (xmlSchemaParserCtxtPtr)
 
134
#define VCTXT_CAST (xmlSchemaValidCtxtPtr)
 
135
#define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
 
136
#define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
 
137
#define WXS_PTC_CAST (xmlSchemaParticlePtr)
 
138
#define WXS_TYPE_CAST (xmlSchemaTypePtr)
 
139
#define WXS_ELEM_CAST (xmlSchemaElementPtr)
 
140
#define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
 
141
#define WXS_ATTR_CAST (xmlSchemaAttributePtr)
 
142
#define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
 
143
#define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
 
144
#define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
 
145
#define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
 
146
#define WXS_IDC_CAST (xmlSchemaIDCPtr)
 
147
#define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
 
148
#define WXS_LIST_CAST (xmlSchemaItemListPtr)
 
149
 
 
150
/*
 
151
* Macros to query common properties of components.
 
152
*/
 
153
#define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
 
154
 
 
155
#define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
 
156
/*
 
157
* Macros for element declarations.
 
158
*/
 
159
#define WXS_ELEM_TYPEDEF(e) (e)->subtypes
 
160
 
 
161
#define WXS_SUBST_HEAD(item) (item)->refDecl
 
162
/*
 
163
* Macros for attribute declarations.
 
164
*/
 
165
#define WXS_ATTR_TYPEDEF(a) (a)->subtypes
 
166
/*
 
167
* Macros for attribute uses.
 
168
*/
 
169
#define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl
 
170
 
 
171
#define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
 
172
 
 
173
#define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
 
174
 
 
175
#define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
 
176
/*
 
177
* Macros for attribute groups.
 
178
*/
 
179
#define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
 
180
#define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
 
181
/*
 
182
* Macros for particles.
 
183
*/
 
184
#define WXS_PARTICLE(p) WXS_PTC_CAST (p)
 
185
 
 
186
#define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
 
187
 
 
188
#define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
 
189
 
 
190
#define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
 
191
/*
 
192
* Macros for model groups definitions.
 
193
*/
 
194
#define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
 
195
/*
 
196
* Macros for model groups.
 
197
*/
 
198
#define WXS_IS_MODEL_GROUP(i) \
 
199
    (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
 
200
     ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
 
201
     ((i)->type == XML_SCHEMA_TYPE_ALL))
 
202
 
 
203
#define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
 
204
/*
 
205
* Macros for schema buckets.
 
206
*/
 
207
#define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
 
208
    ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
 
209
 
 
210
#define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
 
211
    ((t) == XML_SCHEMA_SCHEMA_IMPORT))
 
212
 
 
213
#define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
 
214
 
 
215
#define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
 
216
/*
 
217
* Macros for complex/simple types.
 
218
*/
 
219
#define WXS_IS_ANYTYPE(i) \
 
220
     (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
 
221
      ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
 
222
 
 
223
#define WXS_IS_COMPLEX(i) \
 
224
    (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
 
225
     ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
 
226
 
 
227
#define WXS_IS_SIMPLE(item) \
 
228
    ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
 
229
     ((item->type == XML_SCHEMA_TYPE_BASIC) && \
 
230
      (item->builtInType != XML_SCHEMAS_ANYTYPE)))
 
231
 
 
232
#define WXS_IS_ANY_SIMPLE_TYPE(i) \
 
233
    (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
 
234
      ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
 
235
 
 
236
#define WXS_IS_RESTRICTION(t) \
 
237
    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
 
238
 
 
239
#define WXS_IS_EXTENSION(t) \
 
240
    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
 
241
 
 
242
#define WXS_IS_TYPE_NOT_FIXED(i) \
 
243
    (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
 
244
     (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
 
245
 
 
246
#define WXS_IS_TYPE_NOT_FIXED_1(item) \
 
247
    (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
 
248
     (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
 
249
 
 
250
#define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
 
251
 
 
252
#define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
 
253
/*
 
254
* Macros for exclusively for complex types.
 
255
*/
 
256
#define WXS_HAS_COMPLEX_CONTENT(item) \
 
257
    ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
 
258
     (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
 
259
     (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
 
260
 
 
261
#define WXS_HAS_SIMPLE_CONTENT(item) \
 
262
    ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
 
263
     (item->contentType == XML_SCHEMA_CONTENT_BASIC))
 
264
 
 
265
#define WXS_HAS_MIXED_CONTENT(item) \
 
266
    (item->contentType == XML_SCHEMA_CONTENT_MIXED)
 
267
 
 
268
#define WXS_EMPTIABLE(t) \
 
269
    (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
 
270
 
 
271
#define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
 
272
 
 
273
#define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
 
274
 
 
275
#define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
 
276
/*
 
277
* Macros for exclusively for simple types.
 
278
*/
 
279
#define WXS_LIST_ITEMTYPE(t) (t)->subtypes
 
280
 
 
281
#define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
 
282
 
 
283
#define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
 
284
 
 
285
#define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
 
286
/*
 
287
* Misc parser context macros.
 
288
*/
 
289
#define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
 
290
 
 
291
#define WXS_HAS_BUCKETS(ctx) \
 
292
( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
 
293
(WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
 
294
 
 
295
#define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
 
296
 
 
297
#define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
 
298
 
 
299
#define WXS_SCHEMA(ctx) (ctx)->schema
 
300
 
 
301
#define WXS_ADD_LOCAL(ctx, item) \
 
302
    xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
 
303
 
 
304
#define WXS_ADD_GLOBAL(ctx, item) \
 
305
    xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
 
306
 
 
307
#define WXS_ADD_PENDING(ctx, item) \
 
308
    xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
 
309
/*
 
310
* xmlSchemaItemList macros.
 
311
*/
 
312
#define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
 
313
/*
 
314
* Misc macros.
 
315
*/
 
316
#define IS_SCHEMA(node, type) \
 
317
   ((node != NULL) && (node->ns != NULL) && \
 
318
    (xmlStrEqual(node->name, (const xmlChar *) type)) && \
 
319
    (xmlStrEqual(node->ns->href, xmlSchemaNs)))
 
320
 
 
321
#define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
 
322
 
 
323
/*
 
324
* Since we put the default/fixed values into the dict, we can
 
325
* use pointer comparison for those values.
 
326
* REMOVED: (xmlStrEqual((v1), (v2)))
 
327
*/
 
328
#define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
 
329
 
 
330
#define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
 
331
 
 
332
#define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
 
333
 
 
334
#define HFAILURE if (res == -1) goto exit_failure;
 
335
 
 
336
#define HERROR if (res != 0) goto exit_error;
 
337
 
 
338
#define HSTOP(ctx) if ((ctx)->stop) goto exit;
 
339
/*
 
340
* Some flags used for various schema constraints.
 
341
*/
 
342
#define SUBSET_RESTRICTION  1<<0
 
343
#define SUBSET_EXTENSION    1<<1
 
344
#define SUBSET_SUBSTITUTION 1<<2
 
345
#define SUBSET_LIST         1<<3
 
346
#define SUBSET_UNION        1<<4
 
347
 
 
348
typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
 
349
typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
 
350
 
 
351
typedef struct _xmlSchemaItemList xmlSchemaItemList;
 
352
typedef xmlSchemaItemList *xmlSchemaItemListPtr;
 
353
struct _xmlSchemaItemList {
 
354
    void **items;  /* used for dynamic addition of schemata */
 
355
    int nbItems; /* used for dynamic addition of schemata */
 
356
    int sizeItems; /* used for dynamic addition of schemata */
 
357
};
 
358
 
 
359
#define XML_SCHEMA_CTXT_PARSER 1
 
360
#define XML_SCHEMA_CTXT_VALIDATOR 2
 
361
 
 
362
typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
 
363
typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
 
364
struct _xmlSchemaAbstractCtxt {
 
365
    int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
 
366
};
 
367
 
 
368
typedef struct _xmlSchemaBucket xmlSchemaBucket;
 
369
typedef xmlSchemaBucket *xmlSchemaBucketPtr;
 
370
 
 
371
#define XML_SCHEMA_SCHEMA_MAIN 0
 
372
#define XML_SCHEMA_SCHEMA_IMPORT 1
 
373
#define XML_SCHEMA_SCHEMA_INCLUDE 2
 
374
#define XML_SCHEMA_SCHEMA_REDEFINE 3
 
375
 
 
376
/**
 
377
 * xmlSchemaSchemaRelation: 
 
378
 *
 
379
 * Used to create a graph of schema relationships.
 
380
 */
 
381
typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
 
382
typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
 
383
struct _xmlSchemaSchemaRelation {
 
384
    xmlSchemaSchemaRelationPtr next;
 
385
    int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
 
386
    const xmlChar *importNamespace;
 
387
    xmlSchemaBucketPtr bucket;
 
388
};
 
389
 
 
390
#define XML_SCHEMA_BUCKET_MARKED 1<<0
 
391
#define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
 
392
 
 
393
struct _xmlSchemaBucket {
 
394
    int type;
 
395
    int flags;
 
396
    const xmlChar *schemaLocation;
 
397
    const xmlChar *origTargetNamespace;
 
398
    const xmlChar *targetNamespace;
 
399
    xmlDocPtr doc;
 
400
    xmlSchemaSchemaRelationPtr relations;
 
401
    int located;
 
402
    int parsed;
 
403
    int imported;
 
404
    int preserveDoc;
 
405
    xmlSchemaItemListPtr globals; /* Global components. */ 
 
406
    xmlSchemaItemListPtr locals; /* Local components. */
 
407
};
 
408
 
 
409
/**
 
410
 * xmlSchemaImport: 
 
411
 * (extends xmlSchemaBucket)
 
412
 *
 
413
 * Reflects a schema. Holds some information
 
414
 * about the schema and its toplevel components. Duplicate
 
415
 * toplevel components are not checked at this level.
 
416
 */
 
417
typedef struct _xmlSchemaImport xmlSchemaImport;
 
418
typedef xmlSchemaImport *xmlSchemaImportPtr;
 
419
struct _xmlSchemaImport {
 
420
    int type; /* Main OR import OR include. */
 
421
    int flags;
 
422
    const xmlChar *schemaLocation; /* The URI of the schema document. */
 
423
    /* For chameleon includes, @origTargetNamespace will be NULL */
 
424
    const xmlChar *origTargetNamespace;
 
425
    /* 
 
426
    * For chameleon includes, @targetNamespace will be the
 
427
    * targetNamespace of the including schema. 
 
428
    */
 
429
    const xmlChar *targetNamespace;
 
430
    xmlDocPtr doc; /* The schema node-tree. */
 
431
    /* @relations will hold any included/imported/redefined schemas. */
 
432
    xmlSchemaSchemaRelationPtr relations;
 
433
    int located;
 
434
    int parsed;
 
435
    int imported;
 
436
    int preserveDoc;
 
437
    xmlSchemaItemListPtr globals;
 
438
    xmlSchemaItemListPtr locals;
 
439
    /* The imported schema. */
 
440
    xmlSchemaPtr schema;
 
441
};
 
442
 
 
443
/*
 
444
* (extends xmlSchemaBucket)
 
445
*/
 
446
typedef struct _xmlSchemaInclude xmlSchemaInclude;
 
447
typedef xmlSchemaInclude *xmlSchemaIncludePtr;
 
448
struct _xmlSchemaInclude {
 
449
    int type;
 
450
    int flags;
 
451
    const xmlChar *schemaLocation;
 
452
    const xmlChar *origTargetNamespace;
 
453
    const xmlChar *targetNamespace;
 
454
    xmlDocPtr doc;
 
455
    xmlSchemaSchemaRelationPtr relations;
 
456
    int located;
 
457
    int parsed;
 
458
    int imported;
 
459
    int preserveDoc;
 
460
    xmlSchemaItemListPtr globals; /* Global components. */ 
 
461
    xmlSchemaItemListPtr locals; /* Local components. */
 
462
 
 
463
    /* The owning main or import schema bucket. */
 
464
    xmlSchemaImportPtr ownerImport;
 
465
};
 
466
 
 
467
/**
 
468
 * xmlSchemaBasicItem:
 
469
 *
 
470
 * The abstract base type for schema components.
 
471
 */
 
472
typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
 
473
typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
 
474
struct _xmlSchemaBasicItem {
 
475
    xmlSchemaTypeType type;
 
476
};
 
477
 
 
478
/**
 
479
 * xmlSchemaAnnotItem:
 
480
 *
 
481
 * The abstract base type for annotated schema components.
 
482
 * (Extends xmlSchemaBasicItem)
 
483
 */
 
484
typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
 
485
typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
 
486
struct _xmlSchemaAnnotItem {
 
487
    xmlSchemaTypeType type;
 
488
    xmlSchemaAnnotPtr annot;
 
489
};
 
490
 
 
491
/**
 
492
 * xmlSchemaTreeItem:
 
493
 *
 
494
 * The abstract base type for tree-like structured schema components.
 
495
 * (Extends xmlSchemaAnnotItem)
 
496
 */
 
497
typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
 
498
typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
 
499
struct _xmlSchemaTreeItem {
 
500
    xmlSchemaTypeType type;
 
501
    xmlSchemaAnnotPtr annot;
 
502
    xmlSchemaTreeItemPtr next;
 
503
    xmlSchemaTreeItemPtr children;
 
504
};
 
505
 
 
506
 
 
507
#define XML_SCHEMA_ATTR_USE_FIXED 1<<0
 
508
/**
 
509
 * xmlSchemaAttributeUsePtr:
 
510
 *
 
511
 * The abstract base type for tree-like structured schema components.
 
512
 * (Extends xmlSchemaTreeItem)
 
513
 */
 
514
typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
 
515
typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
 
516
struct _xmlSchemaAttributeUse {
 
517
    xmlSchemaTypeType type;
 
518
    xmlSchemaAnnotPtr annot;
 
519
    xmlSchemaAttributeUsePtr next; /* The next attr. use. */
 
520
    /* 
 
521
    * The attr. decl. OR a QName-ref. to an attr. decl. OR
 
522
    * a QName-ref. to an attribute group definition.
 
523
    */
 
524
    xmlSchemaAttributePtr attrDecl;
 
525
 
 
526
    int flags;
 
527
    xmlNodePtr node;
 
528
    int occurs; /* required, optional */
 
529
    const xmlChar * defValue;
 
530
    xmlSchemaValPtr defVal;
 
531
};
 
532
 
 
533
/**
 
534
 * xmlSchemaAttributeUseProhibPtr:
 
535
 *
 
536
 * A helper component to reflect attribute prohibitions.
 
537
 * (Extends xmlSchemaBasicItem)
 
538
 */
 
539
typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
 
540
typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
 
541
struct _xmlSchemaAttributeUseProhib {
 
542
    xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
 
543
    xmlNodePtr node;
 
544
    const xmlChar *name;
 
545
    const xmlChar *targetNamespace;
 
546
    int isRef;
 
547
};
 
548
 
 
549
/**
 
550
 * xmlSchemaRedef:
 
551
 */
 
552
typedef struct _xmlSchemaRedef xmlSchemaRedef;
 
553
typedef xmlSchemaRedef *xmlSchemaRedefPtr;
 
554
struct _xmlSchemaRedef {
 
555
    xmlSchemaRedefPtr next;
 
556
    xmlSchemaBasicItemPtr item; /* The redefining component. */
 
557
    xmlSchemaBasicItemPtr reference; /* The referencing component. */
 
558
    xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
 
559
    const xmlChar *refName; /* The name of the to-be-redefined component. */
 
560
    const xmlChar *refTargetNs; /* The target namespace of the
 
561
                                   to-be-redefined comp. */
 
562
    xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
 
563
};
 
564
 
 
565
/**
 
566
 * xmlSchemaConstructionCtxt:
 
567
 */
 
568
typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
 
569
typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
 
570
struct _xmlSchemaConstructionCtxt {
 
571
    xmlSchemaPtr mainSchema; /* The main schema. */
 
572
    xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
 
573
    xmlDictPtr dict;
 
574
    xmlSchemaItemListPtr buckets; /* List of schema buckets. */
 
575
    /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
 
576
    xmlSchemaBucketPtr bucket; /* The current schema bucket */    
 
577
    xmlSchemaItemListPtr pending; /* All Components of all schemas that
 
578
                                     need to be fixed. */
 
579
    xmlHashTablePtr substGroups;
 
580
    xmlSchemaRedefPtr redefs;
 
581
    xmlSchemaRedefPtr lastRedef;
 
582
};
 
583
 
 
584
#define XML_SCHEMAS_PARSE_ERROR         1
 
585
#define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
 
586
 
 
587
struct _xmlSchemaParserCtxt {
 
588
    int type;
 
589
    void *errCtxt;             /* user specific error context */
 
590
    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
 
591
    xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
 
592
    int err;
 
593
    int nberrors;
 
594
    xmlStructuredErrorFunc serror;
 
595
 
 
596
    xmlSchemaConstructionCtxtPtr constructor;
 
597
    int ownsConstructor; /* TODO: Move this to parser *flags*. */
 
598
 
 
599
    /* xmlSchemaPtr topschema;  */
 
600
    /* xmlHashTablePtr namespaces;  */
 
601
 
 
602
    xmlSchemaPtr schema;        /* The main schema in use */
 
603
    int counter;
 
604
 
 
605
    const xmlChar *URL;
 
606
    xmlDocPtr doc;
 
607
    int preserve;               /* Whether the doc should be freed  */
 
608
 
 
609
    const char *buffer;
 
610
    int size;
 
611
 
 
612
    /*
 
613
     * Used to build complex element content models
 
614
     */
 
615
    xmlAutomataPtr am;
 
616
    xmlAutomataStatePtr start;
 
617
    xmlAutomataStatePtr end;
 
618
    xmlAutomataStatePtr state;
 
619
 
 
620
    xmlDictPtr dict;            /* dictionnary for interned string names */
 
621
    xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
 
622
    int options;
 
623
    xmlSchemaValidCtxtPtr vctxt;
 
624
    int isS4S;
 
625
    int isRedefine;
 
626
    int xsiAssemble;
 
627
    int stop; /* If the parser should stop; i.e. a critical error. */
 
628
    const xmlChar *targetNamespace;
 
629
    xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
 
630
 
 
631
    xmlSchemaRedefPtr redef; /* Used for redefinitions. */
 
632
    int redefCounter; /* Used for redefinitions. */ 
 
633
    xmlSchemaItemListPtr attrProhibs;
 
634
};
 
635
 
 
636
/**
 
637
 * xmlSchemaQNameRef:
 
638
 *
 
639
 * A component reference item (not a schema component)
 
640
 * (Extends xmlSchemaBasicItem)
 
641
 */
 
642
typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
 
643
typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
 
644
struct _xmlSchemaQNameRef {
 
645
    xmlSchemaTypeType type;
 
646
    xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
 
647
    xmlSchemaTypeType itemType;
 
648
    const xmlChar *name;
 
649
    const xmlChar *targetNamespace;
 
650
    xmlNodePtr node;
 
651
};
 
652
 
 
653
/**
 
654
 * xmlSchemaParticle:
 
655
 *
 
656
 * A particle component.
 
657
 * (Extends xmlSchemaTreeItem)
 
658
 */
 
659
typedef struct _xmlSchemaParticle xmlSchemaParticle;
 
660
typedef xmlSchemaParticle *xmlSchemaParticlePtr;
 
661
struct _xmlSchemaParticle {
 
662
    xmlSchemaTypeType type;
 
663
    xmlSchemaAnnotPtr annot;
 
664
    xmlSchemaTreeItemPtr next; /* next particle */
 
665
    xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
 
666
        a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
 
667
        etc.) */
 
668
    int minOccurs;
 
669
    int maxOccurs;
 
670
    xmlNodePtr node;
 
671
};
 
672
 
 
673
/**
 
674
 * xmlSchemaModelGroup:
 
675
 *
 
676
 * A model group component.
 
677
 * (Extends xmlSchemaTreeItem)
 
678
 */
 
679
typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
 
680
typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
 
681
struct _xmlSchemaModelGroup {
 
682
    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
 
683
    xmlSchemaAnnotPtr annot;
 
684
    xmlSchemaTreeItemPtr next; /* not used */
 
685
    xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
 
686
    xmlNodePtr node;
 
687
};
 
688
 
 
689
#define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
 
690
#define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
 
691
/**
 
692
 * xmlSchemaModelGroupDef:
 
693
 *
 
694
 * A model group definition component.
 
695
 * (Extends xmlSchemaTreeItem)
 
696
 */
 
697
typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
 
698
typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
 
699
struct _xmlSchemaModelGroupDef {
 
700
    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
 
701
    xmlSchemaAnnotPtr annot;
 
702
    xmlSchemaTreeItemPtr next; /* not used */
 
703
    xmlSchemaTreeItemPtr children; /* the "model group" */
 
704
    const xmlChar *name;
 
705
    const xmlChar *targetNamespace;
 
706
    xmlNodePtr node;
 
707
    int flags;
 
708
};
 
709
 
 
710
typedef struct _xmlSchemaIDC xmlSchemaIDC;
 
711
typedef xmlSchemaIDC *xmlSchemaIDCPtr;
 
712
 
 
713
/**
 
714
 * xmlSchemaIDCSelect:
 
715
 *
 
716
 * The identity-constraint "field" and "selector" item, holding the
 
717
 * XPath expression.
 
718
 */
 
719
typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
 
720
typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
 
721
struct _xmlSchemaIDCSelect {
 
722
    xmlSchemaIDCSelectPtr next;
 
723
    xmlSchemaIDCPtr idc;
 
724
    int index; /* an index position if significant for IDC key-sequences */
 
725
    const xmlChar *xpath; /* the XPath expression */
 
726
    void *xpathComp; /* the compiled XPath expression */
 
727
};
 
728
 
 
729
/**
 
730
 * xmlSchemaIDC:
 
731
 *
 
732
 * The identity-constraint definition component.
 
733
 * (Extends xmlSchemaAnnotItem)
 
734
 */
 
735
 
 
736
struct _xmlSchemaIDC {
 
737
    xmlSchemaTypeType type;
 
738
    xmlSchemaAnnotPtr annot;
 
739
    xmlSchemaIDCPtr next;
 
740
    xmlNodePtr node;
 
741
    const xmlChar *name;
 
742
    const xmlChar *targetNamespace;
 
743
    xmlSchemaIDCSelectPtr selector;
 
744
    xmlSchemaIDCSelectPtr fields;
 
745
    int nbFields;
 
746
    xmlSchemaQNameRefPtr ref;
 
747
};
 
748
 
 
749
/**
 
750
 * xmlSchemaIDCAug:
 
751
 *
 
752
 * The augmented IDC information used for validation.
 
753
 */
 
754
typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
 
755
typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
 
756
struct _xmlSchemaIDCAug {
 
757
    xmlSchemaIDCAugPtr next; /* next in a list */
 
758
    xmlSchemaIDCPtr def; /* the IDC definition */
 
759
    int keyrefDepth; /* the lowest tree level to which IDC
 
760
                        tables need to be bubbled upwards */
 
761
};
 
762
 
 
763
/**
 
764
 * xmlSchemaPSVIIDCKeySequence:
 
765
 *
 
766
 * The key sequence of a node table item.
 
767
 */
 
768
typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
 
769
typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
 
770
struct _xmlSchemaPSVIIDCKey {
 
771
    xmlSchemaTypePtr type;
 
772
    xmlSchemaValPtr val;
 
773
};
 
774
 
 
775
/**
 
776
 * xmlSchemaPSVIIDCNode:
 
777
 *
 
778
 * The node table item of a node table.
 
779
 */
 
780
typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
 
781
typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
 
782
struct _xmlSchemaPSVIIDCNode {
 
783
    xmlNodePtr node;
 
784
    xmlSchemaPSVIIDCKeyPtr *keys;
 
785
    int nodeLine;
 
786
    int nodeQNameID;    
 
787
 
 
788
};
 
789
 
 
790
/**
 
791
 * xmlSchemaPSVIIDCBinding:
 
792
 *
 
793
 * The identity-constraint binding item of the [identity-constraint table].
 
794
 */
 
795
typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
 
796
typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
 
797
struct _xmlSchemaPSVIIDCBinding {
 
798
    xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
 
799
    xmlSchemaIDCPtr definition; /* the IDC definition */
 
800
    xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
 
801
    int nbNodes; /* number of entries in the node table */
 
802
    int sizeNodes; /* size of the node table */
 
803
    xmlSchemaItemListPtr dupls;
 
804
};
 
805
 
 
806
 
 
807
#define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
 
808
#define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
 
809
 
 
810
#define XPATH_STATE_OBJ_MATCHES -2
 
811
#define XPATH_STATE_OBJ_BLOCKED -3
 
812
 
 
813
typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
 
814
typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
 
815
 
 
816
/**
 
817
 * xmlSchemaIDCStateObj:
 
818
 *
 
819
 * The state object used to evaluate XPath expressions.
 
820
 */
 
821
typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
 
822
typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
 
823
struct _xmlSchemaIDCStateObj {
 
824
    int type;
 
825
    xmlSchemaIDCStateObjPtr next; /* next if in a list */
 
826
    int depth; /* depth of creation */
 
827
    int *history; /* list of (depth, state-id) tuples */
 
828
    int nbHistory;
 
829
    int sizeHistory;
 
830
    xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
 
831
                                       matcher */
 
832
    xmlSchemaIDCSelectPtr sel;
 
833
    void *xpathCtxt;
 
834
};
 
835
 
 
836
#define IDC_MATCHER 0
 
837
 
 
838
/**
 
839
 * xmlSchemaIDCMatcher:
 
840
 *
 
841
 * Used to evaluate IDC selectors (and fields).
 
842
 */
 
843
struct _xmlSchemaIDCMatcher {
 
844
    int type;
 
845
    int depth; /* the tree depth at creation time */
 
846
    xmlSchemaIDCMatcherPtr next; /* next in the list */
 
847
    xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
 
848
    xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
 
849
    int idcType;
 
850
    xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
 
851
                                         elements */
 
852
    int sizeKeySeqs;
 
853
    xmlSchemaItemListPtr targets; /* list of target-node
 
854
                                     (xmlSchemaPSVIIDCNodePtr) entries */
 
855
};
 
856
 
 
857
/*
 
858
* Element info flags.
 
859
*/
 
860
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES  1<<0
 
861
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
 
862
#define XML_SCHEMA_ELEM_INFO_NILLED            1<<2
 
863
#define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE        1<<3
 
864
 
 
865
#define XML_SCHEMA_NODE_INFO_VALUE_NEEDED      1<<4
 
866
#define XML_SCHEMA_ELEM_INFO_EMPTY             1<<5
 
867
#define XML_SCHEMA_ELEM_INFO_HAS_CONTENT       1<<6
 
868
 
 
869
#define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT  1<<7
 
870
#define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT  1<<8
 
871
#define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED  1<<9
 
872
#define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE  1<<10
 
873
 
 
874
/**
 
875
 * xmlSchemaNodeInfo:
 
876
 *
 
877
 * Holds information of an element node.
 
878
 */
 
879
struct _xmlSchemaNodeInfo {
 
880
    int nodeType;
 
881
    xmlNodePtr node;
 
882
    int nodeLine;    
 
883
    const xmlChar *localName;
 
884
    const xmlChar *nsName;
 
885
    const xmlChar *value;
 
886
    xmlSchemaValPtr val; /* the pre-computed value if any */
 
887
    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
 
888
 
 
889
    int flags; /* combination of node info flags */
 
890
 
 
891
    int valNeeded;
 
892
    int normVal;
 
893
 
 
894
    xmlSchemaElementPtr decl; /* the element/attribute declaration */
 
895
    int depth;
 
896
    xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
 
897
                                            for the scope element*/
 
898
    xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
 
899
                                           element */
 
900
    xmlRegExecCtxtPtr regexCtxt;
 
901
 
 
902
    const xmlChar **nsBindings; /* Namespace bindings on this element */
 
903
    int nbNsBindings;
 
904
    int sizeNsBindings;    
 
905
 
 
906
    int hasKeyrefs;
 
907
    int appliedXPath; /* Indicates that an XPath has been applied. */
 
908
};
 
909
 
 
910
#define XML_SCHEMAS_ATTR_UNKNOWN 1
 
911
#define XML_SCHEMAS_ATTR_ASSESSED 2
 
912
#define XML_SCHEMAS_ATTR_PROHIBITED 3
 
913
#define XML_SCHEMAS_ATTR_ERR_MISSING 4
 
914
#define XML_SCHEMAS_ATTR_INVALID_VALUE 5
 
915
#define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
 
916
#define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
 
917
#define XML_SCHEMAS_ATTR_DEFAULT 8
 
918
#define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
 
919
#define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
 
920
#define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
 
921
#define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
 
922
#define XML_SCHEMAS_ATTR_WILD_SKIP 13
 
923
#define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
 
924
#define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
 
925
#define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
 
926
#define XML_SCHEMAS_ATTR_META 17
 
927
/*
 
928
* @metaType values of xmlSchemaAttrInfo.
 
929
*/
 
930
#define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
 
931
#define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
 
932
#define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
 
933
#define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
 
934
#define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
 
935
 
 
936
typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
 
937
typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
 
938
struct _xmlSchemaAttrInfo {
 
939
    int nodeType;
 
940
    xmlNodePtr node;
 
941
    int nodeLine;    
 
942
    const xmlChar *localName;
 
943
    const xmlChar *nsName;
 
944
    const xmlChar *value;
 
945
    xmlSchemaValPtr val; /* the pre-computed value if any */
 
946
    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
 
947
    int flags; /* combination of node info flags */
 
948
 
 
949
    xmlSchemaAttributePtr decl; /* the attribute declaration */
 
950
    xmlSchemaAttributeUsePtr use;  /* the attribute use */
 
951
    int state;
 
952
    int metaType;
 
953
    const xmlChar *vcValue; /* the value constraint value */
 
954
    xmlSchemaNodeInfoPtr parent;
 
955
};
 
956
 
 
957
 
 
958
#define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
 
959
/**
 
960
 * xmlSchemaValidCtxt:
 
961
 *
 
962
 * A Schemas validation context
 
963
 */
 
964
struct _xmlSchemaValidCtxt {
 
965
    int type;
 
966
    void *errCtxt;             /* user specific data block */
 
967
    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
 
968
    xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
 
969
    xmlStructuredErrorFunc serror;
 
970
 
 
971
    xmlSchemaPtr schema;        /* The schema in use */
 
972
    xmlDocPtr doc;
 
973
    xmlParserInputBufferPtr input;
 
974
    xmlCharEncoding enc;
 
975
    xmlSAXHandlerPtr sax;
 
976
    xmlParserCtxtPtr parserCtxt;
 
977
    void *user_data; /* TODO: What is this for? */
 
978
 
 
979
    int err;
 
980
    int nberrors;
 
981
 
 
982
    xmlNodePtr node;
 
983
    xmlNodePtr cur;
 
984
    /* xmlSchemaTypePtr type; */
 
985
 
 
986
    xmlRegExecCtxtPtr regexp;
 
987
    xmlSchemaValPtr value;
 
988
 
 
989
    int valueWS;
 
990
    int options;
 
991
    xmlNodePtr validationRoot;
 
992
    xmlSchemaParserCtxtPtr pctxt;
 
993
    int xsiAssemble;
 
994
 
 
995
    int depth;
 
996
    xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */
 
997
    int sizeElemInfos;
 
998
    xmlSchemaNodeInfoPtr inode; /* the current element information */
 
999
 
 
1000
    xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */
 
1001
 
 
1002
    xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
 
1003
    xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
 
1004
    xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
 
1005
 
 
1006
    xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
 
1007
    int nbIdcNodes;
 
1008
    int sizeIdcNodes;
 
1009
 
 
1010
    xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
 
1011
    int nbIdcKeys;
 
1012
    int sizeIdcKeys;
 
1013
 
 
1014
    int flags;
 
1015
 
 
1016
    xmlDictPtr dict;
 
1017
 
 
1018
#ifdef LIBXML_READER_ENABLED
 
1019
    xmlTextReaderPtr reader;
 
1020
#endif
 
1021
 
 
1022
    xmlSchemaAttrInfoPtr *attrInfos;
 
1023
    int nbAttrInfos;
 
1024
    int sizeAttrInfos;
 
1025
 
 
1026
    int skipDepth;
 
1027
    xmlSchemaItemListPtr nodeQNames;
 
1028
    int hasKeyrefs;
 
1029
    int createIDCNodeTables;
 
1030
    int psviExposeIDCNodeTables;
 
1031
};
 
1032
 
 
1033
/**
 
1034
 * xmlSchemaSubstGroup:
 
1035
 *
 
1036
 *
 
1037
 */
 
1038
typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
 
1039
typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
 
1040
struct _xmlSchemaSubstGroup {
 
1041
    xmlSchemaElementPtr head;
 
1042
    xmlSchemaItemListPtr members;
 
1043
};
 
1044
 
 
1045
/************************************************************************
 
1046
 *                                                                      *
 
1047
 *                      Some predeclarations                            *
 
1048
 *                                                                      *
 
1049
 ************************************************************************/
 
1050
 
 
1051
static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
 
1052
                                 xmlSchemaPtr schema,
 
1053
                                 xmlNodePtr node);
 
1054
static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
 
1055
                                 xmlSchemaPtr schema,
 
1056
                                 xmlNodePtr node);
 
1057
static int
 
1058
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
 
1059
                   xmlSchemaAbstractCtxtPtr ctxt);
 
1060
static const xmlChar *
 
1061
xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
 
1062
static int
 
1063
xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
1064
                     xmlNodePtr node);
 
1065
static int
 
1066
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
 
1067
                       xmlSchemaParserCtxtPtr ctxt);
 
1068
static void
 
1069
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
 
1070
static xmlSchemaWhitespaceValueType
 
1071
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
 
1072
static xmlSchemaTreeItemPtr
 
1073
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
1074
                         xmlNodePtr node, xmlSchemaTypeType type,
 
1075
                         int withParticle);
 
1076
static const xmlChar *
 
1077
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
 
1078
static xmlSchemaTypeLinkPtr
 
1079
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
 
1080
static void
 
1081
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
 
1082
                     const char *funcName,
 
1083
                     const char *message);
 
1084
static int
 
1085
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
 
1086
                             xmlSchemaTypePtr type,
 
1087
                             xmlSchemaTypePtr baseType,
 
1088
                             int subset);
 
1089
static void
 
1090
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
 
1091
                                   xmlSchemaParserCtxtPtr ctxt);
 
1092
static void
 
1093
xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
 
1094
static xmlSchemaQNameRefPtr
 
1095
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
 
1096
                                xmlSchemaPtr schema,
 
1097
                                xmlNodePtr node);
 
1098
 
 
1099
/************************************************************************
 
1100
 *                                                                      *
 
1101
 *                      Helper functions                                *
 
1102
 *                                                                      *
 
1103
 ************************************************************************/
 
1104
 
 
1105
/**
 
1106
 * xmlSchemaItemTypeToStr:
 
1107
 * @type: the type of the schema item
 
1108
 *
 
1109
 * Returns the component name of a schema item.
 
1110
 */
 
1111
static const xmlChar *
 
1112
xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
 
1113
{
 
1114
    switch (type) {
 
1115
        case XML_SCHEMA_TYPE_BASIC:
 
1116
            return(BAD_CAST "simple type definition");
 
1117
        case XML_SCHEMA_TYPE_SIMPLE:
 
1118
            return(BAD_CAST "simple type definition");
 
1119
        case XML_SCHEMA_TYPE_COMPLEX:
 
1120
            return(BAD_CAST "complex type definition");
 
1121
        case XML_SCHEMA_TYPE_ELEMENT:
 
1122
            return(BAD_CAST "element declaration");
 
1123
        case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 
1124
            return(BAD_CAST "attribute use");
 
1125
        case XML_SCHEMA_TYPE_ATTRIBUTE:
 
1126
            return(BAD_CAST "attribute declaration");
 
1127
        case XML_SCHEMA_TYPE_GROUP:
 
1128
            return(BAD_CAST "model group definition");
 
1129
        case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 
1130
            return(BAD_CAST "attribute group definition");
 
1131
        case XML_SCHEMA_TYPE_NOTATION:
 
1132
            return(BAD_CAST "notation declaration");
 
1133
        case XML_SCHEMA_TYPE_SEQUENCE:
 
1134
            return(BAD_CAST "model group (sequence)");
 
1135
        case XML_SCHEMA_TYPE_CHOICE:
 
1136
            return(BAD_CAST "model group (choice)");
 
1137
        case XML_SCHEMA_TYPE_ALL:
 
1138
            return(BAD_CAST "model group (all)");
 
1139
        case XML_SCHEMA_TYPE_PARTICLE:
 
1140
            return(BAD_CAST "particle");
 
1141
        case XML_SCHEMA_TYPE_IDC_UNIQUE:
 
1142
            return(BAD_CAST "unique identity-constraint");
 
1143
            /* return(BAD_CAST "IDC (unique)"); */
 
1144
        case XML_SCHEMA_TYPE_IDC_KEY:
 
1145
            return(BAD_CAST "key identity-constraint");
 
1146
            /* return(BAD_CAST "IDC (key)"); */
 
1147
        case XML_SCHEMA_TYPE_IDC_KEYREF:
 
1148
            return(BAD_CAST "keyref identity-constraint");
 
1149
            /* return(BAD_CAST "IDC (keyref)"); */
 
1150
        case XML_SCHEMA_TYPE_ANY:
 
1151
            return(BAD_CAST "wildcard (any)");
 
1152
        case XML_SCHEMA_EXTRA_QNAMEREF:
 
1153
            return(BAD_CAST "[helper component] QName reference");
 
1154
        case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
 
1155
            return(BAD_CAST "[helper component] attribute use prohibition");
 
1156
        default:
 
1157
            return(BAD_CAST "Not a schema component");
 
1158
    }
 
1159
}
 
1160
 
 
1161
/**
 
1162
 * xmlSchemaGetComponentTypeStr:
 
1163
 * @type: the type of the schema item
 
1164
 *
 
1165
 * Returns the component name of a schema item.
 
1166
 */
 
1167
static const xmlChar *
 
1168
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
 
1169
{
 
1170
    switch (item->type) {
 
1171
        case XML_SCHEMA_TYPE_BASIC:
 
1172
            if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
 
1173
                return(BAD_CAST "complex type definition");
 
1174
            else
 
1175
                return(BAD_CAST "simple type definition");      
 
1176
        default:
 
1177
            return(xmlSchemaItemTypeToStr(item->type));
 
1178
    }
 
1179
}
 
1180
 
 
1181
/**
 
1182
 * xmlSchemaGetComponentNode:
 
1183
 * @item: a schema component
 
1184
 *
 
1185
 * Returns node associated with the schema component.
 
1186
 * NOTE that such a node need not be available; plus, a component's
 
1187
 * node need not to reflect the component directly, since there is no
 
1188
 * one-to-one relationship between the XML Schema representation and
 
1189
 * the component representation.
 
1190
 */
 
1191
static xmlNodePtr
 
1192
xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
 
1193
{
 
1194
    switch (item->type) {
 
1195
        case XML_SCHEMA_TYPE_ELEMENT:
 
1196
            return (((xmlSchemaElementPtr) item)->node);
 
1197
        case XML_SCHEMA_TYPE_ATTRIBUTE:
 
1198
            return (((xmlSchemaAttributePtr) item)->node);
 
1199
        case XML_SCHEMA_TYPE_COMPLEX:
 
1200
        case XML_SCHEMA_TYPE_SIMPLE:
 
1201
            return (((xmlSchemaTypePtr) item)->node);
 
1202
        case XML_SCHEMA_TYPE_ANY:
 
1203
        case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 
1204
            return (((xmlSchemaWildcardPtr) item)->node);
 
1205
        case XML_SCHEMA_TYPE_PARTICLE:
 
1206
            return (((xmlSchemaParticlePtr) item)->node);
 
1207
        case XML_SCHEMA_TYPE_SEQUENCE:
 
1208
        case XML_SCHEMA_TYPE_CHOICE:
 
1209
        case XML_SCHEMA_TYPE_ALL:
 
1210
            return (((xmlSchemaModelGroupPtr) item)->node);
 
1211
        case XML_SCHEMA_TYPE_GROUP:
 
1212
            return (((xmlSchemaModelGroupDefPtr) item)->node);
 
1213
        case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 
1214
            return (((xmlSchemaAttributeGroupPtr) item)->node);
 
1215
        case XML_SCHEMA_TYPE_IDC_UNIQUE:
 
1216
        case XML_SCHEMA_TYPE_IDC_KEY:
 
1217
        case XML_SCHEMA_TYPE_IDC_KEYREF:
 
1218
            return (((xmlSchemaIDCPtr) item)->node);
 
1219
        case XML_SCHEMA_EXTRA_QNAMEREF:
 
1220
            return(((xmlSchemaQNameRefPtr) item)->node);
 
1221
        /* TODO: What to do with NOTATIONs?
 
1222
        case XML_SCHEMA_TYPE_NOTATION:
 
1223
            return (((xmlSchemaNotationPtr) item)->node);
 
1224
        */
 
1225
        case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 
1226
            return (((xmlSchemaAttributeUsePtr) item)->node);
 
1227
        default:
 
1228
            return (NULL);
 
1229
    }
 
1230
}
 
1231
 
 
1232
#if 0
 
1233
/**
 
1234
 * xmlSchemaGetNextComponent:
 
1235
 * @item: a schema component
 
1236
 *
 
1237
 * Returns the next sibling of the schema component.
 
1238
 */
 
1239
static xmlSchemaBasicItemPtr
 
1240
xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
 
1241
{
 
1242
    switch (item->type) {
 
1243
        case XML_SCHEMA_TYPE_ELEMENT:
 
1244
            return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
 
1245
        case XML_SCHEMA_TYPE_ATTRIBUTE:
 
1246
            return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
 
1247
        case XML_SCHEMA_TYPE_COMPLEX:
 
1248
        case XML_SCHEMA_TYPE_SIMPLE:
 
1249
            return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
 
1250
        case XML_SCHEMA_TYPE_ANY:
 
1251
        case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 
1252
            return (NULL);
 
1253
        case XML_SCHEMA_TYPE_PARTICLE:
 
1254
            return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
 
1255
        case XML_SCHEMA_TYPE_SEQUENCE:
 
1256
        case XML_SCHEMA_TYPE_CHOICE:
 
1257
        case XML_SCHEMA_TYPE_ALL:
 
1258
            return (NULL);
 
1259
        case XML_SCHEMA_TYPE_GROUP:
 
1260
            return (NULL);
 
1261
        case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 
1262
            return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
 
1263
        case XML_SCHEMA_TYPE_IDC_UNIQUE:
 
1264
        case XML_SCHEMA_TYPE_IDC_KEY:
 
1265
        case XML_SCHEMA_TYPE_IDC_KEYREF:
 
1266
            return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
 
1267
        default:
 
1268
            return (NULL);
 
1269
    }
 
1270
}
 
1271
#endif
 
1272
 
 
1273
 
 
1274
/**
 
1275
 * xmlSchemaFormatQName:
 
1276
 * @buf: the string buffer
 
1277
 * @namespaceName:  the namespace name
 
1278
 * @localName: the local name
 
1279
 *
 
1280
 * Returns the given QName in the format "{namespaceName}localName" or
 
1281
 * just "localName" if @namespaceName is NULL.
 
1282
 *
 
1283
 * Returns the localName if @namespaceName is NULL, a formatted
 
1284
 * string otherwise.
 
1285
 */
 
1286
static const xmlChar*
 
1287
xmlSchemaFormatQName(xmlChar **buf,
 
1288
                     const xmlChar *namespaceName,
 
1289
                     const xmlChar *localName)
 
1290
{
 
1291
    FREE_AND_NULL(*buf)
 
1292
    if (namespaceName != NULL) {
 
1293
        *buf = xmlStrdup(BAD_CAST "{");
 
1294
        *buf = xmlStrcat(*buf, namespaceName);
 
1295
        *buf = xmlStrcat(*buf, BAD_CAST "}");
 
1296
    }
 
1297
    if (localName != NULL) {
 
1298
        if (namespaceName == NULL)
 
1299
            return(localName);
 
1300
        *buf = xmlStrcat(*buf, localName);
 
1301
    } else {
 
1302
        *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
 
1303
    }    
 
1304
    return ((const xmlChar *) *buf);
 
1305
}
 
1306
 
 
1307
static const xmlChar*   
 
1308
xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
 
1309
{
 
1310
    if (ns != NULL)
 
1311
        return (xmlSchemaFormatQName(buf, ns->href, localName));
 
1312
    else
 
1313
        return (xmlSchemaFormatQName(buf, NULL, localName));
 
1314
}
 
1315
 
 
1316
static const xmlChar *
 
1317
xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
 
1318
{
 
1319
    switch (item->type) {
 
1320
        case XML_SCHEMA_TYPE_ELEMENT:
 
1321
            return (((xmlSchemaElementPtr) item)->name);
 
1322
        case XML_SCHEMA_TYPE_ATTRIBUTE:
 
1323
            return (((xmlSchemaAttributePtr) item)->name);
 
1324
        case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 
1325
            return (((xmlSchemaAttributeGroupPtr) item)->name);
 
1326
        case XML_SCHEMA_TYPE_BASIC:
 
1327
        case XML_SCHEMA_TYPE_SIMPLE:
 
1328
        case XML_SCHEMA_TYPE_COMPLEX:
 
1329
            return (((xmlSchemaTypePtr) item)->name);
 
1330
        case XML_SCHEMA_TYPE_GROUP:
 
1331
            return (((xmlSchemaModelGroupDefPtr) item)->name);
 
1332
        case XML_SCHEMA_TYPE_IDC_KEY:
 
1333
        case XML_SCHEMA_TYPE_IDC_UNIQUE:
 
1334
        case XML_SCHEMA_TYPE_IDC_KEYREF:
 
1335
            return (((xmlSchemaIDCPtr) item)->name);
 
1336
        case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 
1337
            if (WXS_ATTRUSE_DECL(item) != NULL) {
 
1338
                return(xmlSchemaGetComponentName(
 
1339
                    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
 
1340
            } else
 
1341
                return(NULL);
 
1342
        case XML_SCHEMA_EXTRA_QNAMEREF:
 
1343
            return (((xmlSchemaQNameRefPtr) item)->name);
 
1344
        case XML_SCHEMA_TYPE_NOTATION:
 
1345
            return (((xmlSchemaNotationPtr) item)->name);
 
1346
        default:
 
1347
            /*
 
1348
            * Other components cannot have names.
 
1349
            */
 
1350
            break;
 
1351
    }
 
1352
    return (NULL);
 
1353
}
 
1354
 
 
1355
#define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
 
1356
#define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
 
1357
/*
 
1358
static const xmlChar *
 
1359
xmlSchemaGetQNameRefName(void *ref)
 
1360
{
 
1361
    return(((xmlSchemaQNameRefPtr) ref)->name);
 
1362
}
 
1363
 
 
1364
static const xmlChar *
 
1365
xmlSchemaGetQNameRefTargetNs(void *ref)
 
1366
{
 
1367
    return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
 
1368
}
 
1369
*/
 
1370
 
 
1371
static const xmlChar *
 
1372
xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
 
1373
{
 
1374
    switch (item->type) {
 
1375
        case XML_SCHEMA_TYPE_ELEMENT:
 
1376
            return (((xmlSchemaElementPtr) item)->targetNamespace);
 
1377
        case XML_SCHEMA_TYPE_ATTRIBUTE:
 
1378
            return (((xmlSchemaAttributePtr) item)->targetNamespace);
 
1379
        case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 
1380
            return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
 
1381
        case XML_SCHEMA_TYPE_BASIC:
 
1382
            return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
 
1383
        case XML_SCHEMA_TYPE_SIMPLE:
 
1384
        case XML_SCHEMA_TYPE_COMPLEX:
 
1385
            return (((xmlSchemaTypePtr) item)->targetNamespace);
 
1386
        case XML_SCHEMA_TYPE_GROUP:
 
1387
            return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
 
1388
        case XML_SCHEMA_TYPE_IDC_KEY:
 
1389
        case XML_SCHEMA_TYPE_IDC_UNIQUE:
 
1390
        case XML_SCHEMA_TYPE_IDC_KEYREF:
 
1391
            return (((xmlSchemaIDCPtr) item)->targetNamespace);
 
1392
        case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 
1393
            if (WXS_ATTRUSE_DECL(item) != NULL) {
 
1394
                return(xmlSchemaGetComponentTargetNs(
 
1395
                    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
 
1396
            }
 
1397
            /* TODO: Will returning NULL break something? */
 
1398
            break;
 
1399
        case XML_SCHEMA_EXTRA_QNAMEREF:
 
1400
            return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
 
1401
        case XML_SCHEMA_TYPE_NOTATION:
 
1402
            return (((xmlSchemaNotationPtr) item)->targetNamespace);
 
1403
        default:
 
1404
            /*
 
1405
            * Other components cannot have names.
 
1406
            */
 
1407
            break;
 
1408
    }
 
1409
    return (NULL);
 
1410
}
 
1411
 
 
1412
static const xmlChar*
 
1413
xmlSchemaGetComponentQName(xmlChar **buf,
 
1414
                           void *item)
 
1415
{
 
1416
    return (xmlSchemaFormatQName(buf,
 
1417
        xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
 
1418
        xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
 
1419
}
 
1420
 
 
1421
static const xmlChar*
 
1422
xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
 
1423
{
 
1424
    xmlChar *str = NULL;
 
1425
 
 
1426
    *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
 
1427
    *buf = xmlStrcat(*buf, BAD_CAST " '");
 
1428
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
 
1429
        (xmlSchemaBasicItemPtr) item));
 
1430
    *buf = xmlStrcat(*buf, BAD_CAST "'");
 
1431
    FREE_AND_NULL(str);
 
1432
    return(*buf);
 
1433
}
 
1434
 
 
1435
static const xmlChar*
 
1436
xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
 
1437
{
 
1438
    return(xmlSchemaGetComponentDesignation(buf, idc));
 
1439
}
 
1440
 
 
1441
/**
 
1442
 * xmlSchemaWildcardPCToString:
 
1443
 * @pc: the type of processContents
 
1444
 *
 
1445
 * Returns a string representation of the type of
 
1446
 * processContents.
 
1447
 */
 
1448
static const xmlChar *
 
1449
xmlSchemaWildcardPCToString(int pc)
 
1450
{
 
1451
    switch (pc) {
 
1452
        case XML_SCHEMAS_ANY_SKIP:
 
1453
            return (BAD_CAST "skip");
 
1454
        case XML_SCHEMAS_ANY_LAX:
 
1455
            return (BAD_CAST "lax");
 
1456
        case XML_SCHEMAS_ANY_STRICT:
 
1457
            return (BAD_CAST "strict");
 
1458
        default:
 
1459
            return (BAD_CAST "invalid process contents");
 
1460
    }
 
1461
}
 
1462
 
 
1463
/**
 
1464
 * xmlSchemaGetCanonValueWhtspExt:
 
1465
 * @val: the precomputed value
 
1466
 * @retValue: the returned value
 
1467
 * @ws: the whitespace type of the value
 
1468
 *
 
1469
 * Get a the cononical representation of the value.
 
1470
 * The caller has to free the returned retValue.
 
1471
 *
 
1472
 * Returns 0 if the value could be built and -1 in case of
 
1473
 *         API errors or if the value type is not supported yet.
 
1474
 */
 
1475
static int
 
1476
xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
 
1477
                               xmlSchemaWhitespaceValueType ws,
 
1478
                               xmlChar **retValue)
 
1479
{
 
1480
    int list;
 
1481
    xmlSchemaValType valType;
 
1482
    const xmlChar *value, *value2 = NULL;
 
1483
    
 
1484
 
 
1485
    if ((retValue == NULL) || (val == NULL))
 
1486
        return (-1);
 
1487
    list = xmlSchemaValueGetNext(val) ? 1 : 0;
 
1488
    *retValue = NULL;
 
1489
    do {
 
1490
        value = NULL;   
 
1491
        valType = xmlSchemaGetValType(val);    
 
1492
        switch (valType) {          
 
1493
            case XML_SCHEMAS_STRING:
 
1494
            case XML_SCHEMAS_NORMSTRING:
 
1495
            case XML_SCHEMAS_ANYSIMPLETYPE:
 
1496
                value = xmlSchemaValueGetAsString(val);
 
1497
                if (value != NULL) {
 
1498
                    if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
 
1499
                        value2 = xmlSchemaCollapseString(value);
 
1500
                    else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
 
1501
                        value2 = xmlSchemaWhiteSpaceReplace(value);
 
1502
                    if (value2 != NULL)
 
1503
                        value = value2;
 
1504
                }
 
1505
                break;     
 
1506
            default:
 
1507
                if (xmlSchemaGetCanonValue(val, &value2) == -1) {
 
1508
                    if (value2 != NULL)
 
1509
                        xmlFree((xmlChar *) value2);
 
1510
                    goto internal_error;
 
1511
                }
 
1512
                value = value2;
 
1513
        }
 
1514
        if (*retValue == NULL)
 
1515
            if (value == NULL) {
 
1516
                if (! list)
 
1517
                    *retValue = xmlStrdup(BAD_CAST "");
 
1518
            } else
 
1519
                *retValue = xmlStrdup(value);
 
1520
        else if (value != NULL) {
 
1521
            /* List. */
 
1522
            *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
 
1523
            *retValue = xmlStrcat((xmlChar *) *retValue, value);
 
1524
        }
 
1525
        FREE_AND_NULL(value2)
 
1526
        val = xmlSchemaValueGetNext(val);
 
1527
    } while (val != NULL);
 
1528
 
 
1529
    return (0);
 
1530
internal_error:
 
1531
    if (*retValue != NULL)
 
1532
        xmlFree((xmlChar *) (*retValue));
 
1533
    if (value2 != NULL)
 
1534
        xmlFree((xmlChar *) value2);
 
1535
    return (-1);
 
1536
}
 
1537
 
 
1538
/**
 
1539
 * xmlSchemaFormatItemForReport:
 
1540
 * @buf: the string buffer
 
1541
 * @itemDes: the designation of the item
 
1542
 * @itemName: the name of the item
 
1543
 * @item: the item as an object 
 
1544
 * @itemNode: the node of the item
 
1545
 * @local: the local name
 
1546
 * @parsing: if the function is used during the parse
 
1547
 *
 
1548
 * Returns a representation of the given item used
 
1549
 * for error reports. 
 
1550
 *
 
1551
 * The following order is used to build the resulting 
 
1552
 * designation if the arguments are not NULL:
 
1553
 * 1a. If itemDes not NULL -> itemDes
 
1554
 * 1b. If (itemDes not NULL) and (itemName not NULL)
 
1555
 *     -> itemDes + itemName
 
1556
 * 2. If the preceding was NULL and (item not NULL) -> item
 
1557
 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
 
1558
 * 
 
1559
 * If the itemNode is an attribute node, the name of the attribute
 
1560
 * will be appended to the result.
 
1561
 *
 
1562
 * Returns the formatted string and sets @buf to the resulting value.
 
1563
 */  
 
1564
static xmlChar*   
 
1565
xmlSchemaFormatItemForReport(xmlChar **buf,                  
 
1566
                     const xmlChar *itemDes,
 
1567
                     xmlSchemaBasicItemPtr item,
 
1568
                     xmlNodePtr itemNode)
 
1569
{
 
1570
    xmlChar *str = NULL;
 
1571
    int named = 1;
 
1572
 
 
1573
    if (*buf != NULL) {
 
1574
        xmlFree(*buf);
 
1575
        *buf = NULL;
 
1576
    }
 
1577
            
 
1578
    if (itemDes != NULL) {
 
1579
        *buf = xmlStrdup(itemDes);      
 
1580
    } else if (item != NULL) {
 
1581
        switch (item->type) {
 
1582
        case XML_SCHEMA_TYPE_BASIC: {
 
1583
            xmlSchemaTypePtr type = WXS_TYPE_CAST item;
 
1584
 
 
1585
            if (WXS_IS_ATOMIC(type))
 
1586
                *buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
 
1587
            else if (WXS_IS_LIST(type))
 
1588
                *buf = xmlStrdup(BAD_CAST "list type 'xs:");
 
1589
            else if (WXS_IS_UNION(type))
 
1590
                *buf = xmlStrdup(BAD_CAST "union type 'xs:");
 
1591
            else
 
1592
                *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
 
1593
            *buf = xmlStrcat(*buf, type->name);
 
1594
            *buf = xmlStrcat(*buf, BAD_CAST "'");
 
1595
            }
 
1596
            break;
 
1597
        case XML_SCHEMA_TYPE_SIMPLE: {
 
1598
            xmlSchemaTypePtr type = WXS_TYPE_CAST item;
 
1599
 
 
1600
            if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
 
1601
                *buf = xmlStrdup(BAD_CAST"");
 
1602
            } else {
 
1603
                *buf = xmlStrdup(BAD_CAST "local ");
 
1604
            }
 
1605
            if (WXS_IS_ATOMIC(type))
 
1606
                *buf = xmlStrcat(*buf, BAD_CAST "atomic type");
 
1607
            else if (WXS_IS_LIST(type))
 
1608
                *buf = xmlStrcat(*buf, BAD_CAST "list type");
 
1609
            else if (WXS_IS_UNION(type))
 
1610
                *buf = xmlStrcat(*buf, BAD_CAST "union type");
 
1611
            else
 
1612
                *buf = xmlStrcat(*buf, BAD_CAST "simple type");
 
1613
            if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
 
1614
                *buf = xmlStrcat(*buf, BAD_CAST " '");
 
1615
                *buf = xmlStrcat(*buf, type->name);
 
1616
                *buf = xmlStrcat(*buf, BAD_CAST "'");
 
1617
            }
 
1618
            }
 
1619
            break;
 
1620
        case XML_SCHEMA_TYPE_COMPLEX: {
 
1621
            xmlSchemaTypePtr type = WXS_TYPE_CAST item;
 
1622
 
 
1623
            if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
 
1624
                *buf = xmlStrdup(BAD_CAST "");
 
1625
            else
 
1626
                *buf = xmlStrdup(BAD_CAST "local ");
 
1627
            *buf = xmlStrcat(*buf, BAD_CAST "complex type");
 
1628
            if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
 
1629
                *buf = xmlStrcat(*buf, BAD_CAST " '");
 
1630
                *buf = xmlStrcat(*buf, type->name);
 
1631
                *buf = xmlStrcat(*buf, BAD_CAST "'");
 
1632
            }
 
1633
            }
 
1634
            break;
 
1635
        case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
 
1636
                xmlSchemaAttributeUsePtr ause;
 
1637
            
 
1638
                ause = WXS_ATTR_USE_CAST item;
 
1639
                *buf = xmlStrdup(BAD_CAST "attribute use ");
 
1640
                if (WXS_ATTRUSE_DECL(ause) != NULL) {
 
1641
                    *buf = xmlStrcat(*buf, BAD_CAST "'");
 
1642
                    *buf = xmlStrcat(*buf,
 
1643
                        xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
 
1644
                    FREE_AND_NULL(str)
 
1645
                        *buf = xmlStrcat(*buf, BAD_CAST "'");
 
1646
                } else {
 
1647
                    *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
 
1648
                }
 
1649
            }
 
1650
            break;
 
1651
        case XML_SCHEMA_TYPE_ATTRIBUTE: {
 
1652
                xmlSchemaAttributePtr attr;
 
1653
            
 
1654
                attr = (xmlSchemaAttributePtr) item;
 
1655
                *buf = xmlStrdup(BAD_CAST "attribute decl.");
 
1656
                *buf = xmlStrcat(*buf, BAD_CAST " '");
 
1657
                *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
 
1658
                    attr->targetNamespace, attr->name));
 
1659
                FREE_AND_NULL(str)
 
1660
                    *buf = xmlStrcat(*buf, BAD_CAST "'");
 
1661
            }
 
1662
            break;
 
1663
        case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 
1664
            xmlSchemaGetComponentDesignation(buf, item);
 
1665
            break;
 
1666
        case XML_SCHEMA_TYPE_ELEMENT: {
 
1667
                xmlSchemaElementPtr elem;
 
1668
 
 
1669
                elem = (xmlSchemaElementPtr) item;          
 
1670
                *buf = xmlStrdup(BAD_CAST "element decl.");
 
1671
                *buf = xmlStrcat(*buf, BAD_CAST " '");
 
1672
                *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
 
1673
                    elem->targetNamespace, elem->name));
 
1674
                *buf = xmlStrcat(*buf, BAD_CAST "'");
 
1675
            }
 
1676
            break;
 
1677
        case XML_SCHEMA_TYPE_IDC_UNIQUE:
 
1678
        case XML_SCHEMA_TYPE_IDC_KEY:
 
1679
        case XML_SCHEMA_TYPE_IDC_KEYREF:                
 
1680
            if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
 
1681
                *buf = xmlStrdup(BAD_CAST "unique '");
 
1682
            else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
 
1683
                *buf = xmlStrdup(BAD_CAST "key '");
 
1684
            else
 
1685
                *buf = xmlStrdup(BAD_CAST "keyRef '");
 
1686
            *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
 
1687
            *buf = xmlStrcat(*buf, BAD_CAST "'");
 
1688
            break;
 
1689
        case XML_SCHEMA_TYPE_ANY:
 
1690
        case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 
1691
            *buf = xmlStrdup(xmlSchemaWildcardPCToString(
 
1692
                    ((xmlSchemaWildcardPtr) item)->processContents));
 
1693
            *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
 
1694
            break;
 
1695
        case XML_SCHEMA_FACET_MININCLUSIVE:
 
1696
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
 
1697
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
 
1698
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
 
1699
        case XML_SCHEMA_FACET_TOTALDIGITS:
 
1700
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
 
1701
        case XML_SCHEMA_FACET_PATTERN:
 
1702
        case XML_SCHEMA_FACET_ENUMERATION:
 
1703
        case XML_SCHEMA_FACET_WHITESPACE:
 
1704
        case XML_SCHEMA_FACET_LENGTH:
 
1705
        case XML_SCHEMA_FACET_MAXLENGTH:
 
1706
        case XML_SCHEMA_FACET_MINLENGTH:
 
1707
            *buf = xmlStrdup(BAD_CAST "facet '");
 
1708
            *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
 
1709
            *buf = xmlStrcat(*buf, BAD_CAST "'");
 
1710
            break;
 
1711
        case XML_SCHEMA_TYPE_GROUP: {
 
1712
                *buf = xmlStrdup(BAD_CAST "model group def.");
 
1713
                *buf = xmlStrcat(*buf, BAD_CAST " '");
 
1714
                *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
 
1715
                *buf = xmlStrcat(*buf, BAD_CAST "'");
 
1716
                FREE_AND_NULL(str)
 
1717
            }
 
1718
            break;
 
1719
        case XML_SCHEMA_TYPE_SEQUENCE:
 
1720
        case XML_SCHEMA_TYPE_CHOICE:
 
1721
        case XML_SCHEMA_TYPE_ALL:
 
1722
        case XML_SCHEMA_TYPE_PARTICLE:
 
1723
            *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
 
1724
            break;
 
1725
        case XML_SCHEMA_TYPE_NOTATION: {
 
1726
                *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
 
1727
                *buf = xmlStrcat(*buf, BAD_CAST " '");
 
1728
                *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
 
1729
                *buf = xmlStrcat(*buf, BAD_CAST "'");
 
1730
                FREE_AND_NULL(str);
 
1731
            }
 
1732
        default:
 
1733
            named = 0;
 
1734
        }
 
1735
    } else 
 
1736
        named = 0;
 
1737
 
 
1738
    if ((named == 0) && (itemNode != NULL)) {
 
1739
        xmlNodePtr elem;
 
1740
 
 
1741
        if (itemNode->type == XML_ATTRIBUTE_NODE)
 
1742
            elem = itemNode->parent;
 
1743
        else 
 
1744
            elem = itemNode;
 
1745
        *buf = xmlStrdup(BAD_CAST "Element '");
 
1746
        if (elem->ns != NULL) {
 
1747
            *buf = xmlStrcat(*buf,
 
1748
                xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
 
1749
            FREE_AND_NULL(str)
 
1750
        } else
 
1751
            *buf = xmlStrcat(*buf, elem->name);
 
1752
        *buf = xmlStrcat(*buf, BAD_CAST "'");
 
1753
        
 
1754
    }
 
1755
    if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
 
1756
        *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
 
1757
        if (itemNode->ns != NULL) {
 
1758
            *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
 
1759
                itemNode->ns->href, itemNode->name));
 
1760
            FREE_AND_NULL(str)
 
1761
        } else
 
1762
            *buf = xmlStrcat(*buf, itemNode->name);
 
1763
        *buf = xmlStrcat(*buf, BAD_CAST "'");
 
1764
    }
 
1765
    FREE_AND_NULL(str)
 
1766
    
 
1767
    return (*buf);
 
1768
}
 
1769
 
 
1770
/**
 
1771
 * xmlSchemaFormatFacetEnumSet:
 
1772
 * @buf: the string buffer
 
1773
 * @type: the type holding the enumeration facets
 
1774
 *
 
1775
 * Builds a string consisting of all enumeration elements.
 
1776
 *
 
1777
 * Returns a string of all enumeration elements.
 
1778
 */
 
1779
static const xmlChar *
 
1780
xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
 
1781
                            xmlChar **buf, xmlSchemaTypePtr type)
 
1782
{
 
1783
    xmlSchemaFacetPtr facet;
 
1784
    xmlSchemaWhitespaceValueType ws;
 
1785
    xmlChar *value = NULL;
 
1786
    int res, found = 0;
 
1787
 
 
1788
    if (*buf != NULL)
 
1789
        xmlFree(*buf);    
 
1790
    *buf = NULL;
 
1791
 
 
1792
    do {
 
1793
        /*
 
1794
        * Use the whitespace type of the base type.
 
1795
        */      
 
1796
        ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
 
1797
        for (facet = type->facets; facet != NULL; facet = facet->next) {
 
1798
            if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
 
1799
                continue;
 
1800
            found = 1;
 
1801
            res = xmlSchemaGetCanonValueWhtspExt(facet->val,
 
1802
                ws, &value);
 
1803
            if (res == -1) {
 
1804
                xmlSchemaInternalErr(actxt,
 
1805
                    "xmlSchemaFormatFacetEnumSet",
 
1806
                    "compute the canonical lexical representation");
 
1807
                if (*buf != NULL)
 
1808
                    xmlFree(*buf);
 
1809
                *buf = NULL;
 
1810
                return (NULL);
 
1811
            }
 
1812
            if (*buf == NULL)
 
1813
                *buf = xmlStrdup(BAD_CAST "'");
 
1814
            else
 
1815
                *buf = xmlStrcat(*buf, BAD_CAST ", '");
 
1816
            *buf = xmlStrcat(*buf, BAD_CAST value);
 
1817
            *buf = xmlStrcat(*buf, BAD_CAST "'");
 
1818
            if (value != NULL) {
 
1819
                xmlFree((xmlChar *)value);
 
1820
                value = NULL;
 
1821
            }
 
1822
        }
 
1823
        /*
 
1824
        * The enumeration facet of a type restricts the enumeration
 
1825
        * facet of the ancestor type; i.e., such restricted enumerations
 
1826
        * do not belong to the set of the given type. Thus we break
 
1827
        * on the first found enumeration.
 
1828
        */
 
1829
        if (found)
 
1830
            break;
 
1831
        type = type->baseType;
 
1832
    } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
 
1833
 
 
1834
    return ((const xmlChar *) *buf);
 
1835
}
 
1836
 
 
1837
/************************************************************************
 
1838
 *                                                                      *
 
1839
 *                      Error functions                                 *
 
1840
 *                                                                      *
 
1841
 ************************************************************************/
 
1842
 
 
1843
#if 0
 
1844
static void
 
1845
xmlSchemaErrMemory(const char *msg)
 
1846
{
 
1847
    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
 
1848
                     msg);
 
1849
}
 
1850
#endif
 
1851
 
 
1852
static void
 
1853
xmlSchemaPSimpleErr(const char *msg)
 
1854
{
 
1855
    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
 
1856
                     msg);
 
1857
}
 
1858
 
 
1859
/**
 
1860
 * xmlSchemaPErrMemory:
 
1861
 * @node: a context node
 
1862
 * @extra:  extra informations
 
1863
 *
 
1864
 * Handle an out of memory condition
 
1865
 */
 
1866
static void
 
1867
xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
 
1868
                    const char *extra, xmlNodePtr node)
 
1869
{
 
1870
    if (ctxt != NULL)
 
1871
        ctxt->nberrors++;
 
1872
    __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
 
1873
                     extra);
 
1874
}
 
1875
 
 
1876
/**
 
1877
 * xmlSchemaPErr:
 
1878
 * @ctxt: the parsing context
 
1879
 * @node: the context node
 
1880
 * @error: the error code
 
1881
 * @msg: the error message
 
1882
 * @str1: extra data
 
1883
 * @str2: extra data
 
1884
 * 
 
1885
 * Handle a parser error
 
1886
 */
 
1887
static void
 
1888
xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
 
1889
              const char *msg, const xmlChar * str1, const xmlChar * str2)
 
1890
{
 
1891
    xmlGenericErrorFunc channel = NULL;
 
1892
    xmlStructuredErrorFunc schannel = NULL;
 
1893
    void *data = NULL;
 
1894
 
 
1895
    if (ctxt != NULL) {
 
1896
        ctxt->nberrors++;
 
1897
        ctxt->err = error;
 
1898
        channel = ctxt->error;
 
1899
        data = ctxt->errCtxt;
 
1900
        schannel = ctxt->serror;
 
1901
    }
 
1902
    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
 
1903
                    error, XML_ERR_ERROR, NULL, 0,
 
1904
                    (const char *) str1, (const char *) str2, NULL, 0, 0,
 
1905
                    msg, str1, str2);
 
1906
}
 
1907
 
 
1908
/**
 
1909
 * xmlSchemaPErr2:
 
1910
 * @ctxt: the parsing context
 
1911
 * @node: the context node
 
1912
 * @node: the current child
 
1913
 * @error: the error code
 
1914
 * @msg: the error message
 
1915
 * @str1: extra data
 
1916
 * @str2: extra data
 
1917
 * 
 
1918
 * Handle a parser error
 
1919
 */
 
1920
static void
 
1921
xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
 
1922
               xmlNodePtr child, int error,
 
1923
               const char *msg, const xmlChar * str1, const xmlChar * str2)
 
1924
{
 
1925
    if (child != NULL)
 
1926
        xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
 
1927
    else
 
1928
        xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
 
1929
}
 
1930
 
 
1931
 
 
1932
/**
 
1933
 * xmlSchemaPErrExt:
 
1934
 * @ctxt: the parsing context
 
1935
 * @node: the context node
 
1936
 * @error: the error code 
 
1937
 * @strData1: extra data
 
1938
 * @strData2: extra data
 
1939
 * @strData3: extra data
 
1940
 * @msg: the message
 
1941
 * @str1:  extra parameter for the message display
 
1942
 * @str2:  extra parameter for the message display
 
1943
 * @str3:  extra parameter for the message display
 
1944
 * @str4:  extra parameter for the message display
 
1945
 * @str5:  extra parameter for the message display
 
1946
 * 
 
1947
 * Handle a parser error
 
1948
 */
 
1949
static void
 
1950
xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
 
1951
                const xmlChar * strData1, const xmlChar * strData2, 
 
1952
                const xmlChar * strData3, const char *msg, const xmlChar * str1, 
 
1953
                const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
 
1954
                const xmlChar * str5)
 
1955
{
 
1956
 
 
1957
    xmlGenericErrorFunc channel = NULL;
 
1958
    xmlStructuredErrorFunc schannel = NULL;
 
1959
    void *data = NULL;
 
1960
 
 
1961
    if (ctxt != NULL) {
 
1962
        ctxt->nberrors++;
 
1963
        ctxt->err = error;
 
1964
        channel = ctxt->error;
 
1965
        data = ctxt->errCtxt;
 
1966
        schannel = ctxt->serror;
 
1967
    }
 
1968
    __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
 
1969
                    error, XML_ERR_ERROR, NULL, 0,
 
1970
                    (const char *) strData1, (const char *) strData2, 
 
1971
                    (const char *) strData3, 0, 0, msg, str1, str2, 
 
1972
                    str3, str4, str5);
 
1973
}
 
1974
 
 
1975
/************************************************************************
 
1976
 *                                                                      *
 
1977
 *                      Allround error functions                        *
 
1978
 *                                                                      *
 
1979
 ************************************************************************/
 
1980
 
 
1981
/**
 
1982
 * xmlSchemaVTypeErrMemory:
 
1983
 * @node: a context node
 
1984
 * @extra:  extra informations
 
1985
 *
 
1986
 * Handle an out of memory condition
 
1987
 */
 
1988
static void
 
1989
xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
 
1990
                    const char *extra, xmlNodePtr node)
 
1991
{
 
1992
    if (ctxt != NULL) {
 
1993
        ctxt->nberrors++;
 
1994
        ctxt->err = XML_SCHEMAV_INTERNAL;
 
1995
    }
 
1996
    __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
 
1997
                     extra);
 
1998
}
 
1999
 
 
2000
static void
 
2001
xmlSchemaPSimpleInternalErr(xmlNodePtr node,
 
2002
                            const char *msg, const xmlChar *str)
 
2003
{
 
2004
     __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
 
2005
         msg, (const char *) str);
 
2006
}
 
2007
 
 
2008
#define WXS_ERROR_TYPE_ERROR 1
 
2009
#define WXS_ERROR_TYPE_WARNING 2
 
2010
/**
 
2011
 * xmlSchemaErr3:
 
2012
 * @ctxt: the validation context
 
2013
 * @node: the context node
 
2014
 * @error: the error code
 
2015
 * @msg: the error message
 
2016
 * @str1: extra data
 
2017
 * @str2: extra data
 
2018
 * @str3: extra data
 
2019
 * 
 
2020
 * Handle a validation error
 
2021
 */
 
2022
static void
 
2023
xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
 
2024
                  xmlErrorLevel errorLevel,
 
2025
                  int error, xmlNodePtr node, int line, const char *msg,
 
2026
                  const xmlChar *str1, const xmlChar *str2,
 
2027
                  const xmlChar *str3, const xmlChar *str4)
 
2028
{
 
2029
    xmlStructuredErrorFunc schannel = NULL;
 
2030
    xmlGenericErrorFunc channel = NULL;
 
2031
    void *data = NULL;    
 
2032
    
 
2033
    if (ctxt != NULL) {
 
2034
        if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
 
2035
            xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
 
2036
            const char *file = NULL;
 
2037
            if (errorLevel != XML_ERR_WARNING) {
 
2038
                vctxt->nberrors++;
 
2039
                vctxt->err = error;
 
2040
                channel = vctxt->error;         
 
2041
            } else {
 
2042
                channel = vctxt->warning;
 
2043
            }
 
2044
            schannel = vctxt->serror;
 
2045
            data = vctxt->errCtxt;
 
2046
 
 
2047
            /*
 
2048
            * Error node. If we specify a line number, then
 
2049
            * do not channel any node to the error function.
 
2050
            */
 
2051
            if (line == 0) {
 
2052
                if ((node == NULL) &&
 
2053
                    (vctxt->depth >= 0) &&
 
2054
                    (vctxt->inode != NULL)) {
 
2055
                    node = vctxt->inode->node;
 
2056
                }
 
2057
                /*
 
2058
                * Get filename and line if no node-tree.
 
2059
                */
 
2060
                if ((node == NULL) &&
 
2061
                    (vctxt->parserCtxt != NULL) &&
 
2062
                    (vctxt->parserCtxt->input != NULL)) {
 
2063
                    file = vctxt->parserCtxt->input->filename;
 
2064
                    line = vctxt->parserCtxt->input->line;
 
2065
                }
 
2066
            } else {
 
2067
                /*
 
2068
                * Override the given node's (if any) position
 
2069
                * and channel only the given line number.
 
2070
                */
 
2071
                node = NULL;
 
2072
                /*
 
2073
                * Get filename.
 
2074
                */
 
2075
                if (vctxt->doc != NULL)
 
2076
                    file = (const char *) vctxt->doc->URL;
 
2077
                else if ((vctxt->parserCtxt != NULL) &&
 
2078
                    (vctxt->parserCtxt->input != NULL))
 
2079
                    file = vctxt->parserCtxt->input->filename;
 
2080
            }          
 
2081
            __xmlRaiseError(schannel, channel, data, ctxt,
 
2082
                node, XML_FROM_SCHEMASV,
 
2083
                error, errorLevel, file, line,
 
2084
                (const char *) str1, (const char *) str2,
 
2085
                (const char *) str3, 0, 0, msg, str1, str2, str3, str4);
 
2086
 
 
2087
        } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
 
2088
            xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
 
2089
            if (errorLevel != XML_ERR_WARNING) {
 
2090
                pctxt->nberrors++;
 
2091
                pctxt->err = error;
 
2092
                channel = pctxt->error;         
 
2093
            } else {
 
2094
                channel = pctxt->warning;
 
2095
            }
 
2096
            schannel = pctxt->serror;
 
2097
            data = pctxt->errCtxt;
 
2098
            __xmlRaiseError(schannel, channel, data, ctxt,
 
2099
                node, XML_FROM_SCHEMASP, error,
 
2100
                errorLevel, NULL, 0,
 
2101
                (const char *) str1, (const char *) str2,
 
2102
                (const char *) str3, 0, 0, msg, str1, str2, str3, str4);
 
2103
        } else {
 
2104
            TODO
 
2105
        }
 
2106
    }
 
2107
}
 
2108
 
 
2109
/**
 
2110
 * xmlSchemaErr3:
 
2111
 * @ctxt: the validation context
 
2112
 * @node: the context node
 
2113
 * @error: the error code
 
2114
 * @msg: the error message
 
2115
 * @str1: extra data
 
2116
 * @str2: extra data
 
2117
 * @str3: extra data
 
2118
 * 
 
2119
 * Handle a validation error
 
2120
 */
 
2121
static void
 
2122
xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,  
 
2123
              int error, xmlNodePtr node, const char *msg,
 
2124
              const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
 
2125
{
 
2126
    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
 
2127
        msg, str1, str2, str3, NULL);
 
2128
}
 
2129
 
 
2130
static void
 
2131
xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,  
 
2132
              int error, xmlNodePtr node, const char *msg,
 
2133
              const xmlChar *str1, const xmlChar *str2,
 
2134
              const xmlChar *str3, const xmlChar *str4)
 
2135
{
 
2136
    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
 
2137
        msg, str1, str2, str3, str4);
 
2138
}
 
2139
 
 
2140
static void
 
2141
xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
 
2142
             int error, xmlNodePtr node, const char *msg,
 
2143
             const xmlChar *str1, const xmlChar *str2)
 
2144
{
 
2145
    xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
 
2146
}
 
2147
 
 
2148
static xmlChar *
 
2149
xmlSchemaFormatNodeForError(xmlChar ** msg,
 
2150
                            xmlSchemaAbstractCtxtPtr actxt,
 
2151
                            xmlNodePtr node)
 
2152
{
 
2153
    xmlChar *str = NULL;
 
2154
 
 
2155
    *msg = NULL;
 
2156
    if ((node != NULL) &&
 
2157
        (node->type != XML_ELEMENT_NODE) &&
 
2158
        (node->type != XML_ATTRIBUTE_NODE))
 
2159
    {
 
2160
        /* 
 
2161
        * Don't try to format other nodes than element and
 
2162
        * attribute nodes.
 
2163
        * Play save and return an empty string.
 
2164
        */
 
2165
        *msg = xmlStrdup(BAD_CAST "");
 
2166
        return(*msg);
 
2167
    }
 
2168
    if (node != NULL) {
 
2169
        /*
 
2170
        * Work on tree nodes.
 
2171
        */
 
2172
        if (node->type == XML_ATTRIBUTE_NODE) {
 
2173
            xmlNodePtr elem = node->parent;
 
2174
            
 
2175
            *msg = xmlStrdup(BAD_CAST "Element '");
 
2176
            if (elem->ns != NULL)
 
2177
                *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 
2178
                    elem->ns->href, elem->name));
 
2179
            else
 
2180
                *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 
2181
                    NULL, elem->name));
 
2182
            FREE_AND_NULL(str);
 
2183
            *msg = xmlStrcat(*msg, BAD_CAST "', ");
 
2184
            *msg = xmlStrcat(*msg, BAD_CAST "attribute '");         
 
2185
        } else {
 
2186
            *msg = xmlStrdup(BAD_CAST "Element '");
 
2187
        }
 
2188
        if (node->ns != NULL)
 
2189
            *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 
2190
            node->ns->href, node->name));
 
2191
        else
 
2192
            *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 
2193
            NULL, node->name));
 
2194
        FREE_AND_NULL(str);
 
2195
        *msg = xmlStrcat(*msg, BAD_CAST "': ");
 
2196
    } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
 
2197
        xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
 
2198
        /*
 
2199
        * Work on node infos.
 
2200
        */      
 
2201
        if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
 
2202
            xmlSchemaNodeInfoPtr ielem =
 
2203
                vctxt->elemInfos[vctxt->depth];
 
2204
 
 
2205
            *msg = xmlStrdup(BAD_CAST "Element '");
 
2206
            *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 
2207
                ielem->nsName, ielem->localName));
 
2208
            FREE_AND_NULL(str);
 
2209
            *msg = xmlStrcat(*msg, BAD_CAST "', ");
 
2210
            *msg = xmlStrcat(*msg, BAD_CAST "attribute '");         
 
2211
        } else {
 
2212
            *msg = xmlStrdup(BAD_CAST "Element '");
 
2213
        }
 
2214
        *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 
2215
            vctxt->inode->nsName, vctxt->inode->localName));
 
2216
        FREE_AND_NULL(str);
 
2217
        *msg = xmlStrcat(*msg, BAD_CAST "': ");
 
2218
    } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
 
2219
        /* 
 
2220
        * Hmm, no node while parsing?
 
2221
        * Return an empty string, in case NULL will break something.
 
2222
        */
 
2223
        *msg = xmlStrdup(BAD_CAST "");
 
2224
    } else {
 
2225
        TODO
 
2226
        return (NULL);
 
2227
    }
 
2228
    /*
 
2229
    * VAL TODO: The output of the given schema component is currently
 
2230
    * disabled.
 
2231
    */
 
2232
#if 0
 
2233
    if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
 
2234
        *msg = xmlStrcat(*msg, BAD_CAST " [");
 
2235
        *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
 
2236
            NULL, type, NULL, 0));
 
2237
        FREE_AND_NULL(str)
 
2238
        *msg = xmlStrcat(*msg, BAD_CAST "]");
 
2239
    }
 
2240
#endif
 
2241
    return (*msg);
 
2242
}
 
2243
 
 
2244
static void
 
2245
xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
 
2246
                     const char *funcName,
 
2247
                     const char *message,
 
2248
                     const xmlChar *str1,
 
2249
                     const xmlChar *str2)
 
2250
{
 
2251
    xmlChar *msg = NULL;
 
2252
 
 
2253
    if (actxt == NULL)
 
2254
        return;
 
2255
    msg = xmlStrdup(BAD_CAST "Internal error: ");
 
2256
    msg = xmlStrcat(msg, BAD_CAST funcName);
 
2257
    msg = xmlStrcat(msg, BAD_CAST ", ");    
 
2258
    msg = xmlStrcat(msg, BAD_CAST message);
 
2259
    msg = xmlStrcat(msg, BAD_CAST ".\n");
 
2260
 
 
2261
    if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
 
2262
        xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL,
 
2263
            (const char *) msg, str1, str2);
 
2264
 
 
2265
    else if (actxt->type == XML_SCHEMA_CTXT_PARSER)     
 
2266
        xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL,
 
2267
            (const char *) msg, str1, str2);
 
2268
 
 
2269
    FREE_AND_NULL(msg)
 
2270
}
 
2271
 
 
2272
static void
 
2273
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
 
2274
                     const char *funcName,
 
2275
                     const char *message)
 
2276
{
 
2277
    xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
 
2278
}
 
2279
 
 
2280
#if 0
 
2281
static void
 
2282
xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
 
2283
                     const char *funcName,
 
2284
                     const char *message,
 
2285
                     const xmlChar *str1,
 
2286
                     const xmlChar *str2)
 
2287
{
 
2288
    xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
 
2289
        str1, str2);
 
2290
}
 
2291
#endif
 
2292
 
 
2293
static void
 
2294
xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
 
2295
                   xmlParserErrors error,
 
2296
                   xmlNodePtr node,
 
2297
                   xmlSchemaBasicItemPtr item,
 
2298
                   const char *message,
 
2299
                   const xmlChar *str1, const xmlChar *str2,
 
2300
                   const xmlChar *str3, const xmlChar *str4)
 
2301
{
 
2302
    xmlChar *msg = NULL;
 
2303
 
 
2304
    if ((node == NULL) && (item != NULL) &&
 
2305
        (actxt->type == XML_SCHEMA_CTXT_PARSER)) {
 
2306
        node = WXS_ITEM_NODE(item);
 
2307
        xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
 
2308
        msg = xmlStrcat(msg, BAD_CAST ": ");
 
2309
    } else
 
2310
        xmlSchemaFormatNodeForError(&msg, actxt, node);
 
2311
    msg = xmlStrcat(msg, (const xmlChar *) message);
 
2312
    msg = xmlStrcat(msg, BAD_CAST ".\n");   
 
2313
    xmlSchemaErr4(actxt, error, node,
 
2314
        (const char *) msg, str1, str2, str3, str4);
 
2315
    FREE_AND_NULL(msg)
 
2316
}
 
2317
 
 
2318
static void
 
2319
xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
 
2320
                   xmlParserErrors error,
 
2321
                   xmlNodePtr node,
 
2322
                   xmlSchemaBasicItemPtr item,
 
2323
                   const char *message,
 
2324
                   const xmlChar *str1,
 
2325
                   const xmlChar *str2)
 
2326
{
 
2327
    xmlSchemaCustomErr4(actxt, error, node, item,
 
2328
        message, str1, str2, NULL, NULL);    
 
2329
}
 
2330
 
 
2331
 
 
2332
 
 
2333
static void
 
2334
xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
 
2335
                   xmlParserErrors error,
 
2336
                   xmlNodePtr node,
 
2337
                   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
 
2338
                   const char *message,
 
2339
                   const xmlChar *str1,
 
2340
                   const xmlChar *str2,
 
2341
                   const xmlChar *str3)
 
2342
{
 
2343
    xmlChar *msg = NULL;
 
2344
 
 
2345
    xmlSchemaFormatNodeForError(&msg, actxt, node);
 
2346
    msg = xmlStrcat(msg, (const xmlChar *) message);
 
2347
    msg = xmlStrcat(msg, BAD_CAST ".\n"); 
 
2348
    
 
2349
    /* URGENT TODO: Set the error code to something sane. */
 
2350
    xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
 
2351
        (const char *) msg, str1, str2, str3, NULL);
 
2352
 
 
2353
    FREE_AND_NULL(msg)
 
2354
}
 
2355
 
 
2356
 
 
2357
 
 
2358
static void
 
2359
xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
 
2360
                   xmlParserErrors error,
 
2361
                   xmlSchemaPSVIIDCNodePtr idcNode,
 
2362
                   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
 
2363
                   const char *message,
 
2364
                   const xmlChar *str1,
 
2365
                   const xmlChar *str2)
 
2366
{
 
2367
    xmlChar *msg = NULL, *qname = NULL;
 
2368
    
 
2369
    msg = xmlStrdup(BAD_CAST "Element '%s': ");        
 
2370
    msg = xmlStrcat(msg, (const xmlChar *) message);
 
2371
    msg = xmlStrcat(msg, BAD_CAST ".\n");
 
2372
    xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
 
2373
        error, NULL, idcNode->nodeLine, (const char *) msg,
 
2374
        xmlSchemaFormatQName(&qname,
 
2375
            vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
 
2376
            vctxt->nodeQNames->items[idcNode->nodeQNameID]), 
 
2377
        str1, str2, NULL);
 
2378
    FREE_AND_NULL(qname);
 
2379
    FREE_AND_NULL(msg);
 
2380
}
 
2381
 
 
2382
static int
 
2383
xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
 
2384
                           xmlNodePtr node)
 
2385
{
 
2386
    if (node != NULL)
 
2387
        return (node->type);
 
2388
    if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
 
2389
        (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
 
2390
        return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
 
2391
    return (-1);
 
2392
}
 
2393
 
 
2394
static int
 
2395
xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
 
2396
{
 
2397
    switch (item->type) {
 
2398
        case XML_SCHEMA_TYPE_COMPLEX:
 
2399
        case XML_SCHEMA_TYPE_SIMPLE:
 
2400
            if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
 
2401
                return(1);
 
2402
            break;
 
2403
        case XML_SCHEMA_TYPE_GROUP:
 
2404
            return (1);
 
2405
        case XML_SCHEMA_TYPE_ELEMENT:
 
2406
            if ( ((xmlSchemaElementPtr) item)->flags &
 
2407
                XML_SCHEMAS_ELEM_GLOBAL)
 
2408
                return(1);
 
2409
            break;
 
2410
        case XML_SCHEMA_TYPE_ATTRIBUTE:
 
2411
            if ( ((xmlSchemaAttributePtr) item)->flags &
 
2412
                XML_SCHEMAS_ATTR_GLOBAL)
 
2413
                return(1);
 
2414
            break;
 
2415
        /* Note that attribute groups are always global. */
 
2416
        default:
 
2417
            return(1);
 
2418
    }
 
2419
    return (0);
 
2420
}
 
2421
 
 
2422
static void
 
2423
xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
 
2424
                       xmlParserErrors error,
 
2425
                       xmlNodePtr node,
 
2426
                       const xmlChar *value,
 
2427
                       xmlSchemaTypePtr type,
 
2428
                       int displayValue)
 
2429
{
 
2430
    xmlChar *msg = NULL;
 
2431
 
 
2432
    xmlSchemaFormatNodeForError(&msg, actxt, node);
 
2433
 
 
2434
    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
 
2435
            XML_ATTRIBUTE_NODE))
 
2436
        msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
 
2437
    else
 
2438
        msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
 
2439
            "value of ");
 
2440
 
 
2441
    if (! xmlSchemaIsGlobalItem(type))
 
2442
        msg = xmlStrcat(msg, BAD_CAST "the local ");
 
2443
    else
 
2444
        msg = xmlStrcat(msg, BAD_CAST "the ");
 
2445
 
 
2446
    if (WXS_IS_ATOMIC(type))
 
2447
        msg = xmlStrcat(msg, BAD_CAST "atomic type");
 
2448
    else if (WXS_IS_LIST(type))
 
2449
        msg = xmlStrcat(msg, BAD_CAST "list type");
 
2450
    else if (WXS_IS_UNION(type))
 
2451
        msg = xmlStrcat(msg, BAD_CAST "union type");
 
2452
 
 
2453
    if (xmlSchemaIsGlobalItem(type)) {
 
2454
        xmlChar *str = NULL;
 
2455
        msg = xmlStrcat(msg, BAD_CAST " '");
 
2456
        if (type->builtInType != 0) {
 
2457
            msg = xmlStrcat(msg, BAD_CAST "xs:");
 
2458
            msg = xmlStrcat(msg, type->name);
 
2459
        } else 
 
2460
            msg = xmlStrcat(msg,
 
2461
                xmlSchemaFormatQName(&str,
 
2462
                    type->targetNamespace, type->name));
 
2463
        msg = xmlStrcat(msg, BAD_CAST "'");
 
2464
        FREE_AND_NULL(str);
 
2465
    }
 
2466
    msg = xmlStrcat(msg, BAD_CAST ".\n");
 
2467
    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
 
2468
            XML_ATTRIBUTE_NODE))
 
2469
        xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
 
2470
    else
 
2471
        xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
 
2472
    FREE_AND_NULL(msg)
 
2473
}
 
2474
 
 
2475
static const xmlChar *
 
2476
xmlSchemaFormatErrorNodeQName(xmlChar ** str,
 
2477
                              xmlSchemaNodeInfoPtr ni,
 
2478
                              xmlNodePtr node)
 
2479
{
 
2480
    if (node != NULL) {
 
2481
        if (node->ns != NULL)
 
2482
            return (xmlSchemaFormatQName(str, node->ns->href, node->name));
 
2483
        else
 
2484
            return (xmlSchemaFormatQName(str, NULL, node->name));
 
2485
    } else if (ni != NULL)
 
2486
        return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
 
2487
    return (NULL);
 
2488
}
 
2489
 
 
2490
static void
 
2491
xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
 
2492
                        xmlParserErrors error,
 
2493
                        xmlSchemaAttrInfoPtr ni,
 
2494
                        xmlNodePtr node)
 
2495
{
 
2496
    xmlChar *msg = NULL, *str = NULL;
 
2497
    
 
2498
    xmlSchemaFormatNodeForError(&msg, actxt, node);
 
2499
    msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
 
2500
    xmlSchemaErr(actxt, error, node, (const char *) msg,
 
2501
        xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
 
2502
        NULL);        
 
2503
    FREE_AND_NULL(str)
 
2504
    FREE_AND_NULL(msg)
 
2505
}
 
2506
 
 
2507
static void
 
2508
xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
 
2509
                        xmlParserErrors error,
 
2510
                        xmlNodePtr node,
 
2511
                        xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
 
2512
                        const char *message,
 
2513
                        int nbval,
 
2514
                        int nbneg,
 
2515
                        xmlChar **values)
 
2516
{
 
2517
    xmlChar *str = NULL, *msg = NULL;
 
2518
    xmlChar *localName, *nsName;
 
2519
    const xmlChar *cur, *end;
 
2520
    int i;
 
2521
    
 
2522
    xmlSchemaFormatNodeForError(&msg, actxt, node);
 
2523
    msg = xmlStrcat(msg, (const xmlChar *) message);
 
2524
    msg = xmlStrcat(msg, BAD_CAST ".");
 
2525
    /*
 
2526
    * Note that is does not make sense to report that we have a
 
2527
    * wildcard here, since the wildcard might be unfolded into
 
2528
    * multiple transitions.
 
2529
    */
 
2530
    if (nbval + nbneg > 0) {
 
2531
        if (nbval + nbneg > 1) {
 
2532
            str = xmlStrdup(BAD_CAST " Expected is one of ( ");
 
2533
        } else
 
2534
            str = xmlStrdup(BAD_CAST " Expected is ( ");
 
2535
        nsName = NULL;
 
2536
            
 
2537
        for (i = 0; i < nbval + nbneg; i++) {
 
2538
            cur = values[i];
 
2539
            if (cur == NULL)
 
2540
                continue;
 
2541
            if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
 
2542
                (cur[3] == ' ')) {
 
2543
                cur += 4;
 
2544
                str = xmlStrcat(str, BAD_CAST "##other");
 
2545
            }
 
2546
            /*
 
2547
            * Get the local name.
 
2548
            */
 
2549
            localName = NULL;
 
2550
            
 
2551
            end = cur;
 
2552
            if (*end == '*') {
 
2553
                localName = xmlStrdup(BAD_CAST "*");
 
2554
                end++;
 
2555
            } else {
 
2556
                while ((*end != 0) && (*end != '|'))
 
2557
                    end++;
 
2558
                localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
 
2559
            }           
 
2560
            if (*end != 0) {                
 
2561
                end++;
 
2562
                /*
 
2563
                * Skip "*|*" if they come with negated expressions, since
 
2564
                * they represent the same negated wildcard.
 
2565
                */
 
2566
                if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
 
2567
                    /*
 
2568
                    * Get the namespace name.
 
2569
                    */
 
2570
                    cur = end;
 
2571
                    if (*end == '*') {
 
2572
                        nsName = xmlStrdup(BAD_CAST "{*}");
 
2573
                    } else {
 
2574
                        while (*end != 0)
 
2575
                            end++;
 
2576
                        
 
2577
                        if (i >= nbval)
 
2578
                            nsName = xmlStrdup(BAD_CAST "{##other:");
 
2579
                        else
 
2580
                            nsName = xmlStrdup(BAD_CAST "{");
 
2581
                        
 
2582
                        nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
 
2583
                        nsName = xmlStrcat(nsName, BAD_CAST "}");
 
2584
                    }
 
2585
                    str = xmlStrcat(str, BAD_CAST nsName);
 
2586
                    FREE_AND_NULL(nsName)
 
2587
                } else {
 
2588
                    FREE_AND_NULL(localName);
 
2589
                    continue;
 
2590
                }
 
2591
            }           
 
2592
            str = xmlStrcat(str, BAD_CAST localName);
 
2593
            FREE_AND_NULL(localName);
 
2594
                
 
2595
            if (i < nbval + nbneg -1)
 
2596
                str = xmlStrcat(str, BAD_CAST ", ");
 
2597
        }       
 
2598
        str = xmlStrcat(str, BAD_CAST " ).\n");
 
2599
        msg = xmlStrcat(msg, BAD_CAST str);
 
2600
        FREE_AND_NULL(str)
 
2601
    } else
 
2602
      msg = xmlStrcat(msg, BAD_CAST "\n");
 
2603
    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
 
2604
    xmlFree(msg);
 
2605
}
 
2606
 
 
2607
static void
 
2608
xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
 
2609
                  xmlParserErrors error,
 
2610
                  xmlNodePtr node,
 
2611
                  const xmlChar *value,
 
2612
                  unsigned long length,
 
2613
                  xmlSchemaTypePtr type,
 
2614
                  xmlSchemaFacetPtr facet,
 
2615
                  const char *message,
 
2616
                  const xmlChar *str1,
 
2617
                  const xmlChar *str2)
 
2618
{
 
2619
    xmlChar *str = NULL, *msg = NULL;
 
2620
    xmlSchemaTypeType facetType;
 
2621
    int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
 
2622
 
 
2623
    xmlSchemaFormatNodeForError(&msg, actxt, node);
 
2624
    if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
 
2625
        facetType = XML_SCHEMA_FACET_ENUMERATION;
 
2626
        /*
 
2627
        * If enumerations are validated, one must not expect the
 
2628
        * facet to be given.
 
2629
        */      
 
2630
    } else      
 
2631
        facetType = facet->type;
 
2632
    msg = xmlStrcat(msg, BAD_CAST "[");
 
2633
    msg = xmlStrcat(msg, BAD_CAST "facet '");
 
2634
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
 
2635
    msg = xmlStrcat(msg, BAD_CAST "'] ");
 
2636
    if (message == NULL) {
 
2637
        /*
 
2638
        * Use a default message.
 
2639
        */
 
2640
        if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
 
2641
            (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
 
2642
            (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
 
2643
 
 
2644
            char len[25], actLen[25];
 
2645
 
 
2646
            /* FIXME, TODO: What is the max expected string length of the
 
2647
            * this value?
 
2648
            */
 
2649
            if (nodeType == XML_ATTRIBUTE_NODE)
 
2650
                msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
 
2651
            else
 
2652
                msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
 
2653
 
 
2654
            snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
 
2655
            snprintf(actLen, 24, "%lu", length);
 
2656
 
 
2657
            if (facetType == XML_SCHEMA_FACET_LENGTH)
 
2658
                msg = xmlStrcat(msg, 
 
2659
                BAD_CAST "this differs from the allowed length of '%s'.\n");     
 
2660
            else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
 
2661
                msg = xmlStrcat(msg, 
 
2662
                BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
 
2663
            else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
 
2664
                msg = xmlStrcat(msg, 
 
2665
                BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
 
2666
            
 
2667
            if (nodeType == XML_ATTRIBUTE_NODE)
 
2668
                xmlSchemaErr3(actxt, error, node, (const char *) msg,
 
2669
                    value, (const xmlChar *) actLen, (const xmlChar *) len);
 
2670
            else 
 
2671
                xmlSchemaErr(actxt, error, node, (const char *) msg,
 
2672
                    (const xmlChar *) actLen, (const xmlChar *) len);
 
2673
        
 
2674
        } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
 
2675
            msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
 
2676
                "of the set {%s}.\n");
 
2677
            xmlSchemaErr(actxt, error, node, (const char *) msg, value, 
 
2678
                xmlSchemaFormatFacetEnumSet(actxt, &str, type));
 
2679
        } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
 
2680
            msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
 
2681
                "by the pattern '%s'.\n");
 
2682
            xmlSchemaErr(actxt, error, node, (const char *) msg, value, 
 
2683
                facet->value);
 
2684
        } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
 
2685
            msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
 
2686
                "minimum value allowed ('%s').\n");
 
2687
            xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 
2688
                facet->value);
 
2689
        } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
 
2690
            msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
 
2691
                "maximum value allowed ('%s').\n");
 
2692
            xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 
2693
                facet->value);
 
2694
        } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
 
2695
            msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
 
2696
                "'%s'.\n");
 
2697
            xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 
2698
                facet->value);
 
2699
        } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
 
2700
            msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
 
2701
                "'%s'.\n");
 
2702
            xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 
2703
                facet->value);
 
2704
        } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
 
2705
            msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
 
2706
                "digits than are allowed ('%s').\n");
 
2707
            xmlSchemaErr(actxt, error, node, (const char*) msg, value,
 
2708
                facet->value);
 
2709
        } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
 
2710
            msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
 
2711
                "digits than are allowed ('%s').\n");
 
2712
            xmlSchemaErr(actxt, error, node, (const char*) msg, value,
 
2713
                facet->value);
 
2714
        } else if (nodeType == XML_ATTRIBUTE_NODE) {            
 
2715
            msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
 
2716
            xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);  
 
2717
        } else {            
 
2718
            msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
 
2719
            xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
 
2720
        }
 
2721
    } else {
 
2722
        msg = xmlStrcat(msg, (const xmlChar *) message);
 
2723
        msg = xmlStrcat(msg, BAD_CAST ".\n");
 
2724
        xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
 
2725
    }        
 
2726
    FREE_AND_NULL(str)
 
2727
    xmlFree(msg);
 
2728
}
 
2729
 
 
2730
#define VERROR(err, type, msg) \
 
2731
    xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
 
2732
 
 
2733
#define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
 
2734
 
 
2735
#define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
 
2736
#define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
 
2737
 
 
2738
#define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
 
2739
 
 
2740
 
 
2741
/**
 
2742
 * xmlSchemaPMissingAttrErr:
 
2743
 * @ctxt: the schema validation context
 
2744
 * @ownerDes: the designation of  the owner
 
2745
 * @ownerName: the name of the owner
 
2746
 * @ownerItem: the owner as a schema object
 
2747
 * @ownerElem: the owner as an element node
 
2748
 * @node: the parent element node of the missing attribute node
 
2749
 * @type: the corresponding type of the attribute node
 
2750
 *
 
2751
 * Reports an illegal attribute.
 
2752
 */
 
2753
static void
 
2754
xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
 
2755
                         xmlParserErrors error,
 
2756
                         xmlSchemaBasicItemPtr ownerItem,
 
2757
                         xmlNodePtr ownerElem,
 
2758
                         const char *name,
 
2759
                         const char *message)
 
2760
{
 
2761
    xmlChar *des = NULL;
 
2762
 
 
2763
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
 
2764
 
 
2765
    if (message != NULL)
 
2766
        xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
 
2767
    else
 
2768
        xmlSchemaPErr(ctxt, ownerElem, error,
 
2769
            "%s: The attribute '%s' is required but missing.\n",
 
2770
            BAD_CAST des, BAD_CAST name);
 
2771
    FREE_AND_NULL(des);
 
2772
}
 
2773
 
 
2774
 
 
2775
/**
 
2776
 * xmlSchemaPResCompAttrErr:
 
2777
 * @ctxt: the schema validation context
 
2778
 * @error: the error code
 
2779
 * @ownerDes: the designation of  the owner
 
2780
 * @ownerItem: the owner as a schema object
 
2781
 * @ownerElem: the owner as an element node
 
2782
 * @name: the name of the attribute holding the QName
 
2783
 * @refName: the referenced local name
 
2784
 * @refURI: the referenced namespace URI
 
2785
 * @message: optional message
 
2786
 *
 
2787
 * Used to report QName attribute values that failed to resolve
 
2788
 * to schema components.
 
2789
 */
 
2790
static void
 
2791
xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
 
2792
                         xmlParserErrors error,
 
2793
                         xmlSchemaBasicItemPtr ownerItem,
 
2794
                         xmlNodePtr ownerElem,
 
2795
                         const char *name,
 
2796
                         const xmlChar *refName,
 
2797
                         const xmlChar *refURI,
 
2798
                         xmlSchemaTypeType refType,
 
2799
                         const char *refTypeStr)
 
2800
{
 
2801
    xmlChar *des = NULL, *strA = NULL;
 
2802
 
 
2803
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
 
2804
    if (refTypeStr == NULL)
 
2805
        refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
 
2806
        xmlSchemaPErrExt(ctxt, ownerElem, error,
 
2807
            NULL, NULL, NULL,
 
2808
            "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
 
2809
            "%s.\n", BAD_CAST des, BAD_CAST name,
 
2810
            xmlSchemaFormatQName(&strA, refURI, refName),
 
2811
            BAD_CAST refTypeStr, NULL);
 
2812
    FREE_AND_NULL(des)
 
2813
    FREE_AND_NULL(strA)
 
2814
}
 
2815
 
 
2816
/**
 
2817
 * xmlSchemaPCustomAttrErr:
 
2818
 * @ctxt: the schema parser context
 
2819
 * @error: the error code
 
2820
 * @ownerDes: the designation of the owner
 
2821
 * @ownerItem: the owner as a schema object
 
2822
 * @attr: the illegal attribute node
 
2823
 *
 
2824
 * Reports an illegal attribute during the parse.
 
2825
 */
 
2826
static void
 
2827
xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
 
2828
                        xmlParserErrors error,
 
2829
                        xmlChar **ownerDes,
 
2830
                        xmlSchemaBasicItemPtr ownerItem,
 
2831
                        xmlAttrPtr attr,
 
2832
                        const char *msg)
 
2833
{
 
2834
    xmlChar *des = NULL;
 
2835
 
 
2836
    if (ownerDes == NULL)
 
2837
        xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
 
2838
    else if (*ownerDes == NULL) {
 
2839
        xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
 
2840
        des = *ownerDes;
 
2841
    } else
 
2842
        des = *ownerDes;
 
2843
    if (attr == NULL) {
 
2844
        xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
 
2845
            "%s, attribute '%s': %s.\n",
 
2846
            BAD_CAST des, (const xmlChar *) "Unknown",
 
2847
            (const xmlChar *) msg, NULL, NULL);
 
2848
    } else {
 
2849
        xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
 
2850
            "%s, attribute '%s': %s.\n",
 
2851
            BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
 
2852
    }
 
2853
    if (ownerDes == NULL)
 
2854
        FREE_AND_NULL(des);
 
2855
}
 
2856
 
 
2857
/**
 
2858
 * xmlSchemaPIllegalAttrErr:
 
2859
 * @ctxt: the schema parser context
 
2860
 * @error: the error code
 
2861
 * @ownerDes: the designation of the attribute's owner
 
2862
 * @ownerItem: the attribute's owner item
 
2863
 * @attr: the illegal attribute node
 
2864
 *
 
2865
 * Reports an illegal attribute during the parse.
 
2866
 */
 
2867
static void
 
2868
xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
 
2869
                         xmlParserErrors error,
 
2870
                         xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
 
2871
                         xmlAttrPtr attr)
 
2872
{
 
2873
    xmlChar *strA = NULL, *strB = NULL;
 
2874
 
 
2875
    xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
 
2876
    xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
 
2877
        "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
 
2878
        xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
 
2879
        NULL, NULL);
 
2880
    FREE_AND_NULL(strA);
 
2881
    FREE_AND_NULL(strB);
 
2882
}
 
2883
 
 
2884
/**
 
2885
 * xmlSchemaPCustomErr:
 
2886
 * @ctxt: the schema parser context
 
2887
 * @error: the error code
 
2888
 * @itemDes: the designation of the schema item
 
2889
 * @item: the schema item
 
2890
 * @itemElem: the node of the schema item
 
2891
 * @message: the error message
 
2892
 * @str1: an optional param for the error message
 
2893
 * @str2: an optional param for the error message
 
2894
 * @str3: an optional param for the error message
 
2895
 *
 
2896
 * Reports an error during parsing.
 
2897
 */
 
2898
static void
 
2899
xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
 
2900
                    xmlParserErrors error,
 
2901
                    xmlSchemaBasicItemPtr item,
 
2902
                    xmlNodePtr itemElem,
 
2903
                    const char *message,
 
2904
                    const xmlChar *str1,
 
2905
                    const xmlChar *str2,
 
2906
                    const xmlChar *str3)
 
2907
{
 
2908
    xmlChar *des = NULL, *msg = NULL;
 
2909
 
 
2910
    xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
 
2911
    msg = xmlStrdup(BAD_CAST "%s: ");
 
2912
    msg = xmlStrcat(msg, (const xmlChar *) message);
 
2913
    msg = xmlStrcat(msg, BAD_CAST ".\n");
 
2914
    if ((itemElem == NULL) && (item != NULL))
 
2915
        itemElem = WXS_ITEM_NODE(item);
 
2916
    xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
 
2917
        (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
 
2918
    FREE_AND_NULL(des);
 
2919
    FREE_AND_NULL(msg);
 
2920
}
 
2921
 
 
2922
/**
 
2923
 * xmlSchemaPCustomErr:
 
2924
 * @ctxt: the schema parser context
 
2925
 * @error: the error code
 
2926
 * @itemDes: the designation of the schema item
 
2927
 * @item: the schema item
 
2928
 * @itemElem: the node of the schema item
 
2929
 * @message: the error message
 
2930
 * @str1: the optional param for the error message
 
2931
 *
 
2932
 * Reports an error during parsing.
 
2933
 */
 
2934
static void
 
2935
xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
 
2936
                    xmlParserErrors error,
 
2937
                    xmlSchemaBasicItemPtr item,
 
2938
                    xmlNodePtr itemElem,
 
2939
                    const char *message,
 
2940
                    const xmlChar *str1)
 
2941
{
 
2942
    xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
 
2943
        str1, NULL, NULL);
 
2944
}
 
2945
 
 
2946
/**
 
2947
 * xmlSchemaPAttrUseErr:
 
2948
 * @ctxt: the schema parser context
 
2949
 * @error: the error code
 
2950
 * @itemDes: the designation of the schema type
 
2951
 * @item: the schema type
 
2952
 * @itemElem: the node of the schema type
 
2953
 * @attr: the invalid schema attribute
 
2954
 * @message: the error message
 
2955
 * @str1: the optional param for the error message
 
2956
 *
 
2957
 * Reports an attribute use error during parsing.
 
2958
 */
 
2959
static void
 
2960
xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
 
2961
                    xmlParserErrors error,
 
2962
                    xmlNodePtr node,
 
2963
                    xmlSchemaBasicItemPtr ownerItem,
 
2964
                    const xmlSchemaAttributeUsePtr attruse,
 
2965
                    const char *message,
 
2966
                    const xmlChar *str1, const xmlChar *str2,
 
2967
                    const xmlChar *str3,const xmlChar *str4)
 
2968
{
 
2969
    xmlChar *str = NULL, *msg = NULL;
 
2970
    
 
2971
    xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
 
2972
    msg = xmlStrcat(msg, BAD_CAST ", ");    
 
2973
    msg = xmlStrcat(msg,
 
2974
        BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
 
2975
        WXS_BASIC_CAST attruse, NULL));
 
2976
    FREE_AND_NULL(str);
 
2977
    msg = xmlStrcat(msg, BAD_CAST ": ");
 
2978
    msg = xmlStrcat(msg, (const xmlChar *) message);
 
2979
    msg = xmlStrcat(msg, BAD_CAST ".\n");
 
2980
    xmlSchemaErr4(ACTXT_CAST ctxt, error, node, 
 
2981
        (const char *) msg, str1, str2, str3, str4);
 
2982
    xmlFree(msg);
 
2983
}
 
2984
 
 
2985
/**
 
2986
 * xmlSchemaPIllegalFacetAtomicErr:
 
2987
 * @ctxt: the schema parser context
 
2988
 * @error: the error code
 
2989
 * @type: the schema type
 
2990
 * @baseType: the base type of type
 
2991
 * @facet: the illegal facet
 
2992
 *
 
2993
 * Reports an illegal facet for atomic simple types.
 
2994
 */
 
2995
static void
 
2996
xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
 
2997
                          xmlParserErrors error,
 
2998
                          xmlSchemaTypePtr type,
 
2999
                          xmlSchemaTypePtr baseType,
 
3000
                          xmlSchemaFacetPtr facet)
 
3001
{
 
3002
    xmlChar *des = NULL, *strT = NULL;
 
3003
 
 
3004
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
 
3005
    xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
 
3006
        "%s: The facet '%s' is not allowed on types derived from the "
 
3007
        "type %s.\n",
 
3008
        BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
 
3009
        xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
 
3010
        NULL, NULL);
 
3011
    FREE_AND_NULL(des);
 
3012
    FREE_AND_NULL(strT);
 
3013
}
 
3014
 
 
3015
/**
 
3016
 * xmlSchemaPIllegalFacetListUnionErr:
 
3017
 * @ctxt: the schema parser context
 
3018
 * @error: the error code
 
3019
 * @itemDes: the designation of the schema item involved
 
3020
 * @item: the schema item involved
 
3021
 * @facet: the illegal facet
 
3022
 *
 
3023
 * Reports an illegal facet for <list> and <union>.
 
3024
 */
 
3025
static void
 
3026
xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
 
3027
                          xmlParserErrors error,
 
3028
                          xmlSchemaTypePtr type,
 
3029
                          xmlSchemaFacetPtr facet)
 
3030
{
 
3031
    xmlChar *des = NULL;
 
3032
 
 
3033
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
 
3034
        type->node);
 
3035
    xmlSchemaPErr(ctxt, type->node, error,
 
3036
        "%s: The facet '%s' is not allowed.\n",
 
3037
        BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
 
3038
    FREE_AND_NULL(des);
 
3039
}
 
3040
 
 
3041
/**
 
3042
 * xmlSchemaPMutualExclAttrErr:
 
3043
 * @ctxt: the schema validation context
 
3044
 * @error: the error code
 
3045
 * @elemDes: the designation of the parent element node
 
3046
 * @attr: the bad attribute node
 
3047
 * @type: the corresponding type of the attribute node
 
3048
 *
 
3049
 * Reports an illegal attribute.
 
3050
 */
 
3051
static void
 
3052
xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
 
3053
                         xmlParserErrors error,
 
3054
                         xmlSchemaBasicItemPtr ownerItem,
 
3055
                         xmlAttrPtr attr,
 
3056
                         const char *name1,
 
3057
                         const char *name2)
 
3058
{
 
3059
    xmlChar *des = NULL;
 
3060
 
 
3061
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
 
3062
    xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
 
3063
        "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
 
3064
        BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
 
3065
    FREE_AND_NULL(des);
 
3066
}
 
3067
 
 
3068
/**
 
3069
 * xmlSchemaPSimpleTypeErr:
 
3070
 * @ctxt:  the schema validation context
 
3071
 * @error: the error code
 
3072
 * @type: the type specifier
 
3073
 * @ownerDes: the designation of the owner
 
3074
 * @ownerItem: the schema object if existent 
 
3075
 * @node: the validated node
 
3076
 * @value: the validated value
 
3077
 *
 
3078
 * Reports a simple type validation error.
 
3079
 * TODO: Should this report the value of an element as well?
 
3080
 */
 
3081
static void
 
3082
xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt, 
 
3083
                        xmlParserErrors error,
 
3084
                        xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
 
3085
                        xmlNodePtr node,
 
3086
                        xmlSchemaTypePtr type,
 
3087
                        const char *expected,
 
3088
                        const xmlChar *value,
 
3089
                        const char *message,
 
3090
                        const xmlChar *str1,
 
3091
                        const xmlChar *str2)
 
3092
{
 
3093
    xmlChar *msg = NULL;
 
3094
    
 
3095
    xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
 
3096
    if (message == NULL) {
 
3097
        /*
 
3098
        * Use default messages.
 
3099
        */      
 
3100
        if (type != NULL) {
 
3101
            if (node->type == XML_ATTRIBUTE_NODE)
 
3102
                msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
 
3103
            else
 
3104
                msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
 
3105
                "valid value of ");     
 
3106
            if (! xmlSchemaIsGlobalItem(type))
 
3107
                msg = xmlStrcat(msg, BAD_CAST "the local ");
 
3108
            else
 
3109
                msg = xmlStrcat(msg, BAD_CAST "the ");
 
3110
            
 
3111
            if (WXS_IS_ATOMIC(type))
 
3112
                msg = xmlStrcat(msg, BAD_CAST "atomic type");
 
3113
            else if (WXS_IS_LIST(type))
 
3114
                msg = xmlStrcat(msg, BAD_CAST "list type");
 
3115
            else if (WXS_IS_UNION(type))
 
3116
                msg = xmlStrcat(msg, BAD_CAST "union type");
 
3117
            
 
3118
            if (xmlSchemaIsGlobalItem(type)) {
 
3119
                xmlChar *str = NULL;
 
3120
                msg = xmlStrcat(msg, BAD_CAST " '");
 
3121
                if (type->builtInType != 0) {
 
3122
                    msg = xmlStrcat(msg, BAD_CAST "xs:");
 
3123
                    msg = xmlStrcat(msg, type->name);
 
3124
                } else 
 
3125
                    msg = xmlStrcat(msg,
 
3126
                        xmlSchemaFormatQName(&str,
 
3127
                            type->targetNamespace, type->name));
 
3128
                msg = xmlStrcat(msg, BAD_CAST "'.");
 
3129
                FREE_AND_NULL(str);
 
3130
            }
 
3131
        } else {
 
3132
            if (node->type == XML_ATTRIBUTE_NODE)
 
3133
                msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
 
3134
            else
 
3135
                msg = xmlStrcat(msg, BAD_CAST "The character content is not "
 
3136
                "valid.");
 
3137
        }       
 
3138
        if (expected) {
 
3139
            msg = xmlStrcat(msg, BAD_CAST " Expected is '");
 
3140
            msg = xmlStrcat(msg, BAD_CAST expected);
 
3141
            msg = xmlStrcat(msg, BAD_CAST "'.\n");
 
3142
        } else
 
3143
            msg = xmlStrcat(msg, BAD_CAST "\n");
 
3144
        if (node->type == XML_ATTRIBUTE_NODE)
 
3145
            xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
 
3146
        else
 
3147
            xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
 
3148
    } else {
 
3149
        msg = xmlStrcat(msg, BAD_CAST message);
 
3150
        msg = xmlStrcat(msg, BAD_CAST ".\n");
 
3151
        xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
 
3152
             (const char*) msg, str1, str2, NULL, NULL, NULL);
 
3153
    }
 
3154
    /* Cleanup. */    
 
3155
    FREE_AND_NULL(msg)
 
3156
}
 
3157
 
 
3158
/**
 
3159
 * xmlSchemaPContentErr:
 
3160
 * @ctxt: the schema parser context
 
3161
 * @error: the error code
 
3162
 * @onwerDes: the designation of the holder of the content
 
3163
 * @ownerItem: the owner item of the holder of the content
 
3164
 * @ownerElem: the node of the holder of the content
 
3165
 * @child: the invalid child node
 
3166
 * @message: the optional error message
 
3167
 * @content: the optional string describing the correct content
 
3168
 *
 
3169
 * Reports an error concerning the content of a schema element.
 
3170
 */
 
3171
static void
 
3172
xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
 
3173
                     xmlParserErrors error,
 
3174
                     xmlSchemaBasicItemPtr ownerItem,
 
3175
                     xmlNodePtr ownerElem,
 
3176
                     xmlNodePtr child,
 
3177
                     const char *message,
 
3178
                     const char *content)
 
3179
{
 
3180
    xmlChar *des = NULL;
 
3181
 
 
3182
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
 
3183
    if (message != NULL)
 
3184
        xmlSchemaPErr2(ctxt, ownerElem, child, error,
 
3185
            "%s: %s.\n",
 
3186
            BAD_CAST des, BAD_CAST message);
 
3187
    else {
 
3188
        if (content != NULL) {
 
3189
            xmlSchemaPErr2(ctxt, ownerElem, child, error,
 
3190
                "%s: The content is not valid. Expected is %s.\n",
 
3191
                BAD_CAST des, BAD_CAST content);
 
3192
        } else {
 
3193
            xmlSchemaPErr2(ctxt, ownerElem, child, error,
 
3194
                "%s: The content is not valid.\n",
 
3195
                BAD_CAST des, NULL);
 
3196
        }
 
3197
    }
 
3198
    FREE_AND_NULL(des)
 
3199
}
 
3200
 
 
3201
/************************************************************************
 
3202
 *                                                                      *
 
3203
 *                      Streamable error functions                      *
 
3204
 *                                                                      *
 
3205
 ************************************************************************/
 
3206
 
 
3207
 
 
3208
 
 
3209
 
 
3210
/************************************************************************
 
3211
 *                                                                      *
 
3212
 *                      Validation helper functions                     *
 
3213
 *                                                                      *
 
3214
 ************************************************************************/
 
3215
 
 
3216
 
 
3217
/************************************************************************
 
3218
 *                                                                      *
 
3219
 *                      Allocation functions                            *
 
3220
 *                                                                      *
 
3221
 ************************************************************************/
 
3222
 
 
3223
/**
 
3224
 * xmlSchemaNewSchemaForParserCtxt:
 
3225
 * @ctxt:  a schema validation context
 
3226
 *
 
3227
 * Allocate a new Schema structure.
 
3228
 *
 
3229
 * Returns the newly allocated structure or NULL in case or error
 
3230
 */
 
3231
static xmlSchemaPtr
 
3232
xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
 
3233
{
 
3234
    xmlSchemaPtr ret;
 
3235
 
 
3236
    ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
 
3237
    if (ret == NULL) {
 
3238
        xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
 
3239
        return (NULL);
 
3240
    }
 
3241
    memset(ret, 0, sizeof(xmlSchema));
 
3242
    ret->dict = ctxt->dict;
 
3243
    xmlDictReference(ret->dict);
 
3244
 
 
3245
    return (ret);
 
3246
}
 
3247
 
 
3248
/**
 
3249
 * xmlSchemaNewFacet:
 
3250
 *
 
3251
 * Allocate a new Facet structure.
 
3252
 *
 
3253
 * Returns the newly allocated structure or NULL in case or error
 
3254
 */
 
3255
xmlSchemaFacetPtr
 
3256
xmlSchemaNewFacet(void)
 
3257
{
 
3258
    xmlSchemaFacetPtr ret;
 
3259
 
 
3260
    ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
 
3261
    if (ret == NULL) {
 
3262
        return (NULL);
 
3263
    }
 
3264
    memset(ret, 0, sizeof(xmlSchemaFacet));
 
3265
 
 
3266
    return (ret);
 
3267
}
 
3268
 
 
3269
/**
 
3270
 * xmlSchemaNewAnnot:
 
3271
 * @ctxt:  a schema validation context
 
3272
 * @node:  a node
 
3273
 *
 
3274
 * Allocate a new annotation structure.
 
3275
 *
 
3276
 * Returns the newly allocated structure or NULL in case or error
 
3277
 */
 
3278
static xmlSchemaAnnotPtr
 
3279
xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
 
3280
{
 
3281
    xmlSchemaAnnotPtr ret;
 
3282
 
 
3283
    ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
 
3284
    if (ret == NULL) {
 
3285
        xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
 
3286
        return (NULL);
 
3287
    }
 
3288
    memset(ret, 0, sizeof(xmlSchemaAnnot));
 
3289
    ret->content = node;
 
3290
    return (ret);
 
3291
}
 
3292
 
 
3293
static xmlSchemaItemListPtr
 
3294
xmlSchemaItemListCreate(void)
 
3295
{
 
3296
    xmlSchemaItemListPtr ret;
 
3297
 
 
3298
    ret = xmlMalloc(sizeof(xmlSchemaItemList));
 
3299
    if (ret == NULL) {
 
3300
        xmlSchemaPErrMemory(NULL,
 
3301
            "allocating an item list structure", NULL);
 
3302
        return (NULL);
 
3303
    }
 
3304
    memset(ret, 0, sizeof(xmlSchemaItemList));
 
3305
    return (ret);
 
3306
}
 
3307
 
 
3308
static void
 
3309
xmlSchemaItemListClear(xmlSchemaItemListPtr list)
 
3310
{
 
3311
    if (list->items != NULL) {
 
3312
        xmlFree(list->items);
 
3313
        list->items = NULL;
 
3314
    }
 
3315
    list->nbItems = 0;
 
3316
    list->sizeItems = 0;
 
3317
}
 
3318
 
 
3319
static int
 
3320
xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
 
3321
{
 
3322
    if (list->items == NULL) {
 
3323
        list->items = (void **) xmlMalloc(
 
3324
            20 * sizeof(void *));
 
3325
        if (list->items == NULL) {
 
3326
            xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
 
3327
            return(-1);
 
3328
        }
 
3329
        list->sizeItems = 20;
 
3330
    } else if (list->sizeItems <= list->nbItems) {
 
3331
        list->sizeItems *= 2;
 
3332
        list->items = (void **) xmlRealloc(list->items,
 
3333
            list->sizeItems * sizeof(void *));
 
3334
        if (list->items == NULL) {
 
3335
            xmlSchemaPErrMemory(NULL, "growing item list", NULL);
 
3336
            list->sizeItems = 0;
 
3337
            return(-1);
 
3338
        }
 
3339
    }
 
3340
    list->items[list->nbItems++] = item;
 
3341
    return(0);
 
3342
}
 
3343
 
 
3344
static int
 
3345
xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
 
3346
                         int initialSize,
 
3347
                         void *item)
 
3348
{
 
3349
    if (list->items == NULL) {
 
3350
        if (initialSize <= 0)
 
3351
            initialSize = 1;
 
3352
        list->items = (void **) xmlMalloc(
 
3353
            initialSize * sizeof(void *));
 
3354
        if (list->items == NULL) {
 
3355
            xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
 
3356
            return(-1);
 
3357
        }
 
3358
        list->sizeItems = initialSize;
 
3359
    } else if (list->sizeItems <= list->nbItems) {
 
3360
        list->sizeItems *= 2;
 
3361
        list->items = (void **) xmlRealloc(list->items,
 
3362
            list->sizeItems * sizeof(void *));
 
3363
        if (list->items == NULL) {
 
3364
            xmlSchemaPErrMemory(NULL, "growing item list", NULL);
 
3365
            list->sizeItems = 0;
 
3366
            return(-1);
 
3367
        }
 
3368
    }
 
3369
    list->items[list->nbItems++] = item;
 
3370
    return(0);
 
3371
}
 
3372
 
 
3373
static int
 
3374
xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
 
3375
{    
 
3376
    if (list->items == NULL) {
 
3377
        list->items = (void **) xmlMalloc(
 
3378
            20 * sizeof(void *));
 
3379
        if (list->items == NULL) {
 
3380
            xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
 
3381
            return(-1);
 
3382
        }
 
3383
        list->sizeItems = 20;
 
3384
    } else if (list->sizeItems <= list->nbItems) {
 
3385
        list->sizeItems *= 2;
 
3386
        list->items = (void **) xmlRealloc(list->items,
 
3387
            list->sizeItems * sizeof(void *));
 
3388
        if (list->items == NULL) {
 
3389
            xmlSchemaPErrMemory(NULL, "growing item list", NULL);
 
3390
            list->sizeItems = 0;
 
3391
            return(-1);
 
3392
        }
 
3393
    }
 
3394
    /*
 
3395
    * Just append if the index is greater/equal than the item count.
 
3396
    */
 
3397
    if (idx >= list->nbItems) {
 
3398
        list->items[list->nbItems++] = item;
 
3399
    } else {
 
3400
        int i;
 
3401
        for (i = list->nbItems; i > idx; i--)
 
3402
            list->items[i] = list->items[i-1];
 
3403
        list->items[idx] = item;
 
3404
        list->nbItems++;
 
3405
    }
 
3406
    return(0);
 
3407
}
 
3408
 
 
3409
#if 0 /* enable if ever needed */
 
3410
static int
 
3411
xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
 
3412
                            int initialSize,
 
3413
                            void *item,
 
3414
                            int idx)
 
3415
{    
 
3416
    if (list->items == NULL) {
 
3417
        if (initialSize <= 0)
 
3418
            initialSize = 1;
 
3419
        list->items = (void **) xmlMalloc(
 
3420
            initialSize * sizeof(void *));
 
3421
        if (list->items == NULL) {
 
3422
            xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
 
3423
            return(-1);
 
3424
        }
 
3425
        list->sizeItems = initialSize;
 
3426
    } else if (list->sizeItems <= list->nbItems) {
 
3427
        list->sizeItems *= 2;
 
3428
        list->items = (void **) xmlRealloc(list->items,
 
3429
            list->sizeItems * sizeof(void *));
 
3430
        if (list->items == NULL) {
 
3431
            xmlSchemaPErrMemory(NULL, "growing item list", NULL);
 
3432
            list->sizeItems = 0;
 
3433
            return(-1);
 
3434
        }
 
3435
    }
 
3436
    /*
 
3437
    * Just append if the index is greater/equal than the item count.
 
3438
    */
 
3439
    if (idx >= list->nbItems) {
 
3440
        list->items[list->nbItems++] = item;
 
3441
    } else {
 
3442
        int i;
 
3443
        for (i = list->nbItems; i > idx; i--)
 
3444
            list->items[i] = list->items[i-1];
 
3445
        list->items[idx] = item;
 
3446
        list->nbItems++;
 
3447
    }
 
3448
    return(0);
 
3449
}
 
3450
#endif
 
3451
 
 
3452
static int
 
3453
xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
 
3454
{
 
3455
    int i;
 
3456
    if ((list->items == NULL) || (idx >= list->nbItems)) {
 
3457
        xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
 
3458
            "index error.\n");
 
3459
        return(-1);
 
3460
    }
 
3461
 
 
3462
    if (list->nbItems == 1) {
 
3463
        /* TODO: Really free the list? */
 
3464
        xmlFree(list->items);
 
3465
        list->items = NULL;
 
3466
        list->nbItems = 0;
 
3467
        list->sizeItems = 0;
 
3468
    } else if (list->nbItems -1 == idx) {
 
3469
        list->nbItems--;
 
3470
    } else {    
 
3471
        for (i = idx; i < list->nbItems -1; i++)
 
3472
            list->items[i] = list->items[i+1];
 
3473
        list->nbItems--;
 
3474
    }
 
3475
    return(0);
 
3476
}
 
3477
 
 
3478
/**
 
3479
 * xmlSchemaItemListFree:
 
3480
 * @annot:  a schema type structure
 
3481
 *
 
3482
 * Deallocate a annotation structure
 
3483
 */
 
3484
static void
 
3485
xmlSchemaItemListFree(xmlSchemaItemListPtr list)
 
3486
{
 
3487
    if (list == NULL)
 
3488
        return;
 
3489
    if (list->items != NULL)
 
3490
        xmlFree(list->items);
 
3491
    xmlFree(list);
 
3492
}
 
3493
 
 
3494
static void
 
3495
xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
 
3496
{
 
3497
    if (bucket == NULL)
 
3498
        return;
 
3499
    if (bucket->globals != NULL) {
 
3500
        xmlSchemaComponentListFree(bucket->globals);
 
3501
        xmlSchemaItemListFree(bucket->globals);
 
3502
    }
 
3503
    if (bucket->locals != NULL) {
 
3504
        xmlSchemaComponentListFree(bucket->locals);
 
3505
        xmlSchemaItemListFree(bucket->locals);  
 
3506
    }
 
3507
    if (bucket->relations != NULL) {
 
3508
        xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
 
3509
        do {
 
3510
            prev = cur;     
 
3511
            cur = cur->next;
 
3512
            xmlFree(prev);
 
3513
        } while (cur != NULL);
 
3514
    }
 
3515
    if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
 
3516
        xmlFreeDoc(bucket->doc);
 
3517
    } 
 
3518
    if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
 
3519
        if (WXS_IMPBUCKET(bucket)->schema != NULL)
 
3520
            xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
 
3521
    }
 
3522
    xmlFree(bucket);
 
3523
}
 
3524
 
 
3525
static xmlSchemaBucketPtr
 
3526
xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
 
3527
                         int type, const xmlChar *targetNamespace)
 
3528
{
 
3529
    xmlSchemaBucketPtr ret;
 
3530
    int size;
 
3531
    xmlSchemaPtr mainSchema;
 
3532
 
 
3533
    if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
 
3534
        PERROR_INT("xmlSchemaBucketCreate",
 
3535
            "no main schema on constructor");
 
3536
        return(NULL);
 
3537
    }
 
3538
    mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
 
3539
    /* Create the schema bucket. */
 
3540
    if (WXS_IS_BUCKET_INCREDEF(type))
 
3541
        size = sizeof(xmlSchemaInclude);
 
3542
    else
 
3543
        size = sizeof(xmlSchemaImport);
 
3544
    ret = (xmlSchemaBucketPtr) xmlMalloc(size);
 
3545
    if (ret == NULL) {
 
3546
        xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
 
3547
        return(NULL);
 
3548
    }
 
3549
    memset(ret, 0, size);
 
3550
    ret->targetNamespace = targetNamespace;
 
3551
    ret->type = type;
 
3552
    ret->globals = xmlSchemaItemListCreate();
 
3553
    if (ret->globals == NULL) {
 
3554
        xmlFree(ret);
 
3555
        return(NULL);
 
3556
    }
 
3557
    ret->locals = xmlSchemaItemListCreate();
 
3558
    if (ret->locals == NULL) {
 
3559
        xmlFree(ret);
 
3560
        return(NULL);
 
3561
    }
 
3562
    /* 
 
3563
    * The following will assure that only the first bucket is marked as
 
3564
    * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
 
3565
    * For each following import buckets an xmlSchema will be created.
 
3566
    * An xmlSchema will be created for every distinct targetNamespace.
 
3567
    * We assign the targetNamespace to the schemata here.
 
3568
    */
 
3569
    if (! WXS_HAS_BUCKETS(pctxt)) {
 
3570
        if (WXS_IS_BUCKET_INCREDEF(type)) {
 
3571
            PERROR_INT("xmlSchemaBucketCreate",
 
3572
                "first bucket but it's an include or redefine");
 
3573
            xmlSchemaBucketFree(ret);
 
3574
            return(NULL);
 
3575
        }
 
3576
        /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */ 
 
3577
        ret->type = XML_SCHEMA_SCHEMA_MAIN;
 
3578
        /* Point to the *main* schema. */
 
3579
        WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
 
3580
        WXS_IMPBUCKET(ret)->schema = mainSchema;
 
3581
        /*
 
3582
        * Ensure that the main schema gets a targetNamespace.
 
3583
        */
 
3584
        mainSchema->targetNamespace = targetNamespace;
 
3585
    } else {
 
3586
        if (type == XML_SCHEMA_SCHEMA_MAIN) {       
 
3587
            PERROR_INT("xmlSchemaBucketCreate",
 
3588
                "main bucket but it's not the first one");
 
3589
            xmlSchemaBucketFree(ret);
 
3590
            return(NULL);
 
3591
        } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {      
 
3592
            /*
 
3593
            * Create a schema for imports and assign the
 
3594
            * targetNamespace.
 
3595
            */
 
3596
            WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
 
3597
            if (WXS_IMPBUCKET(ret)->schema == NULL) {
 
3598
                xmlSchemaBucketFree(ret);
 
3599
                return(NULL);
 
3600
            }
 
3601
            WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
 
3602
        }
 
3603
    }    
 
3604
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
 
3605
        int res;
 
3606
        /*
 
3607
        * Imports go into the "schemasImports" slot of the main *schema*.
 
3608
        * Note that we create an import entry for the main schema as well; i.e.,
 
3609
        * even if there's only one schema, we'll get an import.
 
3610
        */
 
3611
        if (mainSchema->schemasImports == NULL) {
 
3612
            mainSchema->schemasImports = xmlHashCreateDict(5,
 
3613
                WXS_CONSTRUCTOR(pctxt)->dict);
 
3614
            if (mainSchema->schemasImports == NULL) {
 
3615
                xmlSchemaBucketFree(ret);
 
3616
                return(NULL);
 
3617
            }
 
3618
        }
 
3619
        if (targetNamespace == NULL)
 
3620
            res = xmlHashAddEntry(mainSchema->schemasImports,
 
3621
                XML_SCHEMAS_NO_NAMESPACE, ret);
 
3622
        else
 
3623
            res = xmlHashAddEntry(mainSchema->schemasImports,
 
3624
                targetNamespace, ret);
 
3625
        if (res != 0) {
 
3626
            PERROR_INT("xmlSchemaBucketCreate",
 
3627
                "failed to add the schema bucket to the hash");
 
3628
            xmlSchemaBucketFree(ret);
 
3629
            return(NULL);
 
3630
        }
 
3631
    } else {
 
3632
        /* Set the @ownerImport of an include bucket. */
 
3633
        if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
 
3634
            WXS_INCBUCKET(ret)->ownerImport =
 
3635
                WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
 
3636
        else
 
3637
            WXS_INCBUCKET(ret)->ownerImport =
 
3638
                WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
 
3639
 
 
3640
        /* Includes got into the "includes" slot of the *main* schema. */
 
3641
        if (mainSchema->includes == NULL) {
 
3642
            mainSchema->includes = xmlSchemaItemListCreate();
 
3643
            if (mainSchema->includes == NULL) {
 
3644
                xmlSchemaBucketFree(ret);
 
3645
                return(NULL);
 
3646
            }       
 
3647
        }
 
3648
        xmlSchemaItemListAdd(mainSchema->includes, ret);
 
3649
    }
 
3650
    /* 
 
3651
    * Add to list of all buckets; this is used for lookup
 
3652
    * during schema construction time only.
 
3653
    */
 
3654
    if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
 
3655
        return(NULL);
 
3656
    return(ret);
 
3657
}
 
3658
 
 
3659
static int
 
3660
xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
 
3661
{
 
3662
    if (*list == NULL) {
 
3663
        *list = xmlSchemaItemListCreate();
 
3664
        if (*list == NULL)
 
3665
            return(-1);
 
3666
    }
 
3667
    xmlSchemaItemListAddSize(*list, initialSize, item);
 
3668
    return(0);
 
3669
}
 
3670
 
 
3671
/**
 
3672
 * xmlSchemaFreeAnnot:
 
3673
 * @annot:  a schema type structure
 
3674
 *
 
3675
 * Deallocate a annotation structure
 
3676
 */
 
3677
static void
 
3678
xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
 
3679
{
 
3680
    if (annot == NULL)
 
3681
        return;
 
3682
    if (annot->next == NULL) {
 
3683
        xmlFree(annot);
 
3684
    } else {
 
3685
        xmlSchemaAnnotPtr prev;
 
3686
 
 
3687
        do {
 
3688
            prev = annot;
 
3689
            annot = annot->next;
 
3690
            xmlFree(prev);
 
3691
        } while (annot != NULL);
 
3692
    }
 
3693
}
 
3694
 
 
3695
/**
 
3696
 * xmlSchemaFreeNotation:
 
3697
 * @schema:  a schema notation structure
 
3698
 *
 
3699
 * Deallocate a Schema Notation structure.
 
3700
 */
 
3701
static void
 
3702
xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
 
3703
{
 
3704
    if (nota == NULL)
 
3705
        return;
 
3706
    xmlFree(nota);
 
3707
}
 
3708
 
 
3709
/**
 
3710
 * xmlSchemaFreeAttribute:
 
3711
 * @attr:  an attribute declaration
 
3712
 *
 
3713
 * Deallocates an attribute declaration structure.
 
3714
 */
 
3715
static void
 
3716
xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
 
3717
{
 
3718
    if (attr == NULL)
 
3719
        return;
 
3720
    if (attr->annot != NULL)
 
3721
        xmlSchemaFreeAnnot(attr->annot);
 
3722
    if (attr->defVal != NULL)
 
3723
        xmlSchemaFreeValue(attr->defVal);
 
3724
    xmlFree(attr);
 
3725
}
 
3726
 
 
3727
/**
 
3728
 * xmlSchemaFreeAttributeUse:
 
3729
 * @use:  an attribute use
 
3730
 *
 
3731
 * Deallocates an attribute use structure.
 
3732
 */
 
3733
static void
 
3734
xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
 
3735
{
 
3736
    if (use == NULL)
 
3737
        return;
 
3738
    if (use->annot != NULL)
 
3739
        xmlSchemaFreeAnnot(use->annot);
 
3740
    if (use->defVal != NULL)
 
3741
        xmlSchemaFreeValue(use->defVal);
 
3742
    xmlFree(use);
 
3743
}
 
3744
 
 
3745
/**
 
3746
 * xmlSchemaFreeAttributeUseProhib:
 
3747
 * @prohib:  an attribute use prohibition
 
3748
 *
 
3749
 * Deallocates an attribute use structure.
 
3750
 */
 
3751
static void
 
3752
xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
 
3753
{
 
3754
    if (prohib == NULL)
 
3755
        return;
 
3756
    xmlFree(prohib);
 
3757
}
 
3758
 
 
3759
/**
 
3760
 * xmlSchemaFreeWildcardNsSet:
 
3761
 * set:  a schema wildcard namespace
 
3762
 *
 
3763
 * Deallocates a list of wildcard constraint structures.
 
3764
 */
 
3765
static void
 
3766
xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
 
3767
{
 
3768
    xmlSchemaWildcardNsPtr next;
 
3769
 
 
3770
    while (set != NULL) {
 
3771
        next = set->next;
 
3772
        xmlFree(set);
 
3773
        set = next;
 
3774
    }
 
3775
}
 
3776
 
 
3777
/**
 
3778
 * xmlSchemaFreeWildcard:
 
3779
 * @wildcard:  a wildcard structure
 
3780
 *
 
3781
 * Deallocates a wildcard structure.
 
3782
 */
 
3783
void
 
3784
xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
 
3785
{
 
3786
    if (wildcard == NULL)
 
3787
        return;
 
3788
    if (wildcard->annot != NULL)
 
3789
        xmlSchemaFreeAnnot(wildcard->annot);
 
3790
    if (wildcard->nsSet != NULL)
 
3791
        xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
 
3792
    if (wildcard->negNsSet != NULL)
 
3793
        xmlFree(wildcard->negNsSet);
 
3794
    xmlFree(wildcard);
 
3795
}
 
3796
 
 
3797
/**
 
3798
 * xmlSchemaFreeAttributeGroup:
 
3799
 * @schema:  a schema attribute group structure
 
3800
 *
 
3801
 * Deallocate a Schema Attribute Group structure.
 
3802
 */
 
3803
static void
 
3804
xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
 
3805
{
 
3806
    if (attrGr == NULL)
 
3807
        return;
 
3808
    if (attrGr->annot != NULL)
 
3809
        xmlSchemaFreeAnnot(attrGr->annot);
 
3810
    if (attrGr->attrUses != NULL)
 
3811
        xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
 
3812
    xmlFree(attrGr);
 
3813
}
 
3814
 
 
3815
/**
 
3816
 * xmlSchemaFreeQNameRef:
 
3817
 * @item: a QName reference structure
 
3818
 *
 
3819
 * Deallocatea a QName reference structure.
 
3820
 */
 
3821
static void
 
3822
xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
 
3823
{
 
3824
    xmlFree(item);
 
3825
}
 
3826
 
 
3827
/**
 
3828
 * xmlSchemaFreeTypeLinkList:
 
3829
 * @alink: a type link
 
3830
 *
 
3831
 * Deallocate a list of types.
 
3832
 */
 
3833
static void
 
3834
xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
 
3835
{
 
3836
    xmlSchemaTypeLinkPtr next;
 
3837
 
 
3838
    while (link != NULL) {
 
3839
        next = link->next;
 
3840
        xmlFree(link);
 
3841
        link = next;
 
3842
    }
 
3843
}
 
3844
 
 
3845
static void
 
3846
xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
 
3847
{
 
3848
    xmlSchemaIDCStateObjPtr next;
 
3849
    while (sto != NULL) {
 
3850
        next = sto->next;
 
3851
        if (sto->history != NULL)
 
3852
            xmlFree(sto->history);
 
3853
        if (sto->xpathCtxt != NULL)
 
3854
            xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
 
3855
        xmlFree(sto);
 
3856
        sto = next;
 
3857
    }
 
3858
}
 
3859
 
 
3860
/**
 
3861
 * xmlSchemaFreeIDC:
 
3862
 * @idc: a identity-constraint definition
 
3863
 *
 
3864
 * Deallocates an identity-constraint definition.
 
3865
 */
 
3866
static void
 
3867
xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
 
3868
{
 
3869
    xmlSchemaIDCSelectPtr cur, prev;
 
3870
 
 
3871
    if (idcDef == NULL)
 
3872
        return;
 
3873
    if (idcDef->annot != NULL)
 
3874
        xmlSchemaFreeAnnot(idcDef->annot);
 
3875
    /* Selector */
 
3876
    if (idcDef->selector != NULL) {
 
3877
        if (idcDef->selector->xpathComp != NULL)
 
3878
            xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
 
3879
        xmlFree(idcDef->selector);
 
3880
    }
 
3881
    /* Fields */
 
3882
    if (idcDef->fields != NULL) {
 
3883
        cur = idcDef->fields;
 
3884
        do {
 
3885
            prev = cur;
 
3886
            cur = cur->next;
 
3887
            if (prev->xpathComp != NULL)
 
3888
                xmlFreePattern((xmlPatternPtr) prev->xpathComp);
 
3889
            xmlFree(prev);
 
3890
        } while (cur != NULL);
 
3891
    }
 
3892
    xmlFree(idcDef);
 
3893
}
 
3894
 
 
3895
/**
 
3896
 * xmlSchemaFreeElement:
 
3897
 * @schema:  a schema element structure
 
3898
 *
 
3899
 * Deallocate a Schema Element structure.
 
3900
 */
 
3901
static void
 
3902
xmlSchemaFreeElement(xmlSchemaElementPtr elem)
 
3903
{
 
3904
    if (elem == NULL)
 
3905
        return;
 
3906
    if (elem->annot != NULL)
 
3907
        xmlSchemaFreeAnnot(elem->annot);
 
3908
    if (elem->contModel != NULL)
 
3909
        xmlRegFreeRegexp(elem->contModel);
 
3910
    if (elem->defVal != NULL)
 
3911
        xmlSchemaFreeValue(elem->defVal);
 
3912
    xmlFree(elem);
 
3913
}
 
3914
 
 
3915
/**
 
3916
 * xmlSchemaFreeFacet:
 
3917
 * @facet:  a schema facet structure
 
3918
 *
 
3919
 * Deallocate a Schema Facet structure.
 
3920
 */
 
3921
void
 
3922
xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
 
3923
{
 
3924
    if (facet == NULL)
 
3925
        return;
 
3926
    if (facet->val != NULL)
 
3927
        xmlSchemaFreeValue(facet->val);
 
3928
    if (facet->regexp != NULL)
 
3929
        xmlRegFreeRegexp(facet->regexp);
 
3930
    if (facet->annot != NULL)
 
3931
        xmlSchemaFreeAnnot(facet->annot);
 
3932
    xmlFree(facet);
 
3933
}
 
3934
 
 
3935
/**
 
3936
 * xmlSchemaFreeType:
 
3937
 * @type:  a schema type structure
 
3938
 *
 
3939
 * Deallocate a Schema Type structure.
 
3940
 */
 
3941
void
 
3942
xmlSchemaFreeType(xmlSchemaTypePtr type)
 
3943
{
 
3944
    if (type == NULL)
 
3945
        return;
 
3946
    if (type->annot != NULL)
 
3947
        xmlSchemaFreeAnnot(type->annot);
 
3948
    if (type->facets != NULL) {
 
3949
        xmlSchemaFacetPtr facet, next;
 
3950
 
 
3951
        facet = type->facets;
 
3952
        while (facet != NULL) {
 
3953
            next = facet->next;
 
3954
            xmlSchemaFreeFacet(facet);
 
3955
            facet = next;
 
3956
        }
 
3957
    }
 
3958
    if (type->attrUses != NULL)
 
3959
        xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
 
3960
    if (type->memberTypes != NULL)
 
3961
        xmlSchemaFreeTypeLinkList(type->memberTypes);
 
3962
    if (type->facetSet != NULL) {
 
3963
        xmlSchemaFacetLinkPtr next, link;
 
3964
 
 
3965
        link = type->facetSet;
 
3966
        do {
 
3967
            next = link->next;
 
3968
            xmlFree(link);
 
3969
            link = next;
 
3970
        } while (link != NULL);
 
3971
    }
 
3972
    if (type->contModel != NULL)
 
3973
        xmlRegFreeRegexp(type->contModel);
 
3974
    xmlFree(type);
 
3975
}
 
3976
 
 
3977
/**
 
3978
 * xmlSchemaFreeModelGroupDef:
 
3979
 * @item:  a schema model group definition
 
3980
 *
 
3981
 * Deallocates a schema model group definition.
 
3982
 */
 
3983
static void
 
3984
xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
 
3985
{
 
3986
    if (item->annot != NULL)
 
3987
        xmlSchemaFreeAnnot(item->annot);
 
3988
    xmlFree(item);
 
3989
}
 
3990
 
 
3991
/**
 
3992
 * xmlSchemaFreeModelGroup:
 
3993
 * @item:  a schema model group
 
3994
 *
 
3995
 * Deallocates a schema model group structure.
 
3996
 */
 
3997
static void
 
3998
xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
 
3999
{
 
4000
    if (item->annot != NULL)
 
4001
        xmlSchemaFreeAnnot(item->annot);
 
4002
    xmlFree(item);
 
4003
}
 
4004
 
 
4005
static void
 
4006
xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
 
4007
{
 
4008
    if ((list == NULL) || (list->nbItems == 0))
 
4009
        return;
 
4010
    {
 
4011
        xmlSchemaTreeItemPtr item;
 
4012
        xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
 
4013
        int i;
 
4014
 
 
4015
        for (i = 0; i < list->nbItems; i++) {
 
4016
            item = items[i];
 
4017
            if (item == NULL)
 
4018
                continue;           
 
4019
            switch (item->type) {
 
4020
                case XML_SCHEMA_TYPE_SIMPLE:
 
4021
                case XML_SCHEMA_TYPE_COMPLEX:
 
4022
                    xmlSchemaFreeType((xmlSchemaTypePtr) item);
 
4023
                    break;
 
4024
                case XML_SCHEMA_TYPE_ATTRIBUTE:
 
4025
                    xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
 
4026
                    break;
 
4027
                case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 
4028
                    xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
 
4029
                    break;
 
4030
                case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
 
4031
                    xmlSchemaFreeAttributeUseProhib(
 
4032
                        (xmlSchemaAttributeUseProhibPtr) item);
 
4033
                    break;
 
4034
                case XML_SCHEMA_TYPE_ELEMENT:
 
4035
                    xmlSchemaFreeElement((xmlSchemaElementPtr) item);
 
4036
                    break;
 
4037
                case XML_SCHEMA_TYPE_PARTICLE:
 
4038
                    if (item->annot != NULL)
 
4039
                        xmlSchemaFreeAnnot(item->annot);
 
4040
                    xmlFree(item);
 
4041
                    break;
 
4042
                case XML_SCHEMA_TYPE_SEQUENCE:
 
4043
                case XML_SCHEMA_TYPE_CHOICE:
 
4044
                case XML_SCHEMA_TYPE_ALL:
 
4045
                    xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
 
4046
                    break;
 
4047
                case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 
4048
                    xmlSchemaFreeAttributeGroup(
 
4049
                        (xmlSchemaAttributeGroupPtr) item);
 
4050
                    break;
 
4051
                case XML_SCHEMA_TYPE_GROUP:
 
4052
                    xmlSchemaFreeModelGroupDef(
 
4053
                        (xmlSchemaModelGroupDefPtr) item);
 
4054
                    break;
 
4055
                case XML_SCHEMA_TYPE_ANY:
 
4056
                case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 
4057
                    xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
 
4058
                    break;
 
4059
                case XML_SCHEMA_TYPE_IDC_KEY:
 
4060
                case XML_SCHEMA_TYPE_IDC_UNIQUE:
 
4061
                case XML_SCHEMA_TYPE_IDC_KEYREF:
 
4062
                    xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
 
4063
                    break;
 
4064
                case XML_SCHEMA_TYPE_NOTATION:
 
4065
                    xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
 
4066
                    break;
 
4067
                case XML_SCHEMA_EXTRA_QNAMEREF:
 
4068
                    xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
 
4069
                    break;
 
4070
                default: {
 
4071
                    /* TODO: This should never be hit. */
 
4072
                    xmlSchemaPSimpleInternalErr(NULL,
 
4073
                        "Internal error: xmlSchemaComponentListFree, "
 
4074
                        "unexpected component type '%s'\n",
 
4075
                        (const xmlChar *) WXS_ITEM_TYPE_NAME(item));
 
4076
                         }
 
4077
                    break;
 
4078
            }
 
4079
        }
 
4080
        list->nbItems = 0;
 
4081
    }
 
4082
}
 
4083
 
 
4084
/**
 
4085
 * xmlSchemaFree:
 
4086
 * @schema:  a schema structure
 
4087
 *
 
4088
 * Deallocate a Schema structure.
 
4089
 */
 
4090
void
 
4091
xmlSchemaFree(xmlSchemaPtr schema)
 
4092
{
 
4093
    if (schema == NULL)
 
4094
        return;
 
4095
    /* @volatiles is not used anymore :-/ */
 
4096
    if (schema->volatiles != NULL)
 
4097
        TODO
 
4098
    /*
 
4099
    * Note that those slots are not responsible for freeing
 
4100
    * schema components anymore; this will now be done by
 
4101
    * the schema buckets.
 
4102
    */
 
4103
    if (schema->notaDecl != NULL)
 
4104
        xmlHashFree(schema->notaDecl, NULL);
 
4105
    if (schema->attrDecl != NULL)
 
4106
        xmlHashFree(schema->attrDecl, NULL);
 
4107
    if (schema->attrgrpDecl != NULL)
 
4108
        xmlHashFree(schema->attrgrpDecl, NULL);
 
4109
    if (schema->elemDecl != NULL)
 
4110
        xmlHashFree(schema->elemDecl, NULL);
 
4111
    if (schema->typeDecl != NULL)
 
4112
        xmlHashFree(schema->typeDecl, NULL);
 
4113
    if (schema->groupDecl != NULL)
 
4114
        xmlHashFree(schema->groupDecl, NULL);
 
4115
    if (schema->idcDef != NULL)
 
4116
        xmlHashFree(schema->idcDef, NULL);
 
4117
 
 
4118
    if (schema->schemasImports != NULL)
 
4119
        xmlHashFree(schema->schemasImports,
 
4120
                    (xmlHashDeallocator) xmlSchemaBucketFree);
 
4121
    if (schema->includes != NULL) {
 
4122
        xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
 
4123
        int i;
 
4124
        for (i = 0; i < list->nbItems; i++) {
 
4125
            xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);   
 
4126
        }
 
4127
        xmlSchemaItemListFree(list);
 
4128
    }
 
4129
    if (schema->annot != NULL)
 
4130
        xmlSchemaFreeAnnot(schema->annot);
 
4131
    /* Never free the doc here, since this will be done by the buckets. */
 
4132
 
 
4133
    xmlDictFree(schema->dict);
 
4134
    xmlFree(schema);
 
4135
}
 
4136
 
 
4137
/************************************************************************
 
4138
 *                                                                      *
 
4139
 *                      Debug functions                                 *
 
4140
 *                                                                      *
 
4141
 ************************************************************************/
 
4142
 
 
4143
#ifdef LIBXML_OUTPUT_ENABLED
 
4144
 
 
4145
static void
 
4146
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
 
4147
 
 
4148
/**
 
4149
 * xmlSchemaElementDump:
 
4150
 * @elem:  an element
 
4151
 * @output:  the file output
 
4152
 *
 
4153
 * Dump the element
 
4154
 */
 
4155
static void
 
4156
xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output,
 
4157
                     const xmlChar * name ATTRIBUTE_UNUSED,
 
4158
                     const xmlChar * namespace ATTRIBUTE_UNUSED,
 
4159
                     const xmlChar * context ATTRIBUTE_UNUSED)
 
4160
{
 
4161
    if (elem == NULL)
 
4162
        return;
 
4163
 
 
4164
 
 
4165
    fprintf(output, "Element");
 
4166
    if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
 
4167
        fprintf(output, " (global)");
 
4168
    fprintf(output, ": '%s' ", elem->name);
 
4169
    if (namespace != NULL)
 
4170
        fprintf(output, "ns '%s'", namespace);
 
4171
    fprintf(output, "\n");
 
4172
#if 0
 
4173
    if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
 
4174
        fprintf(output, "  min %d ", elem->minOccurs);
 
4175
        if (elem->maxOccurs >= UNBOUNDED)
 
4176
            fprintf(output, "max: unbounded\n");
 
4177
        else if (elem->maxOccurs != 1)
 
4178
            fprintf(output, "max: %d\n", elem->maxOccurs);
 
4179
        else
 
4180
            fprintf(output, "\n");
 
4181
    }
 
4182
#endif
 
4183
    /*
 
4184
    * Misc other properties.
 
4185
    */
 
4186
    if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
 
4187
        (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
 
4188
        (elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
 
4189
        (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
 
4190
        fprintf(output, "  props: ");
 
4191
        if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
 
4192
            fprintf(output, "[fixed] ");
 
4193
        if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
 
4194
            fprintf(output, "[default] ");
 
4195
        if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
 
4196
            fprintf(output, "[abstract] ");
 
4197
        if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
 
4198
            fprintf(output, "[nillable] ");
 
4199
        fprintf(output, "\n");
 
4200
    }
 
4201
    /*
 
4202
    * Default/fixed value.
 
4203
    */
 
4204
    if (elem->value != NULL)
 
4205
        fprintf(output, "  value: '%s'\n", elem->value);
 
4206
    /*
 
4207
    * Type.
 
4208
    */
 
4209
    if (elem->namedType != NULL) {
 
4210
        fprintf(output, "  type: '%s' ", elem->namedType);
 
4211
        if (elem->namedTypeNs != NULL)
 
4212
            fprintf(output, "ns '%s'\n", elem->namedTypeNs);
 
4213
        else
 
4214
            fprintf(output, "\n");
 
4215
    } else if (elem->subtypes != NULL) {
 
4216
        /*
 
4217
        * Dump local types.
 
4218
        */
 
4219
        xmlSchemaTypeDump(elem->subtypes, output);
 
4220
    }
 
4221
    /*
 
4222
    * Substitution group.
 
4223
    */
 
4224
    if (elem->substGroup != NULL) {
 
4225
        fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
 
4226
        if (elem->substGroupNs != NULL)
 
4227
            fprintf(output, "ns '%s'\n", elem->substGroupNs);
 
4228
        else
 
4229
            fprintf(output, "\n");
 
4230
    }
 
4231
}
 
4232
 
 
4233
/**
 
4234
 * xmlSchemaAnnotDump:
 
4235
 * @output:  the file output
 
4236
 * @annot:  a annotation
 
4237
 *
 
4238
 * Dump the annotation
 
4239
 */
 
4240
static void
 
4241
xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
 
4242
{
 
4243
    xmlChar *content;
 
4244
 
 
4245
    if (annot == NULL)
 
4246
        return;
 
4247
 
 
4248
    content = xmlNodeGetContent(annot->content);
 
4249
    if (content != NULL) {
 
4250
        fprintf(output, "  Annot: %s\n", content);
 
4251
        xmlFree(content);
 
4252
    } else
 
4253
        fprintf(output, "  Annot: empty\n");
 
4254
}
 
4255
 
 
4256
/**
 
4257
 * xmlSchemaContentModelDump:
 
4258
 * @particle: the schema particle
 
4259
 * @output: the file output
 
4260
 * @depth: the depth used for intentation
 
4261
 *
 
4262
 * Dump a SchemaType structure
 
4263
 */
 
4264
static void
 
4265
xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
 
4266
{
 
4267
    xmlChar *str = NULL;
 
4268
    xmlSchemaTreeItemPtr term;
 
4269
    char shift[100];
 
4270
    int i;
 
4271
 
 
4272
    if (particle == NULL)
 
4273
        return;
 
4274
    for (i = 0;((i < depth) && (i < 25));i++)
 
4275
        shift[2 * i] = shift[2 * i + 1] = ' ';
 
4276
    shift[2 * i] = shift[2 * i + 1] = 0;
 
4277
    fprintf(output, shift);
 
4278
    if (particle->children == NULL) {
 
4279
        fprintf(output, "MISSING particle term\n");
 
4280
        return;
 
4281
    }
 
4282
    term = particle->children;
 
4283
    if (term == NULL) {
 
4284
        fprintf(output, "(NULL)");
 
4285
    } else {
 
4286
        switch (term->type) {
 
4287
            case XML_SCHEMA_TYPE_ELEMENT:
 
4288
                fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
 
4289
                    ((xmlSchemaElementPtr)term)->targetNamespace,
 
4290
                    ((xmlSchemaElementPtr)term)->name));
 
4291
                FREE_AND_NULL(str);
 
4292
                break;
 
4293
            case XML_SCHEMA_TYPE_SEQUENCE:
 
4294
                fprintf(output, "SEQUENCE");
 
4295
                break;
 
4296
            case XML_SCHEMA_TYPE_CHOICE:
 
4297
                fprintf(output, "CHOICE");
 
4298
                break;
 
4299
            case XML_SCHEMA_TYPE_ALL:
 
4300
                fprintf(output, "ALL");
 
4301
                break;
 
4302
            case XML_SCHEMA_TYPE_ANY:
 
4303
                fprintf(output, "ANY");
 
4304
                break;
 
4305
            default:
 
4306
                fprintf(output, "UNKNOWN\n");
 
4307
                return;
 
4308
        }
 
4309
    }
 
4310
    if (particle->minOccurs != 1)
 
4311
        fprintf(output, " min: %d", particle->minOccurs);
 
4312
    if (particle->maxOccurs >= UNBOUNDED)
 
4313
        fprintf(output, " max: unbounded");
 
4314
    else if (particle->maxOccurs != 1)
 
4315
        fprintf(output, " max: %d", particle->maxOccurs);
 
4316
    fprintf(output, "\n");
 
4317
    if (term &&
 
4318
        ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
 
4319
         (term->type == XML_SCHEMA_TYPE_CHOICE) ||
 
4320
         (term->type == XML_SCHEMA_TYPE_ALL)) &&
 
4321
         (term->children != NULL)) {
 
4322
        xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
 
4323
            output, depth +1);
 
4324
    }
 
4325
    if (particle->next != NULL)
 
4326
        xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
 
4327
                output, depth);
 
4328
}
 
4329
 
 
4330
/**
 
4331
 * xmlSchemaAttrUsesDump:
 
4332
 * @uses:  attribute uses list
 
4333
 * @output:  the file output 
 
4334
 *
 
4335
 * Dumps a list of attribute use components.
 
4336
 */
 
4337
static void
 
4338
xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
 
4339
{
 
4340
    xmlSchemaAttributeUsePtr use;
 
4341
    xmlSchemaAttributeUseProhibPtr prohib;
 
4342
    xmlSchemaQNameRefPtr ref;
 
4343
    const xmlChar *name, *tns;
 
4344
    xmlChar *str = NULL;
 
4345
    int i;
 
4346
 
 
4347
    if ((uses == NULL) || (uses->nbItems == 0))
 
4348
        return;
 
4349
 
 
4350
    fprintf(output, "  attributes:\n");    
 
4351
    for (i = 0; i < uses->nbItems; i++) {
 
4352
        use = uses->items[i];
 
4353
        if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
 
4354
            fprintf(output, "  [prohibition] ");
 
4355
            prohib = (xmlSchemaAttributeUseProhibPtr) use;
 
4356
            name = prohib->name;
 
4357
            tns = prohib->targetNamespace;
 
4358
        } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
 
4359
            fprintf(output, "  [reference] ");
 
4360
            ref = (xmlSchemaQNameRefPtr) use;
 
4361
            name = ref->name;
 
4362
            tns = ref->targetNamespace;
 
4363
        } else {
 
4364
            fprintf(output, "  [use] ");
 
4365
            name = WXS_ATTRUSE_DECL_NAME(use);
 
4366
            tns = WXS_ATTRUSE_DECL_TNS(use);
 
4367
        }
 
4368
        fprintf(output, "'%s'\n",
 
4369
            (const char *) xmlSchemaFormatQName(&str, tns, name));
 
4370
        FREE_AND_NULL(str);
 
4371
    }
 
4372
}
 
4373
 
 
4374
/**
 
4375
 * xmlSchemaTypeDump:
 
4376
 * @output:  the file output
 
4377
 * @type:  a type structure
 
4378
 *
 
4379
 * Dump a SchemaType structure
 
4380
 */
 
4381
static void
 
4382
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
 
4383
{
 
4384
    if (type == NULL) {
 
4385
        fprintf(output, "Type: NULL\n");
 
4386
        return;
 
4387
    }
 
4388
    fprintf(output, "Type: ");
 
4389
    if (type->name != NULL)
 
4390
        fprintf(output, "'%s' ", type->name);
 
4391
    else
 
4392
        fprintf(output, "(no name) ");
 
4393
    if (type->targetNamespace != NULL)
 
4394
        fprintf(output, "ns '%s' ", type->targetNamespace);
 
4395
    switch (type->type) {
 
4396
        case XML_SCHEMA_TYPE_BASIC:
 
4397
            fprintf(output, "[basic] ");
 
4398
            break;
 
4399
        case XML_SCHEMA_TYPE_SIMPLE:
 
4400
            fprintf(output, "[simple] ");
 
4401
            break;
 
4402
        case XML_SCHEMA_TYPE_COMPLEX:
 
4403
            fprintf(output, "[complex] ");
 
4404
            break;
 
4405
        case XML_SCHEMA_TYPE_SEQUENCE:
 
4406
            fprintf(output, "[sequence] ");
 
4407
            break;
 
4408
        case XML_SCHEMA_TYPE_CHOICE:
 
4409
            fprintf(output, "[choice] ");
 
4410
            break;
 
4411
        case XML_SCHEMA_TYPE_ALL:
 
4412
            fprintf(output, "[all] ");
 
4413
            break;
 
4414
        case XML_SCHEMA_TYPE_UR:
 
4415
            fprintf(output, "[ur] ");
 
4416
            break;
 
4417
        case XML_SCHEMA_TYPE_RESTRICTION:
 
4418
            fprintf(output, "[restriction] ");
 
4419
            break;
 
4420
        case XML_SCHEMA_TYPE_EXTENSION:
 
4421
            fprintf(output, "[extension] ");
 
4422
            break;
 
4423
        default:
 
4424
            fprintf(output, "[unknown type %d] ", type->type);
 
4425
            break;
 
4426
    }
 
4427
    fprintf(output, "content: ");
 
4428
    switch (type->contentType) {
 
4429
        case XML_SCHEMA_CONTENT_UNKNOWN:
 
4430
            fprintf(output, "[unknown] ");
 
4431
            break;
 
4432
        case XML_SCHEMA_CONTENT_EMPTY:
 
4433
            fprintf(output, "[empty] ");
 
4434
            break;
 
4435
        case XML_SCHEMA_CONTENT_ELEMENTS:
 
4436
            fprintf(output, "[element] ");
 
4437
            break;
 
4438
        case XML_SCHEMA_CONTENT_MIXED:
 
4439
            fprintf(output, "[mixed] ");
 
4440
            break;
 
4441
        case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
 
4442
        /* not used. */
 
4443
            break;
 
4444
        case XML_SCHEMA_CONTENT_BASIC:
 
4445
            fprintf(output, "[basic] ");
 
4446
            break;
 
4447
        case XML_SCHEMA_CONTENT_SIMPLE:
 
4448
            fprintf(output, "[simple] ");
 
4449
            break;
 
4450
        case XML_SCHEMA_CONTENT_ANY:
 
4451
            fprintf(output, "[any] ");
 
4452
            break;
 
4453
    }
 
4454
    fprintf(output, "\n");
 
4455
    if (type->base != NULL) {
 
4456
        fprintf(output, "  base type: '%s'", type->base);
 
4457
        if (type->baseNs != NULL)
 
4458
            fprintf(output, " ns '%s'\n", type->baseNs);
 
4459
        else
 
4460
            fprintf(output, "\n");
 
4461
    }
 
4462
    if (type->attrUses != NULL)
 
4463
        xmlSchemaAttrUsesDump(type->attrUses, output);
 
4464
    if (type->annot != NULL)
 
4465
        xmlSchemaAnnotDump(output, type->annot);
 
4466
#ifdef DUMP_CONTENT_MODEL
 
4467
    if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
 
4468
        (type->subtypes != NULL)) {
 
4469
        xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
 
4470
            output, 1);
 
4471
    }
 
4472
#endif
 
4473
}
 
4474
 
 
4475
/**
 
4476
 * xmlSchemaDump:
 
4477
 * @output:  the file output
 
4478
 * @schema:  a schema structure
 
4479
 *
 
4480
 * Dump a Schema structure.
 
4481
 */
 
4482
void
 
4483
xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
 
4484
{
 
4485
    if (output == NULL)
 
4486
        return;
 
4487
    if (schema == NULL) {
 
4488
        fprintf(output, "Schemas: NULL\n");
 
4489
        return;
 
4490
    }
 
4491
    fprintf(output, "Schemas: ");
 
4492
    if (schema->name != NULL)
 
4493
        fprintf(output, "%s, ", schema->name);
 
4494
    else
 
4495
        fprintf(output, "no name, ");
 
4496
    if (schema->targetNamespace != NULL)
 
4497
        fprintf(output, "%s", (const char *) schema->targetNamespace);
 
4498
    else
 
4499
        fprintf(output, "no target namespace");
 
4500
    fprintf(output, "\n");
 
4501
    if (schema->annot != NULL)
 
4502
        xmlSchemaAnnotDump(output, schema->annot);
 
4503
    xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump,
 
4504
                output);
 
4505
    xmlHashScanFull(schema->elemDecl,
 
4506
                    (xmlHashScannerFull) xmlSchemaElementDump, output);
 
4507
}
 
4508
 
 
4509
#ifdef DEBUG_IDC_NODE_TABLE
 
4510
/**
 
4511
 * xmlSchemaDebugDumpIDCTable:
 
4512
 * @vctxt: the WXS validation context
 
4513
 *
 
4514
 * Displays the current IDC table for debug purposes.
 
4515
 */
 
4516
static void
 
4517
xmlSchemaDebugDumpIDCTable(FILE * output,
 
4518
                           const xmlChar *namespaceName,
 
4519
                           const xmlChar *localName,
 
4520
                           xmlSchemaPSVIIDCBindingPtr bind)
 
4521
{
 
4522
    xmlChar *str = NULL;
 
4523
    const xmlChar *value;
 
4524
    xmlSchemaPSVIIDCNodePtr tab;
 
4525
    xmlSchemaPSVIIDCKeyPtr key;
 
4526
    int i, j, res;
 
4527
 
 
4528
    fprintf(output, "IDC: TABLES on '%s'\n",
 
4529
        xmlSchemaFormatQName(&str, namespaceName, localName));
 
4530
    FREE_AND_NULL(str)
 
4531
 
 
4532
    if (bind == NULL)
 
4533
        return;
 
4534
    do {
 
4535
        fprintf(output, "IDC:   BINDING '%s' (%d)\n",
 
4536
            xmlSchemaGetComponentQName(&str, 
 
4537
                bind->definition), bind->nbNodes);
 
4538
        FREE_AND_NULL(str)
 
4539
        for (i = 0; i < bind->nbNodes; i++) {
 
4540
            tab = bind->nodeTable[i];
 
4541
            fprintf(output, "         ( ");
 
4542
            for (j = 0; j < bind->definition->nbFields; j++) {
 
4543
                key = tab->keys[j];
 
4544
                if ((key != NULL) && (key->val != NULL)) {
 
4545
                    res = xmlSchemaGetCanonValue(key->val, &value);
 
4546
                    if (res >= 0)
 
4547
                        fprintf(output, "'%s' ", value);
 
4548
                    else
 
4549
                        fprintf(output, "CANON-VALUE-FAILED ");
 
4550
                    if (res == 0)
 
4551
                        FREE_AND_NULL(value)
 
4552
                } else if (key != NULL)
 
4553
                    fprintf(output, "(no val), ");
 
4554
                else
 
4555
                    fprintf(output, "(key missing), ");
 
4556
            }
 
4557
            fprintf(output, ")\n");
 
4558
        }
 
4559
        if (bind->dupls && bind->dupls->nbItems) {
 
4560
            fprintf(output, "IDC:     dupls (%d):\n", bind->dupls->nbItems);
 
4561
            for (i = 0; i < bind->dupls->nbItems; i++) {
 
4562
                tab = bind->dupls->items[i];
 
4563
                fprintf(output, "         ( ");
 
4564
                for (j = 0; j < bind->definition->nbFields; j++) {
 
4565
                    key = tab->keys[j];
 
4566
                    if ((key != NULL) && (key->val != NULL)) {
 
4567
                        res = xmlSchemaGetCanonValue(key->val, &value);
 
4568
                        if (res >= 0)
 
4569
                            fprintf(output, "'%s' ", value);
 
4570
                        else
 
4571
                            fprintf(output, "CANON-VALUE-FAILED ");
 
4572
                        if (res == 0)
 
4573
                            FREE_AND_NULL(value)
 
4574
                    } else if (key != NULL)
 
4575
                    fprintf(output, "(no val), ");
 
4576
                        else
 
4577
                            fprintf(output, "(key missing), ");
 
4578
                }
 
4579
                fprintf(output, ")\n");
 
4580
            }
 
4581
        }
 
4582
        bind = bind->next;
 
4583
    } while (bind != NULL);
 
4584
}
 
4585
#endif /* DEBUG_IDC */
 
4586
#endif /* LIBXML_OUTPUT_ENABLED */
 
4587
 
 
4588
/************************************************************************
 
4589
 *                                                                      *
 
4590
 *                      Utilities                                       *
 
4591
 *                                                                      *
 
4592
 ************************************************************************/
 
4593
 
 
4594
/**
 
4595
 * xmlSchemaGetPropNode:
 
4596
 * @node: the element node
 
4597
 * @name: the name of the attribute
 
4598
 *
 
4599
 * Seeks an attribute with a name of @name in
 
4600
 * no namespace.
 
4601
 *
 
4602
 * Returns the attribute or NULL if not present.
 
4603
 */
 
4604
static xmlAttrPtr
 
4605
xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
 
4606
{
 
4607
    xmlAttrPtr prop;
 
4608
 
 
4609
    if ((node == NULL) || (name == NULL))
 
4610
        return(NULL);
 
4611
    prop = node->properties;
 
4612
    while (prop != NULL) {
 
4613
        if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
 
4614
            return(prop);
 
4615
        prop = prop->next;
 
4616
    }
 
4617
    return (NULL);
 
4618
}
 
4619
 
 
4620
/**
 
4621
 * xmlSchemaGetPropNodeNs:
 
4622
 * @node: the element node
 
4623
 * @uri: the uri
 
4624
 * @name: the name of the attribute
 
4625
 *
 
4626
 * Seeks an attribute with a local name of @name and
 
4627
 * a namespace URI of @uri.
 
4628
 *
 
4629
 * Returns the attribute or NULL if not present.
 
4630
 */
 
4631
static xmlAttrPtr
 
4632
xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
 
4633
{
 
4634
    xmlAttrPtr prop;
 
4635
 
 
4636
    if ((node == NULL) || (name == NULL))
 
4637
        return(NULL);    
 
4638
    prop = node->properties;
 
4639
    while (prop != NULL) {
 
4640
        if ((prop->ns != NULL) &&
 
4641
            xmlStrEqual(prop->name, BAD_CAST name) &&
 
4642
            xmlStrEqual(prop->ns->href, BAD_CAST uri))
 
4643
            return(prop);
 
4644
        prop = prop->next;
 
4645
    }
 
4646
    return (NULL);
 
4647
}
 
4648
 
 
4649
static const xmlChar *
 
4650
xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
 
4651
{
 
4652
    xmlChar *val;
 
4653
    const xmlChar *ret;
 
4654
 
 
4655
    val = xmlNodeGetContent(node);
 
4656
    if (val == NULL)
 
4657
        val = xmlStrdup((xmlChar *)"");
 
4658
    ret = xmlDictLookup(ctxt->dict, val, -1);
 
4659
    xmlFree(val);
 
4660
    return(ret);
 
4661
}
 
4662
 
 
4663
static const xmlChar *
 
4664
xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
 
4665
{
 
4666
    return((const xmlChar*) xmlNodeGetContent(node));
 
4667
}
 
4668
 
 
4669
/**
 
4670
 * xmlSchemaGetProp:
 
4671
 * @ctxt: the parser context
 
4672
 * @node: the node
 
4673
 * @name: the property name
 
4674
 *
 
4675
 * Read a attribute value and internalize the string
 
4676
 *
 
4677
 * Returns the string or NULL if not present.
 
4678
 */
 
4679
static const xmlChar *
 
4680
xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
 
4681
                 const char *name)
 
4682
{
 
4683
    xmlChar *val;
 
4684
    const xmlChar *ret;
 
4685
 
 
4686
    val = xmlGetNoNsProp(node, BAD_CAST name);
 
4687
    if (val == NULL)
 
4688
        return(NULL);
 
4689
    ret = xmlDictLookup(ctxt->dict, val, -1);
 
4690
    xmlFree(val);
 
4691
    return(ret);
 
4692
}
 
4693
 
 
4694
/************************************************************************
 
4695
 *                                                                      *
 
4696
 *                      Parsing functions                               *
 
4697
 *                                                                      *
 
4698
 ************************************************************************/
 
4699
 
 
4700
#define WXS_FIND_GLOBAL_ITEM(slot)                      \
 
4701
    if (xmlStrEqual(nsName, schema->targetNamespace)) { \
 
4702
        ret = xmlHashLookup(schema->slot, name); \
 
4703
        if (ret != NULL) goto exit; \
 
4704
    } \
 
4705
    if (xmlHashSize(schema->schemasImports) > 1) { \
 
4706
        xmlSchemaImportPtr import; \
 
4707
        if (nsName == NULL) \
 
4708
            import = xmlHashLookup(schema->schemasImports, \
 
4709
                XML_SCHEMAS_NO_NAMESPACE); \
 
4710
        else \
 
4711
            import = xmlHashLookup(schema->schemasImports, nsName); \
 
4712
        if (import == NULL) \
 
4713
            goto exit; \
 
4714
        ret = xmlHashLookup(import->schema->slot, name); \
 
4715
    }
 
4716
 
 
4717
/**
 
4718
 * xmlSchemaGetElem:
 
4719
 * @schema:  the schema context
 
4720
 * @name:  the element name
 
4721
 * @ns:  the element namespace
 
4722
 *
 
4723
 * Lookup a global element declaration in the schema.
 
4724
 *
 
4725
 * Returns the element declaration or NULL if not found.
 
4726
 */
 
4727
static xmlSchemaElementPtr
 
4728
xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
 
4729
                 const xmlChar * nsName)
 
4730
{
 
4731
    xmlSchemaElementPtr ret = NULL;
 
4732
    
 
4733
    if ((name == NULL) || (schema == NULL))
 
4734
        return(NULL);
 
4735
    if (schema != NULL) {
 
4736
        WXS_FIND_GLOBAL_ITEM(elemDecl)
 
4737
    }   
 
4738
exit:
 
4739
#ifdef DEBUG
 
4740
    if (ret == NULL) {
 
4741
        if (nsName == NULL)
 
4742
            fprintf(stderr, "Unable to lookup element decl. %s", name);
 
4743
        else
 
4744
            fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
 
4745
                    nsName);
 
4746
    }
 
4747
#endif
 
4748
    return (ret);
 
4749
}
 
4750
 
 
4751
/**
 
4752
 * xmlSchemaGetType:
 
4753
 * @schema:  the main schema
 
4754
 * @name:  the type's name
 
4755
 * nsName:  the type's namespace
 
4756
 *
 
4757
 * Lookup a type in the schemas or the predefined types
 
4758
 *
 
4759
 * Returns the group definition or NULL if not found.
 
4760
 */
 
4761
static xmlSchemaTypePtr
 
4762
xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
 
4763
                 const xmlChar * nsName)
 
4764
{
 
4765
    xmlSchemaTypePtr ret = NULL;
 
4766
 
 
4767
    if (name == NULL)
 
4768
        return (NULL);    
 
4769
    /* First try the built-in types. */
 
4770
    if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) { 
 
4771
        ret = xmlSchemaGetPredefinedType(name, nsName);
 
4772
        if (ret != NULL)
 
4773
            goto exit;
 
4774
        /*
 
4775
        * Note that we try the parsed schemas as well here
 
4776
        * since one might have parsed the S4S, which contain more
 
4777
        * than the built-in types.
 
4778
        * TODO: Can we optimize this?
 
4779
        */
 
4780
    }
 
4781
    if (schema != NULL) {
 
4782
        WXS_FIND_GLOBAL_ITEM(typeDecl)
 
4783
    } 
 
4784
exit:
 
4785
 
 
4786
#ifdef DEBUG
 
4787
    if (ret == NULL) {
 
4788
        if (nsName == NULL)
 
4789
            fprintf(stderr, "Unable to lookup type %s", name);
 
4790
        else
 
4791
            fprintf(stderr, "Unable to lookup type %s:%s", name,
 
4792
                    nsName);
 
4793
    }
 
4794
#endif
 
4795
    return (ret);
 
4796
}
 
4797
 
 
4798
/**
 
4799
 * xmlSchemaGetAttributeDecl:
 
4800
 * @schema:  the context of the schema
 
4801
 * @name:  the name of the attribute
 
4802
 * @ns:  the target namespace of the attribute
 
4803
 *
 
4804
 * Lookup a an attribute in the schema or imported schemas
 
4805
 *
 
4806
 * Returns the attribute declaration or NULL if not found.
 
4807
 */
 
4808
static xmlSchemaAttributePtr
 
4809
xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
 
4810
                 const xmlChar * nsName)
 
4811
{
 
4812
    xmlSchemaAttributePtr ret = NULL;
 
4813
 
 
4814
    if ((name == NULL) || (schema == NULL))
 
4815
        return (NULL);
 
4816
    if (schema != NULL) {
 
4817
        WXS_FIND_GLOBAL_ITEM(attrDecl)
 
4818
    }
 
4819
exit:
 
4820
#ifdef DEBUG
 
4821
    if (ret == NULL) {
 
4822
        if (nsName == NULL)
 
4823
            fprintf(stderr, "Unable to lookup attribute %s", name);
 
4824
        else
 
4825
            fprintf(stderr, "Unable to lookup attribute %s:%s", name,
 
4826
                    nsName);
 
4827
    }
 
4828
#endif
 
4829
    return (ret);
 
4830
}
 
4831
 
 
4832
/**
 
4833
 * xmlSchemaGetAttributeGroup:
 
4834
 * @schema:  the context of the schema
 
4835
 * @name:  the name of the attribute group
 
4836
 * @ns:  the target namespace of the attribute group
 
4837
 *
 
4838
 * Lookup a an attribute group in the schema or imported schemas
 
4839
 *
 
4840
 * Returns the attribute group definition or NULL if not found.
 
4841
 */
 
4842
static xmlSchemaAttributeGroupPtr
 
4843
xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
 
4844
                 const xmlChar * nsName)
 
4845
{
 
4846
    xmlSchemaAttributeGroupPtr ret = NULL;
 
4847
 
 
4848
    if ((name == NULL) || (schema == NULL))
 
4849
        return (NULL);
 
4850
    if (schema != NULL) {
 
4851
        WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
 
4852
    }
 
4853
exit:
 
4854
    /* TODO:
 
4855
    if ((ret != NULL) && (ret->redef != NULL)) {
 
4856
        * Return the last redefinition. *
 
4857
        ret = ret->redef;
 
4858
    }
 
4859
    */
 
4860
#ifdef DEBUG
 
4861
    if (ret == NULL) {
 
4862
        if (nsName == NULL)
 
4863
            fprintf(stderr, "Unable to lookup attribute group %s", name);
 
4864
        else
 
4865
            fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
 
4866
                    nsName);
 
4867
    }
 
4868
#endif
 
4869
    return (ret);
 
4870
}
 
4871
 
 
4872
/**
 
4873
 * xmlSchemaGetGroup:
 
4874
 * @schema:  the context of the schema
 
4875
 * @name:  the name of the group
 
4876
 * @ns:  the target namespace of the group
 
4877
 *
 
4878
 * Lookup a group in the schema or imported schemas
 
4879
 *
 
4880
 * Returns the group definition or NULL if not found.
 
4881
 */
 
4882
static xmlSchemaModelGroupDefPtr
 
4883
xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
 
4884
                 const xmlChar * nsName)
 
4885
{
 
4886
    xmlSchemaModelGroupDefPtr ret = NULL;
 
4887
 
 
4888
    if ((name == NULL) || (schema == NULL))
 
4889
        return (NULL);
 
4890
    if (schema != NULL) {
 
4891
        WXS_FIND_GLOBAL_ITEM(groupDecl)
 
4892
    }
 
4893
exit:
 
4894
    
 
4895
#ifdef DEBUG
 
4896
    if (ret == NULL) {
 
4897
        if (nsName == NULL)
 
4898
            fprintf(stderr, "Unable to lookup group %s", name);
 
4899
        else
 
4900
            fprintf(stderr, "Unable to lookup group %s:%s", name,
 
4901
                    nsName);
 
4902
    }
 
4903
#endif
 
4904
    return (ret);
 
4905
}
 
4906
 
 
4907
static xmlSchemaNotationPtr
 
4908
xmlSchemaGetNotation(xmlSchemaPtr schema,
 
4909
                     const xmlChar *name,
 
4910
                     const xmlChar *nsName)
 
4911
{
 
4912
    xmlSchemaNotationPtr ret = NULL;
 
4913
 
 
4914
    if ((name == NULL) || (schema == NULL))
 
4915
        return (NULL);
 
4916
    if (schema != NULL) {
 
4917
        WXS_FIND_GLOBAL_ITEM(notaDecl)
 
4918
    }
 
4919
exit:
 
4920
    return (ret);
 
4921
}
 
4922
 
 
4923
static xmlSchemaIDCPtr
 
4924
xmlSchemaGetIDC(xmlSchemaPtr schema,
 
4925
                const xmlChar *name,
 
4926
                const xmlChar *nsName)
 
4927
{
 
4928
    xmlSchemaIDCPtr ret = NULL;
 
4929
 
 
4930
    if ((name == NULL) || (schema == NULL))
 
4931
        return (NULL);
 
4932
    if (schema != NULL) {
 
4933
        WXS_FIND_GLOBAL_ITEM(idcDef)
 
4934
    }
 
4935
exit:
 
4936
    return (ret);
 
4937
}
 
4938
 
 
4939
/**
 
4940
 * xmlSchemaGetNamedComponent:
 
4941
 * @schema:  the schema
 
4942
 * @name:  the name of the group
 
4943
 * @ns:  the target namespace of the group
 
4944
 *
 
4945
 * Lookup a group in the schema or imported schemas
 
4946
 *
 
4947
 * Returns the group definition or NULL if not found.
 
4948
 */
 
4949
static xmlSchemaBasicItemPtr
 
4950
xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
 
4951
                           xmlSchemaTypeType itemType,
 
4952
                           const xmlChar *name,
 
4953
                           const xmlChar *targetNs)
 
4954
{
 
4955
    switch (itemType) {
 
4956
        case XML_SCHEMA_TYPE_GROUP:
 
4957
            return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
 
4958
                name, targetNs));
 
4959
        case XML_SCHEMA_TYPE_ELEMENT:
 
4960
            return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
 
4961
                name, targetNs));
 
4962
        default:
 
4963
            TODO
 
4964
            return (NULL);
 
4965
    }
 
4966
}
 
4967
 
 
4968
/************************************************************************
 
4969
 *                                                                      *
 
4970
 *                      Parsing functions                               *
 
4971
 *                                                                      *
 
4972
 ************************************************************************/
 
4973
 
 
4974
#define IS_BLANK_NODE(n)                                                \
 
4975
    (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
 
4976
 
 
4977
/**
 
4978
 * xmlSchemaIsBlank:
 
4979
 * @str:  a string
 
4980
 * @len: the length of the string or -1
 
4981
 *
 
4982
 * Check if a string is ignorable
 
4983
 *
 
4984
 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
 
4985
 */
 
4986
static int
 
4987
xmlSchemaIsBlank(xmlChar * str, int len)
 
4988
{
 
4989
    if (str == NULL)
 
4990
        return (1);
 
4991
    if (len < 0) {
 
4992
        while (*str != 0) {
 
4993
            if (!(IS_BLANK_CH(*str)))
 
4994
                return (0);
 
4995
            str++;
 
4996
        }
 
4997
    } else while ((*str != 0) && (len != 0)) {
 
4998
        if (!(IS_BLANK_CH(*str)))
 
4999
            return (0);
 
5000
        str++;
 
5001
        len--;
 
5002
    }
 
5003
    
 
5004
    return (1);
 
5005
}
 
5006
 
 
5007
#define WXS_COMP_NAME(c, t) ((t) (c))->name
 
5008
#define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
 
5009
/*
 
5010
* xmlSchemaFindRedefCompInGraph:
 
5011
* ATTENTION TODO: This uses pointer comp. for strings.
 
5012
*/
 
5013
static xmlSchemaBasicItemPtr
 
5014
xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
 
5015
                              xmlSchemaTypeType type,
 
5016
                              const xmlChar *name,
 
5017
                              const xmlChar *nsName)
 
5018
{
 
5019
    xmlSchemaBasicItemPtr ret;
 
5020
    int i;
 
5021
 
 
5022
    if ((bucket == NULL) || (name == NULL))
 
5023
        return(NULL);
 
5024
    if ((bucket->globals == NULL) ||
 
5025
        (bucket->globals->nbItems == 0))
 
5026
        goto subschemas;
 
5027
    /*
 
5028
    * Search in global components.
 
5029
    */
 
5030
    for (i = 0; i < bucket->globals->nbItems; i++) {
 
5031
        ret = bucket->globals->items[i];
 
5032
        if (ret->type == type) {
 
5033
            switch (type) {
 
5034
                case XML_SCHEMA_TYPE_COMPLEX:
 
5035
                case XML_SCHEMA_TYPE_SIMPLE:
 
5036
                    if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
 
5037
                        (WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
 
5038
                        nsName))
 
5039
                    {
 
5040
                        return(ret);
 
5041
                    }
 
5042
                    break;
 
5043
                case XML_SCHEMA_TYPE_GROUP:
 
5044
                    if ((WXS_COMP_NAME(ret,
 
5045
                            xmlSchemaModelGroupDefPtr) == name) &&
 
5046
                        (WXS_COMP_TNS(ret,
 
5047
                            xmlSchemaModelGroupDefPtr) == nsName))
 
5048
                    {
 
5049
                        return(ret);
 
5050
                    }
 
5051
                    break;
 
5052
                case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 
5053
                    if ((WXS_COMP_NAME(ret,
 
5054
                            xmlSchemaAttributeGroupPtr) == name) &&
 
5055
                        (WXS_COMP_TNS(ret,
 
5056
                            xmlSchemaAttributeGroupPtr) == nsName))
 
5057
                    {
 
5058
                        return(ret);
 
5059
                    }
 
5060
                    break;
 
5061
                default:
 
5062
                    /* Should not be hit. */
 
5063
                    return(NULL);
 
5064
            }           
 
5065
        }
 
5066
    }
 
5067
subschemas:
 
5068
    /*
 
5069
    * Process imported/included schemas.
 
5070
    */
 
5071
    if (bucket->relations != NULL) {
 
5072
        xmlSchemaSchemaRelationPtr rel = bucket->relations;
 
5073
 
 
5074
        /*
 
5075
        * TODO: Marking the bucket will not avoid multiple searches
 
5076
        * in the same schema, but avoids at least circularity.
 
5077
        */
 
5078
        bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
 
5079
        do {
 
5080
            if ((rel->bucket != NULL) &&
 
5081
                ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
 
5082
                ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
 
5083
                    type, name, nsName);
 
5084
                if (ret != NULL)
 
5085
                    return(ret);
 
5086
            }
 
5087
            rel = rel->next;
 
5088
        } while (rel != NULL);
 
5089
         bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
 
5090
    }
 
5091
    return(NULL);
 
5092
}
 
5093
 
 
5094
/**
 
5095
 * xmlSchemaAddNotation:
 
5096
 * @ctxt:  a schema parser context
 
5097
 * @schema:  the schema being built
 
5098
 * @name:  the item name
 
5099
 *
 
5100
 * Add an XML schema annotation declaration
 
5101
 * *WARNING* this interface is highly subject to change
 
5102
 *
 
5103
 * Returns the new struture or NULL in case of error
 
5104
 */
 
5105
static xmlSchemaNotationPtr
 
5106
xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
5107
                     const xmlChar *name, const xmlChar *nsName,
 
5108
                     xmlNodePtr node ATTRIBUTE_UNUSED)
 
5109
{
 
5110
    xmlSchemaNotationPtr ret = NULL;
 
5111
 
 
5112
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
 
5113
        return (NULL);
 
5114
 
 
5115
    ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
 
5116
    if (ret == NULL) {
 
5117
        xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
 
5118
        return (NULL);
 
5119
    }
 
5120
    memset(ret, 0, sizeof(xmlSchemaNotation));
 
5121
    ret->type = XML_SCHEMA_TYPE_NOTATION;
 
5122
    ret->name = name;
 
5123
    ret->targetNamespace = nsName;
 
5124
    /* TODO: do we need the node to be set?
 
5125
    * ret->node = node;*/
 
5126
    WXS_ADD_GLOBAL(ctxt, ret);
 
5127
    return (ret);
 
5128
}
 
5129
 
 
5130
/**
 
5131
 * xmlSchemaAddAttribute:
 
5132
 * @ctxt:  a schema parser context
 
5133
 * @schema:  the schema being built
 
5134
 * @name:  the item name
 
5135
 * @namespace:  the namespace
 
5136
 *
 
5137
 * Add an XML schema Attrribute declaration
 
5138
 * *WARNING* this interface is highly subject to change
 
5139
 *
 
5140
 * Returns the new struture or NULL in case of error
 
5141
 */
 
5142
static xmlSchemaAttributePtr
 
5143
xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
5144
                      const xmlChar * name, const xmlChar * nsName,
 
5145
                      xmlNodePtr node, int topLevel)
 
5146
{
 
5147
    xmlSchemaAttributePtr ret = NULL;
 
5148
 
 
5149
    if ((ctxt == NULL) || (schema == NULL))
 
5150
        return (NULL);
 
5151
 
 
5152
    ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
 
5153
    if (ret == NULL) {
 
5154
        xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
 
5155
        return (NULL);
 
5156
    }
 
5157
    memset(ret, 0, sizeof(xmlSchemaAttribute));
 
5158
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
 
5159
    ret->node = node;
 
5160
    ret->name = name;
 
5161
    ret->targetNamespace = nsName;
 
5162
 
 
5163
    if (topLevel)
 
5164
        WXS_ADD_GLOBAL(ctxt, ret);
 
5165
    else
 
5166
        WXS_ADD_LOCAL(ctxt, ret);
 
5167
    WXS_ADD_PENDING(ctxt, ret);
 
5168
    return (ret);
 
5169
}
 
5170
 
 
5171
/**
 
5172
 * xmlSchemaAddAttributeUse:
 
5173
 * @ctxt:  a schema parser context
 
5174
 * @schema:  the schema being built
 
5175
 * @name:  the item name
 
5176
 * @namespace:  the namespace
 
5177
 *
 
5178
 * Add an XML schema Attrribute declaration
 
5179
 * *WARNING* this interface is highly subject to change
 
5180
 *
 
5181
 * Returns the new struture or NULL in case of error
 
5182
 */
 
5183
static xmlSchemaAttributeUsePtr
 
5184
xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
 
5185
                         xmlNodePtr node)
 
5186
{
 
5187
    xmlSchemaAttributeUsePtr ret = NULL;
 
5188
 
 
5189
    if (pctxt == NULL)
 
5190
        return (NULL);
 
5191
 
 
5192
    ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
 
5193
    if (ret == NULL) {
 
5194
        xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
 
5195
        return (NULL);
 
5196
    }
 
5197
    memset(ret, 0, sizeof(xmlSchemaAttributeUse));
 
5198
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
 
5199
    ret->node = node;
 
5200
 
 
5201
    WXS_ADD_LOCAL(pctxt, ret);
 
5202
    return (ret);
 
5203
}
 
5204
 
 
5205
/*
 
5206
* xmlSchemaAddRedef:
 
5207
*
 
5208
* Adds a redefinition information. This is used at a later stage to:
 
5209
* resolve references to the redefined components and to check constraints.
 
5210
*/
 
5211
static xmlSchemaRedefPtr
 
5212
xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,           
 
5213
                  xmlSchemaBucketPtr targetBucket,
 
5214
                  void *item,
 
5215
                  const xmlChar *refName,
 
5216
                  const xmlChar *refTargetNs)
 
5217
{
 
5218
    xmlSchemaRedefPtr ret;
 
5219
 
 
5220
    ret = (xmlSchemaRedefPtr)
 
5221
        xmlMalloc(sizeof(xmlSchemaRedef));
 
5222
    if (ret == NULL) {
 
5223
        xmlSchemaPErrMemory(pctxt,
 
5224
            "allocating redefinition info", NULL);
 
5225
        return (NULL);
 
5226
    }
 
5227
    memset(ret, 0, sizeof(xmlSchemaRedef));
 
5228
    ret->item = item;
 
5229
    ret->targetBucket = targetBucket;
 
5230
    ret->refName = refName;
 
5231
    ret->refTargetNs = refTargetNs;
 
5232
    if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
 
5233
        WXS_CONSTRUCTOR(pctxt)->redefs = ret;
 
5234
    else
 
5235
        WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
 
5236
    WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
 
5237
 
 
5238
    return (ret);
 
5239
}
 
5240
 
 
5241
/**
 
5242
 * xmlSchemaAddAttributeGroupDefinition:
 
5243
 * @ctxt:  a schema parser context
 
5244
 * @schema:  the schema being built
 
5245
 * @name:  the item name
 
5246
 * @nsName:  the target namespace
 
5247
 * @node: the corresponding node
 
5248
 *
 
5249
 * Add an XML schema Attrribute Group definition.
 
5250
 *
 
5251
 * Returns the new struture or NULL in case of error
 
5252
 */
 
5253
static xmlSchemaAttributeGroupPtr
 
5254
xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
 
5255
                           xmlSchemaPtr schema ATTRIBUTE_UNUSED,
 
5256
                           const xmlChar *name,
 
5257
                           const xmlChar *nsName,
 
5258
                           xmlNodePtr node)
 
5259
{
 
5260
    xmlSchemaAttributeGroupPtr ret = NULL;
 
5261
 
 
5262
    if ((pctxt == NULL) || (name == NULL))
 
5263
        return (NULL);
 
5264
 
 
5265
    ret = (xmlSchemaAttributeGroupPtr)
 
5266
        xmlMalloc(sizeof(xmlSchemaAttributeGroup));
 
5267
    if (ret == NULL) {
 
5268
        xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
 
5269
        return (NULL);
 
5270
    }
 
5271
    memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
 
5272
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
 
5273
    ret->name = name;
 
5274
    ret->targetNamespace = nsName;
 
5275
    ret->node = node;   
 
5276
 
 
5277
    /* TODO: Remove the flag. */
 
5278
    ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
 
5279
    if (pctxt->isRedefine) {
 
5280
        pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
 
5281
            ret, name, nsName);
 
5282
        if (pctxt->redef == NULL) {
 
5283
            xmlFree(ret);
 
5284
            return(NULL);
 
5285
        }           
 
5286
        pctxt->redefCounter = 0;
 
5287
    }
 
5288
    WXS_ADD_GLOBAL(pctxt, ret);
 
5289
    WXS_ADD_PENDING(pctxt, ret);
 
5290
    return (ret);
 
5291
}
 
5292
 
 
5293
/**
 
5294
 * xmlSchemaAddElement:
 
5295
 * @ctxt:  a schema parser context
 
5296
 * @schema:  the schema being built
 
5297
 * @name:  the type name
 
5298
 * @namespace:  the type namespace
 
5299
 *
 
5300
 * Add an XML schema Element declaration
 
5301
 * *WARNING* this interface is highly subject to change
 
5302
 *
 
5303
 * Returns the new struture or NULL in case of error
 
5304
 */
 
5305
static xmlSchemaElementPtr
 
5306
xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
 
5307
                    const xmlChar * name, const xmlChar * nsName,
 
5308
                    xmlNodePtr node, int topLevel)
 
5309
{
 
5310
    xmlSchemaElementPtr ret = NULL;
 
5311
 
 
5312
    if ((ctxt == NULL) || (name == NULL))
 
5313
        return (NULL);
 
5314
 
 
5315
    ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
 
5316
    if (ret == NULL) {
 
5317
        xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
 
5318
        return (NULL);
 
5319
    }
 
5320
    memset(ret, 0, sizeof(xmlSchemaElement));
 
5321
    ret->type = XML_SCHEMA_TYPE_ELEMENT;
 
5322
    ret->name = name;
 
5323
    ret->targetNamespace = nsName;
 
5324
    ret->node = node;
 
5325
 
 
5326
    if (topLevel)
 
5327
        WXS_ADD_GLOBAL(ctxt, ret);
 
5328
    else
 
5329
        WXS_ADD_LOCAL(ctxt, ret);
 
5330
    WXS_ADD_PENDING(ctxt, ret);
 
5331
    return (ret);
 
5332
}
 
5333
 
 
5334
/**
 
5335
 * xmlSchemaAddType:
 
5336
 * @ctxt:  a schema parser context
 
5337
 * @schema:  the schema being built
 
5338
 * @name:  the item name
 
5339
 * @namespace:  the namespace
 
5340
 *
 
5341
 * Add an XML schema item
 
5342
 * *WARNING* this interface is highly subject to change
 
5343
 *
 
5344
 * Returns the new struture or NULL in case of error
 
5345
 */
 
5346
static xmlSchemaTypePtr
 
5347
xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
5348
                 xmlSchemaTypeType type,
 
5349
                 const xmlChar * name, const xmlChar * nsName,
 
5350
                 xmlNodePtr node, int topLevel)
 
5351
{
 
5352
    xmlSchemaTypePtr ret = NULL;
 
5353
 
 
5354
    if ((ctxt == NULL) || (schema == NULL))
 
5355
        return (NULL);
 
5356
 
 
5357
    ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
 
5358
    if (ret == NULL) {
 
5359
        xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
 
5360
        return (NULL);
 
5361
    }
 
5362
    memset(ret, 0, sizeof(xmlSchemaType));
 
5363
    ret->type = type;
 
5364
    ret->name = name;
 
5365
    ret->targetNamespace = nsName;
 
5366
    ret->node = node;
 
5367
    if (topLevel) {
 
5368
        if (ctxt->isRedefine) {
 
5369
            ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
 
5370
                ret, name, nsName);
 
5371
            if (ctxt->redef == NULL) {
 
5372
                xmlFree(ret);
 
5373
                return(NULL);
 
5374
            }       
 
5375
            ctxt->redefCounter = 0;
 
5376
        }
 
5377
        WXS_ADD_GLOBAL(ctxt, ret);
 
5378
    } else
 
5379
        WXS_ADD_LOCAL(ctxt, ret);
 
5380
    WXS_ADD_PENDING(ctxt, ret);    
 
5381
    return (ret);
 
5382
}
 
5383
 
 
5384
static xmlSchemaQNameRefPtr
 
5385
xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
 
5386
                     xmlSchemaTypeType refType,
 
5387
                     const xmlChar *refName,
 
5388
                     const xmlChar *refNs)
 
5389
{
 
5390
    xmlSchemaQNameRefPtr ret;
 
5391
 
 
5392
    ret = (xmlSchemaQNameRefPtr)
 
5393
        xmlMalloc(sizeof(xmlSchemaQNameRef));
 
5394
    if (ret == NULL) {
 
5395
        xmlSchemaPErrMemory(pctxt,
 
5396
            "allocating QName reference item", NULL);
 
5397
        return (NULL);
 
5398
    }
 
5399
    ret->node = NULL;
 
5400
    ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
 
5401
    ret->name = refName;
 
5402
    ret->targetNamespace = refNs;
 
5403
    ret->item = NULL;
 
5404
    ret->itemType = refType;
 
5405
    /*
 
5406
    * Store the reference item in the schema.
 
5407
    */
 
5408
    WXS_ADD_LOCAL(pctxt, ret);
 
5409
    return (ret);
 
5410
}
 
5411
 
 
5412
static xmlSchemaAttributeUseProhibPtr
 
5413
xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
 
5414
{
 
5415
    xmlSchemaAttributeUseProhibPtr ret;
 
5416
 
 
5417
    ret = (xmlSchemaAttributeUseProhibPtr)
 
5418
        xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
 
5419
    if (ret == NULL) {
 
5420
        xmlSchemaPErrMemory(pctxt,
 
5421
            "allocating attribute use prohibition", NULL);
 
5422
        return (NULL);
 
5423
    }
 
5424
    memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
 
5425
    ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
 
5426
    WXS_ADD_LOCAL(pctxt, ret);
 
5427
    return (ret);
 
5428
}
 
5429
 
 
5430
 
 
5431
/**
 
5432
 * xmlSchemaAddModelGroup:
 
5433
 * @ctxt:  a schema parser context
 
5434
 * @schema:  the schema being built
 
5435
 * @type: the "compositor" type of the model group
 
5436
 * @node: the node in the schema doc
 
5437
 *
 
5438
 * Adds a schema model group
 
5439
 * *WARNING* this interface is highly subject to change
 
5440
 *
 
5441
 * Returns the new struture or NULL in case of error
 
5442
 */
 
5443
static xmlSchemaModelGroupPtr
 
5444
xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
 
5445
                       xmlSchemaPtr schema,
 
5446
                       xmlSchemaTypeType type,
 
5447
                       xmlNodePtr node)
 
5448
{
 
5449
    xmlSchemaModelGroupPtr ret = NULL;
 
5450
 
 
5451
    if ((ctxt == NULL) || (schema == NULL))
 
5452
        return (NULL);
 
5453
 
 
5454
    ret = (xmlSchemaModelGroupPtr)
 
5455
        xmlMalloc(sizeof(xmlSchemaModelGroup));
 
5456
    if (ret == NULL) {
 
5457
        xmlSchemaPErrMemory(ctxt, "allocating model group component",
 
5458
            NULL);
 
5459
        return (NULL);
 
5460
    }
 
5461
    memset(ret, 0, sizeof(xmlSchemaModelGroup));
 
5462
    ret->type = type;
 
5463
    ret->node = node;
 
5464
    WXS_ADD_LOCAL(ctxt, ret);
 
5465
    if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
 
5466
        (type == XML_SCHEMA_TYPE_CHOICE))
 
5467
        WXS_ADD_PENDING(ctxt, ret);
 
5468
    return (ret);
 
5469
}
 
5470
 
 
5471
 
 
5472
/**
 
5473
 * xmlSchemaAddParticle:
 
5474
 * @ctxt:  a schema parser context
 
5475
 * @schema:  the schema being built
 
5476
 * @node: the corresponding node in the schema doc
 
5477
 * @min: the minOccurs
 
5478
 * @max: the maxOccurs
 
5479
 *
 
5480
 * Adds an XML schema particle component.
 
5481
 * *WARNING* this interface is highly subject to change
 
5482
 *
 
5483
 * Returns the new struture or NULL in case of error
 
5484
 */
 
5485
static xmlSchemaParticlePtr
 
5486
xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
 
5487
                     xmlNodePtr node, int min, int max)
 
5488
{
 
5489
    xmlSchemaParticlePtr ret = NULL;
 
5490
    if (ctxt == NULL)
 
5491
        return (NULL);
 
5492
 
 
5493
#ifdef DEBUG
 
5494
    fprintf(stderr, "Adding particle component\n");
 
5495
#endif
 
5496
    ret = (xmlSchemaParticlePtr)
 
5497
        xmlMalloc(sizeof(xmlSchemaParticle));
 
5498
    if (ret == NULL) {
 
5499
        xmlSchemaPErrMemory(ctxt, "allocating particle component",
 
5500
            NULL);
 
5501
        return (NULL);
 
5502
    }
 
5503
    ret->type = XML_SCHEMA_TYPE_PARTICLE;
 
5504
    ret->annot = NULL;
 
5505
    ret->node = node;
 
5506
    ret->minOccurs = min;
 
5507
    ret->maxOccurs = max;
 
5508
    ret->next = NULL;
 
5509
    ret->children = NULL;
 
5510
 
 
5511
    WXS_ADD_LOCAL(ctxt, ret);
 
5512
    /* 
 
5513
    * Note that addition to pending components will be done locally
 
5514
    * to the specific parsing function, since the most particles
 
5515
    * need not to be fixed up (i.e. the reference to be resolved).
 
5516
    * REMOVED: WXS_ADD_PENDING(ctxt, ret);
 
5517
    */
 
5518
    return (ret);
 
5519
}
 
5520
 
 
5521
/**
 
5522
 * xmlSchemaAddModelGroupDefinition:
 
5523
 * @ctxt:  a schema validation context
 
5524
 * @schema:  the schema being built
 
5525
 * @name:  the group name
 
5526
 *
 
5527
 * Add an XML schema Group definition
 
5528
 *
 
5529
 * Returns the new struture or NULL in case of error
 
5530
 */
 
5531
static xmlSchemaModelGroupDefPtr
 
5532
xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
 
5533
                                 xmlSchemaPtr schema,
 
5534
                                 const xmlChar *name,
 
5535
                                 const xmlChar *nsName,
 
5536
                                 xmlNodePtr node)
 
5537
{
 
5538
    xmlSchemaModelGroupDefPtr ret = NULL;
 
5539
 
 
5540
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
 
5541
        return (NULL);
 
5542
 
 
5543
    ret = (xmlSchemaModelGroupDefPtr)
 
5544
        xmlMalloc(sizeof(xmlSchemaModelGroupDef));
 
5545
    if (ret == NULL) {
 
5546
        xmlSchemaPErrMemory(ctxt, "adding group", NULL);
 
5547
        return (NULL);
 
5548
    }
 
5549
    memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
 
5550
    ret->name = name;
 
5551
    ret->type = XML_SCHEMA_TYPE_GROUP;
 
5552
    ret->node = node;
 
5553
    ret->targetNamespace = nsName;
 
5554
 
 
5555
    if (ctxt->isRedefine) {
 
5556
        ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
 
5557
            ret, name, nsName);
 
5558
        if (ctxt->redef == NULL) {
 
5559
            xmlFree(ret);
 
5560
            return(NULL);
 
5561
        }           
 
5562
        ctxt->redefCounter = 0;
 
5563
    }
 
5564
    WXS_ADD_GLOBAL(ctxt, ret);
 
5565
    WXS_ADD_PENDING(ctxt, ret);
 
5566
    return (ret);
 
5567
}
 
5568
 
 
5569
/**
 
5570
 * xmlSchemaNewWildcardNs:
 
5571
 * @ctxt:  a schema validation context
 
5572
 *
 
5573
 * Creates a new wildcard namespace constraint.
 
5574
 *
 
5575
 * Returns the new struture or NULL in case of error
 
5576
 */
 
5577
static xmlSchemaWildcardNsPtr
 
5578
xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
 
5579
{
 
5580
    xmlSchemaWildcardNsPtr ret;
 
5581
 
 
5582
    ret = (xmlSchemaWildcardNsPtr)
 
5583
        xmlMalloc(sizeof(xmlSchemaWildcardNs));
 
5584
    if (ret == NULL) {
 
5585
        xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
 
5586
        return (NULL);
 
5587
    }
 
5588
    ret->value = NULL;
 
5589
    ret->next = NULL;
 
5590
    return (ret);
 
5591
}
 
5592
 
 
5593
static xmlSchemaIDCPtr
 
5594
xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
5595
                  const xmlChar *name, const xmlChar *nsName,
 
5596
                  int category, xmlNodePtr node)
 
5597
{
 
5598
    xmlSchemaIDCPtr ret = NULL;    
 
5599
 
 
5600
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
 
5601
        return (NULL);
 
5602
 
 
5603
    ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
 
5604
    if (ret == NULL) {
 
5605
        xmlSchemaPErrMemory(ctxt,
 
5606
            "allocating an identity-constraint definition", NULL);
 
5607
        return (NULL);
 
5608
    }
 
5609
    memset(ret, 0, sizeof(xmlSchemaIDC));
 
5610
    /* The target namespace of the parent element declaration. */
 
5611
    ret->targetNamespace = nsName;
 
5612
    ret->name = name;
 
5613
    ret->type = category;
 
5614
    ret->node = node;        
 
5615
    
 
5616
    WXS_ADD_GLOBAL(ctxt, ret);
 
5617
    /*
 
5618
    * Only keyrefs need to be fixup up.
 
5619
    */
 
5620
    if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
 
5621
        WXS_ADD_PENDING(ctxt, ret);
 
5622
    return (ret);
 
5623
}
 
5624
 
 
5625
/**
 
5626
 * xmlSchemaAddWildcard:
 
5627
 * @ctxt:  a schema validation context
 
5628
 * @schema: a schema
 
5629
 *
 
5630
 * Adds a wildcard.
 
5631
 * It corresponds to a xsd:anyAttribute and xsd:any.
 
5632
 *
 
5633
 * Returns the new struture or NULL in case of error
 
5634
 */
 
5635
static xmlSchemaWildcardPtr
 
5636
xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
5637
                     xmlSchemaTypeType type, xmlNodePtr node)
 
5638
{
 
5639
    xmlSchemaWildcardPtr ret = NULL;
 
5640
 
 
5641
    if ((ctxt == NULL) || (schema == NULL))
 
5642
        return (NULL);
 
5643
 
 
5644
    ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
 
5645
    if (ret == NULL) {
 
5646
        xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
 
5647
        return (NULL);
 
5648
    }
 
5649
    memset(ret, 0, sizeof(xmlSchemaWildcard));
 
5650
    ret->type = type;
 
5651
    ret->node = node;    
 
5652
    WXS_ADD_LOCAL(ctxt, ret);
 
5653
    return (ret);
 
5654
}
 
5655
 
 
5656
static void
 
5657
xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
 
5658
{
 
5659
    if (group == NULL)
 
5660
        return;
 
5661
    if (group->members != NULL)
 
5662
        xmlSchemaItemListFree(group->members);
 
5663
    xmlFree(group);
 
5664
}
 
5665
 
 
5666
static xmlSchemaSubstGroupPtr
 
5667
xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
 
5668
                       xmlSchemaElementPtr head)
 
5669
{
 
5670
    xmlSchemaSubstGroupPtr ret;
 
5671
 
 
5672
    /* Init subst group hash. */
 
5673
    if (WXS_SUBST_GROUPS(pctxt) == NULL) {
 
5674
        WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
 
5675
        if (WXS_SUBST_GROUPS(pctxt) == NULL)
 
5676
            return(NULL);
 
5677
    }
 
5678
    /* Create a new substitution group. */
 
5679
    ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
 
5680
    if (ret == NULL) {
 
5681
        xmlSchemaPErrMemory(NULL,
 
5682
            "allocating a substitution group container", NULL);
 
5683
        return(NULL);
 
5684
    }
 
5685
    memset(ret, 0, sizeof(xmlSchemaSubstGroup));
 
5686
    ret->head = head;
 
5687
    /* Create list of members. */
 
5688
    ret->members = xmlSchemaItemListCreate();
 
5689
    if (ret->members == NULL) {
 
5690
        xmlSchemaSubstGroupFree(ret);
 
5691
        return(NULL);
 
5692
    }
 
5693
    /* Add subst group to hash. */
 
5694
    if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
 
5695
        head->name, head->targetNamespace, ret) != 0) {
 
5696
        PERROR_INT("xmlSchemaSubstGroupAdd",
 
5697
            "failed to add a new substitution container");
 
5698
        xmlSchemaSubstGroupFree(ret);
 
5699
        return(NULL);
 
5700
    }
 
5701
    return(ret);
 
5702
}
 
5703
 
 
5704
static xmlSchemaSubstGroupPtr
 
5705
xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
 
5706
                       xmlSchemaElementPtr head)
 
5707
{   
 
5708
    if (WXS_SUBST_GROUPS(pctxt) == NULL)
 
5709
        return(NULL);
 
5710
    return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
 
5711
        head->name, head->targetNamespace));
 
5712
 
 
5713
}
 
5714
 
 
5715
/**
 
5716
 * xmlSchemaAddElementSubstitutionMember:
 
5717
 * @pctxt:  a schema parser context
 
5718
 * @head:  the head of the substitution group
 
5719
 * @member: the new member of the substitution group
 
5720
 *
 
5721
 * Allocate a new annotation structure.
 
5722
 *
 
5723
 * Returns the newly allocated structure or NULL in case or error
 
5724
 */
 
5725
static int
 
5726
xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
 
5727
                                      xmlSchemaElementPtr head,
 
5728
                                      xmlSchemaElementPtr member)
 
5729
{
 
5730
    xmlSchemaSubstGroupPtr substGroup = NULL;
 
5731
 
 
5732
    if ((pctxt == NULL) || (head == NULL) || (member == NULL))
 
5733
        return (-1);
 
5734
 
 
5735
    substGroup = xmlSchemaSubstGroupGet(pctxt, head);
 
5736
    if (substGroup == NULL)
 
5737
        substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
 
5738
    if (substGroup == NULL)
 
5739
        return(-1);
 
5740
    if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
 
5741
        return(-1);
 
5742
    return(0);
 
5743
}
 
5744
 
 
5745
/************************************************************************
 
5746
 *                                                                      *
 
5747
 *              Utilities for parsing                                   *
 
5748
 *                                                                      *
 
5749
 ************************************************************************/
 
5750
 
 
5751
/**
 
5752
 * xmlSchemaPValAttrNodeQNameValue:
 
5753
 * @ctxt:  a schema parser context
 
5754
 * @schema: the schema context
 
5755
 * @ownerDes: the designation of the parent element
 
5756
 * @ownerItem: the parent as a schema object
 
5757
 * @value:  the QName value
 
5758
 * @local: the resulting local part if found, the attribute value otherwise
 
5759
 * @uri:  the resulting namespace URI if found
 
5760
 *
 
5761
 * Extracts the local name and the URI of a QName value and validates it.
 
5762
 * This one is intended to be used on attribute values that
 
5763
 * should resolve to schema components.
 
5764
 *
 
5765
 * Returns 0, in case the QName is valid, a positive error code
 
5766
 * if not valid and -1 if an internal error occurs.
 
5767
 */
 
5768
static int
 
5769
xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
 
5770
                                       xmlSchemaPtr schema,
 
5771
                                       xmlSchemaBasicItemPtr ownerItem,
 
5772
                                       xmlAttrPtr attr,
 
5773
                                       const xmlChar *value,
 
5774
                                       const xmlChar **uri,
 
5775
                                       const xmlChar **local)
 
5776
{
 
5777
    const xmlChar *pref;
 
5778
    xmlNsPtr ns;
 
5779
    int len, ret;
 
5780
 
 
5781
    *uri = NULL;
 
5782
    *local = NULL;
 
5783
    ret = xmlValidateQName(value, 1);
 
5784
    if (ret > 0) {
 
5785
        xmlSchemaPSimpleTypeErr(ctxt,
 
5786
            XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
5787
            ownerItem, (xmlNodePtr) attr,
 
5788
            xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
 
5789
            NULL, value, NULL, NULL, NULL);
 
5790
        *local = value;
 
5791
        return (ctxt->err);
 
5792
    } else if (ret < 0)
 
5793
        return (-1);
 
5794
 
 
5795
    if (!strchr((char *) value, ':')) {
 
5796
        ns = xmlSearchNs(attr->doc, attr->parent, NULL);
 
5797
        if (ns)
 
5798
            *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
 
5799
        else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
 
5800
            /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
 
5801
            * parser context. */
 
5802
            /*
 
5803
            * This one takes care of included schemas with no
 
5804
            * target namespace.
 
5805
            */
 
5806
            *uri = ctxt->targetNamespace;
 
5807
        }
 
5808
        *local = xmlDictLookup(ctxt->dict, value, -1);
 
5809
        return (0);
 
5810
    }
 
5811
    /*
 
5812
    * At this point xmlSplitQName3 has to return a local name.
 
5813
    */
 
5814
    *local = xmlSplitQName3(value, &len);
 
5815
    *local = xmlDictLookup(ctxt->dict, *local, -1);
 
5816
    pref = xmlDictLookup(ctxt->dict, value, len);
 
5817
    ns = xmlSearchNs(attr->doc, attr->parent, pref);
 
5818
    if (ns == NULL) {
 
5819
        xmlSchemaPSimpleTypeErr(ctxt,
 
5820
            XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
5821
            ownerItem, (xmlNodePtr) attr,
 
5822
            xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
 
5823
            "The value '%s' of simple type 'xs:QName' has no "
 
5824
            "corresponding namespace declaration in scope", value, NULL);
 
5825
        return (ctxt->err);
 
5826
    } else {
 
5827
        *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
 
5828
    }
 
5829
    return (0);
 
5830
}
 
5831
 
 
5832
/**
 
5833
 * xmlSchemaPValAttrNodeQName:
 
5834
 * @ctxt:  a schema parser context
 
5835
 * @schema: the schema context
 
5836
 * @ownerDes: the designation of the owner element
 
5837
 * @ownerItem: the owner as a schema object
 
5838
 * @attr:  the attribute node
 
5839
 * @local: the resulting local part if found, the attribute value otherwise
 
5840
 * @uri:  the resulting namespace URI if found
 
5841
 *
 
5842
 * Extracts and validates the QName of an attribute value.
 
5843
 * This one is intended to be used on attribute values that
 
5844
 * should resolve to schema components.
 
5845
 *
 
5846
 * Returns 0, in case the QName is valid, a positive error code
 
5847
 * if not valid and -1 if an internal error occurs.
 
5848
 */
 
5849
static int
 
5850
xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
 
5851
                                       xmlSchemaPtr schema,
 
5852
                                       xmlSchemaBasicItemPtr ownerItem,
 
5853
                                       xmlAttrPtr attr,
 
5854
                                       const xmlChar **uri,
 
5855
                                       const xmlChar **local)
 
5856
{
 
5857
    const xmlChar *value;
 
5858
 
 
5859
    value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 
5860
    return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
 
5861
        ownerItem, attr, value, uri, local));
 
5862
}
 
5863
 
 
5864
/**
 
5865
 * xmlSchemaPValAttrQName:
 
5866
 * @ctxt:  a schema parser context
 
5867
 * @schema: the schema context
 
5868
 * @ownerDes: the designation of the parent element
 
5869
 * @ownerItem: the owner as a schema object
 
5870
 * @ownerElem:  the parent node of the attribute
 
5871
 * @name:  the name of the attribute
 
5872
 * @local: the resulting local part if found, the attribute value otherwise
 
5873
 * @uri:  the resulting namespace URI if found
 
5874
 *
 
5875
 * Extracts and validates the QName of an attribute value.
 
5876
 *
 
5877
 * Returns 0, in case the QName is valid, a positive error code
 
5878
 * if not valid and -1 if an internal error occurs.
 
5879
 */
 
5880
static int
 
5881
xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
 
5882
                                   xmlSchemaPtr schema,
 
5883
                                   xmlSchemaBasicItemPtr ownerItem,
 
5884
                                   xmlNodePtr ownerElem,
 
5885
                                   const char *name,
 
5886
                                   const xmlChar **uri,
 
5887
                                   const xmlChar **local)
 
5888
{
 
5889
    xmlAttrPtr attr;
 
5890
 
 
5891
    attr = xmlSchemaGetPropNode(ownerElem, name);
 
5892
    if (attr == NULL) {
 
5893
        *local = NULL;
 
5894
        *uri = NULL;
 
5895
        return (0);
 
5896
    }
 
5897
    return (xmlSchemaPValAttrNodeQName(ctxt, schema,
 
5898
        ownerItem, attr, uri, local));
 
5899
}
 
5900
 
 
5901
/**
 
5902
 * xmlSchemaPValAttrID:
 
5903
 * @ctxt:  a schema parser context
 
5904
 * @schema: the schema context
 
5905
 * @ownerDes: the designation of the parent element
 
5906
 * @ownerItem: the owner as a schema object
 
5907
 * @ownerElem:  the parent node of the attribute
 
5908
 * @name:  the name of the attribute
 
5909
 *
 
5910
 * Extracts and validates the ID of an attribute value.
 
5911
 *
 
5912
 * Returns 0, in case the ID is valid, a positive error code
 
5913
 * if not valid and -1 if an internal error occurs.
 
5914
 */
 
5915
static int
 
5916
xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
 
5917
{
 
5918
    int ret;
 
5919
    const xmlChar *value;
 
5920
 
 
5921
    if (attr == NULL)
 
5922
        return(0);
 
5923
    value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
 
5924
    ret = xmlValidateNCName(value, 1);
 
5925
    if (ret == 0) {
 
5926
        /*
 
5927
        * NOTE: the IDness might have already be declared in the DTD
 
5928
        */
 
5929
        if (attr->atype != XML_ATTRIBUTE_ID) {
 
5930
            xmlIDPtr res;
 
5931
            xmlChar *strip;
 
5932
 
 
5933
            /*
 
5934
            * TODO: Use xmlSchemaStrip here; it's not exported at this
 
5935
            * moment.
 
5936
            */
 
5937
            strip = xmlSchemaCollapseString(value);
 
5938
            if (strip != NULL) {
 
5939
                xmlFree((xmlChar *) value);
 
5940
                value = strip;
 
5941
            }
 
5942
            res = xmlAddID(NULL, attr->doc, value, attr);
 
5943
            if (res == NULL) {
 
5944
                ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
 
5945
                xmlSchemaPSimpleTypeErr(ctxt,
 
5946
                    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
5947
                    NULL, (xmlNodePtr) attr,
 
5948
                    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
 
5949
                    NULL, NULL, "Duplicate value '%s' of simple "
 
5950
                    "type 'xs:ID'", value, NULL);
 
5951
            } else
 
5952
                attr->atype = XML_ATTRIBUTE_ID;
 
5953
        }
 
5954
    } else if (ret > 0) {
 
5955
        ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
 
5956
        xmlSchemaPSimpleTypeErr(ctxt,
 
5957
            XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
5958
            NULL, (xmlNodePtr) attr,
 
5959
            xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
 
5960
            NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
 
5961
            "not a valid 'xs:NCName'",
 
5962
            value, NULL);
 
5963
    }
 
5964
    if (value != NULL)
 
5965
        xmlFree((xmlChar *)value);
 
5966
 
 
5967
    return (ret);
 
5968
}
 
5969
 
 
5970
static int
 
5971
xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
 
5972
                    xmlNodePtr ownerElem,
 
5973
                    const xmlChar *name)
 
5974
{
 
5975
    xmlAttrPtr attr;
 
5976
 
 
5977
    attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
 
5978
    if (attr == NULL)
 
5979
        return(0);
 
5980
    return(xmlSchemaPValAttrNodeID(ctxt, attr));
 
5981
 
 
5982
}
 
5983
 
 
5984
/**
 
5985
 * xmlGetMaxOccurs:
 
5986
 * @ctxt:  a schema validation context
 
5987
 * @node:  a subtree containing XML Schema informations
 
5988
 *
 
5989
 * Get the maxOccurs property
 
5990
 *
 
5991
 * Returns the default if not found, or the value
 
5992
 */
 
5993
static int
 
5994
xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
 
5995
                int min, int max, int def, const char *expected)
 
5996
{
 
5997
    const xmlChar *val, *cur;
 
5998
    int ret = 0;
 
5999
    xmlAttrPtr attr;
 
6000
 
 
6001
    attr = xmlSchemaGetPropNode(node, "maxOccurs");
 
6002
    if (attr == NULL)
 
6003
        return (def);
 
6004
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 
6005
 
 
6006
    if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
 
6007
        if (max != UNBOUNDED) {
 
6008
            xmlSchemaPSimpleTypeErr(ctxt,
 
6009
                XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
6010
                /* XML_SCHEMAP_INVALID_MINOCCURS, */
 
6011
                NULL, (xmlNodePtr) attr, NULL, expected,
 
6012
                val, NULL, NULL, NULL);
 
6013
            return (def);
 
6014
        } else
 
6015
            return (UNBOUNDED);  /* encoding it with -1 might be another option */
 
6016
    }
 
6017
 
 
6018
    cur = val;
 
6019
    while (IS_BLANK_CH(*cur))
 
6020
        cur++;
 
6021
    if (*cur == 0) {
 
6022
        xmlSchemaPSimpleTypeErr(ctxt,
 
6023
            XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
6024
            /* XML_SCHEMAP_INVALID_MINOCCURS, */
 
6025
            NULL, (xmlNodePtr) attr, NULL, expected,
 
6026
            val, NULL, NULL, NULL);
 
6027
        return (def);
 
6028
    }
 
6029
    while ((*cur >= '0') && (*cur <= '9')) {
 
6030
        ret = ret * 10 + (*cur - '0');
 
6031
        cur++;
 
6032
    }
 
6033
    while (IS_BLANK_CH(*cur))
 
6034
        cur++;
 
6035
    /*
 
6036
    * TODO: Restrict the maximal value to Integer.
 
6037
    */
 
6038
    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
 
6039
        xmlSchemaPSimpleTypeErr(ctxt,
 
6040
            XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
6041
            /* XML_SCHEMAP_INVALID_MINOCCURS, */
 
6042
            NULL, (xmlNodePtr) attr, NULL, expected,
 
6043
            val, NULL, NULL, NULL);
 
6044
        return (def);
 
6045
    }
 
6046
    return (ret);
 
6047
}
 
6048
 
 
6049
/**
 
6050
 * xmlGetMinOccurs:
 
6051
 * @ctxt:  a schema validation context
 
6052
 * @node:  a subtree containing XML Schema informations
 
6053
 *
 
6054
 * Get the minOccurs property
 
6055
 *
 
6056
 * Returns the default if not found, or the value
 
6057
 */
 
6058
static int
 
6059
xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
 
6060
                int min, int max, int def, const char *expected)
 
6061
{
 
6062
    const xmlChar *val, *cur;
 
6063
    int ret = 0;
 
6064
    xmlAttrPtr attr;
 
6065
 
 
6066
    attr = xmlSchemaGetPropNode(node, "minOccurs");
 
6067
    if (attr == NULL)
 
6068
        return (def);
 
6069
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 
6070
    cur = val;
 
6071
    while (IS_BLANK_CH(*cur))
 
6072
        cur++;
 
6073
    if (*cur == 0) {
 
6074
        xmlSchemaPSimpleTypeErr(ctxt,
 
6075
            XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
6076
            /* XML_SCHEMAP_INVALID_MINOCCURS, */
 
6077
            NULL, (xmlNodePtr) attr, NULL, expected,
 
6078
            val, NULL, NULL, NULL);
 
6079
        return (def);
 
6080
    }
 
6081
    while ((*cur >= '0') && (*cur <= '9')) {
 
6082
        ret = ret * 10 + (*cur - '0');
 
6083
        cur++;
 
6084
    }
 
6085
    while (IS_BLANK_CH(*cur))
 
6086
        cur++;
 
6087
    /*
 
6088
    * TODO: Restrict the maximal value to Integer.
 
6089
    */
 
6090
    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
 
6091
        xmlSchemaPSimpleTypeErr(ctxt,
 
6092
            XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
6093
            /* XML_SCHEMAP_INVALID_MINOCCURS, */
 
6094
            NULL, (xmlNodePtr) attr, NULL, expected,
 
6095
            val, NULL, NULL, NULL);
 
6096
        return (def);
 
6097
    }
 
6098
    return (ret);
 
6099
}
 
6100
 
 
6101
/**
 
6102
 * xmlSchemaPGetBoolNodeValue:
 
6103
 * @ctxt:  a schema validation context
 
6104
 * @ownerDes:  owner designation
 
6105
 * @ownerItem:  the owner as a schema item
 
6106
 * @node: the node holding the value
 
6107
 *
 
6108
 * Converts a boolean string value into 1 or 0.
 
6109
 *
 
6110
 * Returns 0 or 1.
 
6111
 */
 
6112
static int
 
6113
xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
 
6114
                           xmlSchemaBasicItemPtr ownerItem,
 
6115
                           xmlNodePtr node)
 
6116
{
 
6117
    xmlChar *value = NULL;
 
6118
    int res = 0;
 
6119
 
 
6120
    value = xmlNodeGetContent(node);
 
6121
    /*
 
6122
    * 3.2.2.1 Lexical representation
 
6123
    * An instance of a datatype that is defined as ļæ½booleanļæ½
 
6124
    * can have the following legal literals {true, false, 1, 0}.
 
6125
    */
 
6126
    if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
 
6127
        res = 1;
 
6128
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
 
6129
        res = 0;
 
6130
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
 
6131
        res = 1;
 
6132
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
 
6133
        res = 0;
 
6134
    else {
 
6135
        xmlSchemaPSimpleTypeErr(ctxt,
 
6136
            XML_SCHEMAP_INVALID_BOOLEAN,
 
6137
            ownerItem, node,
 
6138
            xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
 
6139
            NULL, BAD_CAST value,
 
6140
            NULL, NULL, NULL);
 
6141
    }
 
6142
    if (value != NULL)
 
6143
        xmlFree(value);
 
6144
    return (res);
 
6145
}
 
6146
 
 
6147
/**
 
6148
 * xmlGetBooleanProp:
 
6149
 * @ctxt:  a schema validation context
 
6150
 * @node:  a subtree containing XML Schema informations
 
6151
 * @name:  the attribute name
 
6152
 * @def:  the default value
 
6153
 *
 
6154
 * Evaluate if a boolean property is set
 
6155
 *
 
6156
 * Returns the default if not found, 0 if found to be false,
 
6157
 * 1 if found to be true
 
6158
 */
 
6159
static int
 
6160
xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
 
6161
                  xmlNodePtr node,
 
6162
                  const char *name, int def)
 
6163
{
 
6164
    const xmlChar *val;
 
6165
 
 
6166
    val = xmlSchemaGetProp(ctxt, node, name);
 
6167
    if (val == NULL)
 
6168
        return (def);
 
6169
    /*
 
6170
    * 3.2.2.1 Lexical representation
 
6171
    * An instance of a datatype that is defined as ļæ½booleanļæ½
 
6172
    * can have the following legal literals {true, false, 1, 0}.
 
6173
    */
 
6174
    if (xmlStrEqual(val, BAD_CAST "true"))
 
6175
        def = 1;
 
6176
    else if (xmlStrEqual(val, BAD_CAST "false"))
 
6177
        def = 0;
 
6178
    else if (xmlStrEqual(val, BAD_CAST "1"))
 
6179
        def = 1;
 
6180
    else if (xmlStrEqual(val, BAD_CAST "0"))
 
6181
        def = 0;
 
6182
    else {
 
6183
        xmlSchemaPSimpleTypeErr(ctxt,
 
6184
            XML_SCHEMAP_INVALID_BOOLEAN,
 
6185
            NULL,
 
6186
            (xmlNodePtr) xmlSchemaGetPropNode(node, name),
 
6187
            xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
 
6188
            NULL, val, NULL, NULL, NULL);
 
6189
    }
 
6190
    return (def);
 
6191
}
 
6192
 
 
6193
/************************************************************************
 
6194
 *                                                                      *
 
6195
 *              Shema extraction from an Infoset                        *
 
6196
 *                                                                      *
 
6197
 ************************************************************************/
 
6198
static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
 
6199
                                                 ctxt, xmlSchemaPtr schema,
 
6200
                                                 xmlNodePtr node,
 
6201
                                                 int topLevel);
 
6202
static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
 
6203
                                                  ctxt,
 
6204
                                                  xmlSchemaPtr schema,
 
6205
                                                  xmlNodePtr node,
 
6206
                                                  int topLevel);
 
6207
static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
 
6208
                                                  ctxt,
 
6209
                                                  xmlSchemaPtr schema,
 
6210
                                                  xmlNodePtr node,
 
6211
                                                  xmlSchemaTypeType parentType);
 
6212
static xmlSchemaBasicItemPtr
 
6213
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
 
6214
                             xmlSchemaPtr schema,
 
6215
                             xmlNodePtr node,
 
6216
                             xmlSchemaItemListPtr uses,
 
6217
                             int parentType);
 
6218
static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
 
6219
                                           xmlSchemaPtr schema,
 
6220
                                           xmlNodePtr node);
 
6221
static xmlSchemaWildcardPtr
 
6222
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
 
6223
                           xmlSchemaPtr schema, xmlNodePtr node);
 
6224
 
 
6225
/**
 
6226
 * xmlSchemaPValAttrNodeValue:
 
6227
 *
 
6228
 * @ctxt:  a schema parser context
 
6229
 * @ownerDes: the designation of the parent element
 
6230
 * @ownerItem: the schema object owner if existent
 
6231
 * @attr:  the schema attribute node being validated
 
6232
 * @value: the value
 
6233
 * @type: the built-in type to be validated against
 
6234
 *
 
6235
 * Validates a value against the given built-in type.
 
6236
 * This one is intended to be used internally for validation
 
6237
 * of schema attribute values during parsing of the schema.
 
6238
 *
 
6239
 * Returns 0 if the value is valid, a positive error code
 
6240
 * number otherwise and -1 in case of an internal or API error.
 
6241
 */
 
6242
static int
 
6243
xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
 
6244
                           xmlSchemaBasicItemPtr ownerItem,
 
6245
                           xmlAttrPtr attr,
 
6246
                           const xmlChar *value,
 
6247
                           xmlSchemaTypePtr type)
 
6248
{
 
6249
 
 
6250
    int ret = 0;
 
6251
 
 
6252
    /*
 
6253
    * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
 
6254
    * one is really meant to be used internally, so better not.
 
6255
    */
 
6256
    if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
 
6257
        return (-1);
 
6258
    if (type->type != XML_SCHEMA_TYPE_BASIC) {
 
6259
        PERROR_INT("xmlSchemaPValAttrNodeValue",
 
6260
            "the given type is not a built-in type");
 
6261
        return (-1);
 
6262
    }
 
6263
    switch (type->builtInType) {
 
6264
        case XML_SCHEMAS_NCNAME:
 
6265
        case XML_SCHEMAS_QNAME:
 
6266
        case XML_SCHEMAS_ANYURI:
 
6267
        case XML_SCHEMAS_TOKEN:
 
6268
        case XML_SCHEMAS_LANGUAGE:
 
6269
            ret = xmlSchemaValPredefTypeNode(type, value, NULL,
 
6270
                (xmlNodePtr) attr);
 
6271
            break;
 
6272
        default: {
 
6273
            PERROR_INT("xmlSchemaPValAttrNodeValue",
 
6274
                "validation using the given type is not supported while "
 
6275
                "parsing a schema");
 
6276
            return (-1);
 
6277
        }
 
6278
    }
 
6279
    /*
 
6280
    * TODO: Should we use the S4S error codes instead?
 
6281
    */
 
6282
    if (ret < 0) {
 
6283
        PERROR_INT("xmlSchemaPValAttrNodeValue",
 
6284
            "failed to validate a schema attribute value");
 
6285
        return (-1);
 
6286
    } else if (ret > 0) {
 
6287
        if (WXS_IS_LIST(type))
 
6288
            ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
 
6289
        else
 
6290
            ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
 
6291
        xmlSchemaPSimpleTypeErr(pctxt, 
 
6292
            ret, ownerItem, (xmlNodePtr) attr,
 
6293
            type, NULL, value, NULL, NULL, NULL);
 
6294
    }
 
6295
    return (ret);
 
6296
}
 
6297
 
 
6298
/**
 
6299
 * xmlSchemaPValAttrNode:
 
6300
 *
 
6301
 * @ctxt:  a schema parser context
 
6302
 * @ownerDes: the designation of the parent element
 
6303
 * @ownerItem: the schema object owner if existent
 
6304
 * @attr:  the schema attribute node being validated
 
6305
 * @type: the built-in type to be validated against
 
6306
 * @value: the resulting value if any
 
6307
 *
 
6308
 * Extracts and validates a value against the given built-in type.
 
6309
 * This one is intended to be used internally for validation
 
6310
 * of schema attribute values during parsing of the schema.
 
6311
 *
 
6312
 * Returns 0 if the value is valid, a positive error code
 
6313
 * number otherwise and -1 in case of an internal or API error.
 
6314
 */
 
6315
static int
 
6316
xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
 
6317
                           xmlSchemaBasicItemPtr ownerItem,
 
6318
                           xmlAttrPtr attr,
 
6319
                           xmlSchemaTypePtr type,
 
6320
                           const xmlChar **value)
 
6321
{
 
6322
    const xmlChar *val;
 
6323
 
 
6324
    if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
 
6325
        return (-1);
 
6326
 
 
6327
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 
6328
    if (value != NULL)
 
6329
        *value = val;
 
6330
 
 
6331
    return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
 
6332
        val, type));
 
6333
}
 
6334
 
 
6335
/**
 
6336
 * xmlSchemaPValAttr:
 
6337
 *
 
6338
 * @ctxt:  a schema parser context
 
6339
 * @node: the element node of the attribute
 
6340
 * @ownerDes: the designation of the parent element
 
6341
 * @ownerItem: the schema object owner if existent
 
6342
 * @ownerElem: the owner element node
 
6343
 * @name:  the name of the schema attribute node
 
6344
 * @type: the built-in type to be validated against
 
6345
 * @value: the resulting value if any
 
6346
 *
 
6347
 * Extracts and validates a value against the given built-in type.
 
6348
 * This one is intended to be used internally for validation
 
6349
 * of schema attribute values during parsing of the schema.
 
6350
 *
 
6351
 * Returns 0 if the value is valid, a positive error code
 
6352
 * number otherwise and -1 in case of an internal or API error.
 
6353
 */
 
6354
static int
 
6355
xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,                 
 
6356
                       xmlSchemaBasicItemPtr ownerItem,
 
6357
                       xmlNodePtr ownerElem,
 
6358
                       const char *name,
 
6359
                       xmlSchemaTypePtr type,
 
6360
                       const xmlChar **value)
 
6361
{
 
6362
    xmlAttrPtr attr;
 
6363
 
 
6364
    if ((ctxt == NULL) || (type == NULL)) {
 
6365
        if (value != NULL)
 
6366
            *value = NULL;
 
6367
        return (-1);
 
6368
    }
 
6369
    if (type->type != XML_SCHEMA_TYPE_BASIC) {
 
6370
        if (value != NULL)
 
6371
            *value = NULL;
 
6372
        xmlSchemaPErr(ctxt, ownerElem,
 
6373
            XML_SCHEMAP_INTERNAL,
 
6374
            "Internal error: xmlSchemaPValAttr, the given "
 
6375
            "type '%s' is not a built-in type.\n",
 
6376
            type->name, NULL);
 
6377
        return (-1);
 
6378
    }
 
6379
    attr = xmlSchemaGetPropNode(ownerElem, name);
 
6380
    if (attr == NULL) {
 
6381
        if (value != NULL)
 
6382
            *value = NULL;
 
6383
        return (0);
 
6384
    }
 
6385
    return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
 
6386
        type, value));
 
6387
}
 
6388
 
 
6389
static int
 
6390
xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
 
6391
                  xmlSchemaPtr schema ATTRIBUTE_UNUSED,
 
6392
                  xmlNodePtr node,
 
6393
                  xmlAttrPtr attr,
 
6394
                  const xmlChar *namespaceName)
 
6395
{
 
6396
    /* TODO: Pointer comparison instead? */
 
6397
    if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
 
6398
        return (0);
 
6399
    if (xmlStrEqual(xmlSchemaNs, namespaceName))
 
6400
        return (0);
 
6401
    /*
 
6402
    * Check if the referenced namespace was <import>ed.
 
6403
    */
 
6404
    if (WXS_BUCKET(pctxt)->relations != NULL) {
 
6405
        xmlSchemaSchemaRelationPtr rel;
 
6406
 
 
6407
        rel = WXS_BUCKET(pctxt)->relations;
 
6408
        do {
 
6409
            if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
 
6410
                xmlStrEqual(namespaceName, rel->importNamespace))
 
6411
                return (0);
 
6412
            rel = rel->next;
 
6413
        } while (rel != NULL);
 
6414
    }
 
6415
    /*
 
6416
    * No matching <import>ed namespace found.
 
6417
    */
 
6418
    {
 
6419
        xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
 
6420
 
 
6421
        if (namespaceName == NULL)
 
6422
            xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
6423
                XML_SCHEMAP_SRC_RESOLVE, n, NULL,
 
6424
                "References from this schema to components in no "
 
6425
                "namespace are not allowed, since not indicated by an "
 
6426
                "import statement", NULL, NULL);
 
6427
        else
 
6428
            xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
6429
                XML_SCHEMAP_SRC_RESOLVE, n, NULL,
 
6430
                "References from this schema to components in the "
 
6431
                "namespace '%s' are not allowed, since not indicated by an "
 
6432
                "import statement", namespaceName, NULL);
 
6433
    }
 
6434
    return (XML_SCHEMAP_SRC_RESOLVE);
 
6435
}
 
6436
 
 
6437
/**
 
6438
 * xmlSchemaParseLocalAttributes:
 
6439
 * @ctxt:  a schema validation context
 
6440
 * @schema:  the schema being built
 
6441
 * @node:  a subtree containing XML Schema informations
 
6442
 * @type:  the hosting type where the attributes will be anchored
 
6443
 *
 
6444
 * Parses attribute uses and attribute declarations and
 
6445
 * attribute group references. 
 
6446
 */
 
6447
static int
 
6448
xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
6449
                        xmlNodePtr *child, xmlSchemaItemListPtr *list,
 
6450
                        int parentType, int *hasRefs)
 
6451
{
 
6452
    void *item;
 
6453
 
 
6454
    while ((IS_SCHEMA((*child), "attribute")) ||
 
6455
           (IS_SCHEMA((*child), "attributeGroup"))) {
 
6456
        if (IS_SCHEMA((*child), "attribute")) {
 
6457
            item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
 
6458
                *list, parentType);
 
6459
        } else {
 
6460
            item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
 
6461
            if ((item != NULL) && (hasRefs != NULL))
 
6462
                *hasRefs = 1;
 
6463
        }
 
6464
        if (item != NULL) {
 
6465
            if (*list == NULL) {
 
6466
                /* TODO: Customize grow factor. */
 
6467
                *list = xmlSchemaItemListCreate();
 
6468
                if (*list == NULL)
 
6469
                    return(-1);
 
6470
            }
 
6471
            if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
 
6472
                return(-1);
 
6473
        }
 
6474
        *child = (*child)->next;
 
6475
    }
 
6476
    return (0);
 
6477
}
 
6478
 
 
6479
/**
 
6480
 * xmlSchemaParseAnnotation:
 
6481
 * @ctxt:  a schema validation context
 
6482
 * @schema:  the schema being built
 
6483
 * @node:  a subtree containing XML Schema informations
 
6484
 *
 
6485
 * parse a XML schema Attrribute declaration
 
6486
 * *WARNING* this interface is highly subject to change
 
6487
 *
 
6488
 * Returns -1 in case of error, 0 if the declaration is improper and
 
6489
 *         1 in case of success.
 
6490
 */
 
6491
static xmlSchemaAnnotPtr
 
6492
xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
 
6493
{
 
6494
    xmlSchemaAnnotPtr ret;
 
6495
    xmlNodePtr child = NULL;
 
6496
    xmlAttrPtr attr;
 
6497
    int barked = 0;
 
6498
 
 
6499
    /*
 
6500
    * INFO: S4S completed.
 
6501
    */
 
6502
    /*
 
6503
    * id = ID
 
6504
    * {any attributes with non-schema namespace . . .}>
 
6505
    * Content: (appinfo | documentation)*
 
6506
    */
 
6507
    if ((ctxt == NULL) || (node == NULL))
 
6508
        return (NULL);
 
6509
    if (needed)
 
6510
        ret = xmlSchemaNewAnnot(ctxt, node);
 
6511
    else
 
6512
        ret = NULL;
 
6513
    attr = node->properties;
 
6514
    while (attr != NULL) {
 
6515
        if (((attr->ns == NULL) &&
 
6516
            (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
 
6517
            ((attr->ns != NULL) &&
 
6518
            xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
 
6519
 
 
6520
            xmlSchemaPIllegalAttrErr(ctxt,
 
6521
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
6522
        }
 
6523
        attr = attr->next;
 
6524
    }
 
6525
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
6526
    /*
 
6527
    * And now for the children...
 
6528
    */
 
6529
    child = node->children;
 
6530
    while (child != NULL) {
 
6531
        if (IS_SCHEMA(child, "appinfo")) {
 
6532
            /* TODO: make available the content of "appinfo". */
 
6533
            /*
 
6534
            * source = anyURI
 
6535
            * {any attributes with non-schema namespace . . .}>
 
6536
            * Content: ({any})*
 
6537
            */
 
6538
            attr = child->properties;
 
6539
            while (attr != NULL) {
 
6540
                if (((attr->ns == NULL) &&
 
6541
                     (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
 
6542
                     ((attr->ns != NULL) &&
 
6543
                      xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
 
6544
 
 
6545
                    xmlSchemaPIllegalAttrErr(ctxt,
 
6546
                        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
6547
                }
 
6548
                attr = attr->next;
 
6549
            }
 
6550
            xmlSchemaPValAttr(ctxt, NULL, child, "source",
 
6551
                xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
 
6552
            child = child->next;
 
6553
        } else if (IS_SCHEMA(child, "documentation")) {
 
6554
            /* TODO: make available the content of "documentation". */
 
6555
            /*
 
6556
            * source = anyURI
 
6557
            * {any attributes with non-schema namespace . . .}>
 
6558
            * Content: ({any})*
 
6559
            */
 
6560
            attr = child->properties;
 
6561
            while (attr != NULL) {
 
6562
                if (attr->ns == NULL) {
 
6563
                    if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
 
6564
                        xmlSchemaPIllegalAttrErr(ctxt,
 
6565
                            XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
6566
                    }
 
6567
                } else {
 
6568
                    if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
 
6569
                        (xmlStrEqual(attr->name, BAD_CAST "lang") &&
 
6570
                        (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
 
6571
 
 
6572
                        xmlSchemaPIllegalAttrErr(ctxt,
 
6573
                            XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
6574
                    }
 
6575
                }
 
6576
                attr = attr->next;
 
6577
            }
 
6578
            /*
 
6579
            * Attribute "xml:lang".
 
6580
            */
 
6581
            attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
 
6582
            if (attr != NULL)
 
6583
                xmlSchemaPValAttrNode(ctxt, NULL, attr,
 
6584
                xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
 
6585
            child = child->next;
 
6586
        } else {
 
6587
            if (!barked)
 
6588
                xmlSchemaPContentErr(ctxt,
 
6589
                    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
6590
                    NULL, node, child, NULL, "(appinfo | documentation)*");
 
6591
            barked = 1;
 
6592
            child = child->next;
 
6593
        }
 
6594
    }
 
6595
 
 
6596
    return (ret);
 
6597
}
 
6598
 
 
6599
/**
 
6600
 * xmlSchemaParseFacet:
 
6601
 * @ctxt:  a schema validation context
 
6602
 * @schema:  the schema being built
 
6603
 * @node:  a subtree containing XML Schema informations
 
6604
 *
 
6605
 * parse a XML schema Facet declaration
 
6606
 * *WARNING* this interface is highly subject to change
 
6607
 *
 
6608
 * Returns the new type structure or NULL in case of error
 
6609
 */
 
6610
static xmlSchemaFacetPtr
 
6611
xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
6612
                    xmlNodePtr node)
 
6613
{
 
6614
    xmlSchemaFacetPtr facet;
 
6615
    xmlNodePtr child = NULL;
 
6616
    const xmlChar *value;
 
6617
 
 
6618
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 
6619
        return (NULL);
 
6620
 
 
6621
    facet = xmlSchemaNewFacet();
 
6622
    if (facet == NULL) {
 
6623
        xmlSchemaPErrMemory(ctxt, "allocating facet", node);
 
6624
        return (NULL);
 
6625
    }
 
6626
    facet->node = node;
 
6627
    value = xmlSchemaGetProp(ctxt, node, "value");
 
6628
    if (value == NULL) {
 
6629
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
 
6630
                       "Facet %s has no value\n", node->name, NULL);
 
6631
        xmlSchemaFreeFacet(facet);
 
6632
        return (NULL);
 
6633
    }
 
6634
    if (IS_SCHEMA(node, "minInclusive")) {
 
6635
        facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
 
6636
    } else if (IS_SCHEMA(node, "minExclusive")) {
 
6637
        facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
 
6638
    } else if (IS_SCHEMA(node, "maxInclusive")) {
 
6639
        facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
 
6640
    } else if (IS_SCHEMA(node, "maxExclusive")) {
 
6641
        facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
 
6642
    } else if (IS_SCHEMA(node, "totalDigits")) {
 
6643
        facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
 
6644
    } else if (IS_SCHEMA(node, "fractionDigits")) {
 
6645
        facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
 
6646
    } else if (IS_SCHEMA(node, "pattern")) {
 
6647
        facet->type = XML_SCHEMA_FACET_PATTERN;
 
6648
    } else if (IS_SCHEMA(node, "enumeration")) {
 
6649
        facet->type = XML_SCHEMA_FACET_ENUMERATION;
 
6650
    } else if (IS_SCHEMA(node, "whiteSpace")) {
 
6651
        facet->type = XML_SCHEMA_FACET_WHITESPACE;
 
6652
    } else if (IS_SCHEMA(node, "length")) {
 
6653
        facet->type = XML_SCHEMA_FACET_LENGTH;
 
6654
    } else if (IS_SCHEMA(node, "maxLength")) {
 
6655
        facet->type = XML_SCHEMA_FACET_MAXLENGTH;
 
6656
    } else if (IS_SCHEMA(node, "minLength")) {
 
6657
        facet->type = XML_SCHEMA_FACET_MINLENGTH;
 
6658
    } else {
 
6659
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
 
6660
                       "Unknown facet type %s\n", node->name, NULL);
 
6661
        xmlSchemaFreeFacet(facet);
 
6662
        return (NULL);
 
6663
    }
 
6664
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
6665
    facet->value = value;
 
6666
    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
 
6667
        (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
 
6668
        const xmlChar *fixed;
 
6669
 
 
6670
        fixed = xmlSchemaGetProp(ctxt, node, "fixed");
 
6671
        if (fixed != NULL) {
 
6672
            if (xmlStrEqual(fixed, BAD_CAST "true"))
 
6673
                facet->fixed = 1;
 
6674
        }
 
6675
    }
 
6676
    child = node->children;
 
6677
 
 
6678
    if (IS_SCHEMA(child, "annotation")) {
 
6679
        facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 
6680
        child = child->next;
 
6681
    }
 
6682
    if (child != NULL) {
 
6683
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
 
6684
                       "Facet %s has unexpected child content\n",
 
6685
                       node->name, NULL);
 
6686
    }
 
6687
    return (facet);
 
6688
}
 
6689
 
 
6690
/**
 
6691
 * xmlSchemaParseWildcardNs:
 
6692
 * @ctxt:  a schema parser context
 
6693
 * @wildc:  the wildcard, already created
 
6694
 * @node:  a subtree containing XML Schema informations
 
6695
 *
 
6696
 * Parses the attribute "processContents" and "namespace"
 
6697
 * of a xsd:anyAttribute and xsd:any.
 
6698
 * *WARNING* this interface is highly subject to change
 
6699
 *
 
6700
 * Returns 0 if everything goes fine, a positive error code
 
6701
 * if something is not valid and -1 if an internal error occurs.
 
6702
 */
 
6703
static int
 
6704
xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
 
6705
                         xmlSchemaPtr schema ATTRIBUTE_UNUSED,
 
6706
                         xmlSchemaWildcardPtr wildc,
 
6707
                         xmlNodePtr node)
 
6708
{
 
6709
    const xmlChar *pc, *ns, *dictnsItem;
 
6710
    int ret = 0;
 
6711
    xmlChar *nsItem;
 
6712
    xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
 
6713
    xmlAttrPtr attr;
 
6714
 
 
6715
    pc = xmlSchemaGetProp(ctxt, node, "processContents");
 
6716
    if ((pc == NULL)
 
6717
        || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
 
6718
        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
 
6719
    } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
 
6720
        wildc->processContents = XML_SCHEMAS_ANY_SKIP;
 
6721
    } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
 
6722
        wildc->processContents = XML_SCHEMAS_ANY_LAX;
 
6723
    } else {
 
6724
        xmlSchemaPSimpleTypeErr(ctxt,
 
6725
            XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
6726
            NULL, node,
 
6727
            NULL, "(strict | skip | lax)", pc,
 
6728
            NULL, NULL, NULL);
 
6729
        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
 
6730
        ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
 
6731
    }
 
6732
    /*
 
6733
     * Build the namespace constraints.
 
6734
     */
 
6735
    attr = xmlSchemaGetPropNode(node, "namespace");
 
6736
    ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 
6737
    if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
 
6738
        wildc->any = 1;
 
6739
    else if (xmlStrEqual(ns, BAD_CAST "##other")) {
 
6740
        wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
 
6741
        if (wildc->negNsSet == NULL) {
 
6742
            return (-1);
 
6743
        }
 
6744
        wildc->negNsSet->value = ctxt->targetNamespace;
 
6745
    } else {
 
6746
        const xmlChar *end, *cur;
 
6747
 
 
6748
        cur = ns;
 
6749
        do {
 
6750
            while (IS_BLANK_CH(*cur))
 
6751
                cur++;
 
6752
            end = cur;
 
6753
            while ((*end != 0) && (!(IS_BLANK_CH(*end))))
 
6754
                end++;
 
6755
            if (end == cur)
 
6756
                break;
 
6757
            nsItem = xmlStrndup(cur, end - cur);
 
6758
            if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
 
6759
                    (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
 
6760
                xmlSchemaPSimpleTypeErr(ctxt,
 
6761
                    XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
 
6762
                    NULL, (xmlNodePtr) attr,
 
6763
                    NULL,
 
6764
                    "((##any | ##other) | List of (xs:anyURI | "
 
6765
                    "(##targetNamespace | ##local)))",
 
6766
                    nsItem, NULL, NULL, NULL);
 
6767
                ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
 
6768
            } else {
 
6769
                if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
 
6770
                    dictnsItem = ctxt->targetNamespace;
 
6771
                } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
 
6772
                    dictnsItem = NULL;
 
6773
                } else {
 
6774
                    /*
 
6775
                    * Validate the item (anyURI).
 
6776
                    */
 
6777
                    xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
 
6778
                        nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
 
6779
                    dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
 
6780
                }
 
6781
                /*
 
6782
                * Avoid dublicate namespaces.
 
6783
                */
 
6784
                tmp = wildc->nsSet;
 
6785
                while (tmp != NULL) {
 
6786
                    if (dictnsItem == tmp->value)
 
6787
                        break;
 
6788
                    tmp = tmp->next;
 
6789
                }
 
6790
                if (tmp == NULL) {
 
6791
                    tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
 
6792
                    if (tmp == NULL) {
 
6793
                        xmlFree(nsItem);
 
6794
                        return (-1);
 
6795
                    }
 
6796
                    tmp->value = dictnsItem;
 
6797
                    tmp->next = NULL;
 
6798
                    if (wildc->nsSet == NULL)
 
6799
                        wildc->nsSet = tmp;
 
6800
                    else
 
6801
                        lastNs->next = tmp;
 
6802
                    lastNs = tmp;
 
6803
                }
 
6804
 
 
6805
            }
 
6806
            xmlFree(nsItem);
 
6807
            cur = end;
 
6808
        } while (*cur != 0);
 
6809
    }
 
6810
    return (ret);
 
6811
}
 
6812
 
 
6813
static int
 
6814
xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
 
6815
                                 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
 
6816
                                 xmlNodePtr node,
 
6817
                                 int minOccurs,
 
6818
                                 int maxOccurs) {
 
6819
 
 
6820
    if ((maxOccurs == 0) && ( minOccurs == 0))
 
6821
        return (0);
 
6822
    if (maxOccurs != UNBOUNDED) {
 
6823
        /*
 
6824
        * TODO: Maybe we should better not create the particle,
 
6825
        * if min/max is invalid, since it could confuse the build of the
 
6826
        * content model.
 
6827
        */
 
6828
        /*
 
6829
        * 3.9.6 Schema Component Constraint: Particle Correct
 
6830
        *
 
6831
        */
 
6832
        if (maxOccurs < 1) {
 
6833
            /*
 
6834
            * 2.2 {max occurs} must be greater than or equal to 1.
 
6835
            */
 
6836
            xmlSchemaPCustomAttrErr(ctxt,
 
6837
                XML_SCHEMAP_P_PROPS_CORRECT_2_2,
 
6838
                NULL, NULL,
 
6839
                xmlSchemaGetPropNode(node, "maxOccurs"),
 
6840
                "The value must be greater than or equal to 1");
 
6841
            return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
 
6842
        } else if (minOccurs > maxOccurs) {
 
6843
            /*
 
6844
            * 2.1 {min occurs} must not be greater than {max occurs}.
 
6845
            */
 
6846
            xmlSchemaPCustomAttrErr(ctxt,
 
6847
                XML_SCHEMAP_P_PROPS_CORRECT_2_1,
 
6848
                NULL, NULL,
 
6849
                xmlSchemaGetPropNode(node, "minOccurs"),
 
6850
                "The value must not be greater than the value of 'maxOccurs'");
 
6851
            return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
 
6852
        }
 
6853
    }
 
6854
    return (0);
 
6855
}
 
6856
 
 
6857
/**
 
6858
 * xmlSchemaParseAny:
 
6859
 * @ctxt:  a schema validation context
 
6860
 * @schema:  the schema being built
 
6861
 * @node:  a subtree containing XML Schema informations
 
6862
 *
 
6863
 * Parsea a XML schema <any> element. A particle and wildcard
 
6864
 * will be created (except if minOccurs==maxOccurs==0, in this case
 
6865
 * nothing will be created).
 
6866
 * *WARNING* this interface is highly subject to change
 
6867
 *
 
6868
 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
 
6869
 */
 
6870
static xmlSchemaParticlePtr
 
6871
xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
6872
                  xmlNodePtr node)
 
6873
{
 
6874
    xmlSchemaParticlePtr particle;
 
6875
    xmlNodePtr child = NULL;
 
6876
    xmlSchemaWildcardPtr wild;
 
6877
    int min, max;
 
6878
    xmlAttrPtr attr;
 
6879
    xmlSchemaAnnotPtr annot = NULL;
 
6880
 
 
6881
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 
6882
        return (NULL);
 
6883
    /*
 
6884
    * Check for illegal attributes.
 
6885
    */
 
6886
    attr = node->properties;
 
6887
    while (attr != NULL) {
 
6888
        if (attr->ns == NULL) {
 
6889
            if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 
6890
                (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
 
6891
                (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
 
6892
                (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
 
6893
                (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
 
6894
                xmlSchemaPIllegalAttrErr(ctxt,
 
6895
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
6896
            }
 
6897
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
6898
            xmlSchemaPIllegalAttrErr(ctxt,
 
6899
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
6900
        }
 
6901
        attr = attr->next;
 
6902
    }
 
6903
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
6904
    /*
 
6905
    * minOccurs/maxOccurs.
 
6906
    */
 
6907
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
 
6908
        "(xs:nonNegativeInteger | unbounded)");
 
6909
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
 
6910
        "xs:nonNegativeInteger");
 
6911
    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
 
6912
    /*
 
6913
    * Create & parse the wildcard.
 
6914
    */
 
6915
    wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
 
6916
    if (wild == NULL)
 
6917
        return (NULL);
 
6918
    xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
 
6919
    /*
 
6920
    * And now for the children...
 
6921
    */
 
6922
    child = node->children;
 
6923
    if (IS_SCHEMA(child, "annotation")) {
 
6924
        annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 
6925
        child = child->next;
 
6926
    }
 
6927
    if (child != NULL) {
 
6928
        xmlSchemaPContentErr(ctxt,
 
6929
            XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
6930
            NULL, node, child,
 
6931
            NULL, "(annotation?)");
 
6932
    }
 
6933
    /*
 
6934
    * No component if minOccurs==maxOccurs==0.
 
6935
    */
 
6936
    if ((min == 0) && (max == 0)) {
 
6937
        /* Don't free the wildcard, since it's already on the list. */
 
6938
        return (NULL);
 
6939
    }
 
6940
    /*
 
6941
    * Create the particle.
 
6942
    */
 
6943
    particle = xmlSchemaAddParticle(ctxt, node, min, max);
 
6944
    if (particle == NULL)
 
6945
        return (NULL);
 
6946
    particle->annot = annot;
 
6947
    particle->children = (xmlSchemaTreeItemPtr) wild;
 
6948
 
 
6949
    return (particle);
 
6950
}
 
6951
 
 
6952
/**
 
6953
 * xmlSchemaParseNotation:
 
6954
 * @ctxt:  a schema validation context
 
6955
 * @schema:  the schema being built
 
6956
 * @node:  a subtree containing XML Schema informations
 
6957
 *
 
6958
 * parse a XML schema Notation declaration
 
6959
 *
 
6960
 * Returns the new structure or NULL in case of error
 
6961
 */
 
6962
static xmlSchemaNotationPtr
 
6963
xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
6964
                       xmlNodePtr node)
 
6965
{
 
6966
    const xmlChar *name;
 
6967
    xmlSchemaNotationPtr ret;
 
6968
    xmlNodePtr child = NULL;
 
6969
 
 
6970
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 
6971
        return (NULL);
 
6972
    name = xmlSchemaGetProp(ctxt, node, "name");
 
6973
    if (name == NULL) {
 
6974
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
 
6975
                       "Notation has no name\n", NULL, NULL);
 
6976
        return (NULL);
 
6977
    }
 
6978
    ret = xmlSchemaAddNotation(ctxt, schema, name,
 
6979
        ctxt->targetNamespace, node);
 
6980
    if (ret == NULL)
 
6981
        return (NULL);
 
6982
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
6983
 
 
6984
    child = node->children;
 
6985
    if (IS_SCHEMA(child, "annotation")) {
 
6986
        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 
6987
        child = child->next;
 
6988
    }
 
6989
    if (child != NULL) {
 
6990
        xmlSchemaPContentErr(ctxt,
 
6991
            XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
6992
            NULL, node, child,
 
6993
            NULL, "(annotation?)");
 
6994
    }
 
6995
 
 
6996
    return (ret);
 
6997
}
 
6998
 
 
6999
/**
 
7000
 * xmlSchemaParseAnyAttribute:
 
7001
 * @ctxt:  a schema validation context
 
7002
 * @schema:  the schema being built
 
7003
 * @node:  a subtree containing XML Schema informations
 
7004
 *
 
7005
 * parse a XML schema AnyAttrribute declaration
 
7006
 * *WARNING* this interface is highly subject to change
 
7007
 *
 
7008
 * Returns a wildcard or NULL.
 
7009
 */
 
7010
static xmlSchemaWildcardPtr
 
7011
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
 
7012
                           xmlSchemaPtr schema, xmlNodePtr node)
 
7013
{
 
7014
    xmlSchemaWildcardPtr ret;
 
7015
    xmlNodePtr child = NULL;
 
7016
    xmlAttrPtr attr;
 
7017
 
 
7018
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 
7019
        return (NULL);
 
7020
 
 
7021
    ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
 
7022
        node);
 
7023
    if (ret == NULL) {
 
7024
        return (NULL);
 
7025
    }
 
7026
    /*
 
7027
    * Check for illegal attributes.
 
7028
    */
 
7029
    attr = node->properties;
 
7030
    while (attr != NULL) {
 
7031
        if (attr->ns == NULL) {
 
7032
            if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 
7033
                (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
 
7034
                (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
 
7035
                xmlSchemaPIllegalAttrErr(ctxt,
 
7036
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
7037
            }
 
7038
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
7039
            xmlSchemaPIllegalAttrErr(ctxt,
 
7040
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
7041
        }
 
7042
        attr = attr->next;
 
7043
    }
 
7044
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
7045
    /*
 
7046
    * Parse the namespace list.
 
7047
    */
 
7048
    if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
 
7049
        return (NULL);
 
7050
    /*
 
7051
    * And now for the children...
 
7052
    */
 
7053
    child = node->children;
 
7054
    if (IS_SCHEMA(child, "annotation")) {
 
7055
        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 
7056
        child = child->next;
 
7057
    }
 
7058
    if (child != NULL) {
 
7059
        xmlSchemaPContentErr(ctxt,
 
7060
            XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
7061
            NULL, node, child,
 
7062
            NULL, "(annotation?)");
 
7063
    }
 
7064
 
 
7065
    return (ret);
 
7066
}
 
7067
 
 
7068
 
 
7069
/**
 
7070
 * xmlSchemaParseAttribute:
 
7071
 * @ctxt:  a schema validation context
 
7072
 * @schema:  the schema being built
 
7073
 * @node:  a subtree containing XML Schema informations
 
7074
 *
 
7075
 * parse a XML schema Attrribute declaration
 
7076
 * *WARNING* this interface is highly subject to change
 
7077
 *
 
7078
 * Returns the attribute declaration.
 
7079
 */
 
7080
static xmlSchemaBasicItemPtr
 
7081
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
 
7082
                             xmlSchemaPtr schema,
 
7083
                             xmlNodePtr node,
 
7084
                             xmlSchemaItemListPtr uses,
 
7085
                             int parentType)
 
7086
{
 
7087
    const xmlChar *attrValue, *name = NULL, *ns = NULL;
 
7088
    xmlSchemaAttributeUsePtr use = NULL;    
 
7089
    xmlNodePtr child = NULL;
 
7090
    xmlAttrPtr attr;
 
7091
    const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
 
7092
    int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
 
7093
    int nberrors, hasForm = 0, defValueType = 0;
 
7094
 
 
7095
#define WXS_ATTR_DEF_VAL_DEFAULT 1
 
7096
#define WXS_ATTR_DEF_VAL_FIXED 2
 
7097
 
 
7098
    /*
 
7099
     * 3.2.3 Constraints on XML Representations of Attribute Declarations
 
7100
     */
 
7101
 
 
7102
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 
7103
        return (NULL);
 
7104
    attr = xmlSchemaGetPropNode(node, "ref");
 
7105
    if (attr != NULL) {
 
7106
        if (xmlSchemaPValAttrNodeQName(pctxt, schema,
 
7107
            NULL, attr, &tmpNs, &tmpName) != 0) {
 
7108
            return (NULL);
 
7109
        }
 
7110
        if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
 
7111
            return(NULL);
 
7112
        isRef = 1;
 
7113
    }
 
7114
    nberrors = pctxt->nberrors;
 
7115
    /*
 
7116
    * Check for illegal attributes.
 
7117
    */
 
7118
    attr = node->properties;
 
7119
    while (attr != NULL) {
 
7120
        if (attr->ns == NULL) {
 
7121
            if (isRef) {
 
7122
                if (xmlStrEqual(attr->name, BAD_CAST "id")) {
 
7123
                    xmlSchemaPValAttrNodeID(pctxt, attr);
 
7124
                    goto attr_next;
 
7125
                } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
 
7126
                    goto attr_next;
 
7127
                }
 
7128
            } else {
 
7129
                if (xmlStrEqual(attr->name, BAD_CAST "name")) {
 
7130
                    goto attr_next;
 
7131
                } else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
 
7132
                    xmlSchemaPValAttrNodeID(pctxt, attr);
 
7133
                    goto attr_next;
 
7134
                } else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
 
7135
                    xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
 
7136
                        attr, &tmpNs, &tmpName);
 
7137
                    goto attr_next;
 
7138
                } else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
 
7139
                    /*
 
7140
                    * Evaluate the target namespace
 
7141
                    */
 
7142
                    hasForm = 1;                    
 
7143
                    attrValue = xmlSchemaGetNodeContent(pctxt,
 
7144
                        (xmlNodePtr) attr);
 
7145
                    if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
 
7146
                        ns = pctxt->targetNamespace;
 
7147
                    } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
 
7148
                    {
 
7149
                        xmlSchemaPSimpleTypeErr(pctxt,
 
7150
                            XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
7151
                            NULL, (xmlNodePtr) attr,
 
7152
                            NULL, "(qualified | unqualified)",
 
7153
                            attrValue, NULL, NULL, NULL);
 
7154
                    }
 
7155
                    goto attr_next;
 
7156
                }
 
7157
            }
 
7158
            if (xmlStrEqual(attr->name, BAD_CAST "use")) {
 
7159
 
 
7160
                attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
 
7161
                /* TODO: Maybe we need to normalize the value beforehand. */
 
7162
                if (xmlStrEqual(attrValue, BAD_CAST "optional"))
 
7163
                    occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
 
7164
                else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
 
7165
                    occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
 
7166
                else if (xmlStrEqual(attrValue, BAD_CAST "required"))
 
7167
                    occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
 
7168
                else {
 
7169
                    xmlSchemaPSimpleTypeErr(pctxt,
 
7170
                        XML_SCHEMAP_INVALID_ATTR_USE,
 
7171
                        NULL, (xmlNodePtr) attr,
 
7172
                        NULL, "(optional | prohibited | required)",
 
7173
                        attrValue, NULL, NULL, NULL);
 
7174
                }
 
7175
                goto attr_next;
 
7176
            } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
 
7177
                /*
 
7178
                * 3.2.3 : 1
 
7179
                * default and fixed must not both be present.
 
7180
                */
 
7181
                if (defValue) {
 
7182
                    xmlSchemaPMutualExclAttrErr(pctxt,
 
7183
                        XML_SCHEMAP_SRC_ATTRIBUTE_1,
 
7184
                        NULL, attr, "default", "fixed");
 
7185
                } else {
 
7186
                    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
 
7187
                    defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
 
7188
                }
 
7189
                goto attr_next;
 
7190
            } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
 
7191
                /*
 
7192
                * 3.2.3 : 1
 
7193
                * default and fixed must not both be present.
 
7194
                */
 
7195
                if (defValue) {
 
7196
                    xmlSchemaPMutualExclAttrErr(pctxt,
 
7197
                        XML_SCHEMAP_SRC_ATTRIBUTE_1,
 
7198
                        NULL, attr, "default", "fixed");
 
7199
                } else {
 
7200
                    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
 
7201
                    defValueType = WXS_ATTR_DEF_VAL_FIXED;
 
7202
                }
 
7203
                goto attr_next;
 
7204
            }
 
7205
        } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
 
7206
            goto attr_next;
 
7207
 
 
7208
        xmlSchemaPIllegalAttrErr(pctxt,
 
7209
            XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
7210
 
 
7211
attr_next:
 
7212
        attr = attr->next;
 
7213
    }        
 
7214
    /*
 
7215
    * 3.2.3 : 2
 
7216
    * If default and use are both present, use must have
 
7217
    * the actual value optional.
 
7218
    */
 
7219
    if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
 
7220
        (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
 
7221
        xmlSchemaPSimpleTypeErr(pctxt,
 
7222
            XML_SCHEMAP_SRC_ATTRIBUTE_2,
 
7223
            NULL, node, NULL,
 
7224
            "(optional | prohibited | required)", NULL,
 
7225
            "The value of the attribute 'use' must be 'optional' "
 
7226
            "if the attribute 'default' is present",
 
7227
            NULL, NULL);
 
7228
    }
 
7229
    /*
 
7230
    * We want correct attributes.
 
7231
    */
 
7232
    if (nberrors != pctxt->nberrors)
 
7233
        return(NULL);
 
7234
    if (! isRef) {
 
7235
        xmlSchemaAttributePtr attrDecl;
 
7236
 
 
7237
        /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
 
7238
        if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
 
7239
            ns = pctxt->targetNamespace;                
 
7240
        /*
 
7241
        * 3.2.6 Schema Component Constraint: xsi: Not Allowed
 
7242
        * TODO: Move this to the component layer.
 
7243
        */
 
7244
        if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
 
7245
            xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
7246
                XML_SCHEMAP_NO_XSI,
 
7247
                node, NULL,
 
7248
                "The target namespace must not match '%s'",
 
7249
                xmlSchemaInstanceNs, NULL);
 
7250
        }
 
7251
        attr = xmlSchemaGetPropNode(node, "name");
 
7252
        if (attr == NULL) {
 
7253
            xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
 
7254
                NULL, node, "name", NULL);
 
7255
            return (NULL);
 
7256
        }
 
7257
        if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
 
7258
            xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
 
7259
            return (NULL);
 
7260
        }
 
7261
        /*
 
7262
        * 3.2.6 Schema Component Constraint: xmlns Not Allowed
 
7263
        * TODO: Move this to the component layer.
 
7264
        */
 
7265
        if (xmlStrEqual(name, BAD_CAST "xmlns")) {
 
7266
            xmlSchemaPSimpleTypeErr(pctxt,
 
7267
                XML_SCHEMAP_NO_XMLNS,
 
7268
                NULL, (xmlNodePtr) attr,
 
7269
                xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
 
7270
                "The value of the attribute must not match 'xmlns'",
 
7271
                NULL, NULL);
 
7272
            return (NULL);
 
7273
        }
 
7274
        if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
 
7275
            goto check_children;
 
7276
        /*
 
7277
        * Create the attribute use component.
 
7278
        */
 
7279
        use = xmlSchemaAddAttributeUse(pctxt, node);
 
7280
        if (use == NULL)
 
7281
            return(NULL);
 
7282
        use->occurs = occurs;
 
7283
        /*
 
7284
        * Create the attribute declaration.
 
7285
        */
 
7286
        attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
 
7287
        if (attrDecl == NULL)
 
7288
            return (NULL);
 
7289
        if (tmpName != NULL) {
 
7290
            attrDecl->typeName = tmpName;
 
7291
            attrDecl->typeNs = tmpNs;
 
7292
        }
 
7293
        use->attrDecl = attrDecl;
 
7294
        /*
 
7295
        * Value constraint.
 
7296
        */      
 
7297
        if (defValue != NULL) {
 
7298
            attrDecl->defValue = defValue;
 
7299
            if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
 
7300
                attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
 
7301
        }
 
7302
    } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
 
7303
        xmlSchemaQNameRefPtr ref;
 
7304
 
 
7305
        /*
 
7306
        * Create the attribute use component.
 
7307
        */
 
7308
        use = xmlSchemaAddAttributeUse(pctxt, node);
 
7309
        if (use == NULL)
 
7310
            return(NULL);
 
7311
        /*
 
7312
        * We need to resolve the reference at later stage.
 
7313
        */
 
7314
        WXS_ADD_PENDING(pctxt, use);
 
7315
        use->occurs = occurs;
 
7316
        /*
 
7317
        * Create a QName reference to the attribute declaration.
 
7318
        */
 
7319
        ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
 
7320
            tmpName, tmpNs);
 
7321
        if (ref == NULL)
 
7322
            return(NULL);
 
7323
        /*
 
7324
        * Assign the reference. This will be substituted for the
 
7325
        * referenced attribute declaration when the QName is resolved.
 
7326
        */
 
7327
        use->attrDecl = WXS_ATTR_CAST ref;
 
7328
        /*
 
7329
        * Value constraint.
 
7330
        */
 
7331
        if (defValue != NULL)
 
7332
            use->defValue = defValue;
 
7333
            if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
 
7334
                use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
 
7335
    }
 
7336
    
 
7337
check_children:
 
7338
    /*
 
7339
    * And now for the children...
 
7340
    */
 
7341
    child = node->children;
 
7342
    if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
 
7343
        xmlSchemaAttributeUseProhibPtr prohib;  
 
7344
 
 
7345
        if (IS_SCHEMA(child, "annotation")) {
 
7346
            xmlSchemaParseAnnotation(pctxt, child, 0);
 
7347
            child = child->next;
 
7348
        }
 
7349
        if (child != NULL) {
 
7350
            xmlSchemaPContentErr(pctxt,
 
7351
                XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
7352
                NULL, node, child, NULL,
 
7353
                "(annotation?)");
 
7354
        }
 
7355
        /*
 
7356
        * Check for pointlessness of attribute prohibitions.
 
7357
        */
 
7358
        if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {             
 
7359
            xmlSchemaCustomWarning(ACTXT_CAST pctxt,
 
7360
                XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
 
7361
                node, NULL,
 
7362
                "Skipping attribute use prohibition, since it is "
 
7363
                "pointless inside an <attributeGroup>",
 
7364
                NULL, NULL, NULL);
 
7365
            return(NULL);
 
7366
        } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
 
7367
            xmlSchemaCustomWarning(ACTXT_CAST pctxt,
 
7368
                XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
 
7369
                node, NULL,
 
7370
                "Skipping attribute use prohibition, since it is "
 
7371
                "pointless when extending a type",
 
7372
                NULL, NULL, NULL);
 
7373
            return(NULL);
 
7374
        }
 
7375
        if (! isRef) {
 
7376
            tmpName = name; 
 
7377
            tmpNs = ns;
 
7378
        }
 
7379
        /*
 
7380
        * Check for duplicate attribute prohibitions.
 
7381
        */
 
7382
        if (uses) {
 
7383
            int i;
 
7384
            
 
7385
            for (i = 0; i < uses->nbItems; i++) {
 
7386
                use = uses->items[i];
 
7387
                if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
 
7388
                    (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
 
7389
                    (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
 
7390
                {
 
7391
                    xmlChar *str = NULL;
 
7392
                    
 
7393
                    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
 
7394
                        XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
 
7395
                        node, NULL,
 
7396
                        "Skipping duplicate attribute use prohibition '%s'",
 
7397
                        xmlSchemaFormatQName(&str, tmpNs, tmpName),
 
7398
                        NULL, NULL);
 
7399
                    FREE_AND_NULL(str)                  
 
7400
                    return(NULL);
 
7401
                }       
 
7402
            }
 
7403
        }
 
7404
        /*
 
7405
        * Create the attribute prohibition helper component.
 
7406
        */
 
7407
        prohib = xmlSchemaAddAttributeUseProhib(pctxt);
 
7408
        if (prohib == NULL)
 
7409
            return(NULL);
 
7410
        prohib->node = node;
 
7411
        prohib->name = tmpName;
 
7412
        prohib->targetNamespace = tmpNs;
 
7413
        if (isRef) {
 
7414
            /*
 
7415
            * We need at least to resolve to the attribute declaration.
 
7416
            */
 
7417
            WXS_ADD_PENDING(pctxt, prohib);
 
7418
        }
 
7419
        return(WXS_BASIC_CAST prohib);
 
7420
    } else {        
 
7421
        if (IS_SCHEMA(child, "annotation")) {
 
7422
            /*
 
7423
            * TODO: Should this go into the attr decl?
 
7424
            */
 
7425
            use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
 
7426
            child = child->next;
 
7427
        }
 
7428
        if (isRef) {
 
7429
            if (child != NULL) {
 
7430
                if (IS_SCHEMA(child, "simpleType"))
 
7431
                    /*
 
7432
                    * 3.2.3 : 3.2
 
7433
                    * If ref is present, then all of <simpleType>,
 
7434
                    * form and type must be absent.
 
7435
                    */
 
7436
                    xmlSchemaPContentErr(pctxt,
 
7437
                        XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
 
7438
                        NULL, node, child, NULL,
 
7439
                        "(annotation?)");
 
7440
                else
 
7441
                    xmlSchemaPContentErr(pctxt,
 
7442
                        XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
7443
                        NULL, node, child, NULL,
 
7444
                        "(annotation?)");
 
7445
            }
 
7446
        } else {
 
7447
            if (IS_SCHEMA(child, "simpleType")) {
 
7448
                if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
 
7449
                    /*
 
7450
                    * 3.2.3 : 4
 
7451
                    * type and <simpleType> must not both be present.
 
7452
                    */
 
7453
                    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
 
7454
                        NULL, node, child,
 
7455
                        "The attribute 'type' and the <simpleType> child "
 
7456
                        "are mutually exclusive", NULL);
 
7457
                } else
 
7458
                    WXS_ATTRUSE_TYPEDEF(use) =
 
7459
                        xmlSchemaParseSimpleType(pctxt, schema, child, 0);
 
7460
                child = child->next;
 
7461
            }
 
7462
            if (child != NULL)
 
7463
                xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
7464
                NULL, node, child, NULL,
 
7465
                "(annotation?, simpleType?)");
 
7466
        }
 
7467
    }   
 
7468
    return (WXS_BASIC_CAST use);
 
7469
}
 
7470
 
 
7471
 
 
7472
static xmlSchemaAttributePtr
 
7473
xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
 
7474
                              xmlSchemaPtr schema,
 
7475
                              xmlNodePtr node)
 
7476
{
 
7477
    const xmlChar *attrValue;
 
7478
    xmlSchemaAttributePtr ret;
 
7479
    xmlNodePtr child = NULL;
 
7480
    xmlAttrPtr attr;
 
7481
 
 
7482
    /*
 
7483
     * Note that the w3c spec assumes the schema to be validated with schema
 
7484
     * for schemas beforehand.
 
7485
     *
 
7486
     * 3.2.3 Constraints on XML Representations of Attribute Declarations
 
7487
     */
 
7488
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 
7489
        return (NULL);        
 
7490
    /*
 
7491
    * 3.2.3 : 3.1
 
7492
    * One of ref or name must be present, but not both
 
7493
    */
 
7494
    attr = xmlSchemaGetPropNode(node, "name");
 
7495
    if (attr == NULL) {
 
7496
        xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
 
7497
            NULL, node, "name", NULL);
 
7498
        return (NULL);
 
7499
    }
 
7500
    if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
 
7501
        xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
 
7502
        return (NULL);
 
7503
    }
 
7504
    /*
 
7505
    * 3.2.6 Schema Component Constraint: xmlns Not Allowed
 
7506
    * TODO: Move this to the component layer.
 
7507
    */
 
7508
    if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
 
7509
        xmlSchemaPSimpleTypeErr(pctxt,
 
7510
            XML_SCHEMAP_NO_XMLNS,
 
7511
            NULL, (xmlNodePtr) attr,
 
7512
            xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
 
7513
            "The value of the attribute must not match 'xmlns'",
 
7514
            NULL, NULL);
 
7515
        return (NULL);
 
7516
    }
 
7517
    /*
 
7518
    * 3.2.6 Schema Component Constraint: xsi: Not Allowed
 
7519
    * TODO: Move this to the component layer.
 
7520
    *       Or better leave it here and add it to the component layer
 
7521
    *       if we have a schema construction API.
 
7522
    */
 
7523
    if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
 
7524
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
7525
            XML_SCHEMAP_NO_XSI, node, NULL,
 
7526
            "The target namespace must not match '%s'",
 
7527
            xmlSchemaInstanceNs, NULL);
 
7528
    }
 
7529
 
 
7530
    ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
 
7531
        pctxt->targetNamespace, node, 1);
 
7532
    if (ret == NULL)
 
7533
        return (NULL);
 
7534
    ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
 
7535
        
 
7536
    /*
 
7537
    * Check for illegal attributes.
 
7538
    */
 
7539
    attr = node->properties;
 
7540
    while (attr != NULL) {
 
7541
        if (attr->ns == NULL) {
 
7542
            if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 
7543
                (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
 
7544
                (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
 
7545
                (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 
7546
                (!xmlStrEqual(attr->name, BAD_CAST "type")))
 
7547
            {
 
7548
                xmlSchemaPIllegalAttrErr(pctxt,
 
7549
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);              
 
7550
            }
 
7551
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
7552
            xmlSchemaPIllegalAttrErr(pctxt,
 
7553
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
7554
        }
 
7555
        attr = attr->next;
 
7556
    }
 
7557
    xmlSchemaPValAttrQName(pctxt, schema, NULL,
 
7558
        node, "type", &ret->typeNs, &ret->typeName);
 
7559
    
 
7560
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
 
7561
    /*
 
7562
    * Attribute "fixed".
 
7563
    */
 
7564
    ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
 
7565
    if (ret->defValue != NULL)
 
7566
        ret->flags |= XML_SCHEMAS_ATTR_FIXED;
 
7567
    /*
 
7568
    * Attribute "default".
 
7569
    */
 
7570
    attr = xmlSchemaGetPropNode(node, "default");
 
7571
    if (attr != NULL) {
 
7572
        /*
 
7573
        * 3.2.3 : 1
 
7574
        * default and fixed must not both be present.
 
7575
        */
 
7576
        if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
 
7577
            xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
 
7578
                WXS_BASIC_CAST ret, attr, "default", "fixed");
 
7579
        } else
 
7580
            ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
 
7581
    }
 
7582
    /*
 
7583
    * And now for the children...
 
7584
    */
 
7585
    child = node->children;
 
7586
    if (IS_SCHEMA(child, "annotation")) {
 
7587
        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
 
7588
        child = child->next;
 
7589
    }
 
7590
    if (IS_SCHEMA(child, "simpleType")) {
 
7591
        if (ret->typeName != NULL) {
 
7592
            /*
 
7593
            * 3.2.3 : 4
 
7594
            * type and <simpleType> must not both be present.
 
7595
            */
 
7596
            xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
 
7597
                NULL, node, child,
 
7598
                "The attribute 'type' and the <simpleType> child "
 
7599
                "are mutually exclusive", NULL);
 
7600
        } else
 
7601
            ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
 
7602
        child = child->next;
 
7603
    }
 
7604
    if (child != NULL)
 
7605
        xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
7606
            NULL, node, child, NULL,
 
7607
            "(annotation?, simpleType?)");
 
7608
 
 
7609
    return (ret);
 
7610
}
 
7611
 
 
7612
/**
 
7613
 * xmlSchemaParseAttributeGroupRef:
 
7614
 * @ctxt:  a schema validation context
 
7615
 * @schema:  the schema being built
 
7616
 * @node:  a subtree containing XML Schema informations
 
7617
 *
 
7618
 * Parse an attribute group definition reference.
 
7619
 * Note that a reference to an attribute group does not
 
7620
 * correspond to any component at all.
 
7621
 * *WARNING* this interface is highly subject to change
 
7622
 *
 
7623
 * Returns the attribute group or NULL in case of error.
 
7624
 */
 
7625
static xmlSchemaQNameRefPtr
 
7626
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
 
7627
                                xmlSchemaPtr schema,
 
7628
                                xmlNodePtr node)
 
7629
{
 
7630
    xmlSchemaQNameRefPtr ret;
 
7631
    xmlNodePtr child = NULL;
 
7632
    xmlAttrPtr attr;
 
7633
    const xmlChar *refNs = NULL, *ref = NULL;
 
7634
 
 
7635
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 
7636
        return (NULL);
 
7637
 
 
7638
    attr = xmlSchemaGetPropNode(node, "ref");
 
7639
    if (attr == NULL) {
 
7640
        xmlSchemaPMissingAttrErr(pctxt,
 
7641
            XML_SCHEMAP_S4S_ATTR_MISSING,
 
7642
            NULL, node, "ref", NULL);
 
7643
        return (NULL);
 
7644
    }   
 
7645
    xmlSchemaPValAttrNodeQName(pctxt, schema,
 
7646
        NULL, attr, &refNs, &ref);
 
7647
    if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
 
7648
        return(NULL);
 
7649
   
 
7650
    /*
 
7651
    * Check for illegal attributes.
 
7652
    */
 
7653
    attr = node->properties;
 
7654
    while (attr != NULL) {
 
7655
        if (attr->ns == NULL) {
 
7656
            if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
 
7657
                (!xmlStrEqual(attr->name, BAD_CAST "id")))
 
7658
            {
 
7659
                xmlSchemaPIllegalAttrErr(pctxt,
 
7660
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
7661
            }
 
7662
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
7663
            xmlSchemaPIllegalAttrErr(pctxt,
 
7664
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
7665
        }
 
7666
        attr = attr->next;
 
7667
    }
 
7668
    /* Attribute ID */
 
7669
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
 
7670
 
 
7671
    /*
 
7672
    * And now for the children...
 
7673
    */
 
7674
    child = node->children;
 
7675
    if (IS_SCHEMA(child, "annotation")) {
 
7676
        /*
 
7677
        * TODO: We do not have a place to store the annotation, do we?
 
7678
        */
 
7679
        xmlSchemaParseAnnotation(pctxt, child, 0);
 
7680
        child = child->next;
 
7681
    }
 
7682
    if (child != NULL) {
 
7683
        xmlSchemaPContentErr(pctxt,
 
7684
            XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
7685
            NULL, node, child, NULL,
 
7686
            "(annotation?)");
 
7687
    }
 
7688
 
 
7689
    /*
 
7690
    * Handle attribute group redefinitions.
 
7691
    */
 
7692
    if (pctxt->isRedefine && pctxt->redef &&
 
7693
        (pctxt->redef->item->type ==
 
7694
            XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
 
7695
        (ref == pctxt->redef->refName) &&
 
7696
        (refNs == pctxt->redef->refTargetNs))
 
7697
    {
 
7698
        /*
 
7699
        * SPEC src-redefine:
 
7700
        * (7.1) "If it has an <attributeGroup> among its contents
 
7701
        * the ļæ½actual valueļæ½ of whose ref [attribute] is the same
 
7702
        * as the ļæ½actual valueļæ½ of its own name attribute plus
 
7703
        * target namespace, then it must have exactly one such group."
 
7704
        */
 
7705
        if (pctxt->redefCounter != 0) {
 
7706
            xmlChar *str = NULL;
 
7707
            
 
7708
            xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
7709
                XML_SCHEMAP_SRC_REDEFINE, node, NULL,
 
7710
                "The redefining attribute group definition "
 
7711
                "'%s' must not contain more than one "
 
7712
                "reference to the redefined definition",
 
7713
                xmlSchemaFormatQName(&str, refNs, ref), NULL);
 
7714
            FREE_AND_NULL(str);
 
7715
            return(NULL);
 
7716
        }
 
7717
        pctxt->redefCounter++;
 
7718
        /*
 
7719
        * URGENT TODO: How to ensure that the reference will not be
 
7720
        * handled by the normal component resolution mechanism?
 
7721
        */
 
7722
        ret = xmlSchemaNewQNameRef(pctxt,
 
7723
            XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
 
7724
        if (ret == NULL)
 
7725
            return(NULL);
 
7726
        ret->node = node;
 
7727
        pctxt->redef->reference = WXS_BASIC_CAST ret;
 
7728
    } else {
 
7729
        /*
 
7730
        * Create a QName-reference helper component. We will substitute this
 
7731
        * component for the attribute uses of the referenced attribute group
 
7732
        * definition.
 
7733
        */
 
7734
        ret = xmlSchemaNewQNameRef(pctxt,
 
7735
            XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
 
7736
        if (ret == NULL)
 
7737
            return(NULL);
 
7738
        ret->node = node;
 
7739
        /* Add to pending items, to be able to resolve the reference. */
 
7740
        WXS_ADD_PENDING(pctxt, ret);
 
7741
    }    
 
7742
    return (ret);
 
7743
}
 
7744
 
 
7745
/**
 
7746
 * xmlSchemaParseAttributeGroupDefinition:
 
7747
 * @pctxt:  a schema validation context
 
7748
 * @schema:  the schema being built
 
7749
 * @node:  a subtree containing XML Schema informations
 
7750
 *
 
7751
 * parse a XML schema Attribute Group declaration
 
7752
 * *WARNING* this interface is highly subject to change
 
7753
 *
 
7754
 * Returns the attribute group definition or NULL in case of error.
 
7755
 */
 
7756
static xmlSchemaAttributeGroupPtr
 
7757
xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
 
7758
                                       xmlSchemaPtr schema,
 
7759
                                       xmlNodePtr node)
 
7760
{
 
7761
    const xmlChar *name;
 
7762
    xmlSchemaAttributeGroupPtr ret;
 
7763
    xmlNodePtr child = NULL;
 
7764
    xmlAttrPtr attr;
 
7765
    int hasRefs = 0;
 
7766
 
 
7767
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 
7768
        return (NULL);
 
7769
 
 
7770
    attr = xmlSchemaGetPropNode(node, "name");
 
7771
    if (attr == NULL) {
 
7772
        xmlSchemaPMissingAttrErr(pctxt,
 
7773
            XML_SCHEMAP_S4S_ATTR_MISSING,
 
7774
            NULL, node, "name", NULL);
 
7775
        return (NULL);
 
7776
    }
 
7777
    /*
 
7778
    * The name is crucial, exit if invalid.
 
7779
    */
 
7780
    if (xmlSchemaPValAttrNode(pctxt,
 
7781
        NULL, attr,
 
7782
        xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
 
7783
        return (NULL);
 
7784
    }
 
7785
    ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
 
7786
        name, pctxt->targetNamespace, node);
 
7787
    if (ret == NULL)
 
7788
        return (NULL);  
 
7789
    /*
 
7790
    * Check for illegal attributes.
 
7791
    */
 
7792
    attr = node->properties;
 
7793
    while (attr != NULL) {
 
7794
        if (attr->ns == NULL) {
 
7795
            if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 
7796
                (!xmlStrEqual(attr->name, BAD_CAST "id")))
 
7797
            {
 
7798
                xmlSchemaPIllegalAttrErr(pctxt,
 
7799
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
7800
            }
 
7801
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
7802
            xmlSchemaPIllegalAttrErr(pctxt,
 
7803
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
7804
        }
 
7805
        attr = attr->next;
 
7806
    }
 
7807
    /* Attribute ID */
 
7808
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
 
7809
    /*
 
7810
    * And now for the children...
 
7811
    */
 
7812
    child = node->children;
 
7813
    if (IS_SCHEMA(child, "annotation")) {
 
7814
        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
 
7815
        child = child->next;
 
7816
    }
 
7817
    /*
 
7818
    * Parse contained attribute decls/refs.
 
7819
    */
 
7820
    if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
 
7821
        (xmlSchemaItemListPtr *) &(ret->attrUses),
 
7822
        XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
 
7823
        return(NULL);
 
7824
    if (hasRefs)
 
7825
        ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
 
7826
    /*
 
7827
    * Parse the attribute wildcard.
 
7828
    */
 
7829
    if (IS_SCHEMA(child, "anyAttribute")) {
 
7830
        ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
 
7831
            schema, child);
 
7832
        child = child->next;
 
7833
    }
 
7834
    if (child != NULL) {
 
7835
        xmlSchemaPContentErr(pctxt,
 
7836
            XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
7837
            NULL, node, child, NULL,
 
7838
            "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
 
7839
    }
 
7840
    return (ret);
 
7841
}
 
7842
 
 
7843
/**
 
7844
 * xmlSchemaPValAttrFormDefault:
 
7845
 * @value:  the value
 
7846
 * @flags: the flags to be modified
 
7847
 * @flagQualified: the specific flag for "qualified"
 
7848
 *
 
7849
 * Returns 0 if the value is valid, 1 otherwise.
 
7850
 */
 
7851
static int
 
7852
xmlSchemaPValAttrFormDefault(const xmlChar *value,
 
7853
                             int *flags,
 
7854
                             int flagQualified)
 
7855
{
 
7856
    if (xmlStrEqual(value, BAD_CAST "qualified")) {
 
7857
        if  ((*flags & flagQualified) == 0)
 
7858
            *flags |= flagQualified;
 
7859
    } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
 
7860
        return (1);
 
7861
 
 
7862
    return (0);
 
7863
}
 
7864
 
 
7865
/**
 
7866
 * xmlSchemaPValAttrBlockFinal:
 
7867
 * @value:  the value
 
7868
 * @flags: the flags to be modified
 
7869
 * @flagAll: the specific flag for "#all"
 
7870
 * @flagExtension: the specific flag for "extension"
 
7871
 * @flagRestriction: the specific flag for "restriction"
 
7872
 * @flagSubstitution: the specific flag for "substitution"
 
7873
 * @flagList: the specific flag for "list"
 
7874
 * @flagUnion: the specific flag for "union"
 
7875
 *
 
7876
 * Validates the value of the attribute "final" and "block". The value
 
7877
 * is converted into the specified flag values and returned in @flags.
 
7878
 *
 
7879
 * Returns 0 if the value is valid, 1 otherwise.
 
7880
 */
 
7881
 
 
7882
static int
 
7883
xmlSchemaPValAttrBlockFinal(const xmlChar *value,
 
7884
                            int *flags,
 
7885
                            int flagAll,
 
7886
                            int flagExtension,
 
7887
                            int flagRestriction,
 
7888
                            int flagSubstitution,
 
7889
                            int flagList,
 
7890
                            int flagUnion)
 
7891
{
 
7892
    int ret = 0;
 
7893
 
 
7894
    /*
 
7895
    * TODO: This does not check for dublicate entries.
 
7896
    */
 
7897
    if ((flags == NULL) || (value == NULL))
 
7898
        return (-1);
 
7899
    if (value[0] == 0)
 
7900
        return (0);
 
7901
    if (xmlStrEqual(value, BAD_CAST "#all")) {
 
7902
        if (flagAll != -1)
 
7903
            *flags |= flagAll;
 
7904
        else {
 
7905
            if (flagExtension != -1)
 
7906
                *flags |= flagExtension;
 
7907
            if (flagRestriction != -1)
 
7908
                *flags |= flagRestriction;
 
7909
            if (flagSubstitution != -1)
 
7910
                *flags |= flagSubstitution;
 
7911
            if (flagList != -1)
 
7912
                *flags |= flagList;
 
7913
            if (flagUnion != -1)
 
7914
                *flags |= flagUnion;
 
7915
        }
 
7916
    } else {
 
7917
        const xmlChar *end, *cur = value;
 
7918
        xmlChar *item;
 
7919
 
 
7920
        do {
 
7921
            while (IS_BLANK_CH(*cur))
 
7922
                cur++;
 
7923
            end = cur;
 
7924
            while ((*end != 0) && (!(IS_BLANK_CH(*end))))
 
7925
                end++;
 
7926
            if (end == cur)
 
7927
                break;
 
7928
            item = xmlStrndup(cur, end - cur);
 
7929
            if (xmlStrEqual(item, BAD_CAST "extension")) {
 
7930
                if (flagExtension != -1) {
 
7931
                    if ((*flags & flagExtension) == 0)
 
7932
                        *flags |= flagExtension;
 
7933
                } else
 
7934
                    ret = 1;
 
7935
            } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
 
7936
                if (flagRestriction != -1) {
 
7937
                    if ((*flags & flagRestriction) == 0)
 
7938
                        *flags |= flagRestriction;
 
7939
                } else
 
7940
                    ret = 1;
 
7941
            } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
 
7942
                if (flagSubstitution != -1) {
 
7943
                    if ((*flags & flagSubstitution) == 0)
 
7944
                        *flags |= flagSubstitution;
 
7945
                } else
 
7946
                    ret = 1;
 
7947
            } else if (xmlStrEqual(item, BAD_CAST "list")) {
 
7948
                if (flagList != -1) {
 
7949
                    if ((*flags & flagList) == 0)
 
7950
                        *flags |= flagList;
 
7951
                } else
 
7952
                    ret = 1;
 
7953
            } else if (xmlStrEqual(item, BAD_CAST "union")) {
 
7954
                if (flagUnion != -1) {
 
7955
                    if ((*flags & flagUnion) == 0)
 
7956
                        *flags |= flagUnion;
 
7957
                } else
 
7958
                    ret = 1;
 
7959
            } else
 
7960
                ret = 1;
 
7961
            if (item != NULL)
 
7962
                xmlFree(item);
 
7963
            cur = end;
 
7964
        } while ((ret == 0) && (*cur != 0));
 
7965
    }
 
7966
 
 
7967
    return (ret);
 
7968
}
 
7969
 
 
7970
static int
 
7971
xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
 
7972
                             xmlSchemaIDCPtr idc,
 
7973
                             xmlSchemaIDCSelectPtr selector,
 
7974
                             xmlAttrPtr attr,
 
7975
                             int isField)
 
7976
{
 
7977
    xmlNodePtr node;
 
7978
 
 
7979
    /*
 
7980
    * c-selector-xpath:
 
7981
    * Schema Component Constraint: Selector Value OK
 
7982
    *
 
7983
    * TODO: 1 The {selector} must be a valid XPath expression, as defined
 
7984
    * in [XPath].
 
7985
    */
 
7986
    if (selector == NULL) {
 
7987
        xmlSchemaPErr(ctxt, idc->node,
 
7988
            XML_SCHEMAP_INTERNAL,
 
7989
            "Internal error: xmlSchemaCheckCSelectorXPath, "
 
7990
            "the selector is not specified.\n", NULL, NULL);
 
7991
        return (-1);
 
7992
    }
 
7993
    if (attr == NULL)
 
7994
        node = idc->node;
 
7995
    else
 
7996
        node = (xmlNodePtr) attr;
 
7997
    if (selector->xpath == NULL) {
 
7998
        xmlSchemaPCustomErr(ctxt,
 
7999
            /* TODO: Adjust error code. */
 
8000
            XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
8001
            NULL, node,
 
8002
            "The XPath expression of the selector is not valid", NULL);
 
8003
        return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
 
8004
    } else {
 
8005
        const xmlChar **nsArray = NULL;
 
8006
        xmlNsPtr *nsList = NULL;
 
8007
        /*
 
8008
        * Compile the XPath expression.
 
8009
        */
 
8010
        /*
 
8011
        * TODO: We need the array of in-scope namespaces for compilation.
 
8012
        * TODO: Call xmlPatterncompile with different options for selector/
 
8013
        * field.
 
8014
        */
 
8015
        if (attr == NULL)
 
8016
            nsList = NULL;
 
8017
        else
 
8018
            nsList = xmlGetNsList(attr->doc, attr->parent);
 
8019
        /*
 
8020
        * Build an array of prefixes and namespaces.
 
8021
        */
 
8022
        if (nsList != NULL) {
 
8023
            int i, count = 0;
 
8024
 
 
8025
            for (i = 0; nsList[i] != NULL; i++)
 
8026
                count++;
 
8027
 
 
8028
            nsArray = (const xmlChar **) xmlMalloc(
 
8029
                (count * 2 + 1) * sizeof(const xmlChar *));
 
8030
            if (nsArray == NULL) {
 
8031
                xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
 
8032
                    NULL);
 
8033
                xmlFree(nsList);
 
8034
                return (-1);
 
8035
            }
 
8036
            for (i = 0; i < count; i++) {
 
8037
                nsArray[2 * i] = nsList[i]->href;
 
8038
                nsArray[2 * i + 1] = nsList[i]->prefix;
 
8039
            }
 
8040
            nsArray[count * 2] = NULL;
 
8041
            xmlFree(nsList);
 
8042
        }
 
8043
        /*
 
8044
        * TODO: Differentiate between "selector" and "field".
 
8045
        */
 
8046
        if (isField)
 
8047
            selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
 
8048
                NULL, XML_PATTERN_XSFIELD, nsArray);
 
8049
        else
 
8050
            selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
 
8051
                NULL, XML_PATTERN_XSSEL, nsArray);
 
8052
        if (nsArray != NULL)
 
8053
            xmlFree((xmlChar **) nsArray);
 
8054
 
 
8055
        if (selector->xpathComp == NULL) {
 
8056
            xmlSchemaPCustomErr(ctxt,
 
8057
                /* TODO: Adjust error code? */
 
8058
                XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
8059
                NULL, node,
 
8060
                "The XPath expression '%s' could not be "
 
8061
                "compiled", selector->xpath);
 
8062
            return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
 
8063
        }
 
8064
    }
 
8065
    return (0);
 
8066
}
 
8067
 
 
8068
#define ADD_ANNOTATION(annot)   \
 
8069
    xmlSchemaAnnotPtr cur = item->annot; \
 
8070
    if (item->annot == NULL) {  \
 
8071
        item->annot = annot;    \
 
8072
        return (annot);         \
 
8073
    }                           \
 
8074
    cur = item->annot;          \
 
8075
    if (cur->next != NULL) {    \
 
8076
        cur = cur->next;        \
 
8077
    }                           \
 
8078
    cur->next = annot;
 
8079
 
 
8080
/**
 
8081
 * xmlSchemaAssignAnnotation:
 
8082
 * @item: the schema component
 
8083
 * @annot: the annotation
 
8084
 *
 
8085
 * Adds the annotation to the given schema component.
 
8086
 *
 
8087
 * Returns the given annotaion.
 
8088
 */
 
8089
static xmlSchemaAnnotPtr
 
8090
xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
 
8091
                       xmlSchemaAnnotPtr annot)
 
8092
{
 
8093
    if ((annItem == NULL) || (annot == NULL))
 
8094
        return (NULL);
 
8095
    switch (annItem->type) {
 
8096
        case XML_SCHEMA_TYPE_ELEMENT: {
 
8097
                xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
 
8098
                ADD_ANNOTATION(annot)
 
8099
            }
 
8100
            break;
 
8101
        case XML_SCHEMA_TYPE_ATTRIBUTE: {
 
8102
                xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
 
8103
                ADD_ANNOTATION(annot)
 
8104
            }
 
8105
            break;
 
8106
        case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 
8107
        case XML_SCHEMA_TYPE_ANY: {
 
8108
                xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
 
8109
                ADD_ANNOTATION(annot)
 
8110
            }
 
8111
            break;
 
8112
        case XML_SCHEMA_TYPE_PARTICLE:
 
8113
        case XML_SCHEMA_TYPE_IDC_KEY:
 
8114
        case XML_SCHEMA_TYPE_IDC_KEYREF:
 
8115
        case XML_SCHEMA_TYPE_IDC_UNIQUE: {
 
8116
                xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
 
8117
                ADD_ANNOTATION(annot)
 
8118
            }
 
8119
            break;
 
8120
        case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
 
8121
                xmlSchemaAttributeGroupPtr item =
 
8122
                    (xmlSchemaAttributeGroupPtr) annItem;
 
8123
                ADD_ANNOTATION(annot)
 
8124
            }
 
8125
            break;
 
8126
        case XML_SCHEMA_TYPE_NOTATION: {
 
8127
                xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
 
8128
                ADD_ANNOTATION(annot)
 
8129
            }
 
8130
            break;
 
8131
        case XML_SCHEMA_FACET_MININCLUSIVE:
 
8132
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
 
8133
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
 
8134
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
 
8135
        case XML_SCHEMA_FACET_TOTALDIGITS:
 
8136
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
 
8137
        case XML_SCHEMA_FACET_PATTERN:
 
8138
        case XML_SCHEMA_FACET_ENUMERATION:
 
8139
        case XML_SCHEMA_FACET_WHITESPACE:
 
8140
        case XML_SCHEMA_FACET_LENGTH:
 
8141
        case XML_SCHEMA_FACET_MAXLENGTH:
 
8142
        case XML_SCHEMA_FACET_MINLENGTH: {
 
8143
                xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
 
8144
                ADD_ANNOTATION(annot)
 
8145
            }
 
8146
            break;
 
8147
        case XML_SCHEMA_TYPE_SIMPLE:
 
8148
        case XML_SCHEMA_TYPE_COMPLEX: {
 
8149
                xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
 
8150
                ADD_ANNOTATION(annot)
 
8151
            }
 
8152
            break;
 
8153
        case XML_SCHEMA_TYPE_GROUP: {
 
8154
                xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
 
8155
                ADD_ANNOTATION(annot)
 
8156
            }
 
8157
            break;
 
8158
        case XML_SCHEMA_TYPE_SEQUENCE:
 
8159
        case XML_SCHEMA_TYPE_CHOICE:
 
8160
        case XML_SCHEMA_TYPE_ALL: {
 
8161
                xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
 
8162
                ADD_ANNOTATION(annot)
 
8163
            }
 
8164
            break;
 
8165
        default:
 
8166
             xmlSchemaPCustomErr(NULL,
 
8167
                XML_SCHEMAP_INTERNAL,
 
8168
                NULL, NULL,
 
8169
                "Internal error: xmlSchemaAddAnnotation, "
 
8170
                "The item is not a annotated schema component", NULL);
 
8171
             break;
 
8172
    }
 
8173
    return (annot);
 
8174
}
 
8175
 
 
8176
/**
 
8177
 * xmlSchemaParseIDCSelectorAndField:
 
8178
 * @ctxt:  a schema validation context
 
8179
 * @schema:  the schema being built
 
8180
 * @node:  a subtree containing XML Schema informations
 
8181
 *
 
8182
 * Parses a XML Schema identity-contraint definition's
 
8183
 * <selector> and <field> elements.
 
8184
 *
 
8185
 * Returns the parsed identity-constraint definition.
 
8186
 */
 
8187
static xmlSchemaIDCSelectPtr
 
8188
xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,                    
 
8189
                          xmlSchemaIDCPtr idc,
 
8190
                          xmlNodePtr node,
 
8191
                          int isField)
 
8192
{
 
8193
    xmlSchemaIDCSelectPtr item;
 
8194
    xmlNodePtr child = NULL;
 
8195
    xmlAttrPtr attr;
 
8196
 
 
8197
    /*
 
8198
    * Check for illegal attributes.
 
8199
    */
 
8200
    attr = node->properties;
 
8201
    while (attr != NULL) {
 
8202
        if (attr->ns == NULL) {
 
8203
            if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 
8204
                (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
 
8205
                xmlSchemaPIllegalAttrErr(ctxt,
 
8206
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
8207
            }
 
8208
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
8209
            xmlSchemaPIllegalAttrErr(ctxt,
 
8210
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
8211
        }
 
8212
        attr = attr->next;
 
8213
    }
 
8214
    /*
 
8215
    * Create the item.
 
8216
    */
 
8217
    item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
 
8218
    if (item == NULL) {
 
8219
        xmlSchemaPErrMemory(ctxt,
 
8220
            "allocating a 'selector' of an identity-constraint definition",
 
8221
            NULL);
 
8222
        return (NULL);
 
8223
    }
 
8224
    memset(item, 0, sizeof(xmlSchemaIDCSelect));
 
8225
    /*
 
8226
    * Attribute "xpath" (mandatory).
 
8227
    */
 
8228
    attr = xmlSchemaGetPropNode(node, "xpath");
 
8229
    if (attr == NULL) {
 
8230
        xmlSchemaPMissingAttrErr(ctxt,
 
8231
            XML_SCHEMAP_S4S_ATTR_MISSING,
 
8232
            NULL, node,
 
8233
            "name", NULL);
 
8234
    } else {
 
8235
        item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 
8236
        /*
 
8237
        * URGENT TODO: "field"s have an other syntax than "selector"s.
 
8238
        */
 
8239
 
 
8240
        if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
 
8241
            isField) == -1) {
 
8242
            xmlSchemaPErr(ctxt,
 
8243
                (xmlNodePtr) attr,
 
8244
                XML_SCHEMAP_INTERNAL,
 
8245
                "Internal error: xmlSchemaParseIDCSelectorAndField, "
 
8246
                "validating the XPath expression of a IDC selector.\n",
 
8247
                NULL, NULL);
 
8248
        }
 
8249
 
 
8250
    }
 
8251
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
8252
    /*
 
8253
    * And now for the children...
 
8254
    */
 
8255
    child = node->children;
 
8256
    if (IS_SCHEMA(child, "annotation")) {
 
8257
        /*
 
8258
        * Add the annotation to the parent IDC.
 
8259
        */
 
8260
        xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
 
8261
            xmlSchemaParseAnnotation(ctxt, child, 1));
 
8262
        child = child->next;
 
8263
    }
 
8264
    if (child != NULL) {
 
8265
        xmlSchemaPContentErr(ctxt,
 
8266
            XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
8267
            NULL, node, child,
 
8268
            NULL, "(annotation?)");
 
8269
    }
 
8270
 
 
8271
    return (item);
 
8272
}
 
8273
 
 
8274
/**
 
8275
 * xmlSchemaParseIDC:
 
8276
 * @ctxt:  a schema validation context
 
8277
 * @schema:  the schema being built
 
8278
 * @node:  a subtree containing XML Schema informations
 
8279
 *
 
8280
 * Parses a XML Schema identity-contraint definition.
 
8281
 *
 
8282
 * Returns the parsed identity-constraint definition.
 
8283
 */
 
8284
static xmlSchemaIDCPtr
 
8285
xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
 
8286
                  xmlSchemaPtr schema,
 
8287
                  xmlNodePtr node,
 
8288
                  xmlSchemaTypeType idcCategory,
 
8289
                  const xmlChar *targetNamespace)
 
8290
{
 
8291
    xmlSchemaIDCPtr item = NULL;
 
8292
    xmlNodePtr child = NULL;
 
8293
    xmlAttrPtr attr;
 
8294
    const xmlChar *name = NULL;
 
8295
    xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
 
8296
 
 
8297
    /*
 
8298
    * Check for illegal attributes.
 
8299
    */
 
8300
    attr = node->properties;
 
8301
    while (attr != NULL) {
 
8302
        if (attr->ns == NULL) {
 
8303
            if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 
8304
                (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 
8305
                ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
 
8306
                 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
 
8307
                xmlSchemaPIllegalAttrErr(ctxt,
 
8308
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
8309
            }
 
8310
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
8311
            xmlSchemaPIllegalAttrErr(ctxt,
 
8312
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
8313
        }
 
8314
        attr = attr->next;
 
8315
    }
 
8316
    /*
 
8317
    * Attribute "name" (mandatory).
 
8318
    */
 
8319
    attr = xmlSchemaGetPropNode(node, "name");
 
8320
    if (attr == NULL) {
 
8321
        xmlSchemaPMissingAttrErr(ctxt,
 
8322
            XML_SCHEMAP_S4S_ATTR_MISSING,
 
8323
            NULL, node,
 
8324
            "name", NULL);
 
8325
        return (NULL);
 
8326
    } else if (xmlSchemaPValAttrNode(ctxt,
 
8327
        NULL, attr,
 
8328
        xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
 
8329
        return (NULL);
 
8330
    }
 
8331
    /* Create the component. */
 
8332
    item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
 
8333
        idcCategory, node);
 
8334
    if (item == NULL)
 
8335
        return(NULL);
 
8336
 
 
8337
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
8338
    if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
 
8339
        /*
 
8340
        * Attribute "refer" (mandatory).
 
8341
        */
 
8342
        attr = xmlSchemaGetPropNode(node, "refer");
 
8343
        if (attr == NULL) {
 
8344
            xmlSchemaPMissingAttrErr(ctxt,
 
8345
                XML_SCHEMAP_S4S_ATTR_MISSING,
 
8346
                NULL, node,
 
8347
                "refer", NULL);
 
8348
        } else {
 
8349
            /*
 
8350
            * Create a reference item.
 
8351
            */
 
8352
            item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
 
8353
                NULL, NULL);
 
8354
            if (item->ref == NULL)
 
8355
                return (NULL);
 
8356
            xmlSchemaPValAttrNodeQName(ctxt, schema,
 
8357
                NULL, attr,
 
8358
                &(item->ref->targetNamespace),
 
8359
                &(item->ref->name));
 
8360
            xmlSchemaCheckReference(ctxt, schema, node, attr,
 
8361
                item->ref->targetNamespace);
 
8362
        }
 
8363
    }
 
8364
    /*
 
8365
    * And now for the children...
 
8366
    */
 
8367
    child = node->children;
 
8368
    if (IS_SCHEMA(child, "annotation")) {
 
8369
        item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 
8370
        child = child->next;
 
8371
    }
 
8372
    if (child == NULL) {
 
8373
        xmlSchemaPContentErr(ctxt,
 
8374
                XML_SCHEMAP_S4S_ELEM_MISSING,
 
8375
                NULL, node, child,
 
8376
                "A child element is missing",
 
8377
                "(annotation?, (selector, field+))");
 
8378
    }
 
8379
    /*
 
8380
    * Child element <selector>.
 
8381
    */
 
8382
    if (IS_SCHEMA(child, "selector")) {
 
8383
        item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
 
8384
            item, child, 0);
 
8385
        child = child->next;
 
8386
        /*
 
8387
        * Child elements <field>.
 
8388
        */
 
8389
        if (IS_SCHEMA(child, "field")) {
 
8390
            do {
 
8391
                field = xmlSchemaParseIDCSelectorAndField(ctxt,
 
8392
                    item, child, 1);
 
8393
                if (field != NULL) {
 
8394
                    field->index = item->nbFields;
 
8395
                    item->nbFields++;
 
8396
                    if (lastField != NULL)
 
8397
                        lastField->next = field;
 
8398
                    else
 
8399
                        item->fields = field;
 
8400
                    lastField = field;
 
8401
                }
 
8402
                child = child->next;
 
8403
            } while (IS_SCHEMA(child, "field"));
 
8404
        } else {
 
8405
            xmlSchemaPContentErr(ctxt,
 
8406
                XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
8407
                NULL, node, child,
 
8408
                NULL, "(annotation?, (selector, field+))");
 
8409
        }
 
8410
    }
 
8411
    if (child != NULL) {
 
8412
        xmlSchemaPContentErr(ctxt,
 
8413
            XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
8414
            NULL, node, child,
 
8415
            NULL, "(annotation?, (selector, field+))");
 
8416
    }
 
8417
 
 
8418
    return (item);
 
8419
}
 
8420
 
 
8421
/**
 
8422
 * xmlSchemaParseElement:
 
8423
 * @ctxt:  a schema validation context
 
8424
 * @schema:  the schema being built
 
8425
 * @node:  a subtree containing XML Schema informations
 
8426
 * @topLevel: indicates if this is global declaration
 
8427
 *
 
8428
 * Parses a XML schema element declaration.
 
8429
 * *WARNING* this interface is highly subject to change
 
8430
 *
 
8431
 * Returns the element declaration or a particle; NULL in case
 
8432
 * of an error or if the particle has minOccurs==maxOccurs==0.
 
8433
 */
 
8434
static xmlSchemaBasicItemPtr
 
8435
xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
8436
                      xmlNodePtr node, int *isElemRef, int topLevel)
 
8437
{
 
8438
    xmlSchemaElementPtr decl = NULL;
 
8439
    xmlSchemaParticlePtr particle = NULL;
 
8440
    xmlSchemaAnnotPtr annot = NULL;
 
8441
    xmlNodePtr child = NULL;
 
8442
    xmlAttrPtr attr, nameAttr;
 
8443
    int min, max, isRef = 0;
 
8444
    xmlChar *des = NULL;
 
8445
 
 
8446
    /* 3.3.3 Constraints on XML Representations of Element Declarations */
 
8447
    /* TODO: Complete implementation of 3.3.6 */
 
8448
 
 
8449
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 
8450
        return (NULL);
 
8451
 
 
8452
    if (isElemRef != NULL)
 
8453
        *isElemRef = 0;
 
8454
    /*
 
8455
    * If we get a "ref" attribute on a local <element> we will assume it's
 
8456
    * a reference - even if there's a "name" attribute; this seems to be more
 
8457
    * robust.
 
8458
    */
 
8459
    nameAttr = xmlSchemaGetPropNode(node, "name");
 
8460
    attr = xmlSchemaGetPropNode(node, "ref");
 
8461
    if ((topLevel) || (attr == NULL)) {
 
8462
        if (nameAttr == NULL) {
 
8463
            xmlSchemaPMissingAttrErr(ctxt,
 
8464
                XML_SCHEMAP_S4S_ATTR_MISSING,
 
8465
                NULL, node, "name", NULL);
 
8466
            return (NULL);
 
8467
        }
 
8468
    } else
 
8469
        isRef = 1;
 
8470
 
 
8471
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
8472
    child = node->children;
 
8473
    if (IS_SCHEMA(child, "annotation")) {
 
8474
        annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 
8475
        child = child->next;
 
8476
    }
 
8477
    /*
 
8478
    * Skip particle part if a global declaration.
 
8479
    */
 
8480
    if (topLevel)
 
8481
        goto declaration_part;
 
8482
    /*
 
8483
    * The particle part ==================================================
 
8484
    */
 
8485
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
 
8486
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
 
8487
    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
 
8488
    particle = xmlSchemaAddParticle(ctxt, node, min, max);
 
8489
    if (particle == NULL)
 
8490
        goto return_null;
 
8491
 
 
8492
    /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
 
8493
 
 
8494
    if (isRef) {
 
8495
        const xmlChar *refNs = NULL, *ref = NULL;
 
8496
        xmlSchemaQNameRefPtr refer = NULL;
 
8497
        /*
 
8498
        * The reference part =============================================
 
8499
        */
 
8500
        if (isElemRef != NULL)
 
8501
            *isElemRef = 1;
 
8502
 
 
8503
        xmlSchemaPValAttrNodeQName(ctxt, schema,
 
8504
            NULL, attr, &refNs, &ref);
 
8505
        xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
 
8506
        /*
 
8507
        * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
 
8508
        */
 
8509
        if (nameAttr != NULL) {
 
8510
            xmlSchemaPMutualExclAttrErr(ctxt,
 
8511
                XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
 
8512
        }
 
8513
        /*
 
8514
        * Check for illegal attributes.
 
8515
        */
 
8516
        attr = node->properties;
 
8517
        while (attr != NULL) {
 
8518
            if (attr->ns == NULL) {
 
8519
                if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
 
8520
                    xmlStrEqual(attr->name, BAD_CAST "name") ||
 
8521
                    xmlStrEqual(attr->name, BAD_CAST "id") ||
 
8522
                    xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
 
8523
                    xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
 
8524
                {
 
8525
                    attr = attr->next;
 
8526
                    continue;
 
8527
                } else {
 
8528
                    /* SPEC (3.3.3 : 2.2) */
 
8529
                    xmlSchemaPCustomAttrErr(ctxt,
 
8530
                        XML_SCHEMAP_SRC_ELEMENT_2_2,
 
8531
                        NULL, NULL, attr,
 
8532
                        "Only the attributes 'minOccurs', 'maxOccurs' and "
 
8533
                        "'id' are allowed in addition to 'ref'");
 
8534
                    break;
 
8535
                }
 
8536
            } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
8537
                xmlSchemaPIllegalAttrErr(ctxt,
 
8538
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
8539
            }
 
8540
            attr = attr->next;
 
8541
        }
 
8542
        /*
 
8543
        * No children except <annotation> expected.
 
8544
        */
 
8545
        if (child != NULL) {
 
8546
            xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
8547
                NULL, node, child, NULL, "(annotation?)");
 
8548
        }
 
8549
        if ((min == 0) && (max == 0))
 
8550
            goto return_null;
 
8551
        /*
 
8552
        * Create the reference item and attach it to the particle.
 
8553
        */
 
8554
        refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
 
8555
            ref, refNs);
 
8556
        if (refer == NULL)
 
8557
            goto return_null;
 
8558
        particle->children = (xmlSchemaTreeItemPtr) refer;
 
8559
        particle->annot = annot;
 
8560
        /*
 
8561
        * Add the particle to pending components, since the reference
 
8562
        * need to be resolved.
 
8563
        */
 
8564
        WXS_ADD_PENDING(ctxt, particle);
 
8565
        return ((xmlSchemaBasicItemPtr) particle);
 
8566
    }
 
8567
    /*
 
8568
    * The declaration part ===============================================
 
8569
    */
 
8570
declaration_part:
 
8571
    {
 
8572
        const xmlChar *ns = NULL, *fixed, *name, *attrValue;
 
8573
        xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
 
8574
 
 
8575
        if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
 
8576
            xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
 
8577
            goto return_null;
 
8578
        /*
 
8579
        * Evaluate the target namespace.
 
8580
        */
 
8581
        if (topLevel) {
 
8582
            ns = ctxt->targetNamespace;
 
8583
        } else {
 
8584
            attr = xmlSchemaGetPropNode(node, "form");
 
8585
            if (attr != NULL) {
 
8586
                attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 
8587
                if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
 
8588
                    ns = ctxt->targetNamespace;
 
8589
                } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
 
8590
                    xmlSchemaPSimpleTypeErr(ctxt,
 
8591
                        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
8592
                        NULL, (xmlNodePtr) attr,
 
8593
                        NULL, "(qualified | unqualified)",
 
8594
                        attrValue, NULL, NULL, NULL);
 
8595
                }
 
8596
            } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
 
8597
                ns = ctxt->targetNamespace;
 
8598
        }
 
8599
        decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
 
8600
        if (decl == NULL) {
 
8601
            goto return_null;
 
8602
        }
 
8603
        /*
 
8604
        * Check for illegal attributes.
 
8605
        */
 
8606
        attr = node->properties;
 
8607
        while (attr != NULL) {
 
8608
            if (attr->ns == NULL) {
 
8609
                if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 
8610
                    (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
 
8611
                    (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 
8612
                    (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
 
8613
                    (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
 
8614
                    (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
 
8615
                    (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
 
8616
                {
 
8617
                    if (topLevel == 0) {
 
8618
                        if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
 
8619
                            (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
 
8620
                            (!xmlStrEqual(attr->name, BAD_CAST "form")))
 
8621
                        {
 
8622
                            xmlSchemaPIllegalAttrErr(ctxt,
 
8623
                                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
8624
                        }
 
8625
                    } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
 
8626
                        (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
 
8627
                        (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
 
8628
 
 
8629
                        xmlSchemaPIllegalAttrErr(ctxt,
 
8630
                            XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
8631
                    }
 
8632
                }
 
8633
            } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
8634
 
 
8635
                xmlSchemaPIllegalAttrErr(ctxt,
 
8636
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
8637
            }
 
8638
            attr = attr->next;
 
8639
        }
 
8640
        /*
 
8641
        * Extract/validate attributes.
 
8642
        */
 
8643
        if (topLevel) {
 
8644
            /*
 
8645
            * Process top attributes of global element declarations here.
 
8646
            */
 
8647
            decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
 
8648
            decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
 
8649
            xmlSchemaPValAttrQName(ctxt, schema,
 
8650
                NULL, node, "substitutionGroup",
 
8651
                &(decl->substGroupNs), &(decl->substGroup));
 
8652
            if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
 
8653
                decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
 
8654
            /*
 
8655
            * Attribute "final".
 
8656
            */
 
8657
            attr = xmlSchemaGetPropNode(node, "final");
 
8658
            if (attr == NULL) {
 
8659
                if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
 
8660
                    decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
 
8661
                if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
 
8662
                    decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
 
8663
            } else {
 
8664
                attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 
8665
                if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
 
8666
                    -1,
 
8667
                    XML_SCHEMAS_ELEM_FINAL_EXTENSION,
 
8668
                    XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
 
8669
                    xmlSchemaPSimpleTypeErr(ctxt,
 
8670
                        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
8671
                        NULL, (xmlNodePtr) attr,
 
8672
                        NULL, "(#all | List of (extension | restriction))",
 
8673
                        attrValue, NULL, NULL, NULL);
 
8674
                }
 
8675
            }
 
8676
        }
 
8677
        /*
 
8678
        * Attribute "block".
 
8679
        */
 
8680
        attr = xmlSchemaGetPropNode(node, "block");
 
8681
        if (attr == NULL) {
 
8682
            /*
 
8683
            * Apply default "block" values.
 
8684
            */
 
8685
            if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
 
8686
                decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
 
8687
            if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
 
8688
                decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
 
8689
            if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
 
8690
                decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
 
8691
        } else {
 
8692
            attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 
8693
            if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
 
8694
                -1,
 
8695
                XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
 
8696
                XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
 
8697
                XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
 
8698
                xmlSchemaPSimpleTypeErr(ctxt,
 
8699
                    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
8700
                    NULL, (xmlNodePtr) attr,
 
8701
                    NULL, "(#all | List of (extension | "
 
8702
                    "restriction | substitution))", attrValue,
 
8703
                    NULL, NULL, NULL);
 
8704
            }
 
8705
        }
 
8706
        if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
 
8707
            decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
 
8708
 
 
8709
        attr = xmlSchemaGetPropNode(node, "type");
 
8710
        if (attr != NULL) {
 
8711
            xmlSchemaPValAttrNodeQName(ctxt, schema,
 
8712
                NULL, attr,
 
8713
                &(decl->namedTypeNs), &(decl->namedType));
 
8714
            xmlSchemaCheckReference(ctxt, schema, node,
 
8715
                attr, decl->namedTypeNs);
 
8716
        }
 
8717
        decl->value = xmlSchemaGetProp(ctxt, node, "default");
 
8718
        attr = xmlSchemaGetPropNode(node, "fixed");
 
8719
        if (attr != NULL) {
 
8720
            fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 
8721
            if (decl->value != NULL) {
 
8722
                /*
 
8723
                * 3.3.3 : 1
 
8724
                * default and fixed must not both be present.
 
8725
                */
 
8726
                xmlSchemaPMutualExclAttrErr(ctxt,
 
8727
                    XML_SCHEMAP_SRC_ELEMENT_1,
 
8728
                    NULL, attr, "default", "fixed");
 
8729
            } else {
 
8730
                decl->flags |= XML_SCHEMAS_ELEM_FIXED;
 
8731
                decl->value = fixed;
 
8732
            }
 
8733
        }
 
8734
        /*
 
8735
        * And now for the children...
 
8736
        */
 
8737
        if (IS_SCHEMA(child, "complexType")) {
 
8738
            /*
 
8739
            * 3.3.3 : 3
 
8740
            * "type" and either <simpleType> or <complexType> are mutually
 
8741
            * exclusive
 
8742
            */
 
8743
            if (decl->namedType != NULL) {
 
8744
                xmlSchemaPContentErr(ctxt,
 
8745
                    XML_SCHEMAP_SRC_ELEMENT_3,
 
8746
                    NULL, node, child,
 
8747
                    "The attribute 'type' and the <complexType> child are "
 
8748
                    "mutually exclusive", NULL);
 
8749
            } else
 
8750
                WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
 
8751
            child = child->next;
 
8752
        } else if (IS_SCHEMA(child, "simpleType")) {
 
8753
            /*
 
8754
            * 3.3.3 : 3
 
8755
            * "type" and either <simpleType> or <complexType> are
 
8756
            * mutually exclusive
 
8757
            */
 
8758
            if (decl->namedType != NULL) {
 
8759
                xmlSchemaPContentErr(ctxt,
 
8760
                    XML_SCHEMAP_SRC_ELEMENT_3,
 
8761
                    NULL, node, child,
 
8762
                    "The attribute 'type' and the <simpleType> child are "
 
8763
                    "mutually exclusive", NULL);
 
8764
            } else
 
8765
                WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
 
8766
            child = child->next;
 
8767
        }
 
8768
        while ((IS_SCHEMA(child, "unique")) ||
 
8769
            (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
 
8770
            if (IS_SCHEMA(child, "unique")) {
 
8771
                curIDC = xmlSchemaParseIDC(ctxt, schema, child,
 
8772
                    XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
 
8773
            } else if (IS_SCHEMA(child, "key")) {
 
8774
                curIDC = xmlSchemaParseIDC(ctxt, schema, child,
 
8775
                    XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
 
8776
            } else if (IS_SCHEMA(child, "keyref")) {
 
8777
                curIDC = xmlSchemaParseIDC(ctxt, schema, child,
 
8778
                    XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
 
8779
            }
 
8780
            if (lastIDC != NULL)
 
8781
                lastIDC->next = curIDC;
 
8782
            else
 
8783
                decl->idcs = (void *) curIDC;
 
8784
            lastIDC = curIDC;
 
8785
            child = child->next;
 
8786
        }
 
8787
        if (child != NULL) {
 
8788
            xmlSchemaPContentErr(ctxt,
 
8789
                XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
8790
                NULL, node, child,
 
8791
                NULL, "(annotation?, ((simpleType | complexType)?, "
 
8792
                "(unique | key | keyref)*))");
 
8793
        }
 
8794
        decl->annot = annot;
 
8795
    }
 
8796
    /*
 
8797
    * NOTE: Element Declaration Representation OK 4. will be checked at a
 
8798
    * different layer.
 
8799
    */
 
8800
    FREE_AND_NULL(des)
 
8801
    if (topLevel)
 
8802
        return ((xmlSchemaBasicItemPtr) decl);
 
8803
    else {
 
8804
        particle->children = (xmlSchemaTreeItemPtr) decl;
 
8805
        return ((xmlSchemaBasicItemPtr) particle);
 
8806
    }
 
8807
 
 
8808
return_null:
 
8809
    FREE_AND_NULL(des);
 
8810
    if (annot != NULL) {
 
8811
        if (particle != NULL)
 
8812
            particle->annot = NULL;
 
8813
        if (decl != NULL)
 
8814
            decl->annot = NULL;
 
8815
        xmlSchemaFreeAnnot(annot);
 
8816
    }
 
8817
    return (NULL);
 
8818
}
 
8819
 
 
8820
/**
 
8821
 * xmlSchemaParseUnion:
 
8822
 * @ctxt:  a schema validation context
 
8823
 * @schema:  the schema being built
 
8824
 * @node:  a subtree containing XML Schema informations
 
8825
 *
 
8826
 * parse a XML schema Union definition
 
8827
 * *WARNING* this interface is highly subject to change
 
8828
 *
 
8829
 * Returns -1 in case of internal error, 0 in case of success and a positive
 
8830
 * error code otherwise.
 
8831
 */
 
8832
static int
 
8833
xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
8834
                    xmlNodePtr node)
 
8835
{
 
8836
    xmlSchemaTypePtr type;
 
8837
    xmlNodePtr child = NULL;
 
8838
    xmlAttrPtr attr;
 
8839
    const xmlChar *cur = NULL;
 
8840
 
 
8841
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 
8842
        return (-1);
 
8843
    /* Not a component, don't create it. */
 
8844
    type = ctxt->ctxtType;
 
8845
    /*
 
8846
    * Mark the simple type as being of variety "union".
 
8847
    */
 
8848
    type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
 
8849
    /*
 
8850
    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
 
8851
    * then the ļæ½simple ur-type definitionļæ½."
 
8852
    */
 
8853
    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
 
8854
    /*
 
8855
    * Check for illegal attributes.
 
8856
    */
 
8857
    attr = node->properties;
 
8858
    while (attr != NULL) {
 
8859
        if (attr->ns == NULL) {
 
8860
            if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 
8861
                (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
 
8862
                xmlSchemaPIllegalAttrErr(ctxt,
 
8863
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
8864
            }
 
8865
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
8866
            xmlSchemaPIllegalAttrErr(ctxt,
 
8867
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
8868
        }
 
8869
        attr = attr->next;
 
8870
    }
 
8871
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
8872
    /*
 
8873
    * Attribute "memberTypes". This is a list of QNames.
 
8874
    * TODO: Check the value to contain anything.
 
8875
    */
 
8876
    attr = xmlSchemaGetPropNode(node, "memberTypes");
 
8877
    if (attr != NULL) {
 
8878
        const xmlChar *end;
 
8879
        xmlChar *tmp;
 
8880
        const xmlChar *localName, *nsName;
 
8881
        xmlSchemaTypeLinkPtr link, lastLink = NULL;
 
8882
        xmlSchemaQNameRefPtr ref;
 
8883
 
 
8884
        cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 
8885
        type->base = cur;
 
8886
        do {
 
8887
            while (IS_BLANK_CH(*cur))
 
8888
                cur++;
 
8889
            end = cur;
 
8890
            while ((*end != 0) && (!(IS_BLANK_CH(*end))))
 
8891
                end++;
 
8892
            if (end == cur)
 
8893
                break;
 
8894
            tmp = xmlStrndup(cur, end - cur);
 
8895
            if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
 
8896
                NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
 
8897
                /*
 
8898
                * Create the member type link.
 
8899
                */
 
8900
                link = (xmlSchemaTypeLinkPtr)
 
8901
                    xmlMalloc(sizeof(xmlSchemaTypeLink));
 
8902
                if (link == NULL) {
 
8903
                    xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
 
8904
                        "allocating a type link", NULL);
 
8905
                    return (-1);
 
8906
                }
 
8907
                link->type = NULL;
 
8908
                link->next = NULL;
 
8909
                if (lastLink == NULL)
 
8910
                    type->memberTypes = link;
 
8911
                else
 
8912
                    lastLink->next = link;
 
8913
                lastLink = link;
 
8914
                /*
 
8915
                * Create a reference item.
 
8916
                */
 
8917
                ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
 
8918
                    localName, nsName);
 
8919
                if (ref == NULL) {
 
8920
                    FREE_AND_NULL(tmp)
 
8921
                    return (-1);
 
8922
                }
 
8923
                /*
 
8924
                * Assign the reference to the link, it will be resolved
 
8925
                * later during fixup of the union simple type.
 
8926
                */
 
8927
                link->type = (xmlSchemaTypePtr) ref;
 
8928
            }
 
8929
            FREE_AND_NULL(tmp)
 
8930
            cur = end;
 
8931
        } while (*cur != 0);
 
8932
 
 
8933
    }
 
8934
    /*
 
8935
    * And now for the children...
 
8936
    */
 
8937
    child = node->children;
 
8938
    if (IS_SCHEMA(child, "annotation")) {
 
8939
        /*
 
8940
        * Add the annotation to the simple type ancestor.
 
8941
        */
 
8942
        xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
 
8943
            xmlSchemaParseAnnotation(ctxt, child, 1));
 
8944
        child = child->next;
 
8945
    }
 
8946
    if (IS_SCHEMA(child, "simpleType")) {
 
8947
        xmlSchemaTypePtr subtype, last = NULL;
 
8948
 
 
8949
        /*
 
8950
        * Anchor the member types in the "subtypes" field of the
 
8951
        * simple type.
 
8952
        */
 
8953
        while (IS_SCHEMA(child, "simpleType")) {
 
8954
            subtype = (xmlSchemaTypePtr)
 
8955
                xmlSchemaParseSimpleType(ctxt, schema, child, 0);
 
8956
            if (subtype != NULL) {
 
8957
                if (last == NULL) {
 
8958
                    type->subtypes = subtype;
 
8959
                    last = subtype;
 
8960
                } else {
 
8961
                    last->next = subtype;
 
8962
                    last = subtype;
 
8963
                }
 
8964
                last->next = NULL;
 
8965
            }
 
8966
            child = child->next;
 
8967
        }
 
8968
    }
 
8969
    if (child != NULL) {
 
8970
        xmlSchemaPContentErr(ctxt,
 
8971
            XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
8972
            NULL, node, child, NULL, "(annotation?, simpleType*)");
 
8973
    }
 
8974
    if ((attr == NULL) && (type->subtypes == NULL)) {
 
8975
         /*
 
8976
        * src-union-memberTypes-or-simpleTypes
 
8977
        * Either the memberTypes [attribute] of the <union> element must
 
8978
        * be non-empty or there must be at least one simpleType [child].
 
8979
        */
 
8980
        xmlSchemaPCustomErr(ctxt,
 
8981
            XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
 
8982
            NULL, node,
 
8983
            "Either the attribute 'memberTypes' or "
 
8984
            "at least one <simpleType> child must be present", NULL);
 
8985
    }
 
8986
    return (0);
 
8987
}
 
8988
 
 
8989
/**
 
8990
 * xmlSchemaParseList:
 
8991
 * @ctxt:  a schema validation context
 
8992
 * @schema:  the schema being built
 
8993
 * @node:  a subtree containing XML Schema informations
 
8994
 *
 
8995
 * parse a XML schema List definition
 
8996
 * *WARNING* this interface is highly subject to change
 
8997
 *
 
8998
 * Returns -1 in case of error, 0 if the declaration is improper and
 
8999
 *         1 in case of success.
 
9000
 */
 
9001
static xmlSchemaTypePtr
 
9002
xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
9003
                   xmlNodePtr node)
 
9004
{
 
9005
    xmlSchemaTypePtr type;
 
9006
    xmlNodePtr child = NULL;
 
9007
    xmlAttrPtr attr;
 
9008
 
 
9009
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 
9010
        return (NULL);
 
9011
    /* Not a component, don't create it. */
 
9012
    type = ctxt->ctxtType;
 
9013
    /*
 
9014
    * Mark the type as being of variety "list".
 
9015
    */
 
9016
    type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
 
9017
    /*
 
9018
    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
 
9019
    * then the ļæ½simple ur-type definitionļæ½."
 
9020
    */
 
9021
    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
 
9022
    /*
 
9023
    * Check for illegal attributes.
 
9024
    */
 
9025
    attr = node->properties;
 
9026
    while (attr != NULL) {
 
9027
        if (attr->ns == NULL) {
 
9028
            if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 
9029
                (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
 
9030
                xmlSchemaPIllegalAttrErr(ctxt,
 
9031
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
9032
            }
 
9033
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
9034
            xmlSchemaPIllegalAttrErr(ctxt,
 
9035
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
9036
        }
 
9037
        attr = attr->next;
 
9038
    }
 
9039
 
 
9040
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
9041
 
 
9042
    /*
 
9043
    * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
 
9044
    * fields for holding the reference to the itemType.
 
9045
    *
 
9046
    * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
 
9047
    * the "ref" fields.
 
9048
    */
 
9049
    xmlSchemaPValAttrQName(ctxt, schema, NULL,
 
9050
        node, "itemType", &(type->baseNs), &(type->base));
 
9051
    /*
 
9052
    * And now for the children...
 
9053
    */
 
9054
    child = node->children;
 
9055
    if (IS_SCHEMA(child, "annotation")) {
 
9056
        xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
 
9057
            xmlSchemaParseAnnotation(ctxt, child, 1));
 
9058
        child = child->next;
 
9059
    }
 
9060
    if (IS_SCHEMA(child, "simpleType")) {
 
9061
        /*
 
9062
        * src-list-itemType-or-simpleType
 
9063
        * Either the itemType [attribute] or the <simpleType> [child] of
 
9064
        * the <list> element must be present, but not both.
 
9065
        */
 
9066
        if (type->base != NULL) {
 
9067
            xmlSchemaPCustomErr(ctxt,
 
9068
                XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
 
9069
                NULL, node,
 
9070
                "The attribute 'itemType' and the <simpleType> child "
 
9071
                "are mutually exclusive", NULL);
 
9072
        } else {
 
9073
            type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
 
9074
        }
 
9075
        child = child->next;
 
9076
    } else if (type->base == NULL) {
 
9077
        xmlSchemaPCustomErr(ctxt,
 
9078
            XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
 
9079
            NULL, node,
 
9080
            "Either the attribute 'itemType' or the <simpleType> child "
 
9081
            "must be present", NULL);
 
9082
    }
 
9083
    if (child != NULL) {
 
9084
        xmlSchemaPContentErr(ctxt,
 
9085
            XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
9086
            NULL, node, child, NULL, "(annotation?, simpleType?)");
 
9087
    }
 
9088
    if ((type->base == NULL) &&
 
9089
        (type->subtypes == NULL) &&
 
9090
        (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
 
9091
        xmlSchemaPCustomErr(ctxt,
 
9092
            XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
 
9093
            NULL, node,
 
9094
            "Either the attribute 'itemType' or the <simpleType> child "
 
9095
            "must be present", NULL);
 
9096
    }
 
9097
    return (NULL);
 
9098
}
 
9099
 
 
9100
/**
 
9101
 * xmlSchemaParseSimpleType:
 
9102
 * @ctxt:  a schema validation context
 
9103
 * @schema:  the schema being built
 
9104
 * @node:  a subtree containing XML Schema informations
 
9105
 *
 
9106
 * parse a XML schema Simple Type definition
 
9107
 * *WARNING* this interface is highly subject to change
 
9108
 *
 
9109
 * Returns -1 in case of error, 0 if the declaration is improper and
 
9110
 * 1 in case of success.
 
9111
 */
 
9112
static xmlSchemaTypePtr
 
9113
xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
9114
                         xmlNodePtr node, int topLevel)
 
9115
{
 
9116
    xmlSchemaTypePtr type, oldCtxtType;
 
9117
    xmlNodePtr child = NULL;
 
9118
    const xmlChar *attrValue = NULL;
 
9119
    xmlAttrPtr attr;
 
9120
    int hasRestriction = 0;
 
9121
 
 
9122
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 
9123
        return (NULL);
 
9124
 
 
9125
    if (topLevel) {
 
9126
        attr = xmlSchemaGetPropNode(node, "name");
 
9127
        if (attr == NULL) {
 
9128
            xmlSchemaPMissingAttrErr(ctxt,
 
9129
                XML_SCHEMAP_S4S_ATTR_MISSING,
 
9130
                NULL, node,
 
9131
                "name", NULL);
 
9132
            return (NULL);
 
9133
        } else {
 
9134
            if (xmlSchemaPValAttrNode(ctxt,
 
9135
                NULL, attr,
 
9136
                xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
 
9137
                return (NULL);
 
9138
            /*
 
9139
            * Skip built-in types.
 
9140
            */
 
9141
            if (ctxt->isS4S) {
 
9142
                xmlSchemaTypePtr biType;
 
9143
 
 
9144
                if (ctxt->isRedefine) {
 
9145
                    /*
 
9146
                    * REDEFINE: Disallow redefinition of built-in-types.
 
9147
                    * TODO: It seems that the spec does not say anything
 
9148
                    * about this case.
 
9149
                    */
 
9150
                    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
 
9151
                        NULL, node,
 
9152
                        "Redefinition of built-in simple types is not "
 
9153
                        "supported", NULL);
 
9154
                    return(NULL);
 
9155
                }
 
9156
                biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
 
9157
                if (biType != NULL)
 
9158
                    return (biType);
 
9159
            }
 
9160
        }
 
9161
    }
 
9162
    /*
 
9163
    * TargetNamespace:
 
9164
    * SPEC "The ļæ½actual valueļæ½ of the targetNamespace [attribute]
 
9165
    * of the <schema> ancestor element information item if present,
 
9166
    * otherwise ļæ½absentļæ½.
 
9167
    */
 
9168
    if (topLevel == 0) {
 
9169
#ifdef ENABLE_NAMED_LOCALS
 
9170
        char buf[40];
 
9171
#endif
 
9172
        /*
 
9173
        * Parse as local simple type definition.
 
9174
        */
 
9175
#ifdef ENABLE_NAMED_LOCALS
 
9176
        snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
 
9177
        type = xmlSchemaAddType(ctxt, schema,
 
9178
            XML_SCHEMA_TYPE_SIMPLE,
 
9179
            xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
 
9180
            ctxt->targetNamespace, node, 0);
 
9181
#else
 
9182
        type = xmlSchemaAddType(ctxt, schema,
 
9183
            XML_SCHEMA_TYPE_SIMPLE,
 
9184
            NULL, ctxt->targetNamespace, node, 0);
 
9185
#endif
 
9186
        if (type == NULL)
 
9187
            return (NULL);
 
9188
        type->type = XML_SCHEMA_TYPE_SIMPLE;
 
9189
        type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
 
9190
        /*
 
9191
        * Check for illegal attributes.
 
9192
        */
 
9193
        attr = node->properties;
 
9194
        while (attr != NULL) {
 
9195
            if (attr->ns == NULL) {
 
9196
                if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
 
9197
                    xmlSchemaPIllegalAttrErr(ctxt,
 
9198
                        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 
 
9199
                }
 
9200
            } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
9201
                    xmlSchemaPIllegalAttrErr(ctxt,
 
9202
                        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
9203
            }
 
9204
            attr = attr->next;
 
9205
        }
 
9206
    } else {
 
9207
        /*
 
9208
        * Parse as global simple type definition.
 
9209
        *
 
9210
        * Note that attrValue is the value of the attribute "name" here.
 
9211
        */
 
9212
        type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
 
9213
            attrValue, ctxt->targetNamespace, node, 1);
 
9214
        if (type == NULL)
 
9215
            return (NULL);
 
9216
        type->type = XML_SCHEMA_TYPE_SIMPLE;
 
9217
        type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
 
9218
        type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
 
9219
        /*
 
9220
        * Check for illegal attributes.
 
9221
        */
 
9222
        attr = node->properties;
 
9223
        while (attr != NULL) {
 
9224
            if (attr->ns == NULL) {
 
9225
                if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 
9226
                    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 
9227
                    (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
 
9228
                    xmlSchemaPIllegalAttrErr(ctxt,
 
9229
                        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
9230
                }
 
9231
            } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
9232
                xmlSchemaPIllegalAttrErr(ctxt,
 
9233
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
9234
            }
 
9235
            attr = attr->next;
 
9236
        }
 
9237
        /*
 
9238
        * Attribute "final".
 
9239
        */
 
9240
        attr = xmlSchemaGetPropNode(node, "final");
 
9241
        if (attr == NULL) {
 
9242
            if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
 
9243
                type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
 
9244
            if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
 
9245
                type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
 
9246
            if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
 
9247
                type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
 
9248
        } else {
 
9249
            attrValue = xmlSchemaGetProp(ctxt, node, "final");
 
9250
            if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
 
9251
                -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
 
9252
                XML_SCHEMAS_TYPE_FINAL_LIST,
 
9253
                XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
 
9254
 
 
9255
                xmlSchemaPSimpleTypeErr(ctxt,
 
9256
                    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
9257
                    WXS_BASIC_CAST type, (xmlNodePtr) attr,
 
9258
                    NULL, "(#all | List of (list | union | restriction)",
 
9259
                    attrValue, NULL, NULL, NULL);
 
9260
            }
 
9261
        }
 
9262
    }
 
9263
    type->targetNamespace = ctxt->targetNamespace;
 
9264
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
9265
    /*
 
9266
    * And now for the children...
 
9267
    */
 
9268
    oldCtxtType = ctxt->ctxtType;
 
9269
    
 
9270
    ctxt->ctxtType = type;
 
9271
    
 
9272
    child = node->children;
 
9273
    if (IS_SCHEMA(child, "annotation")) {
 
9274
        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 
9275
        child = child->next;
 
9276
    }
 
9277
    if (child == NULL) {
 
9278
        xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
 
9279
            NULL, node, child, NULL,
 
9280
            "(annotation?, (restriction | list | union))");
 
9281
    } else if (IS_SCHEMA(child, "restriction")) {       
 
9282
        xmlSchemaParseRestriction(ctxt, schema, child,
 
9283
            XML_SCHEMA_TYPE_SIMPLE);    
 
9284
        hasRestriction = 1;     
 
9285
        child = child->next;
 
9286
    } else if (IS_SCHEMA(child, "list")) {
 
9287
        xmlSchemaParseList(ctxt, schema, child);
 
9288
        child = child->next;
 
9289
    } else if (IS_SCHEMA(child, "union")) {
 
9290
        xmlSchemaParseUnion(ctxt, schema, child);
 
9291
        child = child->next;
 
9292
    }
 
9293
    if (child != NULL) {
 
9294
        xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
9295
            NULL, node, child, NULL,
 
9296
            "(annotation?, (restriction | list | union))");
 
9297
    }
 
9298
    /*
 
9299
    * REDEFINE: SPEC src-redefine (5)
 
9300
    * "Within the [children], each <simpleType> must have a
 
9301
    * <restriction> among its [children] ... the ļæ½actual valueļæ½ of whose
 
9302
    * base [attribute] must be the same as the ļæ½actual valueļæ½ of its own
 
9303
    * name attribute plus target namespace;"
 
9304
    */
 
9305
    if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
 
9306
        xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
 
9307
            NULL, node, "This is a redefinition, thus the "
 
9308
            "<simpleType> must have a <restriction> child", NULL);
 
9309
    }
 
9310
    
 
9311
    ctxt->ctxtType = oldCtxtType;
 
9312
    return (type);
 
9313
}
 
9314
 
 
9315
/**
 
9316
 * xmlSchemaParseModelGroupDefRef:
 
9317
 * @ctxt:  the parser context
 
9318
 * @schema: the schema being built
 
9319
 * @node:  the node
 
9320
 *
 
9321
 * Parses a reference to a model group definition.
 
9322
 *
 
9323
 * We will return a particle component with a qname-component or
 
9324
 * NULL in case of an error.
 
9325
 */
 
9326
static xmlSchemaTreeItemPtr
 
9327
xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
 
9328
                               xmlSchemaPtr schema,
 
9329
                               xmlNodePtr node)
 
9330
{
 
9331
    xmlSchemaParticlePtr item;
 
9332
    xmlNodePtr child = NULL;
 
9333
    xmlAttrPtr attr;
 
9334
    const xmlChar *ref = NULL, *refNs = NULL;
 
9335
    int min, max;
 
9336
 
 
9337
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 
9338
        return (NULL);
 
9339
 
 
9340
    attr = xmlSchemaGetPropNode(node, "ref");
 
9341
    if (attr == NULL) {
 
9342
        xmlSchemaPMissingAttrErr(ctxt,
 
9343
            XML_SCHEMAP_S4S_ATTR_MISSING,
 
9344
            NULL, node, "ref", NULL);
 
9345
        return (NULL);
 
9346
    } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
 
9347
        attr, &refNs, &ref) != 0) {
 
9348
        return (NULL);
 
9349
    }
 
9350
    xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
 
9351
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
 
9352
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
 
9353
        "(xs:nonNegativeInteger | unbounded)");
 
9354
    /*
 
9355
    * Check for illegal attributes.
 
9356
    */
 
9357
    attr = node->properties;
 
9358
    while (attr != NULL) {
 
9359
        if (attr->ns == NULL) {
 
9360
            if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
 
9361
                (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 
9362
                (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
 
9363
                (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
 
9364
                xmlSchemaPIllegalAttrErr(ctxt,
 
9365
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
9366
            }
 
9367
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
9368
            xmlSchemaPIllegalAttrErr(ctxt,
 
9369
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
9370
        }
 
9371
        attr = attr->next;
 
9372
    }
 
9373
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
9374
    item = xmlSchemaAddParticle(ctxt, node, min, max);
 
9375
    if (item == NULL)
 
9376
        return (NULL);    
 
9377
    /*
 
9378
    * Create a qname-reference and set as the term; it will be substituted
 
9379
    * for the model group after the reference has been resolved.
 
9380
    */
 
9381
    item->children = (xmlSchemaTreeItemPtr)
 
9382
        xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);    
 
9383
    xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
 
9384
    /*
 
9385
    * And now for the children...
 
9386
    */
 
9387
    child = node->children;
 
9388
    /* TODO: Is annotation even allowed for a model group reference? */
 
9389
    if (IS_SCHEMA(child, "annotation")) {
 
9390
        /*
 
9391
        * TODO: What to do exactly with the annotation?
 
9392
        */
 
9393
        item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 
9394
        child = child->next;
 
9395
    }
 
9396
    if (child != NULL) {
 
9397
        xmlSchemaPContentErr(ctxt,
 
9398
            XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
9399
            NULL, node, child, NULL,
 
9400
            "(annotation?)");
 
9401
    }
 
9402
    /*
 
9403
    * Corresponds to no component at all if minOccurs==maxOccurs==0.
 
9404
    */
 
9405
    if ((min == 0) && (max == 0))
 
9406
        return (NULL);
 
9407
 
 
9408
    return ((xmlSchemaTreeItemPtr) item);
 
9409
}
 
9410
 
 
9411
/**
 
9412
 * xmlSchemaParseModelGroupDefinition:
 
9413
 * @ctxt:  a schema validation context
 
9414
 * @schema:  the schema being built
 
9415
 * @node:  a subtree containing XML Schema informations
 
9416
 *
 
9417
 * Parses a XML schema model group definition.
 
9418
 *
 
9419
 * Note that the contraint src-redefine (6.2) can't be applied until
 
9420
 * references have been resolved. So we will do this at the
 
9421
 * component fixup level.
 
9422
 *    
 
9423
 * *WARNING* this interface is highly subject to change
 
9424
 *
 
9425
 * Returns -1 in case of error, 0 if the declaration is improper and
 
9426
 *         1 in case of success.
 
9427
 */
 
9428
static xmlSchemaModelGroupDefPtr
 
9429
xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
 
9430
                                   xmlSchemaPtr schema,
 
9431
                                   xmlNodePtr node)
 
9432
{
 
9433
    xmlSchemaModelGroupDefPtr item;
 
9434
    xmlNodePtr child = NULL;
 
9435
    xmlAttrPtr attr;
 
9436
    const xmlChar *name;
 
9437
 
 
9438
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 
9439
        return (NULL);
 
9440
 
 
9441
    attr = xmlSchemaGetPropNode(node, "name");
 
9442
    if (attr == NULL) {
 
9443
        xmlSchemaPMissingAttrErr(ctxt,
 
9444
            XML_SCHEMAP_S4S_ATTR_MISSING,
 
9445
            NULL, node,
 
9446
            "name", NULL);
 
9447
        return (NULL);
 
9448
    } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
 
9449
        xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
 
9450
        return (NULL);
 
9451
    }
 
9452
    item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
 
9453
        ctxt->targetNamespace, node);
 
9454
    if (item == NULL)
 
9455
        return (NULL);
 
9456
    /*
 
9457
    * Check for illegal attributes.
 
9458
    */
 
9459
    attr = node->properties;
 
9460
    while (attr != NULL) {
 
9461
        if (attr->ns == NULL) {
 
9462
            if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 
9463
                (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
 
9464
                xmlSchemaPIllegalAttrErr(ctxt,
 
9465
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
9466
            }
 
9467
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
9468
            xmlSchemaPIllegalAttrErr(ctxt,
 
9469
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
9470
        }
 
9471
        attr = attr->next;
 
9472
    }
 
9473
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
9474
    /*
 
9475
    * And now for the children...
 
9476
    */
 
9477
    child = node->children;
 
9478
    if (IS_SCHEMA(child, "annotation")) {
 
9479
        item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 
9480
        child = child->next;
 
9481
    }
 
9482
    if (IS_SCHEMA(child, "all")) {
 
9483
        item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
 
9484
            XML_SCHEMA_TYPE_ALL, 0);
 
9485
        child = child->next;
 
9486
    } else if (IS_SCHEMA(child, "choice")) {
 
9487
        item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
 
9488
            XML_SCHEMA_TYPE_CHOICE, 0);
 
9489
        child = child->next;
 
9490
    } else if (IS_SCHEMA(child, "sequence")) {
 
9491
        item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
 
9492
            XML_SCHEMA_TYPE_SEQUENCE, 0);
 
9493
        child = child->next;
 
9494
    }
 
9495
 
 
9496
   
 
9497
 
 
9498
    if (child != NULL) {
 
9499
        xmlSchemaPContentErr(ctxt,
 
9500
            XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
9501
            NULL, node, child, NULL,
 
9502
            "(annotation?, (all | choice | sequence)?)");
 
9503
    }
 
9504
    return (item);
 
9505
}
 
9506
 
 
9507
/**
 
9508
 * xmlSchemaCleanupDoc:
 
9509
 * @ctxt:  a schema validation context
 
9510
 * @node:  the root of the document.
 
9511
 *
 
9512
 * removes unwanted nodes in a schemas document tree
 
9513
 */
 
9514
static void
 
9515
xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
 
9516
{
 
9517
    xmlNodePtr delete, cur;
 
9518
 
 
9519
    if ((ctxt == NULL) || (root == NULL)) return;
 
9520
 
 
9521
    /*
 
9522
     * Remove all the blank text nodes
 
9523
     */
 
9524
    delete = NULL;
 
9525
    cur = root;
 
9526
    while (cur != NULL) {
 
9527
        if (delete != NULL) {
 
9528
            xmlUnlinkNode(delete);
 
9529
            xmlFreeNode(delete);
 
9530
            delete = NULL;
 
9531
        }
 
9532
        if (cur->type == XML_TEXT_NODE) {
 
9533
            if (IS_BLANK_NODE(cur)) {
 
9534
                if (xmlNodeGetSpacePreserve(cur) != 1) {
 
9535
                    delete = cur;
 
9536
                }
 
9537
            }
 
9538
        } else if ((cur->type != XML_ELEMENT_NODE) &&
 
9539
                   (cur->type != XML_CDATA_SECTION_NODE)) {
 
9540
            delete = cur;
 
9541
            goto skip_children;
 
9542
        }
 
9543
 
 
9544
        /*
 
9545
         * Skip to next node
 
9546
         */
 
9547
        if (cur->children != NULL) {
 
9548
            if ((cur->children->type != XML_ENTITY_DECL) &&
 
9549
                (cur->children->type != XML_ENTITY_REF_NODE) &&
 
9550
                (cur->children->type != XML_ENTITY_NODE)) {
 
9551
                cur = cur->children;
 
9552
                continue;
 
9553
            }
 
9554
        }
 
9555
      skip_children:
 
9556
        if (cur->next != NULL) {
 
9557
            cur = cur->next;
 
9558
            continue;
 
9559
        }
 
9560
 
 
9561
        do {
 
9562
            cur = cur->parent;
 
9563
            if (cur == NULL)
 
9564
                break;
 
9565
            if (cur == root) {
 
9566
                cur = NULL;
 
9567
                break;
 
9568
            }
 
9569
            if (cur->next != NULL) {
 
9570
                cur = cur->next;
 
9571
                break;
 
9572
            }
 
9573
        } while (cur != NULL);
 
9574
    }
 
9575
    if (delete != NULL) {
 
9576
        xmlUnlinkNode(delete);
 
9577
        xmlFreeNode(delete);
 
9578
        delete = NULL;
 
9579
    }
 
9580
}
 
9581
 
 
9582
 
 
9583
static void
 
9584
xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
 
9585
{
 
9586
    if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
 
9587
        schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
 
9588
 
 
9589
    if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
 
9590
        schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
 
9591
 
 
9592
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
 
9593
        schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
 
9594
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
 
9595
        schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
 
9596
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
 
9597
        schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
 
9598
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
 
9599
        schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
 
9600
 
 
9601
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
 
9602
        schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
 
9603
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
 
9604
        schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
 
9605
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
 
9606
        schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
 
9607
}
 
9608
 
 
9609
static int
 
9610
xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
 
9611
                             xmlSchemaPtr schema,
 
9612
                             xmlNodePtr node)
 
9613
{
 
9614
    xmlAttrPtr attr;
 
9615
    const xmlChar *val;
 
9616
    int res = 0, oldErrs = ctxt->nberrors;
 
9617
 
 
9618
    /*
 
9619
    * Those flags should be moved to the parser context flags,
 
9620
    * since they are not visible at the component level. I.e.
 
9621
    * they are used if processing schema *documents* only.
 
9622
    */
 
9623
    res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
9624
    HFAILURE;
 
9625
 
 
9626
    /*
 
9627
    * Since the version is of type xs:token, we won't bother to
 
9628
    * check it.
 
9629
    */
 
9630
    /* REMOVED:
 
9631
    attr = xmlSchemaGetPropNode(node, "version");
 
9632
    if (attr != NULL) {
 
9633
        res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
 
9634
            xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);    
 
9635
        HFAILURE;
 
9636
    }
 
9637
    */
 
9638
    attr = xmlSchemaGetPropNode(node, "targetNamespace");
 
9639
    if (attr != NULL) {
 
9640
        res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
 
9641
            xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
 
9642
        HFAILURE;
 
9643
        if (res != 0) {
 
9644
            ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
 
9645
            goto exit;
 
9646
        }
 
9647
    }
 
9648
    attr = xmlSchemaGetPropNode(node, "elementFormDefault");
 
9649
    if (attr != NULL) {
 
9650
        val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 
9651
        res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
 
9652
            XML_SCHEMAS_QUALIF_ELEM);
 
9653
        HFAILURE;
 
9654
        if (res != 0) {
 
9655
            xmlSchemaPSimpleTypeErr(ctxt,
 
9656
                XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
 
9657
                NULL, (xmlNodePtr) attr, NULL,
 
9658
                "(qualified | unqualified)", val, NULL, NULL, NULL);
 
9659
        }
 
9660
    }
 
9661
    attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
 
9662
    if (attr != NULL) {
 
9663
        val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 
9664
        res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
 
9665
            XML_SCHEMAS_QUALIF_ATTR);
 
9666
        HFAILURE;
 
9667
        if (res != 0) {
 
9668
            xmlSchemaPSimpleTypeErr(ctxt,
 
9669
                XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
 
9670
                NULL, (xmlNodePtr) attr, NULL,
 
9671
                "(qualified | unqualified)", val, NULL, NULL, NULL);
 
9672
        }
 
9673
    }
 
9674
    attr = xmlSchemaGetPropNode(node, "finalDefault");
 
9675
    if (attr != NULL) {
 
9676
        val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 
9677
        res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
 
9678
            XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
 
9679
            XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
 
9680
            -1,
 
9681
            XML_SCHEMAS_FINAL_DEFAULT_LIST,
 
9682
            XML_SCHEMAS_FINAL_DEFAULT_UNION);
 
9683
        HFAILURE;
 
9684
        if (res != 0) {
 
9685
            xmlSchemaPSimpleTypeErr(ctxt,
 
9686
                XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
9687
                NULL, (xmlNodePtr) attr, NULL,
 
9688
                "(#all | List of (extension | restriction | list | union))",
 
9689
                val, NULL, NULL, NULL);
 
9690
        }
 
9691
    }
 
9692
    attr = xmlSchemaGetPropNode(node, "blockDefault");
 
9693
    if (attr != NULL) {
 
9694
        val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 
 
9695
        res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
 
9696
            XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
 
9697
            XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
 
9698
            XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
 
9699
        HFAILURE;
 
9700
        if (res != 0) {
 
9701
            xmlSchemaPSimpleTypeErr(ctxt,
 
9702
                XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
9703
                NULL, (xmlNodePtr) attr, NULL,
 
9704
                "(#all | List of (extension | restriction | substitution))",
 
9705
                val, NULL, NULL, NULL);
 
9706
        }
 
9707
    }
 
9708
 
 
9709
exit:
 
9710
    if (oldErrs != ctxt->nberrors)
 
9711
        res = ctxt->err;
 
9712
    return(res);
 
9713
exit_failure:
 
9714
    return(-1);
 
9715
}
 
9716
 
 
9717
/**
 
9718
 * xmlSchemaParseSchemaTopLevel:
 
9719
 * @ctxt:  a schema validation context
 
9720
 * @schema:  the schemas
 
9721
 * @nodes:  the list of top level nodes
 
9722
 *
 
9723
 * Returns the internal XML Schema structure built from the resource or
 
9724
 *         NULL in case of error
 
9725
 */
 
9726
static int
 
9727
xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
 
9728
                             xmlSchemaPtr schema, xmlNodePtr nodes)
 
9729
{
 
9730
    xmlNodePtr child;
 
9731
    xmlSchemaAnnotPtr annot;
 
9732
    int res = 0, oldErrs, tmpOldErrs;
 
9733
 
 
9734
    if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
 
9735
        return(-1);
 
9736
 
 
9737
    oldErrs = ctxt->nberrors;
 
9738
    child = nodes;
 
9739
    while ((IS_SCHEMA(child, "include")) ||
 
9740
           (IS_SCHEMA(child, "import")) ||
 
9741
           (IS_SCHEMA(child, "redefine")) ||
 
9742
           (IS_SCHEMA(child, "annotation"))) {
 
9743
        if (IS_SCHEMA(child, "annotation")) {
 
9744
            annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 
9745
            if (schema->annot == NULL)
 
9746
                schema->annot = annot;
 
9747
            else
 
9748
                xmlSchemaFreeAnnot(annot);
 
9749
        } else if (IS_SCHEMA(child, "import")) {
 
9750
            tmpOldErrs = ctxt->nberrors;
 
9751
            res = xmlSchemaParseImport(ctxt, schema, child);
 
9752
            HFAILURE;
 
9753
            HSTOP(ctxt);
 
9754
            if (tmpOldErrs != ctxt->nberrors)
 
9755
                goto exit;          
 
9756
        } else if (IS_SCHEMA(child, "include")) {
 
9757
            tmpOldErrs = ctxt->nberrors;
 
9758
            res = xmlSchemaParseInclude(ctxt, schema, child);
 
9759
            HFAILURE;
 
9760
            HSTOP(ctxt);
 
9761
            if (tmpOldErrs != ctxt->nberrors)
 
9762
                goto exit;          
 
9763
        } else if (IS_SCHEMA(child, "redefine")) {
 
9764
            tmpOldErrs = ctxt->nberrors;
 
9765
            res = xmlSchemaParseRedefine(ctxt, schema, child);
 
9766
            HFAILURE;
 
9767
            HSTOP(ctxt);
 
9768
            if (tmpOldErrs != ctxt->nberrors)
 
9769
                goto exit;
 
9770
        }
 
9771
        child = child->next;
 
9772
    }
 
9773
    /*
 
9774
    * URGENT TODO: Change the functions to return int results.
 
9775
    * We need especially to catch internal errors.
 
9776
    */
 
9777
    while (child != NULL) {
 
9778
        if (IS_SCHEMA(child, "complexType")) {
 
9779
            xmlSchemaParseComplexType(ctxt, schema, child, 1);
 
9780
            child = child->next;
 
9781
        } else if (IS_SCHEMA(child, "simpleType")) {
 
9782
            xmlSchemaParseSimpleType(ctxt, schema, child, 1);
 
9783
            child = child->next;
 
9784
        } else if (IS_SCHEMA(child, "element")) {
 
9785
            xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
 
9786
            child = child->next;
 
9787
        } else if (IS_SCHEMA(child, "attribute")) {
 
9788
            xmlSchemaParseGlobalAttribute(ctxt, schema, child);
 
9789
            child = child->next;
 
9790
        } else if (IS_SCHEMA(child, "attributeGroup")) {
 
9791
            xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
 
9792
            child = child->next;
 
9793
        } else if (IS_SCHEMA(child, "group")) {
 
9794
            xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
 
9795
            child = child->next;
 
9796
        } else if (IS_SCHEMA(child, "notation")) {
 
9797
            xmlSchemaParseNotation(ctxt, schema, child);
 
9798
            child = child->next;
 
9799
        } else {
 
9800
            xmlSchemaPContentErr(ctxt,
 
9801
                XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
9802
                NULL, child->parent, child,
 
9803
                NULL, "((include | import | redefine | annotation)*, "
 
9804
                "(((simpleType | complexType | group | attributeGroup) "
 
9805
                "| element | attribute | notation), annotation*)*)");
 
9806
            child = child->next;
 
9807
        }
 
9808
        while (IS_SCHEMA(child, "annotation")) {
 
9809
            /*
 
9810
            * TODO: We should add all annotations.
 
9811
            */
 
9812
            annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 
9813
            if (schema->annot == NULL)
 
9814
                schema->annot = annot;
 
9815
            else
 
9816
                xmlSchemaFreeAnnot(annot);
 
9817
            child = child->next;
 
9818
        }
 
9819
    }
 
9820
exit:
 
9821
    ctxt->ctxtType = NULL;
 
9822
    if (oldErrs != ctxt->nberrors)
 
9823
        res = ctxt->err;
 
9824
    return(res);
 
9825
exit_failure:
 
9826
    return(-1);
 
9827
}
 
9828
 
 
9829
static xmlSchemaSchemaRelationPtr
 
9830
xmlSchemaSchemaRelationCreate(void)
 
9831
{
 
9832
    xmlSchemaSchemaRelationPtr ret;
 
9833
 
 
9834
    ret = (xmlSchemaSchemaRelationPtr)
 
9835
        xmlMalloc(sizeof(xmlSchemaSchemaRelation));
 
9836
    if (ret == NULL) {
 
9837
        xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
 
9838
        return(NULL);
 
9839
    }
 
9840
    memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
 
9841
    return(ret);
 
9842
}
 
9843
 
 
9844
#if 0
 
9845
static void
 
9846
xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
 
9847
{
 
9848
    xmlFree(rel);
 
9849
}
 
9850
#endif
 
9851
 
 
9852
static void
 
9853
xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
 
9854
{
 
9855
    xmlSchemaRedefPtr prev;
 
9856
 
 
9857
    while (redef != NULL) {
 
9858
        prev = redef;
 
9859
        redef = redef->next;
 
9860
        xmlFree(prev);
 
9861
    }
 
9862
}
 
9863
 
 
9864
static void
 
9865
xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
 
9866
{
 
9867
    /*
 
9868
    * After the construction context has been freed, there will be
 
9869
    * no schema graph available any more. Only the schema buckets
 
9870
    * will stay alive, which are put into the "schemasImports" and
 
9871
    * "includes" slots of the xmlSchema.
 
9872
    */
 
9873
    if (con->buckets != NULL)
 
9874
        xmlSchemaItemListFree(con->buckets);
 
9875
    if (con->pending != NULL)
 
9876
        xmlSchemaItemListFree(con->pending);
 
9877
    if (con->substGroups != NULL)
 
9878
        xmlHashFree(con->substGroups,
 
9879
            (xmlHashDeallocator) xmlSchemaSubstGroupFree);
 
9880
    if (con->redefs != NULL)
 
9881
        xmlSchemaRedefListFree(con->redefs);
 
9882
    if (con->dict != NULL)
 
9883
        xmlDictFree(con->dict);
 
9884
    xmlFree(con);
 
9885
}
 
9886
 
 
9887
static xmlSchemaConstructionCtxtPtr 
 
9888
xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
 
9889
{
 
9890
    xmlSchemaConstructionCtxtPtr ret;
 
9891
 
 
9892
    ret = (xmlSchemaConstructionCtxtPtr)
 
9893
        xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
 
9894
    if (ret == NULL) {
 
9895
        xmlSchemaPErrMemory(NULL,
 
9896
            "allocating schema construction context", NULL);
 
9897
        return (NULL);
 
9898
    }
 
9899
    memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
 
9900
 
 
9901
    ret->buckets = xmlSchemaItemListCreate();
 
9902
    if (ret->buckets == NULL) {
 
9903
        xmlSchemaPErrMemory(NULL,
 
9904
            "allocating list of schema buckets", NULL);
 
9905
        xmlFree(ret);
 
9906
        return (NULL);
 
9907
    }
 
9908
    ret->pending = xmlSchemaItemListCreate();
 
9909
    if (ret->pending == NULL) {
 
9910
        xmlSchemaPErrMemory(NULL,
 
9911
            "allocating list of pending global components", NULL);
 
9912
        xmlSchemaConstructionCtxtFree(ret);
 
9913
        return (NULL);
 
9914
    }
 
9915
    ret->dict = dict;
 
9916
    xmlDictReference(dict);
 
9917
    return(ret);
 
9918
}
 
9919
 
 
9920
static xmlSchemaParserCtxtPtr
 
9921
xmlSchemaParserCtxtCreate(void)
 
9922
{
 
9923
    xmlSchemaParserCtxtPtr ret;
 
9924
 
 
9925
    ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
 
9926
    if (ret == NULL) {
 
9927
        xmlSchemaPErrMemory(NULL, "allocating schema parser context",
 
9928
                            NULL);
 
9929
        return (NULL);
 
9930
    }
 
9931
    memset(ret, 0, sizeof(xmlSchemaParserCtxt));
 
9932
    ret->type = XML_SCHEMA_CTXT_PARSER;
 
9933
    ret->attrProhibs = xmlSchemaItemListCreate();
 
9934
    if (ret->attrProhibs == NULL) {
 
9935
        xmlFree(ret);
 
9936
        return(NULL);
 
9937
    }
 
9938
    return(ret);
 
9939
}
 
9940
 
 
9941
/**
 
9942
 * xmlSchemaNewParserCtxtUseDict:
 
9943
 * @URL:  the location of the schema
 
9944
 * @dict: the dictionary to be used
 
9945
 *
 
9946
 * Create an XML Schemas parse context for that file/resource expected
 
9947
 * to contain an XML Schemas file.
 
9948
 *
 
9949
 * Returns the parser context or NULL in case of error
 
9950
 */
 
9951
static xmlSchemaParserCtxtPtr
 
9952
xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
 
9953
{
 
9954
    xmlSchemaParserCtxtPtr ret;
 
9955
 
 
9956
    ret = xmlSchemaParserCtxtCreate();
 
9957
    if (ret == NULL)        
 
9958
        return (NULL);
 
9959
    ret->dict = dict;
 
9960
    xmlDictReference(dict);    
 
9961
    if (URL != NULL)
 
9962
        ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
 
9963
    return (ret);
 
9964
}
 
9965
 
 
9966
static int
 
9967
xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
 
9968
{
 
9969
    if (vctxt->pctxt == NULL) {
 
9970
        if (vctxt->schema != NULL)
 
9971
            vctxt->pctxt =
 
9972
                xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
 
9973
        else
 
9974
            vctxt->pctxt = xmlSchemaNewParserCtxt("*");
 
9975
        if (vctxt->pctxt == NULL) {
 
9976
            VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
 
9977
                "failed to create a temp. parser context");
 
9978
            return (-1);
 
9979
        }
 
9980
        /* TODO: Pass user data. */
 
9981
        xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
 
9982
            vctxt->warning, vctxt->errCtxt);
 
9983
        xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
 
9984
            vctxt->errCtxt);
 
9985
    }
 
9986
    return (0);
 
9987
}
 
9988
 
 
9989
/**
 
9990
 * xmlSchemaGetSchemaBucket:
 
9991
 * @pctxt: the schema parser context
 
9992
 * @schemaLocation: the URI of the schema document
 
9993
 *
 
9994
 * Returns a schema bucket if it was already parsed.
 
9995
 *
 
9996
 * Returns a schema bucket if it was already parsed from
 
9997
 *         @schemaLocation, NULL otherwise.
 
9998
 */
 
9999
static xmlSchemaBucketPtr
 
10000
xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
 
10001
                            const xmlChar *schemaLocation)
 
10002
{
 
10003
    xmlSchemaBucketPtr cur;
 
10004
    xmlSchemaItemListPtr list;
 
10005
 
 
10006
    list = pctxt->constructor->buckets;
 
10007
    if (list->nbItems == 0)
 
10008
        return(NULL);
 
10009
    else {
 
10010
        int i;
 
10011
        for (i = 0; i < list->nbItems; i++) {
 
10012
            cur = (xmlSchemaBucketPtr) list->items[i];
 
10013
            /* Pointer comparison! */
 
10014
            if (cur->schemaLocation == schemaLocation)
 
10015
                return(cur);
 
10016
        }
 
10017
    }
 
10018
    return(NULL);
 
10019
}
 
10020
 
 
10021
static xmlSchemaBucketPtr
 
10022
xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
 
10023
                                     const xmlChar *schemaLocation,
 
10024
                                     const xmlChar *targetNamespace)
 
10025
{
 
10026
    xmlSchemaBucketPtr cur;
 
10027
    xmlSchemaItemListPtr list;
 
10028
 
 
10029
    list = pctxt->constructor->buckets;
 
10030
    if (list->nbItems == 0)
 
10031
        return(NULL);
 
10032
    else {
 
10033
        int i;
 
10034
        for (i = 0; i < list->nbItems; i++) {
 
10035
            cur = (xmlSchemaBucketPtr) list->items[i];
 
10036
            /* Pointer comparison! */
 
10037
            if ((cur->origTargetNamespace == NULL) &&
 
10038
                (cur->schemaLocation == schemaLocation) &&
 
10039
                (cur->targetNamespace == targetNamespace))
 
10040
                return(cur);
 
10041
        }
 
10042
    }
 
10043
    return(NULL);
 
10044
}
 
10045
 
 
10046
 
 
10047
#define IS_BAD_SCHEMA_DOC(b) \
 
10048
    (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
 
10049
 
 
10050
static xmlSchemaBucketPtr
 
10051
xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
 
10052
                                 const xmlChar *targetNamespace,
 
10053
                                 int imported)
 
10054
{
 
10055
    xmlSchemaBucketPtr cur;
 
10056
    xmlSchemaItemListPtr list;
 
10057
 
 
10058
    list = pctxt->constructor->buckets;
 
10059
    if (list->nbItems == 0)
 
10060
        return(NULL);
 
10061
    else {
 
10062
        int i;
 
10063
        for (i = 0; i < list->nbItems; i++) {
 
10064
            cur = (xmlSchemaBucketPtr) list->items[i];
 
10065
            if ((! IS_BAD_SCHEMA_DOC(cur)) &&
 
10066
                (cur->origTargetNamespace == targetNamespace) &&
 
10067
                ((imported && cur->imported) ||
 
10068
                 ((!imported) && (!cur->imported))))
 
10069
                return(cur);
 
10070
        }
 
10071
    }
 
10072
    return(NULL);
 
10073
}
 
10074
 
 
10075
static int
 
10076
xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
 
10077
                     xmlSchemaPtr schema,
 
10078
                     xmlSchemaBucketPtr bucket)
 
10079
{
 
10080
    int oldFlags;
 
10081
    xmlDocPtr oldDoc;
 
10082
    xmlNodePtr node;
 
10083
    int ret, oldErrs;
 
10084
    xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
 
10085
    
 
10086
    /* 
 
10087
    * Save old values; reset the *main* schema.
 
10088
    * URGENT TODO: This is not good; move the per-document information
 
10089
    * to the parser. Get rid of passing the main schema to the
 
10090
    * parsing functions.
 
10091
    */
 
10092
    oldFlags = schema->flags;
 
10093
    oldDoc = schema->doc;
 
10094
    if (schema->flags != 0)
 
10095
        xmlSchemaClearSchemaDefaults(schema);
 
10096
    schema->doc = bucket->doc;    
 
10097
    pctxt->schema = schema;
 
10098
    /* 
 
10099
    * Keep the current target namespace on the parser *not* on the
 
10100
    * main schema.
 
10101
    */
 
10102
    pctxt->targetNamespace = bucket->targetNamespace;
 
10103
    WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
 
10104
 
 
10105
    if ((bucket->targetNamespace != NULL) &&
 
10106
        xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
 
10107
        /*
 
10108
        * We are parsing the schema for schemas!
 
10109
        */
 
10110
        pctxt->isS4S = 1;
 
10111
    }    
 
10112
    /* Mark it as parsed, even if parsing fails. */
 
10113
    bucket->parsed++;
 
10114
    /* Compile the schema doc. */
 
10115
    node = xmlDocGetRootElement(bucket->doc);
 
10116
    ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
 
10117
    if (ret != 0)
 
10118
        goto exit;
 
10119
    /* An empty schema; just get out. */
 
10120
    if (node->children == NULL)
 
10121
        goto exit;
 
10122
    oldErrs = pctxt->nberrors;
 
10123
    ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
 
10124
    if (ret != 0)
 
10125
        goto exit;
 
10126
    /*
 
10127
    * TODO: Not nice, but I'm not 100% sure we will get always an error
 
10128
    * as a result of the obove functions; so better rely on pctxt->err
 
10129
    * as well.
 
10130
    */
 
10131
    if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
 
10132
        ret = pctxt->err;
 
10133
        goto exit;
 
10134
    }
 
10135
    
 
10136
exit:
 
10137
    WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
 
10138
    /* Restore schema values. */
 
10139
    schema->doc = oldDoc;
 
10140
    schema->flags = oldFlags;
 
10141
    return(ret);
 
10142
}
 
10143
 
 
10144
static int
 
10145
xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
 
10146
                     xmlSchemaPtr schema,
 
10147
                     xmlSchemaBucketPtr bucket)
 
10148
{
 
10149
    xmlSchemaParserCtxtPtr newpctxt;
 
10150
    int res = 0;
 
10151
 
 
10152
    if (bucket == NULL)
 
10153
        return(0);
 
10154
    if (bucket->parsed) {
 
10155
        PERROR_INT("xmlSchemaParseNewDoc",
 
10156
            "reparsing a schema doc");
 
10157
        return(-1);
 
10158
    }
 
10159
    if (bucket->doc == NULL) {
 
10160
        PERROR_INT("xmlSchemaParseNewDoc",
 
10161
            "parsing a schema doc, but there's no doc");
 
10162
        return(-1);
 
10163
    }
 
10164
    if (pctxt->constructor == NULL) {
 
10165
        PERROR_INT("xmlSchemaParseNewDoc",
 
10166
            "no constructor");
 
10167
        return(-1);
 
10168
    }    
 
10169
    /* Create and init the temporary parser context. */
 
10170
    newpctxt = xmlSchemaNewParserCtxtUseDict(
 
10171
        (const char *) bucket->schemaLocation, pctxt->dict);
 
10172
    if (newpctxt == NULL)
 
10173
        return(-1);
 
10174
    newpctxt->constructor = pctxt->constructor;
 
10175
    /*
 
10176
    * TODO: Can we avoid that the parser knows about the main schema? 
 
10177
    * It would be better if he knows about the current schema bucket
 
10178
    * only.
 
10179
    */
 
10180
    newpctxt->schema = schema;
 
10181
    xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
 
10182
        pctxt->errCtxt);
 
10183
    xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
 
10184
        pctxt->errCtxt);
 
10185
    newpctxt->counter = pctxt->counter;
 
10186
    
 
10187
 
 
10188
    res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
 
10189
    
 
10190
    /* Channel back errors and cleanup the temporary parser context. */
 
10191
    if (res != 0)
 
10192
        pctxt->err = res;
 
10193
    pctxt->nberrors += newpctxt->nberrors;
 
10194
    pctxt->counter = newpctxt->counter;
 
10195
    newpctxt->constructor = NULL;    
 
10196
    /* Free the parser context. */
 
10197
    xmlSchemaFreeParserCtxt(newpctxt);
 
10198
    return(res);
 
10199
}
 
10200
 
 
10201
static void
 
10202
xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
 
10203
                                xmlSchemaSchemaRelationPtr rel)
 
10204
{
 
10205
    xmlSchemaSchemaRelationPtr cur = bucket->relations;
 
10206
 
 
10207
    if (cur == NULL) {
 
10208
        bucket->relations = rel;
 
10209
        return;
 
10210
    }
 
10211
    while (cur->next != NULL)
 
10212
        cur = cur->next;
 
10213
    cur->next = rel;
 
10214
}
 
10215
 
 
10216
 
 
10217
static const xmlChar *
 
10218
xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
 
10219
                          xmlNodePtr ctxtNode)
 
10220
{    
 
10221
    /*
 
10222
    * Build an absolue location URI.
 
10223
    */
 
10224
    if (location != NULL) {     
 
10225
        if (ctxtNode == NULL)
 
10226
            return(location);
 
10227
        else {
 
10228
            xmlChar *base, *URI;
 
10229
            const xmlChar *ret = NULL;
 
10230
 
 
10231
            base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
 
10232
            if (base == NULL) {
 
10233
                URI = xmlBuildURI(location, ctxtNode->doc->URL);
 
10234
            } else {
 
10235
                URI = xmlBuildURI(location, base);
 
10236
                xmlFree(base);
 
10237
            }
 
10238
            if (URI != NULL) {
 
10239
                ret = xmlDictLookup(dict, URI, -1);
 
10240
                xmlFree(URI);
 
10241
                return(ret);
 
10242
            }
 
10243
        }
 
10244
    }
 
10245
    return(NULL);
 
10246
}
 
10247
    
 
10248
 
 
10249
 
 
10250
/**
 
10251
 * xmlSchemaAddSchemaDoc:
 
10252
 * @pctxt:  a schema validation context
 
10253
 * @schema:  the schema being built
 
10254
 * @node:  a subtree containing XML Schema informations
 
10255
 *
 
10256
 * Parse an included (and to-be-redefined) XML schema document.
 
10257
 *
 
10258
 * Returns 0 on success, a positive error code on errors and
 
10259
 *         -1 in case of an internal or API error.
 
10260
 */
 
10261
 
 
10262
static int
 
10263
xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
 
10264
                int type, /* import or include or redefine */
 
10265
                const xmlChar *schemaLocation,
 
10266
                xmlDocPtr schemaDoc,
 
10267
                const char *schemaBuffer,
 
10268
                int schemaBufferLen,
 
10269
                xmlNodePtr invokingNode,
 
10270
                const xmlChar *sourceTargetNamespace,           
 
10271
                const xmlChar *importNamespace, 
 
10272
                xmlSchemaBucketPtr *bucket)
 
10273
{
 
10274
    const xmlChar *targetNamespace = NULL;
 
10275
    xmlSchemaSchemaRelationPtr relation = NULL;
 
10276
    xmlDocPtr doc = NULL;
 
10277
    int res = 0, err = 0, located = 0, preserveDoc = 0;
 
10278
    xmlSchemaBucketPtr bkt = NULL;
 
10279
 
 
10280
    if (bucket != NULL)
 
10281
        *bucket = NULL;
 
10282
    
 
10283
    switch (type) {
 
10284
        case XML_SCHEMA_SCHEMA_IMPORT:
 
10285
        case XML_SCHEMA_SCHEMA_MAIN:
 
10286
            err = XML_SCHEMAP_SRC_IMPORT;
 
10287
            break;
 
10288
        case XML_SCHEMA_SCHEMA_INCLUDE:
 
10289
            err = XML_SCHEMAP_SRC_INCLUDE;
 
10290
            break;
 
10291
        case XML_SCHEMA_SCHEMA_REDEFINE:
 
10292
            err = XML_SCHEMAP_SRC_REDEFINE;
 
10293
            break;
 
10294
    }    
 
10295
       
 
10296
 
 
10297
    /* Special handling for the main schema:
 
10298
    * skip the location and relation logic and just parse the doc.
 
10299
    * We need just a bucket to be returned in this case.
 
10300
    */    
 
10301
    if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
 
10302
        goto doc_load;  
 
10303
 
 
10304
    /* Note that we expect the location to be an absulute URI. */ 
 
10305
    if (schemaLocation != NULL) {
 
10306
        bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
 
10307
        if ((bkt != NULL) &&
 
10308
            (pctxt->constructor->bucket == bkt)) {
 
10309
            /* Report self-imports/inclusions/redefinitions. */
 
10310
            
 
10311
            xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
 
10312
                invokingNode, NULL,
 
10313
                "The schema must not import/include/redefine itself",
 
10314
                NULL, NULL);
 
10315
            goto exit;
 
10316
        }
 
10317
    }
 
10318
    /*
 
10319
    * Create a relation for the graph of schemas.
 
10320
    */
 
10321
    relation = xmlSchemaSchemaRelationCreate();
 
10322
    if (relation == NULL)
 
10323
        return(-1);    
 
10324
    xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
 
10325
        relation);
 
10326
    relation->type = type;
 
10327
 
 
10328
    /*
 
10329
    * Save the namespace import information.
 
10330
    */
 
10331
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
 
10332
        relation->importNamespace = importNamespace;    
 
10333
        if (schemaLocation == NULL) {
 
10334
            /*
 
10335
            * No location; this is just an import of the namespace.
 
10336
            * Note that we don't assign a bucket to the relation
 
10337
            * in this case.
 
10338
            */
 
10339
            goto exit;
 
10340
        }
 
10341
        targetNamespace = importNamespace;
 
10342
    }
 
10343
 
 
10344
    /* Did we already fetch the doc? */
 
10345
    if (bkt != NULL) {          
 
10346
        /* TODO: The following nasty cases will produce an error. */
 
10347
        if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
 
10348
            /* We included/redefined and then try to import a schema. */
 
10349
            if (schemaLocation == NULL)
 
10350
                schemaLocation = BAD_CAST "in_memory_buffer";
 
10351
            xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
 
10352
                invokingNode, NULL,
 
10353
                "The schema document '%s' cannot be imported, since "
 
10354
                "it was already included or redefined",
 
10355
                schemaLocation, NULL);
 
10356
            goto exit;
 
10357
        } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
 
10358
            /* We imported and then try to include/redefine a schema. */
 
10359
            if (schemaLocation == NULL)
 
10360
                schemaLocation = BAD_CAST "in_memory_buffer";
 
10361
            xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
 
10362
                invokingNode, NULL,
 
10363
                "The schema document '%s' cannot be included or "
 
10364
                "redefined, since it was already imported",
 
10365
                schemaLocation, NULL);
 
10366
            goto exit;
 
10367
        }       
 
10368
    }
 
10369
        
 
10370
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
 
10371
        /*
 
10372
        * Given that the schemaLocation [attribute] is only a hint, it is open
 
10373
        * to applications to ignore all but the first <import> for a given
 
10374
        * namespace, regardless of the ļæ½actual valueļæ½ of schemaLocation, but
 
10375
        * such a strategy risks missing useful information when new
 
10376
        * schemaLocations are offered.
 
10377
        *
 
10378
        * We will use the first <import> that comes with a location.
 
10379
        * Further <import>s *with* a location, will result in an error.
 
10380
        * TODO: Better would be to just report a warning here, but
 
10381
        * we'll try it this way until someone complains.
 
10382
        *
 
10383
        * Schema Document Location Strategy:
 
10384
        * 3 Based on the namespace name, identify an existing schema document,
 
10385
        * either as a resource which is an XML document or a <schema> element
 
10386
        * information item, in some local schema repository;
 
10387
        * 5 Attempt to resolve the namespace name to locate such a resource.
 
10388
        *
 
10389
        * NOTE: (3) and (5) are not supported.
 
10390
        */      
 
10391
        if (bkt != NULL) {
 
10392
            relation->bucket = bkt;
 
10393
            goto exit;
 
10394
        }
 
10395
        bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
 
10396
            importNamespace, 1);
 
10397
 
 
10398
        if (bkt != NULL) {          
 
10399
            relation->bucket = bkt;
 
10400
            if (bkt->schemaLocation == NULL) {
 
10401
                /* First given location of the schema; load the doc. */
 
10402
                bkt->schemaLocation = schemaLocation;
 
10403
            } else {
 
10404
                if (!xmlStrEqual(schemaLocation,
 
10405
                    bkt->schemaLocation)) {
 
10406
                    /*
 
10407
                    * Additional location given; just skip it.
 
10408
                    * URGENT TODO: We should report a warning here.
 
10409
                    * res = XML_SCHEMAP_SRC_IMPORT;
 
10410
                    */
 
10411
                    if (schemaLocation == NULL)
 
10412
                        schemaLocation = BAD_CAST "in_memory_buffer";
 
10413
 
 
10414
                    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
 
10415
                        XML_SCHEMAP_WARN_SKIP_SCHEMA,
 
10416
                        invokingNode, NULL,
 
10417
                        "Skipping import of schema located at '%s' for the "
 
10418
                        "namespace '%s', since this namespace was already "
 
10419
                        "imported with the schema located at '%s'",
 
10420
                        schemaLocation, importNamespace, bkt->schemaLocation);
 
10421
                }
 
10422
                goto exit;
 
10423
            }
 
10424
        }       
 
10425
        /* 
 
10426
        * No bucket + first location: load the doc and create a
 
10427
        * bucket.
 
10428
        */
 
10429
    } else {
 
10430
        /* <include> and <redefine> */
 
10431
        if (bkt != NULL) {
 
10432
                    
 
10433
            if ((bkt->origTargetNamespace == NULL) &&
 
10434
                (bkt->targetNamespace != sourceTargetNamespace)) {
 
10435
                xmlSchemaBucketPtr chamel;
 
10436
                
 
10437
                /*
 
10438
                * Chameleon include/redefine: skip loading only if it was
 
10439
                * aleady build for the targetNamespace of the including
 
10440
                * schema.
 
10441
                */
 
10442
                /*
 
10443
                * URGENT TODO: If the schema is a chameleon-include then copy
 
10444
                * the components into the including schema and modify the
 
10445
                * targetNamespace of those components, do nothing otherwise.
 
10446
                * NOTE: This is currently worked-around by compiling the
 
10447
                * chameleon for every destinct including targetNamespace; thus
 
10448
                * not performant at the moment.
 
10449
                * TODO: Check when the namespace in wildcards for chameleons
 
10450
                * needs to be converted: before we built wildcard intersections
 
10451
                * or after.
 
10452
                *   Answer: after!
 
10453
                */
 
10454
                chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
 
10455
                    schemaLocation, sourceTargetNamespace);
 
10456
                if (chamel != NULL) {
 
10457
                    /* A fitting chameleon was already parsed; NOP. */
 
10458
                    relation->bucket = chamel;
 
10459
                    goto exit;
 
10460
                }
 
10461
                /* 
 
10462
                * We need to parse the chameleon again for a different
 
10463
                * targetNamespace.
 
10464
                * CHAMELEON TODO: Optimize this by only parsing the
 
10465
                * chameleon once, and then copying the components to
 
10466
                * the new targetNamespace.
 
10467
                */
 
10468
                bkt = NULL;
 
10469
            } else {
 
10470
                relation->bucket = bkt;
 
10471
                goto exit;
 
10472
            }       
 
10473
        }
 
10474
    }
 
10475
    if ((bkt != NULL) && (bkt->doc != NULL)) {
 
10476
        PERROR_INT("xmlSchemaAddSchemaDoc",
 
10477
            "trying to load a schema doc, but a doc is already "
 
10478
            "assigned to the schema bucket");
 
10479
        goto exit_failure;
 
10480
    }
 
10481
 
 
10482
doc_load:
 
10483
    /*
 
10484
    * Load the document.
 
10485
    */
 
10486
    if (schemaDoc != NULL) {
 
10487
        doc = schemaDoc;
 
10488
        /* Don' free this one, since it was provided by the caller. */
 
10489
        preserveDoc = 1;
 
10490
        /* TODO: Does the context or the doc hold the location? */
 
10491
        if (schemaDoc->URL != NULL)
 
10492
            schemaLocation = xmlDictLookup(pctxt->dict,
 
10493
                schemaDoc->URL, -1);
 
10494
        else
 
10495
            schemaLocation = BAD_CAST "in_memory_buffer";
 
10496
    } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
 
10497
        xmlParserCtxtPtr parserCtxt;
 
10498
 
 
10499
        parserCtxt = xmlNewParserCtxt();
 
10500
        if (parserCtxt == NULL) {
 
10501
            xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
 
10502
                "allocating a parser context", NULL);
 
10503
            goto exit_failure;
 
10504
        }
 
10505
        if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
 
10506
            /*
 
10507
            * TODO: Do we have to burden the schema parser dict with all
 
10508
            * the content of the schema doc?
 
10509
            */
 
10510
            xmlDictFree(parserCtxt->dict);
 
10511
            parserCtxt->dict = pctxt->dict;
 
10512
            xmlDictReference(parserCtxt->dict);
 
10513
        }
 
10514
        if (schemaLocation != NULL) {
 
10515
            /* Parse from file. */
 
10516
            doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
 
10517
                NULL, SCHEMAS_PARSE_OPTIONS);
 
10518
        } else if (schemaBuffer != NULL) {
 
10519
            /* Parse from memory buffer. */
 
10520
            doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
 
10521
                NULL, NULL, SCHEMAS_PARSE_OPTIONS);
 
10522
            schemaLocation = xmlStrdup(BAD_CAST "in_memory_buffer");
 
10523
            if (doc != NULL)
 
10524
                doc->URL = schemaLocation;          
 
10525
        }
 
10526
        /*
 
10527
        * For <import>:
 
10528
        * 2.1 The referent is (a fragment of) a resource which is an
 
10529
        * XML document (see clause 1.1), which in turn corresponds to
 
10530
        * a <schema> element information item in a well-formed information
 
10531
        * set, which in turn corresponds to a valid schema.
 
10532
        * TODO: (2.1) fragments of XML documents are not supported.
 
10533
        *
 
10534
        * 2.2 The referent is a <schema> element information item in
 
10535
        * a well-formed information set, which in turn corresponds
 
10536
        * to a valid schema.
 
10537
        * TODO: (2.2) is not supported.
 
10538
        */
 
10539
        if (doc == NULL) {
 
10540
            xmlErrorPtr lerr;
 
10541
            lerr = xmlGetLastError();
 
10542
            /*
 
10543
            * Check if this a parser error, or if the document could
 
10544
            * just not be located.
 
10545
            * TODO: Try to find specific error codes to react only on
 
10546
            * localisation failures.
 
10547
            */
 
10548
            if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
 
10549
                /*
 
10550
                * We assume a parser error here.
 
10551
                */
 
10552
                located = 1;
 
10553
                /* TODO: Error code ?? */
 
10554
                res = XML_SCHEMAP_SRC_IMPORT_2_1;
 
10555
                xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
 
10556
                    invokingNode, NULL,
 
10557
                    "Failed to parse the XML resource '%s'",
 
10558
                    schemaLocation, NULL);
 
10559
            }
 
10560
        }
 
10561
        xmlFreeParserCtxt(parserCtxt);
 
10562
        if ((doc == NULL) && located)
 
10563
            goto exit_error;
 
10564
    } else {
 
10565
        xmlSchemaPErr(pctxt, NULL,
 
10566
            XML_SCHEMAP_NOTHING_TO_PARSE,
 
10567
            "No information for parsing was provided with the "
 
10568
            "given schema parser context.\n",
 
10569
            NULL, NULL);
 
10570
        goto exit_failure;
 
10571
    }
 
10572
    /*
 
10573
    * Preprocess the document.
 
10574
    */
 
10575
    if (doc != NULL) {
 
10576
        xmlNodePtr docElem = NULL;
 
10577
 
 
10578
        located = 1;    
 
10579
        docElem = xmlDocGetRootElement(doc);
 
10580
        if (docElem == NULL) {
 
10581
            xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
 
10582
                invokingNode, NULL, 
 
10583
                "The document '%s' has no document element",
 
10584
                schemaLocation, NULL);
 
10585
            goto exit_error;
 
10586
        }
 
10587
        /*
 
10588
        * Remove all the blank text nodes.
 
10589
        */
 
10590
        xmlSchemaCleanupDoc(pctxt, docElem);
 
10591
        /*
 
10592
        * Check the schema's top level element.
 
10593
        */
 
10594
        if (!IS_SCHEMA(docElem, "schema")) {
 
10595
            xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
 
10596
                invokingNode, NULL,
 
10597
                "The XML document '%s' is not a schema document",
 
10598
                schemaLocation, NULL);
 
10599
            goto exit_error;
 
10600
        }
 
10601
        /* 
 
10602
        * Note that we don't apply a type check for the
 
10603
        * targetNamespace value here.
 
10604
        */
 
10605
        targetNamespace = xmlSchemaGetProp(pctxt, docElem,
 
10606
            "targetNamespace");
 
10607
    }
 
10608
    
 
10609
/* after_doc_loading: */
 
10610
    if ((bkt == NULL) && located) {
 
10611
        /* Only create a bucket if the schema was located. */
 
10612
        bkt = xmlSchemaBucketCreate(pctxt, type,
 
10613
            targetNamespace);
 
10614
        if (bkt == NULL)
 
10615
            goto exit_failure;
 
10616
    }
 
10617
    if (bkt != NULL) {
 
10618
        bkt->schemaLocation = schemaLocation;
 
10619
        bkt->located = located;
 
10620
        if (doc != NULL) {
 
10621
            bkt->doc = doc;
 
10622
            bkt->targetNamespace = targetNamespace;
 
10623
            bkt->origTargetNamespace = targetNamespace;
 
10624
            if (preserveDoc)
 
10625
                bkt->preserveDoc = 1;
 
10626
        }
 
10627
        if (WXS_IS_BUCKET_IMPMAIN(type))
 
10628
            bkt->imported++;
 
10629
            /*
 
10630
            * Add it to the graph of schemas.
 
10631
            */
 
10632
        if (relation != NULL)
 
10633
            relation->bucket = bkt;
 
10634
    }
 
10635
  
 
10636
exit:
 
10637
    /*
 
10638
    * Return the bucket explicitely; this is needed for the
 
10639
    * main schema.
 
10640
    */
 
10641
    if (bucket != NULL)
 
10642
        *bucket = bkt;    
 
10643
    return (0);
 
10644
 
 
10645
exit_error:
 
10646
    if ((doc != NULL) && (! preserveDoc)) {
 
10647
        xmlFreeDoc(doc);
 
10648
        if (bkt != NULL)
 
10649
            bkt->doc = NULL;
 
10650
    }
 
10651
    return(pctxt->err);
 
10652
 
 
10653
exit_failure:
 
10654
    if ((doc != NULL) && (! preserveDoc)) {
 
10655
        xmlFreeDoc(doc);
 
10656
        if (bkt != NULL)
 
10657
            bkt->doc = NULL;
 
10658
    }    
 
10659
    return (-1);
 
10660
}
 
10661
 
 
10662
/**
 
10663
 * xmlSchemaParseImport:
 
10664
 * @ctxt:  a schema validation context
 
10665
 * @schema:  the schema being built
 
10666
 * @node:  a subtree containing XML Schema informations
 
10667
 *
 
10668
 * parse a XML schema Import definition
 
10669
 * *WARNING* this interface is highly subject to change
 
10670
 *
 
10671
 * Returns 0 in case of success, a positive error code if
 
10672
 * not valid and -1 in case of an internal error.
 
10673
 */
 
10674
static int
 
10675
xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
 
10676
                     xmlNodePtr node)
 
10677
{
 
10678
    xmlNodePtr child;
 
10679
    const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
 
10680
    const xmlChar *thisTargetNamespace;
 
10681
    xmlAttrPtr attr;
 
10682
    int ret = 0;
 
10683
    xmlSchemaBucketPtr bucket = NULL;
 
10684
 
 
10685
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 
10686
        return (-1);
 
10687
 
 
10688
    /*
 
10689
    * Check for illegal attributes.
 
10690
    */
 
10691
    attr = node->properties;
 
10692
    while (attr != NULL) {
 
10693
        if (attr->ns == NULL) {
 
10694
            if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 
10695
                (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
 
10696
                (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
 
10697
                xmlSchemaPIllegalAttrErr(pctxt,
 
10698
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
10699
            }
 
10700
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
10701
            xmlSchemaPIllegalAttrErr(pctxt,
 
10702
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
10703
        }
 
10704
        attr = attr->next;
 
10705
    }
 
10706
    /*
 
10707
    * Extract and validate attributes.
 
10708
    */
 
10709
    if (xmlSchemaPValAttr(pctxt, NULL, node,
 
10710
        "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
 
10711
        &namespaceName) != 0) {
 
10712
        xmlSchemaPSimpleTypeErr(pctxt,
 
10713
            XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
10714
            NULL, node,
 
10715
            xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
 
10716
            NULL, namespaceName, NULL, NULL, NULL);
 
10717
        return (pctxt->err);
 
10718
    }
 
10719
 
 
10720
    if (xmlSchemaPValAttr(pctxt, NULL, node,
 
10721
        "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
 
10722
        &schemaLocation) != 0) {
 
10723
        xmlSchemaPSimpleTypeErr(pctxt,
 
10724
            XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
10725
            NULL, node,
 
10726
            xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
 
10727
            NULL, namespaceName, NULL, NULL, NULL);
 
10728
        return (pctxt->err);
 
10729
    }
 
10730
    /*
 
10731
    * And now for the children...
 
10732
    */
 
10733
    child = node->children;
 
10734
    if (IS_SCHEMA(child, "annotation")) {
 
10735
        /*
 
10736
         * the annotation here is simply discarded ...
 
10737
         * TODO: really?
 
10738
         */
 
10739
        child = child->next;
 
10740
    }
 
10741
    if (child != NULL) {
 
10742
        xmlSchemaPContentErr(pctxt,
 
10743
            XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
10744
            NULL, node, child, NULL,
 
10745
            "(annotation?)");
 
10746
    }
 
10747
    /*
 
10748
    * Apply additional constraints.
 
10749
    *
 
10750
    * Note that it is important to use the original @targetNamespace
 
10751
    * (or none at all), to rule out imports of schemas _with_ a
 
10752
    * @targetNamespace if the importing schema is a chameleon schema
 
10753
    * (with no @targetNamespace).
 
10754
    */
 
10755
    thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
 
10756
    if (namespaceName != NULL) {
 
10757
        /*
 
10758
        * 1.1 If the namespace [attribute] is present, then its ļæ½actual valueļæ½
 
10759
        * must not match the ļæ½actual valueļæ½ of the enclosing <schema>'s
 
10760
        * targetNamespace [attribute].
 
10761
        */
 
10762
        if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
 
10763
            xmlSchemaPCustomErr(pctxt,
 
10764
                XML_SCHEMAP_SRC_IMPORT_1_1,
 
10765
                NULL, node,
 
10766
                "The value of the attribute 'namespace' must not match "
 
10767
                "the target namespace '%s' of the importing schema",
 
10768
                thisTargetNamespace);
 
10769
            return (pctxt->err);
 
10770
        }
 
10771
    } else {
 
10772
        /*
 
10773
        * 1.2 If the namespace [attribute] is not present, then the enclosing
 
10774
        * <schema> must have a targetNamespace [attribute].
 
10775
        */
 
10776
        if (thisTargetNamespace == NULL) {
 
10777
            xmlSchemaPCustomErr(pctxt,
 
10778
                XML_SCHEMAP_SRC_IMPORT_1_2,
 
10779
                NULL, node,
 
10780
                "The attribute 'namespace' must be existent if "
 
10781
                "the importing schema has no target namespace",
 
10782
                NULL);
 
10783
            return (pctxt->err);
 
10784
        }
 
10785
    }
 
10786
    /*
 
10787
    * Locate and acquire the schema document.
 
10788
    */
 
10789
    if (schemaLocation != NULL)
 
10790
        schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
 
10791
            schemaLocation, node);
 
10792
    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
 
10793
        schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
 
10794
        namespaceName, &bucket);
 
10795
 
 
10796
    if (ret != 0)
 
10797
        return(ret);
 
10798
 
 
10799
    /*
 
10800
    * For <import>: "It is *not* an error for the application
 
10801
    * schema reference strategy to fail."
 
10802
    * So just don't parse if no schema document was found.
 
10803
    * Note that we will get no bucket if the schema could not be
 
10804
    * located or if there was no schemaLocation.
 
10805
    */
 
10806
    if ((bucket == NULL) && (schemaLocation != NULL)) {
 
10807
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
 
10808
            XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
 
10809
            node, NULL,
 
10810
            "Failed to locate a schema at location '%s'. "
 
10811
            "Skipping the import", schemaLocation, NULL, NULL);
 
10812
    }
 
10813
    
 
10814
    if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) { 
 
10815
        ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
 
10816
    }
 
10817
    
 
10818
    return (ret);
 
10819
}
 
10820
 
 
10821
static int
 
10822
xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
 
10823
                                     xmlSchemaPtr schema,
 
10824
                                     xmlNodePtr node,
 
10825
                                     xmlChar **schemaLocation,
 
10826
                                     int type)
 
10827
{
 
10828
    xmlAttrPtr attr;
 
10829
 
 
10830
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
 
10831
        (schemaLocation == NULL))
 
10832
        return (-1);
 
10833
 
 
10834
    *schemaLocation = NULL;
 
10835
    /*
 
10836
    * Check for illegal attributes.
 
10837
    * Applies for both <include> and <redefine>.
 
10838
    */
 
10839
    attr = node->properties;
 
10840
    while (attr != NULL) {
 
10841
        if (attr->ns == NULL) {
 
10842
            if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 
10843
                (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
 
10844
                xmlSchemaPIllegalAttrErr(pctxt,
 
10845
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
10846
            }
 
10847
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
10848
            xmlSchemaPIllegalAttrErr(pctxt,
 
10849
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
10850
        }
 
10851
        attr = attr->next;
 
10852
    }
 
10853
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
 
10854
    /*
 
10855
    * Preliminary step, extract the URI-Reference and make an URI
 
10856
    * from the base.
 
10857
    */
 
10858
    /*
 
10859
    * Attribute "schemaLocation" is mandatory.
 
10860
    */
 
10861
    attr = xmlSchemaGetPropNode(node, "schemaLocation");
 
10862
    if (attr != NULL) {
 
10863
        xmlChar *base = NULL;
 
10864
        xmlChar *uri = NULL;
 
10865
 
 
10866
        if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
 
10867
            xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
 
10868
            (const xmlChar **) schemaLocation) != 0)
 
10869
            goto exit_error;
 
10870
        base = xmlNodeGetBase(node->doc, node);
 
10871
        if (base == NULL) {
 
10872
            uri = xmlBuildURI(*schemaLocation, node->doc->URL);
 
10873
        } else {
 
10874
            uri = xmlBuildURI(*schemaLocation, base);
 
10875
            xmlFree(base);
 
10876
        }
 
10877
        if (uri == NULL) {
 
10878
            PERROR_INT("xmlSchemaParseIncludeOrRedefine",
 
10879
                "could not build an URI from the schemaLocation")
 
10880
            goto exit_failure;
 
10881
        }
 
10882
        (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
 
10883
        xmlFree(uri);
 
10884
    } else {
 
10885
        xmlSchemaPMissingAttrErr(pctxt,
 
10886
            XML_SCHEMAP_S4S_ATTR_MISSING,
 
10887
            NULL, node, "schemaLocation", NULL);
 
10888
        goto exit_error;
 
10889
    }
 
10890
    /*
 
10891
    * Report self-inclusion and self-redefinition.
 
10892
    */
 
10893
    if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
 
10894
        if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
 
10895
            xmlSchemaPCustomErr(pctxt,
 
10896
                XML_SCHEMAP_SRC_REDEFINE,
 
10897
                NULL, node,
 
10898
                "The schema document '%s' cannot redefine itself.",
 
10899
                *schemaLocation);           
 
10900
        } else {
 
10901
            xmlSchemaPCustomErr(pctxt,
 
10902
                XML_SCHEMAP_SRC_INCLUDE,
 
10903
                NULL, node,
 
10904
                "The schema document '%s' cannot include itself.",
 
10905
                *schemaLocation);
 
10906
        }
 
10907
        goto exit_error;
 
10908
    }
 
10909
    
 
10910
    return(0);
 
10911
exit_error:
 
10912
    return(pctxt->err);
 
10913
exit_failure:
 
10914
    return(-1);
 
10915
}
 
10916
 
 
10917
static int
 
10918
xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
 
10919
                                xmlSchemaPtr schema,
 
10920
                                xmlNodePtr node,
 
10921
                                int type)
 
10922
{
 
10923
    xmlNodePtr child = NULL;
 
10924
    const xmlChar *schemaLocation = NULL;
 
10925
    int res = 0; /* hasRedefinitions = 0 */
 
10926
    int isChameleon = 0, wasChameleon = 0;
 
10927
    xmlSchemaBucketPtr bucket = NULL;
 
10928
 
 
10929
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 
10930
        return (-1);
 
10931
 
 
10932
    /*
 
10933
    * Parse attributes. Note that the returned schemaLocation will
 
10934
    * be already converted to an absolute URI.
 
10935
    */
 
10936
    res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
 
10937
        node, (xmlChar **) (&schemaLocation), type);
 
10938
    if (res != 0)
 
10939
        return(res);               
 
10940
    /*
 
10941
    * Load and add the schema document.
 
10942
    */
 
10943
    res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
 
10944
        NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
 
10945
    if (res != 0)
 
10946
        return(res);    
 
10947
    /*
 
10948
    * If we get no schema bucket back, then this means that the schema
 
10949
    * document could not be located or was broken XML or was not
 
10950
    * a schema document.
 
10951
    */    
 
10952
    if ((bucket == NULL) || (bucket->doc == NULL)) {
 
10953
        if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
 
10954
            /*
 
10955
            * WARNING for <include>:
 
10956
            * We will raise an error if the schema cannot be located
 
10957
            * for inclusions, since the that was the feedback from the
 
10958
            * schema people. I.e. the following spec piece will *not* be
 
10959
            * satisfied:
 
10960
            * SPEC src-include: "It is not an error for the ļæ½actual valueļæ½ of the
 
10961
            * schemaLocation [attribute] to fail to resolve it all, in which
 
10962
            * case no corresponding inclusion is performed.
 
10963
            * So do we need a warning report here?"
 
10964
            */
 
10965
            res = XML_SCHEMAP_SRC_INCLUDE;
 
10966
            xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
 
10967
                node, NULL,
 
10968
                "Failed to load the document '%s' for inclusion",
 
10969
                schemaLocation, NULL);
 
10970
        } else {
 
10971
            /*
 
10972
            * NOTE: This was changed to raise an error even if no redefinitions
 
10973
            * are specified.
 
10974
            *
 
10975
            * SPEC src-redefine (1)
 
10976
            * "If there are any element information items among the [children]
 
10977
            * other than <annotation> then the ļæ½actual valueļæ½ of the
 
10978
            * schemaLocation [attribute] must successfully resolve."
 
10979
            * TODO: Ask the WG if a the location has always to resolve
 
10980
            * here as well!
 
10981
            */
 
10982
            res = XML_SCHEMAP_SRC_REDEFINE;
 
10983
            xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
 
10984
                node, NULL,
 
10985
                "Failed to load the document '%s' for redefinition",
 
10986
                schemaLocation, NULL);
 
10987
        }
 
10988
    } else {
 
10989
        /*
 
10990
        * Check targetNamespace sanity before parsing the new schema.
 
10991
        * TODO: Note that we won't check further content if the
 
10992
        * targetNamespace was bad.
 
10993
        */    
 
10994
        if (bucket->origTargetNamespace != NULL) {          
 
10995
            /*
 
10996
            * SPEC src-include (2.1)
 
10997
            * "SII has a targetNamespace [attribute], and its ļæ½actual
 
10998
            * valueļæ½ is identical to the ļæ½actual valueļæ½ of the targetNamespace
 
10999
            * [attribute] of SIIļæ½ (which must have such an [attribute])."
 
11000
            */
 
11001
            if (pctxt->targetNamespace == NULL) {
 
11002
                xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
11003
                    XML_SCHEMAP_SRC_INCLUDE,
 
11004
                    node, NULL,
 
11005
                    "The target namespace of the included/redefined schema "
 
11006
                    "'%s' has to be absent, since the including/redefining "
 
11007
                    "schema has no target namespace",
 
11008
                    schemaLocation, NULL);
 
11009
                goto exit_error;
 
11010
            } else if (!xmlStrEqual(bucket->origTargetNamespace,
 
11011
                pctxt->targetNamespace)) {
 
11012
                /* TODO: Change error function. */
 
11013
                xmlSchemaPCustomErrExt(pctxt,
 
11014
                    XML_SCHEMAP_SRC_INCLUDE,
 
11015
                    NULL, node,
 
11016
                    "The target namespace '%s' of the included/redefined "
 
11017
                    "schema '%s' differs from '%s' of the "
 
11018
                    "including/redefining schema",
 
11019
                    bucket->origTargetNamespace, schemaLocation,
 
11020
                    pctxt->targetNamespace);
 
11021
                goto exit_error;
 
11022
            }
 
11023
        } else if (pctxt->targetNamespace != NULL) {        
 
11024
            /*
 
11025
            * Chameleons: the original target namespace will
 
11026
            * differ from the resulting namespace.
 
11027
            */
 
11028
            isChameleon = 1;
 
11029
            if (bucket->parsed &&
 
11030
                (bucket->targetNamespace != pctxt->targetNamespace)) {
 
11031
                /*
 
11032
                * This is a sanity check, I dunno yet if this can happen.
 
11033
                */
 
11034
                PERROR_INT("xmlSchemaParseIncludeOrRedefine",
 
11035
                    "trying to use an already parsed schema for a "
 
11036
                    "different targetNamespace");
 
11037
                return(-1);
 
11038
            }
 
11039
            bucket->targetNamespace = pctxt->targetNamespace;
 
11040
        }
 
11041
    }    
 
11042
    /*
 
11043
    * Parse the schema.
 
11044
    */   
 
11045
    if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
 
11046
        if (isChameleon) {
 
11047
            /* TODO: Get rid of this flag on the schema itself. */
 
11048
            if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
 
11049
                schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
 
11050
            } else
 
11051
                wasChameleon = 1;
 
11052
        }
 
11053
        xmlSchemaParseNewDoc(pctxt, schema, bucket);
 
11054
        /* Restore chameleon flag. */
 
11055
        if (isChameleon && (!wasChameleon))
 
11056
            schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
 
11057
    }
 
11058
    /*
 
11059
    * And now for the children...
 
11060
    */
 
11061
    child = node->children;    
 
11062
    if (type == XML_SCHEMA_SCHEMA_REDEFINE) {   
 
11063
        /*
 
11064
        * Parse (simpleType | complexType | group | attributeGroup))*
 
11065
        */
 
11066
        pctxt->redefined = bucket;
 
11067
        /*
 
11068
        * How to proceed if the redefined schema was not located?
 
11069
        */
 
11070
        pctxt->isRedefine = 1;
 
11071
        while (IS_SCHEMA(child, "annotation") ||
 
11072
            IS_SCHEMA(child, "simpleType") ||
 
11073
            IS_SCHEMA(child, "complexType") ||
 
11074
            IS_SCHEMA(child, "group") ||
 
11075
            IS_SCHEMA(child, "attributeGroup")) {
 
11076
            if (IS_SCHEMA(child, "annotation")) {
 
11077
                /*
 
11078
                * TODO: discard or not?
 
11079
                */
 
11080
            } else if (IS_SCHEMA(child, "simpleType")) {
 
11081
                xmlSchemaParseSimpleType(pctxt, schema, child, 1);
 
11082
            } else if (IS_SCHEMA(child, "complexType")) {
 
11083
                xmlSchemaParseComplexType(pctxt, schema, child, 1);
 
11084
                /* hasRedefinitions = 1; */
 
11085
            } else if (IS_SCHEMA(child, "group")) {             
 
11086
                /* hasRedefinitions = 1; */
 
11087
                xmlSchemaParseModelGroupDefinition(pctxt,
 
11088
                    schema, child);
 
11089
            } else if (IS_SCHEMA(child, "attributeGroup")) {
 
11090
                /* hasRedefinitions = 1; */
 
11091
                xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
 
11092
                    child);
 
11093
            }
 
11094
            child = child->next;
 
11095
        }
 
11096
        pctxt->redefined = NULL;
 
11097
        pctxt->isRedefine = 0;
 
11098
    } else {
 
11099
        if (IS_SCHEMA(child, "annotation")) {
 
11100
            /*
 
11101
            * TODO: discard or not?
 
11102
            */
 
11103
            child = child->next;
 
11104
        }
 
11105
    }    
 
11106
    if (child != NULL) {
 
11107
        res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
 
11108
        if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
 
11109
            xmlSchemaPContentErr(pctxt, res,
 
11110
                NULL, node, child, NULL,
 
11111
                "(annotation | (simpleType | complexType | group | attributeGroup))*");
 
11112
        } else {
 
11113
             xmlSchemaPContentErr(pctxt, res,
 
11114
                NULL, node, child, NULL,
 
11115
                "(annotation?)");
 
11116
        }       
 
11117
    }       
 
11118
    return(res);
 
11119
 
 
11120
exit_error:
 
11121
    return(pctxt->err);
 
11122
}
 
11123
 
 
11124
static int
 
11125
xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
 
11126
                       xmlNodePtr node)
 
11127
{
 
11128
    int res;
 
11129
#ifndef ENABLE_REDEFINE
 
11130
    TODO
 
11131
    return(0);
 
11132
#endif
 
11133
    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
 
11134
        XML_SCHEMA_SCHEMA_REDEFINE);
 
11135
    if (res != 0)
 
11136
        return(res);
 
11137
    return(0);
 
11138
}
 
11139
 
 
11140
static int
 
11141
xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
 
11142
                       xmlNodePtr node)
 
11143
{
 
11144
    int res;
 
11145
 
 
11146
    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
 
11147
        XML_SCHEMA_SCHEMA_INCLUDE);
 
11148
    if (res != 0)
 
11149
        return(res);
 
11150
    return(0);
 
11151
}
 
11152
 
 
11153
/**
 
11154
 * xmlSchemaParseModelGroup:
 
11155
 * @ctxt:  a schema validation context
 
11156
 * @schema:  the schema being built
 
11157
 * @node:  a subtree containing XML Schema informations
 
11158
 * @type: the "compositor" type
 
11159
 * @particleNeeded: if a a model group with a particle
 
11160
 *
 
11161
 * parse a XML schema Sequence definition.
 
11162
 * Applies parts of:
 
11163
 *   Schema Representation Constraint:
 
11164
 *     Redefinition Constraints and Semantics (src-redefine)
 
11165
 *     (6.1), (6.1.1), (6.1.2)
 
11166
 *
 
11167
 *   Schema Component Constraint: 
 
11168
 *     All Group Limited (cos-all-limited) (2)
 
11169
 *     TODO: Actually this should go to component-level checks,
 
11170
 *     but is done here due to performance. Move it to an other layer
 
11171
 *     is schema construction via an API is implemented.
 
11172
 *
 
11173
 * *WARNING* this interface is highly subject to change
 
11174
 *
 
11175
 * Returns -1 in case of error, 0 if the declaration is improper and
 
11176
 *         1 in case of success.
 
11177
 */
 
11178
static xmlSchemaTreeItemPtr
 
11179
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
11180
                         xmlNodePtr node, xmlSchemaTypeType type,
 
11181
                         int withParticle)
 
11182
{
 
11183
    xmlSchemaModelGroupPtr item;
 
11184
    xmlSchemaParticlePtr particle = NULL;
 
11185
    xmlNodePtr child = NULL;
 
11186
    xmlAttrPtr attr;
 
11187
    int min = 1, max = 1, isElemRef, hasRefs = 0;
 
11188
 
 
11189
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 
11190
        return (NULL);
 
11191
    /*
 
11192
    * Create a model group with the given compositor.
 
11193
    */
 
11194
    item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
 
11195
    if (item == NULL)
 
11196
        return (NULL);
 
11197
 
 
11198
    if (withParticle) {
 
11199
        if (type == XML_SCHEMA_TYPE_ALL) {
 
11200
            min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
 
11201
            max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
 
11202
        } else {
 
11203
            /* choice + sequence */
 
11204
            min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
 
11205
            max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
 
11206
                "(xs:nonNegativeInteger | unbounded)");
 
11207
        }
 
11208
        xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
 
11209
        /*
 
11210
        * Create a particle
 
11211
        */
 
11212
        particle = xmlSchemaAddParticle(ctxt, node, min, max);
 
11213
        if (particle == NULL)
 
11214
            return (NULL);
 
11215
        particle->children = (xmlSchemaTreeItemPtr) item;
 
11216
        /*
 
11217
        * Check for illegal attributes.
 
11218
        */
 
11219
        attr = node->properties;
 
11220
        while (attr != NULL) {
 
11221
            if (attr->ns == NULL) {
 
11222
                if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 
11223
                    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
 
11224
                    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
 
11225
                    xmlSchemaPIllegalAttrErr(ctxt,
 
11226
                        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
11227
                }
 
11228
            } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
11229
                xmlSchemaPIllegalAttrErr(ctxt,
 
11230
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
11231
            }
 
11232
            attr = attr->next;
 
11233
        }
 
11234
    } else {
 
11235
        /*
 
11236
        * Check for illegal attributes.
 
11237
        */
 
11238
        attr = node->properties;
 
11239
        while (attr != NULL) {
 
11240
            if (attr->ns == NULL) {
 
11241
                if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
 
11242
                    xmlSchemaPIllegalAttrErr(ctxt,
 
11243
                        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
11244
                }
 
11245
            } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
11246
                xmlSchemaPIllegalAttrErr(ctxt,
 
11247
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
11248
            }
 
11249
            attr = attr->next;
 
11250
        }
 
11251
    }
 
11252
 
 
11253
    /*
 
11254
    * Extract and validate attributes.
 
11255
    */
 
11256
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
11257
    /*
 
11258
    * And now for the children...
 
11259
    */
 
11260
    child = node->children;
 
11261
    if (IS_SCHEMA(child, "annotation")) {
 
11262
        item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 
11263
        child = child->next;
 
11264
    }
 
11265
    if (type == XML_SCHEMA_TYPE_ALL) {
 
11266
        xmlSchemaParticlePtr part, last = NULL;
 
11267
 
 
11268
        while (IS_SCHEMA(child, "element")) {
 
11269
            part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
 
11270
                schema, child, &isElemRef, 0);
 
11271
            /*
 
11272
            * SPEC cos-all-limited (2)
 
11273
            * "The {max occurs} of all the particles in the {particles}
 
11274
            * of the ('all') group must be 0 or 1.
 
11275
            */
 
11276
            if (part != NULL) {
 
11277
                if (isElemRef)
 
11278
                    hasRefs++;
 
11279
                if (part->minOccurs > 1) {
 
11280
                    xmlSchemaPCustomErr(ctxt,
 
11281
                        XML_SCHEMAP_COS_ALL_LIMITED,
 
11282
                        NULL, child,
 
11283
                        "Invalid value for minOccurs (must be 0 or 1)",
 
11284
                        NULL);
 
11285
                    /* Reset to 1. */
 
11286
                    part->minOccurs = 1;
 
11287
                }
 
11288
                if (part->maxOccurs > 1) {
 
11289
                    xmlSchemaPCustomErr(ctxt,
 
11290
                        XML_SCHEMAP_COS_ALL_LIMITED,
 
11291
                        NULL, child,
 
11292
                        "Invalid value for maxOccurs (must be 0 or 1)",
 
11293
                        NULL);
 
11294
                    /* Reset to 1. */
 
11295
                    part->maxOccurs = 1;
 
11296
                }
 
11297
                if (last == NULL)
 
11298
                    item->children = (xmlSchemaTreeItemPtr) part;
 
11299
                else
 
11300
                    last->next = (xmlSchemaTreeItemPtr) part;
 
11301
                last = part;
 
11302
            }
 
11303
            child = child->next;
 
11304
        }
 
11305
        if (child != NULL) {
 
11306
            xmlSchemaPContentErr(ctxt,
 
11307
                XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
11308
                NULL, node, child, NULL,
 
11309
                "(annotation?, (annotation?, element*)");
 
11310
        }
 
11311
    } else {
 
11312
        /* choice + sequence */
 
11313
        xmlSchemaTreeItemPtr part = NULL, last = NULL;
 
11314
 
 
11315
        while ((IS_SCHEMA(child, "element")) ||
 
11316
            (IS_SCHEMA(child, "group")) ||
 
11317
            (IS_SCHEMA(child, "any")) ||
 
11318
            (IS_SCHEMA(child, "choice")) ||
 
11319
            (IS_SCHEMA(child, "sequence"))) {
 
11320
 
 
11321
            if (IS_SCHEMA(child, "element")) {
 
11322
                part = (xmlSchemaTreeItemPtr)
 
11323
                    xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
 
11324
                if (part && isElemRef)
 
11325
                    hasRefs++;
 
11326
            } else if (IS_SCHEMA(child, "group")) {
 
11327
                part =
 
11328
                    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
 
11329
                if (part != NULL)
 
11330
                    hasRefs++;
 
11331
                /*
 
11332
                * Handle redefinitions.
 
11333
                */
 
11334
                if (ctxt->isRedefine && ctxt->redef &&
 
11335
                    (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
 
11336
                    part && part->children)
 
11337
                {
 
11338
                    if ((xmlSchemaGetQNameRefName(part->children) ==
 
11339
                            ctxt->redef->refName) &&
 
11340
                        (xmlSchemaGetQNameRefTargetNs(part->children) ==
 
11341
                            ctxt->redef->refTargetNs))
 
11342
                    {
 
11343
                        /*
 
11344
                        * SPEC src-redefine:
 
11345
                        * (6.1) "If it has a <group> among its contents at
 
11346
                        * some level the ļæ½actual valueļæ½ of whose ref
 
11347
                        * [attribute] is the same as the ļæ½actual valueļæ½ of
 
11348
                        * its own name attribute plus target namespace, then
 
11349
                        * all of the following must be true:"
 
11350
                        * (6.1.1) "It must have exactly one such group."
 
11351
                        */
 
11352
                        if (ctxt->redefCounter != 0) {
 
11353
                            xmlChar *str = NULL;
 
11354
 
 
11355
                            xmlSchemaCustomErr(ACTXT_CAST ctxt,
 
11356
                                XML_SCHEMAP_SRC_REDEFINE, child, NULL,
 
11357
                                "The redefining model group definition "
 
11358
                                "'%s' must not contain more than one "
 
11359
                                "reference to the redefined definition",
 
11360
                                xmlSchemaFormatQName(&str,
 
11361
                                    ctxt->redef->refTargetNs,
 
11362
                                    ctxt->redef->refName),
 
11363
                                NULL);
 
11364
                            FREE_AND_NULL(str)
 
11365
                            part = NULL;
 
11366
                        } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
 
11367
                            ((WXS_PARTICLE(part))->maxOccurs != 1))
 
11368
                        {
 
11369
                            xmlChar *str = NULL;
 
11370
                            /*
 
11371
                            * SPEC src-redefine:
 
11372
                            * (6.1.2) "The ļæ½actual valueļæ½ of both that
 
11373
                            * group's minOccurs and maxOccurs [attribute]
 
11374
                            * must be 1 (or ļæ½absentļæ½).
 
11375
                            */
 
11376
                            xmlSchemaCustomErr(ACTXT_CAST ctxt,
 
11377
                                XML_SCHEMAP_SRC_REDEFINE, child, NULL,
 
11378
                                "The redefining model group definition "
 
11379
                                "'%s' must not contain a reference to the "
 
11380
                                "redefined definition with a "
 
11381
                                "maxOccurs/minOccurs other than 1",
 
11382
                                xmlSchemaFormatQName(&str,
 
11383
                                    ctxt->redef->refTargetNs,
 
11384
                                    ctxt->redef->refName),
 
11385
                                NULL);
 
11386
                            FREE_AND_NULL(str)
 
11387
                            part = NULL;
 
11388
                        }
 
11389
                        ctxt->redef->reference = WXS_BASIC_CAST part;
 
11390
                        ctxt->redefCounter++;
 
11391
                    }                                      
 
11392
                }
 
11393
            } else if (IS_SCHEMA(child, "any")) {
 
11394
                part = (xmlSchemaTreeItemPtr)
 
11395
                    xmlSchemaParseAny(ctxt, schema, child);
 
11396
            } else if (IS_SCHEMA(child, "choice")) {
 
11397
                part = xmlSchemaParseModelGroup(ctxt, schema, child,
 
11398
                    XML_SCHEMA_TYPE_CHOICE, 1);
 
11399
            } else if (IS_SCHEMA(child, "sequence")) {
 
11400
                part = xmlSchemaParseModelGroup(ctxt, schema, child,
 
11401
                    XML_SCHEMA_TYPE_SEQUENCE, 1);
 
11402
            }
 
11403
            if (part != NULL) {
 
11404
                if (last == NULL)
 
11405
                    item->children = part;
 
11406
                else
 
11407
                    last->next = part;
 
11408
                last = part;
 
11409
            }
 
11410
            child = child->next;
 
11411
        }
 
11412
        if (child != NULL) {
 
11413
            xmlSchemaPContentErr(ctxt,
 
11414
                XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
11415
                NULL, node, child, NULL,
 
11416
                "(annotation?, (element | group | choice | sequence | any)*)");
 
11417
        }
 
11418
    }
 
11419
    if ((max == 0) && (min == 0))
 
11420
        return (NULL);
 
11421
    if (hasRefs) {
 
11422
        /*
 
11423
        * We need to resolve references.
 
11424
        */
 
11425
        WXS_ADD_PENDING(ctxt, item);
 
11426
    }
 
11427
    if (withParticle)
 
11428
        return ((xmlSchemaTreeItemPtr) particle);       
 
11429
    else
 
11430
        return ((xmlSchemaTreeItemPtr) item);
 
11431
}
 
11432
 
 
11433
/**
 
11434
 * xmlSchemaParseRestriction:
 
11435
 * @ctxt:  a schema validation context
 
11436
 * @schema:  the schema being built
 
11437
 * @node:  a subtree containing XML Schema informations
 
11438
 *
 
11439
 * parse a XML schema Restriction definition
 
11440
 * *WARNING* this interface is highly subject to change
 
11441
 *
 
11442
 * Returns the type definition or NULL in case of error
 
11443
 */
 
11444
static xmlSchemaTypePtr
 
11445
xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
11446
                          xmlNodePtr node, xmlSchemaTypeType parentType)
 
11447
{
 
11448
    xmlSchemaTypePtr type;
 
11449
    xmlNodePtr child = NULL;
 
11450
    xmlAttrPtr attr;
 
11451
 
 
11452
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 
11453
        return (NULL);
 
11454
    /* Not a component, don't create it. */
 
11455
    type = ctxt->ctxtType;
 
11456
    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
 
11457
 
 
11458
    /*
 
11459
    * Check for illegal attributes.
 
11460
    */
 
11461
    attr = node->properties;
 
11462
    while (attr != NULL) {
 
11463
        if (attr->ns == NULL) {
 
11464
            if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 
11465
                (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
 
11466
                xmlSchemaPIllegalAttrErr(ctxt,
 
11467
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
11468
            }
 
11469
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
11470
            xmlSchemaPIllegalAttrErr(ctxt,
 
11471
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
11472
        }
 
11473
        attr = attr->next;
 
11474
    }
 
11475
    /*
 
11476
    * Extract and validate attributes.
 
11477
    */
 
11478
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
11479
    /*
 
11480
    * Attribute 
 
11481
    */
 
11482
    /*
 
11483
    * Extract the base type. The "base" attribute is mandatory if inside
 
11484
    * a complex type or if redefining.
 
11485
    *
 
11486
    * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
 
11487
    * among its [children]), the simple type definition which is
 
11488
    * the {content type} of the type definition ļæ½resolvedļæ½ to by
 
11489
    * the ļæ½actual valueļæ½ of the base [attribute]"
 
11490
    */
 
11491
    if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
 
11492
        &(type->baseNs), &(type->base)) == 0)
 
11493
    {
 
11494
        if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
 
11495
            xmlSchemaPMissingAttrErr(ctxt,
 
11496
                XML_SCHEMAP_S4S_ATTR_MISSING,
 
11497
                NULL, node, "base", NULL);
 
11498
        } else if ((ctxt->isRedefine) &&
 
11499
            (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
 
11500
        {
 
11501
            if (type->base == NULL) {
 
11502
                xmlSchemaPMissingAttrErr(ctxt,
 
11503
                    XML_SCHEMAP_S4S_ATTR_MISSING,
 
11504
                    NULL, node, "base", NULL);
 
11505
            } else if ((! xmlStrEqual(type->base, type->name)) ||
 
11506
                (! xmlStrEqual(type->baseNs, type->targetNamespace)))
 
11507
            {
 
11508
                xmlChar *str1 = NULL, *str2 = NULL;
 
11509
                /*
 
11510
                * REDEFINE: SPEC src-redefine (5)
 
11511
                * "Within the [children], each <simpleType> must have a
 
11512
                * <restriction> among its [children] ... the ļæ½actual valueļæ½ of
 
11513
                * whose base [attribute] must be the same as the ļæ½actual valueļæ½
 
11514
                * of its own name attribute plus target namespace;"
 
11515
                */
 
11516
                xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
 
11517
                    NULL, node, "This is a redefinition, but the QName "
 
11518
                    "value '%s' of the 'base' attribute does not match the "
 
11519
                    "type's designation '%s'",
 
11520
                    xmlSchemaFormatQName(&str1, type->baseNs, type->base),
 
11521
                    xmlSchemaFormatQName(&str2, type->targetNamespace,
 
11522
                        type->name), NULL);
 
11523
                FREE_AND_NULL(str1);
 
11524
                FREE_AND_NULL(str2);
 
11525
                /* Avoid confusion and erase the values. */
 
11526
                type->base = NULL;
 
11527
                type->baseNs = NULL;
 
11528
            }
 
11529
        }               
 
11530
    }
 
11531
    /*
 
11532
    * And now for the children...
 
11533
    */
 
11534
    child = node->children;
 
11535
    if (IS_SCHEMA(child, "annotation")) {
 
11536
        /*
 
11537
        * Add the annotation to the simple type ancestor.
 
11538
        */
 
11539
        xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
 
11540
            xmlSchemaParseAnnotation(ctxt, child, 1));
 
11541
        child = child->next;
 
11542
    }
 
11543
    if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
 
11544
        /*
 
11545
        * Corresponds to <simpleType><restriction><simpleType>.
 
11546
        */
 
11547
        if (IS_SCHEMA(child, "simpleType")) {
 
11548
            if (type->base != NULL) {
 
11549
                /*
 
11550
                * src-restriction-base-or-simpleType
 
11551
                * Either the base [attribute] or the simpleType [child] of the
 
11552
                * <restriction> element must be present, but not both.
 
11553
                */
 
11554
                xmlSchemaPContentErr(ctxt,
 
11555
                    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
 
11556
                    NULL, node, child,
 
11557
                    "The attribute 'base' and the <simpleType> child are "
 
11558
                    "mutually exclusive", NULL);
 
11559
            } else {
 
11560
                type->baseType = (xmlSchemaTypePtr)
 
11561
                    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
 
11562
            }
 
11563
            child = child->next;
 
11564
        } else if (type->base == NULL) {
 
11565
            xmlSchemaPContentErr(ctxt,
 
11566
                XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
 
11567
                NULL, node, child,
 
11568
                "Either the attribute 'base' or a <simpleType> child "
 
11569
                "must be present", NULL);
 
11570
        }
 
11571
    } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
 
11572
        /*
 
11573
        * Corresponds to <complexType><complexContent><restriction>...
 
11574
        * followed by:
 
11575
        *
 
11576
        * Model groups <all>, <choice> and <sequence>.
 
11577
        */
 
11578
        if (IS_SCHEMA(child, "all")) {
 
11579
            type->subtypes = (xmlSchemaTypePtr)
 
11580
                xmlSchemaParseModelGroup(ctxt, schema, child,
 
11581
                    XML_SCHEMA_TYPE_ALL, 1);
 
11582
            child = child->next;
 
11583
        } else if (IS_SCHEMA(child, "choice")) {
 
11584
            type->subtypes = (xmlSchemaTypePtr)
 
11585
                xmlSchemaParseModelGroup(ctxt,
 
11586
                    schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
 
11587
            child = child->next;
 
11588
        } else if (IS_SCHEMA(child, "sequence")) {
 
11589
            type->subtypes = (xmlSchemaTypePtr)
 
11590
                xmlSchemaParseModelGroup(ctxt, schema, child,
 
11591
                    XML_SCHEMA_TYPE_SEQUENCE, 1);
 
11592
            child = child->next;
 
11593
        /*
 
11594
        * Model group reference <group>.
 
11595
        */
 
11596
        } else if (IS_SCHEMA(child, "group")) {     
 
11597
            type->subtypes = (xmlSchemaTypePtr)
 
11598
                xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
 
11599
            /*
 
11600
            * Note that the reference will be resolved in
 
11601
            * xmlSchemaResolveTypeReferences();
 
11602
            */
 
11603
            child = child->next;
 
11604
        }
 
11605
    } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
 
11606
        /*
 
11607
        * Corresponds to <complexType><simpleContent><restriction>...
 
11608
        *
 
11609
        * "1.1 the simple type definition corresponding to the <simpleType>
 
11610
        * among the [children] of <restriction> if there is one;"
 
11611
        */
 
11612
        if (IS_SCHEMA(child, "simpleType")) {
 
11613
            /*
 
11614
            * We will store the to-be-restricted simple type in
 
11615
            * type->contentTypeDef *temporarily*.
 
11616
            */
 
11617
            type->contentTypeDef = (xmlSchemaTypePtr)
 
11618
                xmlSchemaParseSimpleType(ctxt, schema, child, 0);
 
11619
            if ( type->contentTypeDef == NULL)
 
11620
                return (NULL);
 
11621
            child = child->next;
 
11622
        }
 
11623
    }
 
11624
 
 
11625
    if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
 
11626
        (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
 
11627
        xmlSchemaFacetPtr facet, lastfacet = NULL;
 
11628
        /*
 
11629
        * Corresponds to <complexType><simpleContent><restriction>...
 
11630
        * <simpleType><restriction>...
 
11631
        */
 
11632
 
 
11633
        /*
 
11634
        * Add the facets to the simple type ancestor.
 
11635
        */
 
11636
        /*
 
11637
        * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
 
11638
        * Simple Type Definition Schema Representation Constraint:
 
11639
        * *Single Facet Value*
 
11640
        */
 
11641
        while ((IS_SCHEMA(child, "minInclusive")) ||
 
11642
            (IS_SCHEMA(child, "minExclusive")) ||
 
11643
            (IS_SCHEMA(child, "maxInclusive")) ||
 
11644
            (IS_SCHEMA(child, "maxExclusive")) ||
 
11645
            (IS_SCHEMA(child, "totalDigits")) ||
 
11646
            (IS_SCHEMA(child, "fractionDigits")) ||
 
11647
            (IS_SCHEMA(child, "pattern")) ||
 
11648
            (IS_SCHEMA(child, "enumeration")) ||
 
11649
            (IS_SCHEMA(child, "whiteSpace")) ||
 
11650
            (IS_SCHEMA(child, "length")) ||
 
11651
            (IS_SCHEMA(child, "maxLength")) ||
 
11652
            (IS_SCHEMA(child, "minLength"))) {
 
11653
            facet = xmlSchemaParseFacet(ctxt, schema, child);
 
11654
            if (facet != NULL) {
 
11655
                if (lastfacet == NULL)
 
11656
                    type->facets = facet;
 
11657
                else
 
11658
                    lastfacet->next = facet;
 
11659
                lastfacet = facet;
 
11660
                lastfacet->next = NULL;
 
11661
            }
 
11662
            child = child->next;
 
11663
        }
 
11664
        /*
 
11665
        * Create links for derivation and validation.
 
11666
        */
 
11667
        if (type->facets != NULL) {
 
11668
            xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
 
11669
 
 
11670
            facet = type->facets;
 
11671
            do {
 
11672
                facetLink = (xmlSchemaFacetLinkPtr)
 
11673
                    xmlMalloc(sizeof(xmlSchemaFacetLink));
 
11674
                if (facetLink == NULL) {
 
11675
                    xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
 
11676
                    xmlFree(facetLink);
 
11677
                    return (NULL);
 
11678
                }
 
11679
                facetLink->facet = facet;
 
11680
                facetLink->next = NULL;
 
11681
                if (lastFacetLink == NULL)
 
11682
                    type->facetSet = facetLink;
 
11683
                else
 
11684
                    lastFacetLink->next = facetLink;
 
11685
                lastFacetLink = facetLink;
 
11686
                facet = facet->next;
 
11687
            } while (facet != NULL);
 
11688
        }
 
11689
    }
 
11690
    if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
 
11691
        /*
 
11692
        * Attribute uses/declarations.
 
11693
        */
 
11694
        if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
 
11695
            (xmlSchemaItemListPtr *) &(type->attrUses),
 
11696
            XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
 
11697
            return(NULL);
 
11698
        /*
 
11699
        * Attribute wildcard.
 
11700
        */
 
11701
        if (IS_SCHEMA(child, "anyAttribute")) {
 
11702
            type->attributeWildcard =
 
11703
                xmlSchemaParseAnyAttribute(ctxt, schema, child);
 
11704
            child = child->next;
 
11705
        }
 
11706
    }
 
11707
    if (child != NULL) {
 
11708
        if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
 
11709
            xmlSchemaPContentErr(ctxt,
 
11710
                XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
11711
                NULL, node, child, NULL,
 
11712
                "annotation?, (group | all | choice | sequence)?, "
 
11713
                "((attribute | attributeGroup)*, anyAttribute?))");
 
11714
        } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
 
11715
             xmlSchemaPContentErr(ctxt,
 
11716
                XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
11717
                NULL, node, child, NULL,
 
11718
                "(annotation?, (simpleType?, (minExclusive | minInclusive | "
 
11719
                "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
 
11720
                "length | minLength | maxLength | enumeration | whiteSpace | "
 
11721
                "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
 
11722
        } else {
 
11723
            /* Simple type */
 
11724
            xmlSchemaPContentErr(ctxt,
 
11725
                XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
11726
                NULL, node, child, NULL,
 
11727
                "(annotation?, (simpleType?, (minExclusive | minInclusive | "
 
11728
                "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
 
11729
                "length | minLength | maxLength | enumeration | whiteSpace | "
 
11730
                "pattern)*))");
 
11731
        }
 
11732
    }
 
11733
    return (NULL);
 
11734
}
 
11735
 
 
11736
/**
 
11737
 * xmlSchemaParseExtension:
 
11738
 * @ctxt:  a schema validation context
 
11739
 * @schema:  the schema being built
 
11740
 * @node:  a subtree containing XML Schema informations
 
11741
 *
 
11742
 * Parses an <extension>, which is found inside a
 
11743
 * <simpleContent> or <complexContent>.
 
11744
 * *WARNING* this interface is highly subject to change.
 
11745
 *
 
11746
 * TODO: Returns the type definition or NULL in case of error
 
11747
 */
 
11748
static xmlSchemaTypePtr
 
11749
xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
11750
                        xmlNodePtr node, xmlSchemaTypeType parentType)
 
11751
{
 
11752
    xmlSchemaTypePtr type;
 
11753
    xmlNodePtr child = NULL;
 
11754
    xmlAttrPtr attr;
 
11755
 
 
11756
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 
11757
        return (NULL);
 
11758
    /* Not a component, don't create it. */
 
11759
    type = ctxt->ctxtType;
 
11760
    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
 
11761
 
 
11762
    /*
 
11763
    * Check for illegal attributes.
 
11764
    */
 
11765
    attr = node->properties;
 
11766
    while (attr != NULL) {
 
11767
        if (attr->ns == NULL) {
 
11768
            if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 
11769
                (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
 
11770
                xmlSchemaPIllegalAttrErr(ctxt,
 
11771
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
11772
            }
 
11773
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
11774
            xmlSchemaPIllegalAttrErr(ctxt,
 
11775
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
11776
        }
 
11777
        attr = attr->next;
 
11778
    }
 
11779
 
 
11780
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
11781
 
 
11782
    /*
 
11783
    * Attribute "base" - mandatory.
 
11784
    */
 
11785
    if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
 
11786
        "base", &(type->baseNs), &(type->base)) == 0) &&
 
11787
        (type->base == NULL)) {
 
11788
        xmlSchemaPMissingAttrErr(ctxt,
 
11789
            XML_SCHEMAP_S4S_ATTR_MISSING,
 
11790
            NULL, node, "base", NULL);
 
11791
    }
 
11792
    /*
 
11793
    * And now for the children...
 
11794
    */
 
11795
    child = node->children;
 
11796
    if (IS_SCHEMA(child, "annotation")) {
 
11797
        /*
 
11798
        * Add the annotation to the type ancestor.
 
11799
        */
 
11800
        xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
 
11801
            xmlSchemaParseAnnotation(ctxt, child, 1));
 
11802
        child = child->next;
 
11803
    }
 
11804
    if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
 
11805
        /*
 
11806
        * Corresponds to <complexType><complexContent><extension>... and:
 
11807
        *
 
11808
        * Model groups <all>, <choice>, <sequence> and <group>.
 
11809
        */
 
11810
        if (IS_SCHEMA(child, "all")) {
 
11811
            type->subtypes = (xmlSchemaTypePtr)
 
11812
                xmlSchemaParseModelGroup(ctxt, schema,
 
11813
                    child, XML_SCHEMA_TYPE_ALL, 1);
 
11814
            child = child->next;
 
11815
        } else if (IS_SCHEMA(child, "choice")) {
 
11816
            type->subtypes = (xmlSchemaTypePtr)
 
11817
                xmlSchemaParseModelGroup(ctxt, schema,
 
11818
                    child, XML_SCHEMA_TYPE_CHOICE, 1);
 
11819
            child = child->next;
 
11820
        } else if (IS_SCHEMA(child, "sequence")) {
 
11821
            type->subtypes = (xmlSchemaTypePtr)
 
11822
                xmlSchemaParseModelGroup(ctxt, schema,
 
11823
                child, XML_SCHEMA_TYPE_SEQUENCE, 1);
 
11824
            child = child->next;
 
11825
        } else if (IS_SCHEMA(child, "group")) {
 
11826
            type->subtypes = (xmlSchemaTypePtr)
 
11827
                xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
 
11828
            /*
 
11829
            * Note that the reference will be resolved in
 
11830
            * xmlSchemaResolveTypeReferences();
 
11831
            */
 
11832
            child = child->next;
 
11833
        }
 
11834
    }
 
11835
    if (child != NULL) {
 
11836
        /*
 
11837
        * Attribute uses/declarations.
 
11838
        */
 
11839
        if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
 
11840
            (xmlSchemaItemListPtr *) &(type->attrUses),
 
11841
            XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
 
11842
            return(NULL);
 
11843
        /*
 
11844
        * Attribute wildcard.
 
11845
        */
 
11846
        if (IS_SCHEMA(child, "anyAttribute")) {
 
11847
            ctxt->ctxtType->attributeWildcard =
 
11848
                xmlSchemaParseAnyAttribute(ctxt, schema, child);
 
11849
            child = child->next;
 
11850
        }
 
11851
    }
 
11852
    if (child != NULL) {
 
11853
        if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
 
11854
            /* Complex content extension. */
 
11855
            xmlSchemaPContentErr(ctxt,
 
11856
                XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
11857
                NULL, node, child, NULL,
 
11858
                "(annotation?, ((group | all | choice | sequence)?, "
 
11859
                "((attribute | attributeGroup)*, anyAttribute?)))");
 
11860
        } else {
 
11861
            /* Simple content extension. */
 
11862
            xmlSchemaPContentErr(ctxt,
 
11863
                XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
11864
                NULL, node, child, NULL,
 
11865
                "(annotation?, ((attribute | attributeGroup)*, "
 
11866
                "anyAttribute?))");
 
11867
        }
 
11868
    }
 
11869
    return (NULL);
 
11870
}
 
11871
 
 
11872
/**
 
11873
 * xmlSchemaParseSimpleContent:
 
11874
 * @ctxt:  a schema validation context
 
11875
 * @schema:  the schema being built
 
11876
 * @node:  a subtree containing XML Schema informations
 
11877
 *
 
11878
 * parse a XML schema SimpleContent definition
 
11879
 * *WARNING* this interface is highly subject to change
 
11880
 *
 
11881
 * Returns the type definition or NULL in case of error
 
11882
 */
 
11883
static int
 
11884
xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
 
11885
                            xmlSchemaPtr schema, xmlNodePtr node,
 
11886
                            int *hasRestrictionOrExtension)
 
11887
{
 
11888
    xmlSchemaTypePtr type;
 
11889
    xmlNodePtr child = NULL;
 
11890
    xmlAttrPtr attr;
 
11891
 
 
11892
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
 
11893
        (hasRestrictionOrExtension == NULL))
 
11894
        return (-1);
 
11895
    *hasRestrictionOrExtension = 0;
 
11896
    /* Not a component, don't create it. */
 
11897
    type = ctxt->ctxtType;
 
11898
    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
 
11899
    /*
 
11900
    * Check for illegal attributes.
 
11901
    */
 
11902
    attr = node->properties;
 
11903
    while (attr != NULL) {
 
11904
        if (attr->ns == NULL) {
 
11905
            if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
 
11906
                xmlSchemaPIllegalAttrErr(ctxt,
 
11907
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
11908
            }
 
11909
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
11910
            xmlSchemaPIllegalAttrErr(ctxt,
 
11911
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
11912
        }
 
11913
        attr = attr->next;
 
11914
    }
 
11915
 
 
11916
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
11917
 
 
11918
    /*
 
11919
    * And now for the children...
 
11920
    */
 
11921
    child = node->children;
 
11922
    if (IS_SCHEMA(child, "annotation")) {
 
11923
        /*
 
11924
        * Add the annotation to the complex type ancestor.
 
11925
        */
 
11926
        xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
 
11927
            xmlSchemaParseAnnotation(ctxt, child, 1));
 
11928
        child = child->next;
 
11929
    }
 
11930
    if (child == NULL) {
 
11931
        xmlSchemaPContentErr(ctxt,
 
11932
            XML_SCHEMAP_S4S_ELEM_MISSING,
 
11933
            NULL, node, NULL, NULL,
 
11934
            "(annotation?, (restriction | extension))");        
 
11935
    }
 
11936
    if (child == NULL) {
 
11937
        xmlSchemaPContentErr(ctxt,
 
11938
            XML_SCHEMAP_S4S_ELEM_MISSING,
 
11939
            NULL, node, NULL, NULL,
 
11940
            "(annotation?, (restriction | extension))");        
 
11941
    }
 
11942
    if (IS_SCHEMA(child, "restriction")) {
 
11943
        xmlSchemaParseRestriction(ctxt, schema, child,
 
11944
            XML_SCHEMA_TYPE_SIMPLE_CONTENT);
 
11945
        (*hasRestrictionOrExtension) = 1;
 
11946
        child = child->next;
 
11947
    } else if (IS_SCHEMA(child, "extension")) {
 
11948
        xmlSchemaParseExtension(ctxt, schema, child,
 
11949
            XML_SCHEMA_TYPE_SIMPLE_CONTENT);
 
11950
        (*hasRestrictionOrExtension) = 1;
 
11951
        child = child->next;
 
11952
    }
 
11953
    if (child != NULL) {
 
11954
        xmlSchemaPContentErr(ctxt,
 
11955
            XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
11956
            NULL, node, child, NULL,
 
11957
            "(annotation?, (restriction | extension))");
 
11958
    }
 
11959
    return (0);
 
11960
}
 
11961
 
 
11962
/**
 
11963
 * xmlSchemaParseComplexContent:
 
11964
 * @ctxt:  a schema validation context
 
11965
 * @schema:  the schema being built
 
11966
 * @node:  a subtree containing XML Schema informations
 
11967
 *
 
11968
 * parse a XML schema ComplexContent definition
 
11969
 * *WARNING* this interface is highly subject to change
 
11970
 *
 
11971
 * Returns the type definition or NULL in case of error
 
11972
 */
 
11973
static int
 
11974
xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
 
11975
                             xmlSchemaPtr schema, xmlNodePtr node,
 
11976
                             int *hasRestrictionOrExtension)
 
11977
{
 
11978
    xmlSchemaTypePtr type;
 
11979
    xmlNodePtr child = NULL;
 
11980
    xmlAttrPtr attr;
 
11981
 
 
11982
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
 
11983
        (hasRestrictionOrExtension == NULL))
 
11984
        return (-1);
 
11985
    *hasRestrictionOrExtension = 0;
 
11986
    /* Not a component, don't create it. */
 
11987
    type = ctxt->ctxtType;
 
11988
    /*
 
11989
    * Check for illegal attributes.
 
11990
    */
 
11991
    attr = node->properties;
 
11992
    while (attr != NULL) {
 
11993
        if (attr->ns == NULL) {
 
11994
            if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 
11995
                (!xmlStrEqual(attr->name, BAD_CAST "mixed")))
 
11996
            {
 
11997
                xmlSchemaPIllegalAttrErr(ctxt,
 
11998
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
11999
            }
 
12000
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
12001
            xmlSchemaPIllegalAttrErr(ctxt,
 
12002
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
12003
        }
 
12004
        attr = attr->next;
 
12005
    }
 
12006
 
 
12007
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
12008
 
 
12009
    /*
 
12010
    * Set the 'mixed' on the complex type ancestor.
 
12011
    */
 
12012
    if (xmlGetBooleanProp(ctxt, node, "mixed", 0))  {
 
12013
        if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
 
12014
            type->flags |= XML_SCHEMAS_TYPE_MIXED;
 
12015
    }
 
12016
    child = node->children;
 
12017
    if (IS_SCHEMA(child, "annotation")) {
 
12018
        /*
 
12019
        * Add the annotation to the complex type ancestor.
 
12020
        */
 
12021
        xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
 
12022
            xmlSchemaParseAnnotation(ctxt, child, 1));
 
12023
        child = child->next;
 
12024
    }
 
12025
    if (child == NULL) {
 
12026
        xmlSchemaPContentErr(ctxt,
 
12027
            XML_SCHEMAP_S4S_ELEM_MISSING,
 
12028
            NULL, node, NULL,
 
12029
            NULL, "(annotation?, (restriction | extension))");
 
12030
    }
 
12031
    if (child == NULL) {
 
12032
        xmlSchemaPContentErr(ctxt,
 
12033
            XML_SCHEMAP_S4S_ELEM_MISSING,
 
12034
            NULL, node, NULL,
 
12035
            NULL, "(annotation?, (restriction | extension))");
 
12036
    }
 
12037
    if (IS_SCHEMA(child, "restriction")) {
 
12038
        xmlSchemaParseRestriction(ctxt, schema, child,
 
12039
            XML_SCHEMA_TYPE_COMPLEX_CONTENT);
 
12040
        (*hasRestrictionOrExtension) = 1;
 
12041
        child = child->next;
 
12042
    } else if (IS_SCHEMA(child, "extension")) {
 
12043
        xmlSchemaParseExtension(ctxt, schema, child,
 
12044
            XML_SCHEMA_TYPE_COMPLEX_CONTENT);
 
12045
        (*hasRestrictionOrExtension) = 1;
 
12046
        child = child->next;
 
12047
    }
 
12048
    if (child != NULL) {
 
12049
        xmlSchemaPContentErr(ctxt,
 
12050
            XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
12051
            NULL, node, child,
 
12052
            NULL, "(annotation?, (restriction | extension))");
 
12053
    }
 
12054
    return (0);
 
12055
}
 
12056
 
 
12057
/**
 
12058
 * xmlSchemaParseComplexType:
 
12059
 * @ctxt:  a schema validation context
 
12060
 * @schema:  the schema being built
 
12061
 * @node:  a subtree containing XML Schema informations
 
12062
 *
 
12063
 * parse a XML schema Complex Type definition
 
12064
 * *WARNING* this interface is highly subject to change
 
12065
 *
 
12066
 * Returns the type definition or NULL in case of error
 
12067
 */
 
12068
static xmlSchemaTypePtr
 
12069
xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 
12070
                          xmlNodePtr node, int topLevel)
 
12071
{
 
12072
    xmlSchemaTypePtr type, ctxtType;
 
12073
    xmlNodePtr child = NULL;
 
12074
    const xmlChar *name = NULL;
 
12075
    xmlAttrPtr attr;
 
12076
    const xmlChar *attrValue;
 
12077
#ifdef ENABLE_NAMED_LOCALS
 
12078
    char buf[40];
 
12079
#endif
 
12080
    int final = 0, block = 0, hasRestrictionOrExtension = 0;
 
12081
 
 
12082
 
 
12083
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 
12084
        return (NULL);
 
12085
 
 
12086
    ctxtType = ctxt->ctxtType;
 
12087
 
 
12088
    if (topLevel) {
 
12089
        attr = xmlSchemaGetPropNode(node, "name");
 
12090
        if (attr == NULL) {
 
12091
            xmlSchemaPMissingAttrErr(ctxt,
 
12092
                XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
 
12093
            return (NULL);
 
12094
        } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
 
12095
            xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
 
12096
            return (NULL);
 
12097
        }       
 
12098
    }
 
12099
 
 
12100
    if (topLevel == 0) {
 
12101
        /*
 
12102
        * Parse as local complex type definition.
 
12103
        */
 
12104
#ifdef ENABLE_NAMED_LOCALS
 
12105
        snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
 
12106
        type = xmlSchemaAddType(ctxt, schema,
 
12107
            XML_SCHEMA_TYPE_COMPLEX,
 
12108
            xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
 
12109
            ctxt->targetNamespace, node, 0);
 
12110
#else
 
12111
        type = xmlSchemaAddType(ctxt, schema,
 
12112
            XML_SCHEMA_TYPE_COMPLEX,
 
12113
            NULL, ctxt->targetNamespace, node, 0);
 
12114
#endif
 
12115
        if (type == NULL)
 
12116
            return (NULL);
 
12117
        name = type->name;
 
12118
        type->node = node;
 
12119
        type->type = XML_SCHEMA_TYPE_COMPLEX;
 
12120
        /*
 
12121
        * TODO: We need the target namespace.
 
12122
        */
 
12123
    } else {
 
12124
        /*
 
12125
        * Parse as global complex type definition.
 
12126
        */
 
12127
        type = xmlSchemaAddType(ctxt, schema,
 
12128
            XML_SCHEMA_TYPE_COMPLEX,
 
12129
            name, ctxt->targetNamespace, node, 1);
 
12130
        if (type == NULL)
 
12131
            return (NULL);
 
12132
        type->node = node;
 
12133
        type->type = XML_SCHEMA_TYPE_COMPLEX;
 
12134
        type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
 
12135
    }
 
12136
    type->targetNamespace = ctxt->targetNamespace;
 
12137
    /*
 
12138
    * Handle attributes.
 
12139
    */
 
12140
    attr = node->properties;
 
12141
    while (attr != NULL) {
 
12142
        if (attr->ns == NULL) {
 
12143
            if (xmlStrEqual(attr->name, BAD_CAST "id")) {
 
12144
                /*
 
12145
                * Attribute "id".
 
12146
                */
 
12147
                xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 
12148
            } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
 
12149
                /*
 
12150
                * Attribute "mixed".
 
12151
                */
 
12152
                if (xmlSchemaPGetBoolNodeValue(ctxt,
 
12153
                        NULL, (xmlNodePtr) attr))
 
12154
                    type->flags |= XML_SCHEMAS_TYPE_MIXED;
 
12155
            } else if (topLevel) {
 
12156
                /*
 
12157
                * Attributes of global complex type definitions.
 
12158
                */
 
12159
                if (xmlStrEqual(attr->name, BAD_CAST "name")) {
 
12160
                    /* Pass. */
 
12161
                } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
 
12162
                    /*
 
12163
                    * Attribute "abstract".
 
12164
                    */
 
12165
                    if (xmlSchemaPGetBoolNodeValue(ctxt,
 
12166
                            NULL, (xmlNodePtr) attr))
 
12167
                        type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
 
12168
                } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
 
12169
                    /*
 
12170
                    * Attribute "final".
 
12171
                    */
 
12172
                    attrValue = xmlSchemaGetNodeContent(ctxt,
 
12173
                        (xmlNodePtr) attr);
 
12174
                    if (xmlSchemaPValAttrBlockFinal(attrValue,
 
12175
                        &(type->flags),
 
12176
                        -1,
 
12177
                        XML_SCHEMAS_TYPE_FINAL_EXTENSION,
 
12178
                        XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
 
12179
                        -1, -1, -1) != 0)
 
12180
                    {
 
12181
                        xmlSchemaPSimpleTypeErr(ctxt,
 
12182
                            XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
12183
                            NULL, (xmlNodePtr) attr, NULL,
 
12184
                            "(#all | List of (extension | restriction))",
 
12185
                            attrValue, NULL, NULL, NULL);
 
12186
                    } else 
 
12187
                        final = 1;
 
12188
                } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
 
12189
                    /*
 
12190
                    * Attribute "block".
 
12191
                    */
 
12192
                    attrValue = xmlSchemaGetNodeContent(ctxt,
 
12193
                        (xmlNodePtr) attr);
 
12194
                    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
 
12195
                        -1,
 
12196
                        XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
 
12197
                        XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
 
12198
                        -1, -1, -1) != 0) {
 
12199
                        xmlSchemaPSimpleTypeErr(ctxt,
 
12200
                            XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 
12201
                            NULL, (xmlNodePtr) attr, NULL,
 
12202
                            "(#all | List of (extension | restriction)) ",
 
12203
                            attrValue, NULL, NULL, NULL);
 
12204
                    } else 
 
12205
                        block = 1;
 
12206
                } else {
 
12207
                        xmlSchemaPIllegalAttrErr(ctxt,
 
12208
                            XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
12209
                }
 
12210
            } else {
 
12211
                xmlSchemaPIllegalAttrErr(ctxt,
 
12212
                    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
12213
            }
 
12214
        } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 
12215
            xmlSchemaPIllegalAttrErr(ctxt, 
 
12216
                XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 
12217
        }
 
12218
        attr = attr->next;
 
12219
    }
 
12220
    if (! block) {
 
12221
        /*
 
12222
        * Apply default "block" values.
 
12223
        */
 
12224
        if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
 
12225
            type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
 
12226
        if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
 
12227
            type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
 
12228
    }
 
12229
    if (! final) {
 
12230
        /*
 
12231
        * Apply default "block" values.
 
12232
        */
 
12233
        if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
 
12234
            type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
 
12235
        if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
 
12236
            type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
 
12237
    }
 
12238
    /*
 
12239
    * And now for the children...
 
12240
    */
 
12241
    child = node->children;
 
12242
    if (IS_SCHEMA(child, "annotation")) {
 
12243
        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 
12244
        child = child->next;
 
12245
    }
 
12246
    ctxt->ctxtType = type;
 
12247
    if (IS_SCHEMA(child, "simpleContent")) {
 
12248
        /*
 
12249
        * <complexType><simpleContent>...
 
12250
        * 3.4.3 : 2.2
 
12251
        * Specifying mixed='true' when the <simpleContent>
 
12252
        * alternative is chosen has no effect
 
12253
        */
 
12254
        if (type->flags & XML_SCHEMAS_TYPE_MIXED)
 
12255
            type->flags ^= XML_SCHEMAS_TYPE_MIXED;
 
12256
        xmlSchemaParseSimpleContent(ctxt, schema, child,
 
12257
            &hasRestrictionOrExtension);
 
12258
        child = child->next;
 
12259
    } else if (IS_SCHEMA(child, "complexContent")) {
 
12260
        /*
 
12261
        * <complexType><complexContent>...
 
12262
        */
 
12263
        type->contentType = XML_SCHEMA_CONTENT_EMPTY;
 
12264
        xmlSchemaParseComplexContent(ctxt, schema, child,
 
12265
            &hasRestrictionOrExtension);
 
12266
        child = child->next;
 
12267
    } else {
 
12268
        /*
 
12269
        * E.g <complexType><sequence>... or <complexType><attribute>... etc.
 
12270
        *
 
12271
        * SPEC
 
12272
        * "...the third alternative (neither <simpleContent> nor
 
12273
        * <complexContent>) is chosen. This case is understood as shorthand
 
12274
        * for complex content restricting the ļæ½ur-type definitionļæ½, and the
 
12275
        * details of the mappings should be modified as necessary.
 
12276
        */
 
12277
        type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
 
12278
        type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
 
12279
        /*
 
12280
        * Parse model groups.
 
12281
        */
 
12282
        if (IS_SCHEMA(child, "all")) {
 
12283
            type->subtypes = (xmlSchemaTypePtr)
 
12284
                xmlSchemaParseModelGroup(ctxt, schema, child,
 
12285
                    XML_SCHEMA_TYPE_ALL, 1);
 
12286
            child = child->next;
 
12287
        } else if (IS_SCHEMA(child, "choice")) {
 
12288
            type->subtypes = (xmlSchemaTypePtr)
 
12289
                xmlSchemaParseModelGroup(ctxt, schema, child,
 
12290
                    XML_SCHEMA_TYPE_CHOICE, 1);
 
12291
            child = child->next;
 
12292
        } else if (IS_SCHEMA(child, "sequence")) {
 
12293
            type->subtypes = (xmlSchemaTypePtr)
 
12294
                xmlSchemaParseModelGroup(ctxt, schema, child,
 
12295
                    XML_SCHEMA_TYPE_SEQUENCE, 1);
 
12296
            child = child->next;
 
12297
        } else if (IS_SCHEMA(child, "group")) {
 
12298
            type->subtypes = (xmlSchemaTypePtr)
 
12299
                xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
 
12300
            /*
 
12301
            * Note that the reference will be resolved in
 
12302
            * xmlSchemaResolveTypeReferences();
 
12303
            */
 
12304
            child = child->next;
 
12305
        }
 
12306
        /*
 
12307
        * Parse attribute decls/refs.
 
12308
        */
 
12309
        if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
 
12310
            (xmlSchemaItemListPtr *) &(type->attrUses),
 
12311
            XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
 
12312
            return(NULL);
 
12313
        /*
 
12314
        * Parse attribute wildcard.
 
12315
        */
 
12316
        if (IS_SCHEMA(child, "anyAttribute")) {
 
12317
            type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
 
12318
            child = child->next;
 
12319
        }
 
12320
    }
 
12321
    if (child != NULL) {
 
12322
        xmlSchemaPContentErr(ctxt,
 
12323
            XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 
12324
            NULL, node, child,
 
12325
            NULL, "(annotation?, (simpleContent | complexContent | "
 
12326
            "((group | all | choice | sequence)?, ((attribute | "
 
12327
            "attributeGroup)*, anyAttribute?))))");
 
12328
    }
 
12329
    /*
 
12330
    * REDEFINE: SPEC src-redefine (5)
 
12331
    */
 
12332
    if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
 
12333
        xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
 
12334
            NULL, node, "This is a redefinition, thus the "
 
12335
            "<complexType> must have a <restriction> or <extension> "
 
12336
            "grand-child", NULL);
 
12337
    }
 
12338
    ctxt->ctxtType = ctxtType;
 
12339
    return (type);
 
12340
}
 
12341
 
 
12342
/************************************************************************
 
12343
 *                                                                      *
 
12344
 *                      Validating using Schemas                        *
 
12345
 *                                                                      *
 
12346
 ************************************************************************/
 
12347
 
 
12348
/************************************************************************
 
12349
 *                                                                      *
 
12350
 *                      Reading/Writing Schemas                         *
 
12351
 *                                                                      *
 
12352
 ************************************************************************/
 
12353
 
 
12354
#if 0 /* Will be enabled if it is clear what options are needed. */
 
12355
/**
 
12356
 * xmlSchemaParserCtxtSetOptions:
 
12357
 * @ctxt:       a schema parser context
 
12358
 * @options: a combination of xmlSchemaParserOption
 
12359
 *
 
12360
 * Sets the options to be used during the parse.
 
12361
 *
 
12362
 * Returns 0 in case of success, -1 in case of an
 
12363
 * API error.
 
12364
 */
 
12365
static int
 
12366
xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
 
12367
                              int options)
 
12368
 
 
12369
{
 
12370
    int i;
 
12371
 
 
12372
    if (ctxt == NULL)
 
12373
        return (-1);
 
12374
    /*
 
12375
    * WARNING: Change the start value if adding to the
 
12376
    * xmlSchemaParseOption.
 
12377
    */
 
12378
    for (i = 1; i < (int) sizeof(int) * 8; i++) {
 
12379
        if (options & 1<<i) {
 
12380
            return (-1);
 
12381
        }
 
12382
    }
 
12383
    ctxt->options = options;
 
12384
    return (0);
 
12385
}
 
12386
 
 
12387
/**
 
12388
 * xmlSchemaValidCtxtGetOptions:
 
12389
 * @ctxt: a schema parser context
 
12390
 *
 
12391
 * Returns the option combination of the parser context.
 
12392
 */
 
12393
static int
 
12394
xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
 
12395
 
 
12396
{
 
12397
    if (ctxt == NULL)
 
12398
        return (-1);
 
12399
    else
 
12400
        return (ctxt->options);
 
12401
}
 
12402
#endif
 
12403
 
 
12404
/**
 
12405
 * xmlSchemaNewParserCtxt:
 
12406
 * @URL:  the location of the schema
 
12407
 *
 
12408
 * Create an XML Schemas parse context for that file/resource expected
 
12409
 * to contain an XML Schemas file.
 
12410
 *
 
12411
 * Returns the parser context or NULL in case of error
 
12412
 */
 
12413
xmlSchemaParserCtxtPtr
 
12414
xmlSchemaNewParserCtxt(const char *URL)
 
12415
{
 
12416
    xmlSchemaParserCtxtPtr ret;
 
12417
 
 
12418
    if (URL == NULL)
 
12419
        return (NULL);
 
12420
 
 
12421
    ret = xmlSchemaParserCtxtCreate();
 
12422
    if (ret == NULL)
 
12423
        return(NULL);
 
12424
    ret->dict = xmlDictCreate();
 
12425
    ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
 
12426
    return (ret);
 
12427
}
 
12428
 
 
12429
/**
 
12430
 * xmlSchemaNewMemParserCtxt:
 
12431
 * @buffer:  a pointer to a char array containing the schemas
 
12432
 * @size:  the size of the array
 
12433
 *
 
12434
 * Create an XML Schemas parse context for that memory buffer expected
 
12435
 * to contain an XML Schemas file.
 
12436
 *
 
12437
 * Returns the parser context or NULL in case of error
 
12438
 */
 
12439
xmlSchemaParserCtxtPtr
 
12440
xmlSchemaNewMemParserCtxt(const char *buffer, int size)
 
12441
{
 
12442
    xmlSchemaParserCtxtPtr ret;
 
12443
 
 
12444
    if ((buffer == NULL) || (size <= 0))
 
12445
        return (NULL);
 
12446
    ret = xmlSchemaParserCtxtCreate();
 
12447
    if (ret == NULL)
 
12448
        return(NULL);
 
12449
    ret->buffer = buffer;
 
12450
    ret->size = size;
 
12451
    ret->dict = xmlDictCreate();    
 
12452
    return (ret);
 
12453
}
 
12454
 
 
12455
/**
 
12456
 * xmlSchemaNewDocParserCtxt:
 
12457
 * @doc:  a preparsed document tree
 
12458
 *
 
12459
 * Create an XML Schemas parse context for that document.
 
12460
 * NB. The document may be modified during the parsing process.
 
12461
 *
 
12462
 * Returns the parser context or NULL in case of error
 
12463
 */
 
12464
xmlSchemaParserCtxtPtr
 
12465
xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
 
12466
{
 
12467
    xmlSchemaParserCtxtPtr ret;
 
12468
 
 
12469
    if (doc == NULL)
 
12470
      return (NULL);
 
12471
    ret = xmlSchemaParserCtxtCreate();
 
12472
    if (ret == NULL)
 
12473
        return(NULL);
 
12474
    ret->doc = doc;
 
12475
    ret->dict = xmlDictCreate();
 
12476
    /* The application has responsibility for the document */
 
12477
    ret->preserve = 1;
 
12478
 
 
12479
    return (ret);
 
12480
}
 
12481
 
 
12482
/**
 
12483
 * xmlSchemaFreeParserCtxt:
 
12484
 * @ctxt:  the schema parser context
 
12485
 *
 
12486
 * Free the resources associated to the schema parser context
 
12487
 */
 
12488
void
 
12489
xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
 
12490
{
 
12491
    if (ctxt == NULL)
 
12492
        return;
 
12493
    if (ctxt->doc != NULL && !ctxt->preserve)
 
12494
        xmlFreeDoc(ctxt->doc);    
 
12495
    if (ctxt->vctxt != NULL) {
 
12496
        xmlSchemaFreeValidCtxt(ctxt->vctxt);
 
12497
    }
 
12498
    if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
 
12499
        xmlSchemaConstructionCtxtFree(ctxt->constructor);
 
12500
        ctxt->constructor = NULL;
 
12501
        ctxt->ownsConstructor = 0;
 
12502
    }
 
12503
    if (ctxt->attrProhibs != NULL)
 
12504
        xmlSchemaItemListFree(ctxt->attrProhibs);
 
12505
    xmlDictFree(ctxt->dict);
 
12506
    xmlFree(ctxt);
 
12507
}
 
12508
 
 
12509
/************************************************************************
 
12510
 *                                                                      *
 
12511
 *                      Building the content models                     *
 
12512
 *                                                                      *
 
12513
 ************************************************************************/
 
12514
 
 
12515
static void
 
12516
xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
 
12517
        xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
 
12518
{
 
12519
    xmlAutomataStatePtr start, tmp;
 
12520
    xmlSchemaElementPtr elemDecl, member;
 
12521
    xmlSchemaSubstGroupPtr substGroup;
 
12522
    int i;
 
12523
 
 
12524
    elemDecl = (xmlSchemaElementPtr) particle->children;
 
12525
    /*
 
12526
    * Wrap the substitution group with a CHOICE.
 
12527
    */
 
12528
    start = pctxt->state;
 
12529
    if (end == NULL)
 
12530
        end = xmlAutomataNewState(pctxt->am);
 
12531
    substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
 
12532
    if (substGroup == NULL) {
 
12533
        xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
 
12534
            XML_SCHEMAP_INTERNAL,
 
12535
            "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
 
12536
            "declaration is marked having a subst. group but none "
 
12537
            "available.\n", elemDecl->name, NULL);
 
12538
        return;
 
12539
    }
 
12540
    if (counter >= 0) {
 
12541
        /*
 
12542
        * NOTE that we put the declaration in, even if it's abstract.
 
12543
        * However, an error will be raised during *validation* if an element
 
12544
        * information item shall be validated against an abstract element
 
12545
        * declaration.
 
12546
        */
 
12547
        tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
 
12548
        xmlAutomataNewTransition2(pctxt->am, tmp, end,
 
12549
                    elemDecl->name, elemDecl->targetNamespace, elemDecl);
 
12550
        /*
 
12551
        * Add subst. group members.
 
12552
        */
 
12553
        for (i = 0; i < substGroup->members->nbItems; i++) {
 
12554
            member = (xmlSchemaElementPtr) substGroup->members->items[i];
 
12555
            xmlAutomataNewTransition2(pctxt->am, tmp, end,
 
12556
                               member->name, member->targetNamespace, member);
 
12557
        }
 
12558
    } else if (particle->maxOccurs == 1) {
 
12559
        /*
 
12560
        * NOTE that we put the declaration in, even if it's abstract,
 
12561
        */
 
12562
        xmlAutomataNewEpsilon(pctxt->am,
 
12563
            xmlAutomataNewTransition2(pctxt->am,
 
12564
            start, NULL,
 
12565
            elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
 
12566
        /*
 
12567
        * Add subst. group members.
 
12568
        */
 
12569
        for (i = 0; i < substGroup->members->nbItems; i++) {
 
12570
            member = (xmlSchemaElementPtr) substGroup->members->items[i];
 
12571
            /*
 
12572
            * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
 
12573
            *  was incorrectly used instead of xmlAutomataNewTransition2()
 
12574
            *  (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
 
12575
            *  section in xmlSchemaBuildAContentModel() ).
 
12576
            * TODO: Check if xmlAutomataNewOnceTrans2() was instead 
 
12577
            *  intended for the above "counter" section originally. I.e.,
 
12578
            *  check xs:all with subst-groups.
 
12579
            *
 
12580
            * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
 
12581
            *                  member->name, member->targetNamespace,
 
12582
            *                  1, 1, member);
 
12583
            */
 
12584
            tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
 
12585
                member->name, member->targetNamespace, member);     
 
12586
            xmlAutomataNewEpsilon(pctxt->am, tmp, end);
 
12587
        }
 
12588
    } else {
 
12589
        xmlAutomataStatePtr hop;
 
12590
        int maxOccurs = particle->maxOccurs == UNBOUNDED ?
 
12591
            UNBOUNDED : particle->maxOccurs - 1;
 
12592
        int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
 
12593
 
 
12594
        counter =
 
12595
            xmlAutomataNewCounter(pctxt->am, minOccurs,
 
12596
            maxOccurs);
 
12597
        hop = xmlAutomataNewState(pctxt->am);
 
12598
 
 
12599
        xmlAutomataNewEpsilon(pctxt->am,
 
12600
            xmlAutomataNewTransition2(pctxt->am,
 
12601
            start, NULL,
 
12602
            elemDecl->name, elemDecl->targetNamespace, elemDecl),
 
12603
            hop);
 
12604
        /*
 
12605
         * Add subst. group members.
 
12606
         */
 
12607
        for (i = 0; i < substGroup->members->nbItems; i++) {
 
12608
            member = (xmlSchemaElementPtr) substGroup->members->items[i];
 
12609
            xmlAutomataNewEpsilon(pctxt->am,
 
12610
                xmlAutomataNewTransition2(pctxt->am,
 
12611
                start, NULL,
 
12612
                member->name, member->targetNamespace, member),
 
12613
                hop);
 
12614
        }
 
12615
        xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
 
12616
        xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
 
12617
    }
 
12618
    if (particle->minOccurs == 0)
 
12619
        xmlAutomataNewEpsilon(pctxt->am, start, end);
 
12620
    pctxt->state = end;
 
12621
}
 
12622
 
 
12623
static void
 
12624
xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
 
12625
                                     xmlSchemaParticlePtr particle)
 
12626
{
 
12627
    if (((xmlSchemaElementPtr) particle->children)->flags &
 
12628
        XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
 
12629
        /*
 
12630
        * Substitution groups.
 
12631
        */
 
12632
        xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
 
12633
    } else {
 
12634
        xmlSchemaElementPtr elemDecl;
 
12635
        xmlAutomataStatePtr start;
 
12636
 
 
12637
        elemDecl = (xmlSchemaElementPtr) particle->children;
 
12638
 
 
12639
        if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
 
12640
            return;
 
12641
        if (particle->maxOccurs == 1) {
 
12642
            start = ctxt->state;
 
12643
            ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
 
12644
                    elemDecl->name, elemDecl->targetNamespace, elemDecl);
 
12645
        } else if ((particle->maxOccurs >= UNBOUNDED) &&
 
12646
                   (particle->minOccurs < 2)) {
 
12647
            /* Special case. */
 
12648
            start = ctxt->state;            
 
12649
            ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
 
12650
                elemDecl->name, elemDecl->targetNamespace, elemDecl);       
 
12651
            ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
 
12652
                elemDecl->name, elemDecl->targetNamespace, elemDecl);       
 
12653
        } else {
 
12654
            int counter;
 
12655
            int maxOccurs = particle->maxOccurs == UNBOUNDED ?
 
12656
                            UNBOUNDED : particle->maxOccurs - 1;
 
12657
            int minOccurs = particle->minOccurs < 1 ?
 
12658
                            0 : particle->minOccurs - 1;
 
12659
 
 
12660
            start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
 
12661
            counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
 
12662
            ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
 
12663
                elemDecl->name, elemDecl->targetNamespace, elemDecl);
 
12664
            xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
 
12665
            ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
 
12666
                NULL, counter);
 
12667
        }
 
12668
        if (particle->minOccurs == 0)
 
12669
            xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
 
12670
    }
 
12671
}
 
12672
 
 
12673
/**
 
12674
 * xmlSchemaBuildAContentModel:
 
12675
 * @ctxt:  the schema parser context
 
12676
 * @particle:  the particle component
 
12677
 * @name:  the complex type's name whose content is being built
 
12678
 *
 
12679
 * Create the automaton for the {content type} of a complex type.
 
12680
 *
 
12681
 */
 
12682
static void
 
12683
xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
 
12684
                            xmlSchemaParticlePtr particle)
 
12685
{
 
12686
    if (particle == NULL) {
 
12687
        PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");      
 
12688
        return;
 
12689
    }
 
12690
    if (particle->children == NULL) {
 
12691
        /*
 
12692
        * Just return in this case. A missing "term" of the particle
 
12693
        * might arise due to an invalid "term" component.
 
12694
        */
 
12695
        return;
 
12696
    }
 
12697
 
 
12698
    switch (particle->children->type) {
 
12699
        case XML_SCHEMA_TYPE_ANY: {
 
12700
            xmlAutomataStatePtr start, end;
 
12701
            xmlSchemaWildcardPtr wild;
 
12702
            xmlSchemaWildcardNsPtr ns;
 
12703
 
 
12704
            wild = (xmlSchemaWildcardPtr) particle->children;
 
12705
 
 
12706
            start = pctxt->state;
 
12707
            end = xmlAutomataNewState(pctxt->am);
 
12708
 
 
12709
            if (particle->maxOccurs == 1) {
 
12710
                if (wild->any == 1) {
 
12711
                    /*
 
12712
                    * We need to add both transitions:
 
12713
                    *
 
12714
                    * 1. the {"*", "*"} for elements in a namespace.
 
12715
                    */
 
12716
                    pctxt->state =
 
12717
                        xmlAutomataNewTransition2(pctxt->am,
 
12718
                        start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
 
12719
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
 
12720
                    /*
 
12721
                    * 2. the {"*"} for elements in no namespace.
 
12722
                    */
 
12723
                    pctxt->state =
 
12724
                        xmlAutomataNewTransition2(pctxt->am,
 
12725
                        start, NULL, BAD_CAST "*", NULL, wild);
 
12726
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
 
12727
 
 
12728
                } else if (wild->nsSet != NULL) {
 
12729
                    ns = wild->nsSet;
 
12730
                    do {
 
12731
                        pctxt->state = start;
 
12732
                        pctxt->state = xmlAutomataNewTransition2(pctxt->am,
 
12733
                            pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
 
12734
                        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
 
12735
                        ns = ns->next;
 
12736
                    } while (ns != NULL);
 
12737
 
 
12738
                } else if (wild->negNsSet != NULL) {
 
12739
                    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
 
12740
                        start, end, BAD_CAST "*", wild->negNsSet->value,
 
12741
                        wild);
 
12742
                }
 
12743
            } else {
 
12744
                int counter;
 
12745
                xmlAutomataStatePtr hop;
 
12746
                int maxOccurs =
 
12747
                    particle->maxOccurs == UNBOUNDED ? UNBOUNDED : particle->maxOccurs - 1;
 
12748
                int minOccurs =
 
12749
                    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
 
12750
 
 
12751
                counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
 
12752
                hop = xmlAutomataNewState(pctxt->am);
 
12753
                if (wild->any == 1) {
 
12754
                    pctxt->state =
 
12755
                        xmlAutomataNewTransition2(pctxt->am,
 
12756
                        start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
 
12757
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
 
12758
                    pctxt->state =
 
12759
                        xmlAutomataNewTransition2(pctxt->am,
 
12760
                        start, NULL, BAD_CAST "*", NULL, wild);
 
12761
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
 
12762
                } else if (wild->nsSet != NULL) {
 
12763
                    ns = wild->nsSet;
 
12764
                    do {
 
12765
                        pctxt->state =
 
12766
                            xmlAutomataNewTransition2(pctxt->am,
 
12767
                                start, NULL, BAD_CAST "*", ns->value, wild);
 
12768
                        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
 
12769
                        ns = ns->next;
 
12770
                    } while (ns != NULL);
 
12771
 
 
12772
                } else if (wild->negNsSet != NULL) {
 
12773
                    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
 
12774
                        start, hop, BAD_CAST "*", wild->negNsSet->value,
 
12775
                        wild);
 
12776
                }
 
12777
                xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
 
12778
                xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
 
12779
            }
 
12780
            if (particle->minOccurs == 0) {
 
12781
                xmlAutomataNewEpsilon(pctxt->am, start, end);
 
12782
            }
 
12783
            pctxt->state = end;
 
12784
            break;
 
12785
        }
 
12786
        case XML_SCHEMA_TYPE_ELEMENT:
 
12787
            xmlSchemaBuildContentModelForElement(pctxt, particle);
 
12788
            break;
 
12789
        case XML_SCHEMA_TYPE_SEQUENCE:{
 
12790
                xmlSchemaTreeItemPtr sub;
 
12791
 
 
12792
                /*
 
12793
                 * If max and min occurances are default (1) then
 
12794
                 * simply iterate over the particles of the <sequence>.
 
12795
                 */
 
12796
                if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
 
12797
                    sub = particle->children->children;
 
12798
                    while (sub != NULL) {
 
12799
                        xmlSchemaBuildAContentModel(pctxt,
 
12800
                            (xmlSchemaParticlePtr) sub);
 
12801
                        sub = sub->next;
 
12802
                    }
 
12803
                } else {
 
12804
                    xmlAutomataStatePtr oldstate = pctxt->state;
 
12805
 
 
12806
                    if (particle->maxOccurs >= UNBOUNDED) {
 
12807
                        if (particle->minOccurs > 1) {
 
12808
                            xmlAutomataStatePtr tmp;
 
12809
                            int counter;
 
12810
 
 
12811
                            pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
 
12812
                                oldstate, NULL);
 
12813
                            oldstate = pctxt->state;
 
12814
 
 
12815
                            counter = xmlAutomataNewCounter(pctxt->am,
 
12816
                                particle->minOccurs - 1, UNBOUNDED);
 
12817
 
 
12818
                            sub = particle->children->children;
 
12819
                            while (sub != NULL) {
 
12820
                                xmlSchemaBuildAContentModel(pctxt,
 
12821
                                    (xmlSchemaParticlePtr) sub);
 
12822
                                sub = sub->next;
 
12823
                            }
 
12824
                            tmp = pctxt->state;
 
12825
                            xmlAutomataNewCountedTrans(pctxt->am, tmp,
 
12826
                                                       oldstate, counter);
 
12827
                            pctxt->state =
 
12828
                                xmlAutomataNewCounterTrans(pctxt->am, tmp,
 
12829
                                                           NULL, counter);
 
12830
 
 
12831
                        } else {
 
12832
                            pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
 
12833
                                oldstate, NULL);
 
12834
                            oldstate = pctxt->state;
 
12835
 
 
12836
                            sub = particle->children->children;
 
12837
                            while (sub != NULL) {
 
12838
                                xmlSchemaBuildAContentModel(pctxt,
 
12839
                                    (xmlSchemaParticlePtr) sub);
 
12840
                                sub = sub->next;
 
12841
                            }
 
12842
                            xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
 
12843
                                                  oldstate);
 
12844
                            /*
 
12845
                             * epsilon needed to block previous trans from
 
12846
                             * being allowed to enter back from another
 
12847
                             * construct
 
12848
                             */
 
12849
                            pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
 
12850
                                                pctxt->state, NULL);
 
12851
                            if (particle->minOccurs == 0) {
 
12852
                                xmlAutomataNewEpsilon(pctxt->am,
 
12853
                                    oldstate, pctxt->state);
 
12854
                            }
 
12855
                        }
 
12856
                    } else if ((particle->maxOccurs > 1)
 
12857
                               || (particle->minOccurs > 1)) {
 
12858
                        xmlAutomataStatePtr tmp;
 
12859
                        int counter;
 
12860
 
 
12861
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
 
12862
                            oldstate, NULL);
 
12863
                        oldstate = pctxt->state;
 
12864
 
 
12865
                        counter = xmlAutomataNewCounter(pctxt->am,
 
12866
                            particle->minOccurs - 1,
 
12867
                            particle->maxOccurs - 1);
 
12868
 
 
12869
                        sub = particle->children->children;
 
12870
                        while (sub != NULL) {
 
12871
                            xmlSchemaBuildAContentModel(pctxt,
 
12872
                                (xmlSchemaParticlePtr) sub);
 
12873
                            sub = sub->next;
 
12874
                        }
 
12875
                        tmp = pctxt->state;
 
12876
                        xmlAutomataNewCountedTrans(pctxt->am,
 
12877
                            tmp, oldstate, counter);
 
12878
                        pctxt->state =
 
12879
                            xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
 
12880
                                                       counter);
 
12881
                        if (particle->minOccurs == 0) {
 
12882
                            xmlAutomataNewEpsilon(pctxt->am,
 
12883
                                oldstate, pctxt->state);
 
12884
                        }
 
12885
                    } else {
 
12886
                        sub = particle->children->children;
 
12887
                        while (sub != NULL) {
 
12888
                            xmlSchemaBuildAContentModel(pctxt,
 
12889
                                (xmlSchemaParticlePtr) sub);
 
12890
                            sub = sub->next;
 
12891
                        }
 
12892
                        if (particle->minOccurs == 0) {
 
12893
                            xmlAutomataNewEpsilon(pctxt->am, oldstate,
 
12894
                                                  pctxt->state);
 
12895
                        }
 
12896
                    }
 
12897
                }
 
12898
                break;
 
12899
            }
 
12900
        case XML_SCHEMA_TYPE_CHOICE:{
 
12901
                xmlSchemaTreeItemPtr sub;
 
12902
                xmlAutomataStatePtr start, end;
 
12903
 
 
12904
                start = pctxt->state;
 
12905
                end = xmlAutomataNewState(pctxt->am);
 
12906
 
 
12907
                /*
 
12908
                 * iterate over the subtypes and remerge the end with an
 
12909
                 * epsilon transition
 
12910
                 */
 
12911
                if (particle->maxOccurs == 1) {
 
12912
                    sub = particle->children->children;
 
12913
                    while (sub != NULL) {
 
12914
                        pctxt->state = start;
 
12915
                        xmlSchemaBuildAContentModel(pctxt,
 
12916
                            (xmlSchemaParticlePtr) sub);
 
12917
                        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
 
12918
                        sub = sub->next;
 
12919
                    }
 
12920
                } else {
 
12921
                    int counter;
 
12922
                    xmlAutomataStatePtr hop, base;
 
12923
                    int maxOccurs = particle->maxOccurs == UNBOUNDED ?
 
12924
                        UNBOUNDED : particle->maxOccurs - 1;
 
12925
                    int minOccurs =
 
12926
                        particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
 
12927
 
 
12928
                    /*
 
12929
                     * use a counter to keep track of the number of transtions
 
12930
                     * which went through the choice.
 
12931
                     */
 
12932
                    counter =
 
12933
                        xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
 
12934
                    hop = xmlAutomataNewState(pctxt->am);
 
12935
                    base = xmlAutomataNewState(pctxt->am);
 
12936
 
 
12937
                    sub = particle->children->children;
 
12938
                    while (sub != NULL) {
 
12939
                        pctxt->state = base;
 
12940
                        xmlSchemaBuildAContentModel(pctxt,
 
12941
                            (xmlSchemaParticlePtr) sub);
 
12942
                        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
 
12943
                        sub = sub->next;
 
12944
                    }
 
12945
                    xmlAutomataNewEpsilon(pctxt->am, start, base);
 
12946
                    xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
 
12947
                    xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
 
12948
                }
 
12949
                if (particle->minOccurs == 0) {
 
12950
                    xmlAutomataNewEpsilon(pctxt->am, start, end);
 
12951
                }
 
12952
                pctxt->state = end;
 
12953
                break;
 
12954
            }
 
12955
        case XML_SCHEMA_TYPE_ALL:{
 
12956
                xmlAutomataStatePtr start;
 
12957
                xmlSchemaParticlePtr sub;
 
12958
                xmlSchemaElementPtr elemDecl;
 
12959
                int lax;
 
12960
 
 
12961
                sub = (xmlSchemaParticlePtr) particle->children->children;
 
12962
                if (sub == NULL)
 
12963
                    break;
 
12964
                start = pctxt->state;
 
12965
                while (sub != NULL) {
 
12966
                    pctxt->state = start;
 
12967
 
 
12968
                    elemDecl = (xmlSchemaElementPtr) sub->children;
 
12969
                    if (elemDecl == NULL) {
 
12970
                        PERROR_INT("xmlSchemaBuildAContentModel",
 
12971
                            "<element> particle has no term");
 
12972
                        return;
 
12973
                    };
 
12974
                    /*
 
12975
                    * NOTE: The {max occurs} of all the particles in the
 
12976
                    * {particles} of the group must be 0 or 1; this is
 
12977
                    * already ensured during the parse of the content of
 
12978
                    * <all>.
 
12979
                    */
 
12980
                    if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
 
12981
                        int counter;
 
12982
 
 
12983
                        /*
 
12984
                         * This is an abstract group, we need to share
 
12985
                         * the same counter for all the element transitions
 
12986
                         * derived from the group
 
12987
                         */
 
12988
                        counter = xmlAutomataNewCounter(pctxt->am,
 
12989
                                           sub->minOccurs, sub->maxOccurs);
 
12990
                        xmlSchemaBuildContentModelForSubstGroup(pctxt,
 
12991
                                           sub, counter, pctxt->state);
 
12992
                    } else {
 
12993
                        if ((sub->minOccurs == 1) &&
 
12994
                            (sub->maxOccurs == 1)) {
 
12995
                            xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
 
12996
                                                    pctxt->state,
 
12997
                                                    elemDecl->name,
 
12998
                                                    elemDecl->targetNamespace,
 
12999
                                                    1, 1, elemDecl);
 
13000
                        } else if ((sub->minOccurs == 0) &&
 
13001
                            (sub->maxOccurs == 1)) {
 
13002
 
 
13003
                            xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
 
13004
                                                     pctxt->state,
 
13005
                                                     elemDecl->name,
 
13006
                                                     elemDecl->targetNamespace,
 
13007
                                                     0,
 
13008
                                                     1,
 
13009
                                                     elemDecl);
 
13010
                        }
 
13011
                    }
 
13012
                    sub = (xmlSchemaParticlePtr) sub->next;
 
13013
                }
 
13014
                lax = particle->minOccurs == 0;
 
13015
                pctxt->state =
 
13016
                    xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, lax);
 
13017
                break;
 
13018
            }
 
13019
        case XML_SCHEMA_TYPE_GROUP:
 
13020
            /*
 
13021
            * If we hit a model group definition, then this means that
 
13022
            * it was empty, thus was not substituted for the containing
 
13023
            * model group. Just do nothing in this case.
 
13024
            * TODO: But the group should be substituted and not occur at
 
13025
            * all in the content model at this point. Fix this.
 
13026
            */
 
13027
            break;
 
13028
        default:
 
13029
            xmlSchemaInternalErr2(ACTXT_CAST pctxt,
 
13030
                "xmlSchemaBuildAContentModel",
 
13031
                "found unexpected term of type '%s' in content model",
 
13032
                WXS_ITEM_TYPE_NAME(particle->children), NULL);
 
13033
            return;
 
13034
    }
 
13035
}
 
13036
 
 
13037
/**
 
13038
 * xmlSchemaBuildContentModel:
 
13039
 * @ctxt:  the schema parser context
 
13040
 * @type:  the complex type definition
 
13041
 * @name:  the element name
 
13042
 *
 
13043
 * Builds the content model of the complex type.
 
13044
 */
 
13045
static void
 
13046
xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
 
13047
                           xmlSchemaParserCtxtPtr ctxt)
 
13048
{
 
13049
    if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
 
13050
        (type->contModel != NULL) ||
 
13051
        ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
 
13052
        (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
 
13053
        return;
 
13054
 
 
13055
#ifdef DEBUG_CONTENT
 
13056
    xmlGenericError(xmlGenericErrorContext,
 
13057
                    "Building content model for %s\n", name);
 
13058
#endif
 
13059
    ctxt->am = NULL;
 
13060
    ctxt->am = xmlNewAutomata();
 
13061
    if (ctxt->am == NULL) {
 
13062
        xmlGenericError(xmlGenericErrorContext,
 
13063
            "Cannot create automata for complex type %s\n", type->name);
 
13064
        return;
 
13065
    }
 
13066
    ctxt->state = xmlAutomataGetInitState(ctxt->am);
 
13067
    /*
 
13068
    * Build the automaton.
 
13069
    */
 
13070
    xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
 
13071
    xmlAutomataSetFinalState(ctxt->am, ctxt->state);
 
13072
    type->contModel = xmlAutomataCompile(ctxt->am);
 
13073
    if (type->contModel == NULL) {
 
13074
        xmlSchemaPCustomErr(ctxt,
 
13075
            XML_SCHEMAP_INTERNAL,
 
13076
            WXS_BASIC_CAST type, type->node,
 
13077
            "Failed to compile the content model", NULL);
 
13078
    } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
 
13079
        xmlSchemaPCustomErr(ctxt,
 
13080
            XML_SCHEMAP_NOT_DETERMINISTIC,
 
13081
            /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
 
13082
            WXS_BASIC_CAST type, type->node,
 
13083
            "The content model is not determinist", NULL);
 
13084
    } else {
 
13085
#ifdef DEBUG_CONTENT_REGEXP
 
13086
        xmlGenericError(xmlGenericErrorContext,
 
13087
                        "Content model of %s:\n", type->name);
 
13088
        xmlRegexpPrint(stderr, type->contModel);
 
13089
#endif
 
13090
    }
 
13091
    ctxt->state = NULL;
 
13092
    xmlFreeAutomata(ctxt->am);
 
13093
    ctxt->am = NULL;
 
13094
}
 
13095
 
 
13096
/**
 
13097
 * xmlSchemaResolveElementReferences:
 
13098
 * @elem:  the schema element context
 
13099
 * @ctxt:  the schema parser context
 
13100
 *
 
13101
 * Resolves the references of an element declaration
 
13102
 * or particle, which has an element declaration as it's
 
13103
 * term.
 
13104
 */
 
13105
static void
 
13106
xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
 
13107
                                  xmlSchemaParserCtxtPtr ctxt)
 
13108
{
 
13109
    if ((ctxt == NULL) || (elemDecl == NULL) ||
 
13110
        ((elemDecl != NULL) &&
 
13111
        (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
 
13112
        return;
 
13113
    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
 
13114
 
 
13115
    if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
 
13116
        xmlSchemaTypePtr type;
 
13117
 
 
13118
        /* (type definition) ... otherwise the type definition ļæ½resolvedļæ½
 
13119
        * to by the ļæ½actual valueļæ½ of the type [attribute] ...
 
13120
        */
 
13121
        type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
 
13122
            elemDecl->namedTypeNs);
 
13123
        if (type == NULL) {
 
13124
            xmlSchemaPResCompAttrErr(ctxt,
 
13125
                XML_SCHEMAP_SRC_RESOLVE,
 
13126
                WXS_BASIC_CAST elemDecl, elemDecl->node,
 
13127
                "type", elemDecl->namedType, elemDecl->namedTypeNs,
 
13128
                XML_SCHEMA_TYPE_BASIC, "type definition");
 
13129
        } else
 
13130
            elemDecl->subtypes = type;
 
13131
    }
 
13132
    if (elemDecl->substGroup != NULL) {
 
13133
        xmlSchemaElementPtr substHead;
 
13134
 
 
13135
        /*
 
13136
        * FIXME TODO: Do we need a new field in _xmlSchemaElement for
 
13137
        * substitutionGroup?
 
13138
        */
 
13139
        substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
 
13140
            elemDecl->substGroupNs);
 
13141
        if (substHead == NULL) {
 
13142
            xmlSchemaPResCompAttrErr(ctxt,
 
13143
                XML_SCHEMAP_SRC_RESOLVE,
 
13144
                WXS_BASIC_CAST elemDecl, NULL,
 
13145
                "substitutionGroup", elemDecl->substGroup,
 
13146
                elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
 
13147
        } else {
 
13148
            xmlSchemaResolveElementReferences(substHead, ctxt);
 
13149
            /*
 
13150
            * Set the "substitution group affiliation".
 
13151
            * NOTE that now we use the "refDecl" field for this.
 
13152
            */
 
13153
            WXS_SUBST_HEAD(elemDecl) = substHead;
 
13154
            /*
 
13155
            * The type definitions is set to:
 
13156
            * SPEC "...the {type definition} of the element
 
13157
            * declaration ļæ½resolvedļæ½ to by the ļæ½actual valueļæ½
 
13158
            * of the substitutionGroup [attribute], if present"
 
13159
            */
 
13160
            if (elemDecl->subtypes == NULL)
 
13161
                elemDecl->subtypes = substHead->subtypes;
 
13162
        }
 
13163
    }
 
13164
    /*
 
13165
    * SPEC "The definition of anyType serves as the default type definition
 
13166
    * for element declarations whose XML representation does not specify one."
 
13167
    */
 
13168
    if ((elemDecl->subtypes == NULL) &&
 
13169
        (elemDecl->namedType == NULL) &&
 
13170
        (elemDecl->substGroup == NULL))
 
13171
        elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
 
13172
}
 
13173
 
 
13174
/**
 
13175
 * xmlSchemaResolveUnionMemberTypes:
 
13176
 * @ctxt:  the schema parser context
 
13177
 * @type:  the schema simple type definition
 
13178
 *
 
13179
 * Checks and builds the "member type definitions" property of the union
 
13180
 * simple type. This handles part (1), part (2) is done in
 
13181
 * xmlSchemaFinishMemberTypeDefinitionsProperty()
 
13182
 *
 
13183
 * Returns -1 in case of an internal error, 0 otherwise.
 
13184
 */
 
13185
static int
 
13186
xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
 
13187
                                 xmlSchemaTypePtr type)
 
13188
{
 
13189
 
 
13190
    xmlSchemaTypeLinkPtr link, lastLink, newLink;
 
13191
    xmlSchemaTypePtr memberType;
 
13192
 
 
13193
    /*
 
13194
    * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
 
13195
    * define the explicit members as the type definitions ļæ½resolvedļæ½
 
13196
    * to by the items in the ļæ½actual valueļæ½ of the memberTypes [attribute],
 
13197
    * if any, followed by the type definitions corresponding to the
 
13198
    * <simpleType>s among the [children] of <union>, if any."
 
13199
    */
 
13200
    /*
 
13201
    * Resolve references.
 
13202
    */
 
13203
    link = type->memberTypes;
 
13204
    lastLink = NULL;
 
13205
    while (link != NULL) {
 
13206
        const xmlChar *name, *nsName;
 
13207
 
 
13208
        name = ((xmlSchemaQNameRefPtr) link->type)->name;
 
13209
        nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
 
13210
 
 
13211
        memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
 
13212
        if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
 
13213
            xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
 
13214
                WXS_BASIC_CAST type, type->node, "memberTypes",
 
13215
                name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
 
13216
            /*
 
13217
            * Remove the member type link.
 
13218
            */
 
13219
            if (lastLink == NULL)
 
13220
                type->memberTypes = link->next;
 
13221
            else
 
13222
                lastLink->next = link->next;
 
13223
            newLink = link;
 
13224
            link = link->next;
 
13225
            xmlFree(newLink);
 
13226
        } else {
 
13227
            link->type = memberType;
 
13228
            lastLink = link;
 
13229
            link = link->next;
 
13230
        }
 
13231
    }
 
13232
    /*
 
13233
    * Add local simple types,
 
13234
    */
 
13235
    memberType = type->subtypes;
 
13236
    while (memberType != NULL) {
 
13237
        link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
 
13238
        if (link == NULL) {
 
13239
            xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
 
13240
            return (-1);
 
13241
        }
 
13242
        link->type = memberType;
 
13243
        link->next = NULL;
 
13244
        if (lastLink == NULL)
 
13245
            type->memberTypes = link;
 
13246
        else
 
13247
            lastLink->next = link;
 
13248
        lastLink = link;
 
13249
        memberType = memberType->next;
 
13250
    }
 
13251
    return (0);
 
13252
}
 
13253
 
 
13254
/**
 
13255
 * xmlSchemaIsDerivedFromBuiltInType:
 
13256
 * @ctxt:  the schema parser context
 
13257
 * @type:  the type definition
 
13258
 * @valType: the value type
 
13259
 *
 
13260
 *
 
13261
 * Returns 1 if the type has the given value type, or
 
13262
 * is derived from such a type.
 
13263
 */
 
13264
static int
 
13265
xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
 
13266
{
 
13267
    if (type == NULL)
 
13268
        return (0);
 
13269
    if (WXS_IS_COMPLEX(type))
 
13270
        return (0);
 
13271
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
 
13272
        if (type->builtInType == valType)
 
13273
            return(1);
 
13274
        if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
 
13275
            (type->builtInType == XML_SCHEMAS_ANYTYPE))
 
13276
            return (0);
 
13277
        return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
 
13278
    }
 
13279
    return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
 
13280
}
 
13281
 
 
13282
#if 0
 
13283
/**
 
13284
 * xmlSchemaIsDerivedFromBuiltInType:
 
13285
 * @ctxt:  the schema parser context
 
13286
 * @type:  the type definition
 
13287
 * @valType: the value type
 
13288
 *
 
13289
 *
 
13290
 * Returns 1 if the type has the given value type, or
 
13291
 * is derived from such a type.
 
13292
 */
 
13293
static int
 
13294
xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
 
13295
{
 
13296
    if (type == NULL)
 
13297
        return (0);
 
13298
    if (WXS_IS_COMPLEX(type))
 
13299
        return (0);
 
13300
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
 
13301
        if (type->builtInType == valType)
 
13302
            return(1);
 
13303
        return (0);
 
13304
    } else
 
13305
        return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
 
13306
 
 
13307
    return (0);
 
13308
}
 
13309
#endif
 
13310
 
 
13311
static xmlSchemaTypePtr
 
13312
xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
 
13313
{
 
13314
    if (type == NULL)
 
13315
        return (NULL);
 
13316
    if (WXS_IS_COMPLEX(type))
 
13317
        return (NULL);
 
13318
    if (type->type == XML_SCHEMA_TYPE_BASIC)
 
13319
        return(type);
 
13320
    return(xmlSchemaQueryBuiltInType(type->subtypes));
 
13321
}
 
13322
 
 
13323
/**
 
13324
 * xmlSchemaGetPrimitiveType:
 
13325
 * @type:  the simpleType definition
 
13326
 *
 
13327
 * Returns the primitive type of the given type or
 
13328
 * NULL in case of error.
 
13329
 */
 
13330
static xmlSchemaTypePtr
 
13331
xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
 
13332
{
 
13333
 
 
13334
    while (type != NULL) {
 
13335
        /*
 
13336
        * Note that anySimpleType is actually not a primitive type
 
13337
        * but we need that here.
 
13338
        */
 
13339
        if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
 
13340
           (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
 
13341
            return (type);
 
13342
        type = type->baseType;
 
13343
    }
 
13344
 
 
13345
    return (NULL);
 
13346
}
 
13347
 
 
13348
#if 0
 
13349
/**
 
13350
 * xmlSchemaGetBuiltInTypeAncestor:
 
13351
 * @type:  the simpleType definition
 
13352
 *
 
13353
 * Returns the primitive type of the given type or
 
13354
 * NULL in case of error.
 
13355
 */
 
13356
static xmlSchemaTypePtr
 
13357
xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
 
13358
{
 
13359
    if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
 
13360
        return (0);
 
13361
    while (type != NULL) {
 
13362
        if (type->type == XML_SCHEMA_TYPE_BASIC)
 
13363
            return (type);
 
13364
        type = type->baseType;
 
13365
    }
 
13366
 
 
13367
    return (NULL);
 
13368
}
 
13369
#endif
 
13370
 
 
13371
/**
 
13372
 * xmlSchemaCloneWildcardNsConstraints:
 
13373
 * @ctxt:  the schema parser context
 
13374
 * @dest:  the destination wildcard
 
13375
 * @source: the source wildcard
 
13376
 *
 
13377
 * Clones the namespace constraints of source
 
13378
 * and assignes them to dest.
 
13379
 * Returns -1 on internal error, 0 otherwise.
 
13380
 */
 
13381
static int
 
13382
xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
 
13383
                                    xmlSchemaWildcardPtr dest,
 
13384
                                    xmlSchemaWildcardPtr source)
 
13385
{
 
13386
    xmlSchemaWildcardNsPtr cur, tmp, last;
 
13387
 
 
13388
    if ((source == NULL) || (dest == NULL))
 
13389
        return(-1);
 
13390
    dest->any = source->any;
 
13391
    cur = source->nsSet;
 
13392
    last = NULL;
 
13393
    while (cur != NULL) {
 
13394
        tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
 
13395
        if (tmp == NULL)
 
13396
            return(-1);
 
13397
        tmp->value = cur->value;
 
13398
        if (last == NULL)
 
13399
            dest->nsSet = tmp;
 
13400
        else
 
13401
            last->next = tmp;
 
13402
        last = tmp;
 
13403
        cur = cur->next;
 
13404
    }
 
13405
    if (dest->negNsSet != NULL)
 
13406
        xmlSchemaFreeWildcardNsSet(dest->negNsSet);
 
13407
    if (source->negNsSet != NULL) {
 
13408
        dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
 
13409
        if (dest->negNsSet == NULL)
 
13410
            return(-1);
 
13411
        dest->negNsSet->value = source->negNsSet->value;
 
13412
    } else
 
13413
        dest->negNsSet = NULL;
 
13414
    return(0);
 
13415
}
 
13416
 
 
13417
/**
 
13418
 * xmlSchemaUnionWildcards:
 
13419
 * @ctxt:  the schema parser context
 
13420
 * @completeWild:  the first wildcard
 
13421
 * @curWild: the second wildcard
 
13422
 *
 
13423
 * Unions the namespace constraints of the given wildcards.
 
13424
 * @completeWild will hold the resulting union.
 
13425
 * Returns a positive error code on failure, -1 in case of an
 
13426
 * internal error, 0 otherwise.
 
13427
 */
 
13428
static int
 
13429
xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
 
13430
                            xmlSchemaWildcardPtr completeWild,
 
13431
                            xmlSchemaWildcardPtr curWild)
 
13432
{
 
13433
    xmlSchemaWildcardNsPtr cur, curB, tmp;
 
13434
 
 
13435
    /*
 
13436
    * 1 If O1 and O2 are the same value, then that value must be the
 
13437
    * value.
 
13438
    */
 
13439
    if ((completeWild->any == curWild->any) &&
 
13440
        ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
 
13441
        ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
 
13442
 
 
13443
        if ((completeWild->negNsSet == NULL) ||
 
13444
            (completeWild->negNsSet->value == curWild->negNsSet->value)) {
 
13445
 
 
13446
            if (completeWild->nsSet != NULL) {
 
13447
                int found = 0;
 
13448
 
 
13449
                /*
 
13450
                * Check equality of sets.
 
13451
                */
 
13452
                cur = completeWild->nsSet;
 
13453
                while (cur != NULL) {
 
13454
                    found = 0;
 
13455
                    curB = curWild->nsSet;
 
13456
                    while (curB != NULL) {
 
13457
                        if (cur->value == curB->value) {
 
13458
                            found = 1;
 
13459
                            break;
 
13460
                        }
 
13461
                        curB = curB->next;
 
13462
                    }
 
13463
                    if (!found)
 
13464
                        break;
 
13465
                    cur = cur->next;
 
13466
                }
 
13467
                if (found)
 
13468
                    return(0);
 
13469
            } else
 
13470
                return(0);
 
13471
        }
 
13472
    }
 
13473
    /*
 
13474
    * 2 If either O1 or O2 is any, then any must be the value
 
13475
    */
 
13476
    if (completeWild->any != curWild->any) {
 
13477
        if (completeWild->any == 0) {
 
13478
            completeWild->any = 1;
 
13479
            if (completeWild->nsSet != NULL) {
 
13480
                xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
 
13481
                completeWild->nsSet = NULL;
 
13482
            }
 
13483
            if (completeWild->negNsSet != NULL) {
 
13484
                xmlFree(completeWild->negNsSet);
 
13485
                completeWild->negNsSet = NULL;
 
13486
            }
 
13487
        }
 
13488
        return (0);
 
13489
    }
 
13490
    /*
 
13491
    * 3 If both O1 and O2 are sets of (namespace names or ļæ½absentļæ½),
 
13492
    * then the union of those sets must be the value.
 
13493
    */
 
13494
    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
 
13495
        int found;
 
13496
        xmlSchemaWildcardNsPtr start;
 
13497
 
 
13498
        cur = curWild->nsSet;
 
13499
        start = completeWild->nsSet;
 
13500
        while (cur != NULL) {
 
13501
            found = 0;
 
13502
            curB = start;
 
13503
            while (curB != NULL) {
 
13504
                if (cur->value == curB->value) {
 
13505
                    found = 1;
 
13506
                    break;
 
13507
                }
 
13508
                curB = curB->next;
 
13509
            }
 
13510
            if (!found) {
 
13511
                tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
 
13512
                if (tmp == NULL)
 
13513
                    return (-1);
 
13514
                tmp->value = cur->value;
 
13515
                tmp->next = completeWild->nsSet;
 
13516
                completeWild->nsSet = tmp;
 
13517
            }
 
13518
            cur = cur->next;
 
13519
        }
 
13520
 
 
13521
        return(0);
 
13522
    }
 
13523
    /*
 
13524
    * 4 If the two are negations of different values (namespace names
 
13525
    * or ļæ½absentļæ½), then a pair of not and ļæ½absentļæ½ must be the value.
 
13526
    */
 
13527
    if ((completeWild->negNsSet != NULL) &&
 
13528
        (curWild->negNsSet != NULL) &&
 
13529
        (completeWild->negNsSet->value != curWild->negNsSet->value)) {
 
13530
        completeWild->negNsSet->value = NULL;
 
13531
 
 
13532
        return(0);
 
13533
    }
 
13534
    /*
 
13535
     * 5.
 
13536
     */
 
13537
    if (((completeWild->negNsSet != NULL) &&
 
13538
        (completeWild->negNsSet->value != NULL) &&
 
13539
        (curWild->nsSet != NULL)) ||
 
13540
        ((curWild->negNsSet != NULL) &&
 
13541
        (curWild->negNsSet->value != NULL) &&
 
13542
        (completeWild->nsSet != NULL))) {
 
13543
 
 
13544
        int nsFound, absentFound = 0;
 
13545
 
 
13546
        if (completeWild->nsSet != NULL) {
 
13547
            cur = completeWild->nsSet;
 
13548
            curB = curWild->negNsSet;
 
13549
        } else {
 
13550
            cur = curWild->nsSet;
 
13551
            curB = completeWild->negNsSet;
 
13552
        }
 
13553
        nsFound = 0;
 
13554
        while (cur != NULL) {
 
13555
            if (cur->value == NULL)
 
13556
                absentFound = 1;
 
13557
            else if (cur->value == curB->value)
 
13558
                nsFound = 1;
 
13559
            if (nsFound && absentFound)
 
13560
                break;
 
13561
            cur = cur->next;
 
13562
        }
 
13563
 
 
13564
        if (nsFound && absentFound) {
 
13565
            /*
 
13566
            * 5.1 If the set S includes both the negated namespace
 
13567
            * name and ļæ½absentļæ½, then any must be the value.
 
13568
            */
 
13569
            completeWild->any = 1;
 
13570
            if (completeWild->nsSet != NULL) {
 
13571
                xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
 
13572
                completeWild->nsSet = NULL;
 
13573
            }
 
13574
            if (completeWild->negNsSet != NULL) {
 
13575
                xmlFree(completeWild->negNsSet);
 
13576
                completeWild->negNsSet = NULL;
 
13577
            }
 
13578
        } else if (nsFound && (!absentFound)) {
 
13579
            /*
 
13580
            * 5.2 If the set S includes the negated namespace name
 
13581
            * but not ļæ½absentļæ½, then a pair of not and ļæ½absentļæ½ must
 
13582
            * be the value.
 
13583
            */
 
13584
            if (completeWild->nsSet != NULL) {
 
13585
                xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
 
13586
                completeWild->nsSet = NULL;
 
13587
            }
 
13588
            if (completeWild->negNsSet == NULL) {
 
13589
                completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
 
13590
                if (completeWild->negNsSet == NULL)
 
13591
                    return (-1);
 
13592
            }
 
13593
            completeWild->negNsSet->value = NULL;
 
13594
        } else if ((!nsFound) && absentFound) {
 
13595
            /*
 
13596
            * 5.3 If the set S includes ļæ½absentļæ½ but not the negated
 
13597
            * namespace name, then the union is not expressible.
 
13598
            */
 
13599
            xmlSchemaPErr(ctxt, completeWild->node,
 
13600
                XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
 
13601
                "The union of the wilcard is not expressible.\n",
 
13602
                NULL, NULL);
 
13603
            return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
 
13604
        } else if ((!nsFound) && (!absentFound)) {
 
13605
            /*
 
13606
            * 5.4 If the set S does not include either the negated namespace
 
13607
            * name or ļæ½absentļæ½, then whichever of O1 or O2 is a pair of not
 
13608
            * and a namespace name must be the value.
 
13609
            */
 
13610
            if (completeWild->negNsSet == NULL) {
 
13611
                if (completeWild->nsSet != NULL) {
 
13612
                    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
 
13613
                    completeWild->nsSet = NULL;
 
13614
                }
 
13615
                completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
 
13616
                if (completeWild->negNsSet == NULL)
 
13617
                    return (-1);
 
13618
                completeWild->negNsSet->value = curWild->negNsSet->value;
 
13619
            }
 
13620
        }
 
13621
        return (0);
 
13622
    }
 
13623
    /*
 
13624
     * 6.
 
13625
     */
 
13626
    if (((completeWild->negNsSet != NULL) &&
 
13627
        (completeWild->negNsSet->value == NULL) &&
 
13628
        (curWild->nsSet != NULL)) ||
 
13629
        ((curWild->negNsSet != NULL) &&
 
13630
        (curWild->negNsSet->value == NULL) &&
 
13631
        (completeWild->nsSet != NULL))) {
 
13632
 
 
13633
        if (completeWild->nsSet != NULL) {
 
13634
            cur = completeWild->nsSet;
 
13635
        } else {
 
13636
            cur = curWild->nsSet;
 
13637
        }
 
13638
        while (cur != NULL) {
 
13639
            if (cur->value == NULL) {
 
13640
                /*
 
13641
                * 6.1 If the set S includes ļæ½absentļæ½, then any must be the
 
13642
                * value.
 
13643
                */
 
13644
                completeWild->any = 1;
 
13645
                if (completeWild->nsSet != NULL) {
 
13646
                    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
 
13647
                    completeWild->nsSet = NULL;
 
13648
                }
 
13649
                if (completeWild->negNsSet != NULL) {
 
13650
                    xmlFree(completeWild->negNsSet);
 
13651
                    completeWild->negNsSet = NULL;
 
13652
                }
 
13653
                return (0);
 
13654
            }
 
13655
            cur = cur->next;
 
13656
        }
 
13657
        if (completeWild->negNsSet == NULL) {
 
13658
            /*
 
13659
            * 6.2 If the set S does not include ļæ½absentļæ½, then a pair of not
 
13660
            * and ļæ½absentļæ½ must be the value.
 
13661
            */
 
13662
            if (completeWild->nsSet != NULL) {
 
13663
                xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
 
13664
                completeWild->nsSet = NULL;
 
13665
            }
 
13666
            completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
 
13667
            if (completeWild->negNsSet == NULL)
 
13668
                return (-1);
 
13669
            completeWild->negNsSet->value = NULL;
 
13670
        }
 
13671
        return (0);
 
13672
    }
 
13673
    return (0);
 
13674
 
 
13675
}
 
13676
 
 
13677
/**
 
13678
 * xmlSchemaIntersectWildcards:
 
13679
 * @ctxt:  the schema parser context
 
13680
 * @completeWild:  the first wildcard
 
13681
 * @curWild: the second wildcard
 
13682
 *
 
13683
 * Intersects the namespace constraints of the given wildcards.
 
13684
 * @completeWild will hold the resulting intersection.
 
13685
 * Returns a positive error code on failure, -1 in case of an
 
13686
 * internal error, 0 otherwise.
 
13687
 */
 
13688
static int
 
13689
xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
 
13690
                            xmlSchemaWildcardPtr completeWild,
 
13691
                            xmlSchemaWildcardPtr curWild)
 
13692
{
 
13693
    xmlSchemaWildcardNsPtr cur, curB, prev,  tmp;
 
13694
 
 
13695
    /*
 
13696
    * 1 If O1 and O2 are the same value, then that value must be the
 
13697
    * value.
 
13698
    */
 
13699
    if ((completeWild->any == curWild->any) &&
 
13700
        ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
 
13701
        ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
 
13702
 
 
13703
        if ((completeWild->negNsSet == NULL) ||
 
13704
            (completeWild->negNsSet->value == curWild->negNsSet->value)) {
 
13705
 
 
13706
            if (completeWild->nsSet != NULL) {
 
13707
                int found = 0;
 
13708
 
 
13709
                /*
 
13710
                * Check equality of sets.
 
13711
                */
 
13712
                cur = completeWild->nsSet;
 
13713
                while (cur != NULL) {
 
13714
                    found = 0;
 
13715
                    curB = curWild->nsSet;
 
13716
                    while (curB != NULL) {
 
13717
                        if (cur->value == curB->value) {
 
13718
                            found = 1;
 
13719
                            break;
 
13720
                        }
 
13721
                        curB = curB->next;
 
13722
                    }
 
13723
                    if (!found)
 
13724
                        break;
 
13725
                    cur = cur->next;
 
13726
                }
 
13727
                if (found)
 
13728
                    return(0);
 
13729
            } else
 
13730
                return(0);
 
13731
        }
 
13732
    }
 
13733
    /*
 
13734
    * 2 If either O1 or O2 is any, then the other must be the value.
 
13735
    */
 
13736
    if ((completeWild->any != curWild->any) && (completeWild->any)) {
 
13737
        if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
 
13738
            return(-1);
 
13739
        return(0);
 
13740
    }
 
13741
    /*
 
13742
    * 3 If either O1 or O2 is a pair of not and a value (a namespace
 
13743
    * name or ļæ½absentļæ½) and the other is a set of (namespace names or
 
13744
    * ļæ½absentļæ½), then that set, minus the negated value if it was in
 
13745
    * the set, minus ļæ½absentļæ½ if it was in the set, must be the value.
 
13746
    */
 
13747
    if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
 
13748
        ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
 
13749
        const xmlChar *neg;
 
13750
 
 
13751
        if (completeWild->nsSet == NULL) {
 
13752
            neg = completeWild->negNsSet->value;
 
13753
            if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
 
13754
                return(-1);
 
13755
        } else
 
13756
            neg = curWild->negNsSet->value;
 
13757
        /*
 
13758
        * Remove absent and negated.
 
13759
        */
 
13760
        prev = NULL;
 
13761
        cur = completeWild->nsSet;
 
13762
        while (cur != NULL) {
 
13763
            if (cur->value == NULL) {
 
13764
                if (prev == NULL)
 
13765
                    completeWild->nsSet = cur->next;
 
13766
                else
 
13767
                    prev->next = cur->next;
 
13768
                xmlFree(cur);
 
13769
                break;
 
13770
            }
 
13771
            prev = cur;
 
13772
            cur = cur->next;
 
13773
        }
 
13774
        if (neg != NULL) {
 
13775
            prev = NULL;
 
13776
            cur = completeWild->nsSet;
 
13777
            while (cur != NULL) {
 
13778
                if (cur->value == neg) {
 
13779
                    if (prev == NULL)
 
13780
                        completeWild->nsSet = cur->next;
 
13781
                    else
 
13782
                        prev->next = cur->next;
 
13783
                    xmlFree(cur);
 
13784
                    break;
 
13785
                }
 
13786
                prev = cur;
 
13787
                cur = cur->next;
 
13788
            }
 
13789
        }
 
13790
 
 
13791
        return(0);
 
13792
    }
 
13793
    /*
 
13794
    * 4 If both O1 and O2 are sets of (namespace names or ļæ½absentļæ½),
 
13795
    * then the intersection of those sets must be the value.
 
13796
    */
 
13797
    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
 
13798
        int found;
 
13799
 
 
13800
        cur = completeWild->nsSet;
 
13801
        prev = NULL;
 
13802
        while (cur != NULL) {
 
13803
            found = 0;
 
13804
            curB = curWild->nsSet;
 
13805
            while (curB != NULL) {
 
13806
                if (cur->value == curB->value) {
 
13807
                    found = 1;
 
13808
                    break;
 
13809
                }
 
13810
                curB = curB->next;
 
13811
            }
 
13812
            if (!found) {
 
13813
                if (prev == NULL)
 
13814
                    completeWild->nsSet = cur->next;
 
13815
                else
 
13816
                    prev->next = cur->next;
 
13817
                tmp = cur->next;
 
13818
                xmlFree(cur);
 
13819
                cur = tmp;
 
13820
                continue;
 
13821
            }
 
13822
            prev = cur;
 
13823
            cur = cur->next;
 
13824
        }
 
13825
 
 
13826
        return(0);
 
13827
    }
 
13828
    /* 5 If the two are negations of different namespace names,
 
13829
    * then the intersection is not expressible
 
13830
    */
 
13831
    if ((completeWild->negNsSet != NULL) &&
 
13832
        (curWild->negNsSet != NULL) &&
 
13833
        (completeWild->negNsSet->value != curWild->negNsSet->value) &&
 
13834
        (completeWild->negNsSet->value != NULL) &&
 
13835
        (curWild->negNsSet->value != NULL)) {
 
13836
 
 
13837
        xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
 
13838
            "The intersection of the wilcard is not expressible.\n",
 
13839
            NULL, NULL);
 
13840
        return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
 
13841
    }
 
13842
    /*
 
13843
    * 6 If the one is a negation of a namespace name and the other
 
13844
    * is a negation of ļæ½absentļæ½, then the one which is the negation
 
13845
    * of a namespace name must be the value.
 
13846
    */
 
13847
    if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
 
13848
        (completeWild->negNsSet->value != curWild->negNsSet->value) &&
 
13849
        (completeWild->negNsSet->value == NULL)) {
 
13850
        completeWild->negNsSet->value =  curWild->negNsSet->value;
 
13851
    }
 
13852
    return(0);
 
13853
}
 
13854
 
 
13855
/**
 
13856
 * xmlSchemaIsWildcardNsConstraintSubset:
 
13857
 * @ctxt:  the schema parser context
 
13858
 * @sub:  the first wildcard
 
13859
 * @super: the second wildcard
 
13860
 *
 
13861
 * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
 
13862
 *
 
13863
 * Returns 0 if the namespace constraint of @sub is an intensional
 
13864
 * subset of @super, 1 otherwise.
 
13865
 */
 
13866
static int
 
13867
xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
 
13868
                          xmlSchemaWildcardPtr super)
 
13869
{
 
13870
    /*
 
13871
    * 1 super must be any.
 
13872
    */
 
13873
    if (super->any)
 
13874
        return (0);
 
13875
    /*
 
13876
    * 2.1 sub must be a pair of not and a namespace name or ļæ½absentļæ½.
 
13877
    * 2.2 super must be a pair of not and the same value.
 
13878
    */
 
13879
    if ((sub->negNsSet != NULL) &&
 
13880
        (super->negNsSet != NULL) &&
 
13881
        (sub->negNsSet->value == sub->negNsSet->value))
 
13882
        return (0);
 
13883
    /*
 
13884
    * 3.1 sub must be a set whose members are either namespace names or ļæ½absentļæ½.
 
13885
    */
 
13886
    if (sub->nsSet != NULL) {
 
13887
        /*
 
13888
        * 3.2.1 super must be the same set or a superset thereof.
 
13889
        */
 
13890
        if (super->nsSet != NULL) {
 
13891
            xmlSchemaWildcardNsPtr cur, curB;
 
13892
            int found = 0;
 
13893
 
 
13894
            cur = sub->nsSet;
 
13895
            while (cur != NULL) {
 
13896
                found = 0;
 
13897
                curB = super->nsSet;
 
13898
                while (curB != NULL) {
 
13899
                    if (cur->value == curB->value) {
 
13900
                        found = 1;
 
13901
                        break;
 
13902
                    }
 
13903
                    curB = curB->next;
 
13904
                }
 
13905
                if (!found)
 
13906
                    return (1);
 
13907
                cur = cur->next;
 
13908
            }
 
13909
            if (found)
 
13910
                return (0);
 
13911
        } else if (super->negNsSet != NULL) {
 
13912
            xmlSchemaWildcardNsPtr cur;
 
13913
            /*
 
13914
            * 3.2.2 super must be a pair of not and a namespace name or
 
13915
            * ļæ½absentļæ½ and that value must not be in sub's set.
 
13916
            */
 
13917
            cur = sub->nsSet;
 
13918
            while (cur != NULL) {
 
13919
                if (cur->value == super->negNsSet->value)
 
13920
                    return (1);
 
13921
                cur = cur->next;
 
13922
            }
 
13923
            return (0);
 
13924
        }
 
13925
    }
 
13926
    return (1);
 
13927
}
 
13928
 
 
13929
static int
 
13930
xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
 
13931
                                     int *fixed,
 
13932
                                     const xmlChar **value,
 
13933
                                     xmlSchemaValPtr *val)
 
13934
{
 
13935
    *fixed = 0;
 
13936
    *value = NULL;
 
13937
    if (val != 0)
 
13938
        *val = NULL;
 
13939
 
 
13940
    if (attruse->defValue != NULL) {        
 
13941
        *value = attruse->defValue;
 
13942
        if (val != NULL)
 
13943
            *val = attruse->defVal;
 
13944
        if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
 
13945
            *fixed = 1;
 
13946
        return(1);
 
13947
    } else if ((attruse->attrDecl != NULL) &&
 
13948
        (attruse->attrDecl->defValue != NULL)) {
 
13949
        *value = attruse->attrDecl->defValue;
 
13950
        if (val != NULL)
 
13951
            *val = attruse->attrDecl->defVal;
 
13952
        if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
 
13953
            *fixed = 1;
 
13954
        return(1);
 
13955
    }
 
13956
    return(0);
 
13957
}
 
13958
/**
 
13959
 * xmlSchemaCheckCVCWildcardNamespace:
 
13960
 * @wild:  the wildcard
 
13961
 * @ns:  the namespace
 
13962
 *
 
13963
 * Validation Rule: Wildcard allows Namespace Name
 
13964
 * (cvc-wildcard-namespace)
 
13965
 *
 
13966
 * Returns 0 if the given namespace matches the wildcard,
 
13967
 * 1 otherwise and -1 on API errors.
 
13968
 */
 
13969
static int
 
13970
xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
 
13971
                                   const xmlChar* ns)
 
13972
{
 
13973
    if (wild == NULL)
 
13974
        return(-1);
 
13975
 
 
13976
    if (wild->any)
 
13977
        return(0);
 
13978
    else if (wild->nsSet != NULL) {
 
13979
        xmlSchemaWildcardNsPtr cur;
 
13980
 
 
13981
        cur = wild->nsSet;
 
13982
        while (cur != NULL) {
 
13983
            if (xmlStrEqual(cur->value, ns))
 
13984
                return(0);
 
13985
            cur = cur->next;
 
13986
        }
 
13987
    } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
 
13988
        (!xmlStrEqual(wild->negNsSet->value, ns)))
 
13989
        return(0);
 
13990
 
 
13991
    return(1);
 
13992
}
 
13993
 
 
13994
#define XML_SCHEMA_ACTION_DERIVE 0
 
13995
#define XML_SCHEMA_ACTION_REDEFINE 1
 
13996
 
 
13997
#define WXS_ACTION_STR(a) \
 
13998
((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
 
13999
 
 
14000
/*
 
14001
* Schema Component Constraint:
 
14002
*   Derivation Valid (Restriction, Complex)
 
14003
*   derivation-ok-restriction (2) - (4)
 
14004
*
 
14005
* ATTENTION:
 
14006
* In XML Schema 1.1 this will be:
 
14007
* Validation Rule:
 
14008
*     Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
 
14009
*
 
14010
*/
 
14011
static int
 
14012
xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
 
14013
                                       int action,
 
14014
                                       xmlSchemaBasicItemPtr item,
 
14015
                                       xmlSchemaBasicItemPtr baseItem,
 
14016
                                       xmlSchemaItemListPtr uses,
 
14017
                                       xmlSchemaItemListPtr baseUses,
 
14018
                                       xmlSchemaWildcardPtr wild,
 
14019
                                       xmlSchemaWildcardPtr baseWild)
 
14020
{        
 
14021
    xmlSchemaAttributeUsePtr cur = NULL, bcur;
 
14022
    int i, j, found; /* err = 0; */
 
14023
    const xmlChar *bEffValue;
 
14024
    int effFixed;
 
14025
    
 
14026
    if (uses != NULL) {
 
14027
        for (i = 0; i < uses->nbItems; i++) {
 
14028
            cur = uses->items[i];
 
14029
            found = 0;
 
14030
            if (baseUses == NULL)
 
14031
                goto not_found;
 
14032
            for (j = 0; j < baseUses->nbItems; j++) {
 
14033
                bcur = baseUses->items[j];      
 
14034
                if ((WXS_ATTRUSE_DECL_NAME(cur) ==
 
14035
                        WXS_ATTRUSE_DECL_NAME(bcur)) &&
 
14036
                    (WXS_ATTRUSE_DECL_TNS(cur) ==
 
14037
                        WXS_ATTRUSE_DECL_TNS(bcur)))
 
14038
                {
 
14039
                    /*
 
14040
                    * (2.1) "If there is an attribute use in the {attribute
 
14041
                    * uses} of the {base type definition} (call this B) whose
 
14042
                    * {attribute declaration} has the same {name} and {target
 
14043
                    * namespace}, then  all of the following must be true:"
 
14044
                    */
 
14045
                    found = 1;
 
14046
                    
 
14047
                    if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
 
14048
                        (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
 
14049
                    {
 
14050
                        xmlChar *str = NULL;
 
14051
                        /*
 
14052
                        * (2.1.1) "one of the following must be true:"
 
14053
                        * (2.1.1.1) "B's {required} is false."
 
14054
                        * (2.1.1.2) "R's {required} is true."
 
14055
                        */
 
14056
                        xmlSchemaPAttrUseErr4(pctxt,
 
14057
                            XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
 
14058
                            WXS_ITEM_NODE(item), item, cur,
 
14059
                            "The 'optional' attribute use is inconsistent "
 
14060
                            "with the corresponding 'required' attribute use of "
 
14061
                            "the %s %s",
 
14062
                            WXS_ACTION_STR(action),
 
14063
                            xmlSchemaGetComponentDesignation(&str, baseItem),
 
14064
                            NULL, NULL);
 
14065
                        FREE_AND_NULL(str);
 
14066
                        /* err = pctxt->err; */
 
14067
                    } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
 
14068
                        WXS_ATTRUSE_TYPEDEF(cur),
 
14069
                        WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
 
14070
                    {
 
14071
                        xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
 
14072
                        
 
14073
                        /*
 
14074
                        * SPEC (2.1.2) "R's {attribute declaration}'s
 
14075
                        * {type definition} must be validly derived from
 
14076
                        * B's {type definition} given the empty set as
 
14077
                        * defined in Type Derivation OK (Simple) (ļæ½3.14.6)."
 
14078
                        */
 
14079
                        xmlSchemaPAttrUseErr4(pctxt,
 
14080
                            XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
 
14081
                            WXS_ITEM_NODE(item), item, cur,
 
14082
                            "The attribute declaration's %s "
 
14083
                            "is not validly derived from "
 
14084
                            "the corresponding %s of the "
 
14085
                            "attribute declaration in the %s %s",
 
14086
                            xmlSchemaGetComponentDesignation(&strA,
 
14087
                                WXS_ATTRUSE_TYPEDEF(cur)),
 
14088
                            xmlSchemaGetComponentDesignation(&strB,
 
14089
                                WXS_ATTRUSE_TYPEDEF(bcur)),
 
14090
                            WXS_ACTION_STR(action),
 
14091
                            xmlSchemaGetComponentDesignation(&strC, baseItem));
 
14092
                            /* xmlSchemaGetComponentDesignation(&str, baseItem), */
 
14093
                        FREE_AND_NULL(strA);
 
14094
                        FREE_AND_NULL(strB);
 
14095
                        FREE_AND_NULL(strC);
 
14096
                        /* err = pctxt->err; */
 
14097
                    } else {
 
14098
                        /*
 
14099
                        * 2.1.3 [Definition:]  Let the effective value
 
14100
                        * constraint of an attribute use be its {value
 
14101
                        * constraint}, if present, otherwise its {attribute
 
14102
                        * declaration}'s {value constraint} .
 
14103
                        */
 
14104
                        xmlSchemaGetEffectiveValueConstraint(bcur,
 
14105
                            &effFixed, &bEffValue, NULL);
 
14106
                        /*
 
14107
                        * 2.1.3 ... one of the following must be true
 
14108
                        *
 
14109
                        * 2.1.3.1 B's ļæ½effective value constraintļæ½ is
 
14110
                        * ļæ½absentļæ½ or default.
 
14111
                        */
 
14112
                        if ((bEffValue != NULL) &&
 
14113
                            (effFixed == 1)) {
 
14114
                            const xmlChar *rEffValue = NULL;
 
14115
                            
 
14116
                            xmlSchemaGetEffectiveValueConstraint(bcur,
 
14117
                                &effFixed, &rEffValue, NULL);
 
14118
                            /*
 
14119
                            * 2.1.3.2 R's ļæ½effective value constraintļæ½ is
 
14120
                            * fixed with the same string as B's.
 
14121
                            * MAYBE TODO: Compare the computed values.
 
14122
                            *       Hmm, it says "same string" so
 
14123
                            *       string-equality might really be sufficient.
 
14124
                            */
 
14125
                            if ((effFixed == 0) ||
 
14126
                                (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
 
14127
                            {
 
14128
                                xmlChar *str = NULL;
 
14129
                                
 
14130
                                xmlSchemaPAttrUseErr4(pctxt,
 
14131
                                    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
 
14132
                                    WXS_ITEM_NODE(item), item, cur,
 
14133
                                    "The effective value constraint of the "
 
14134
                                    "attribute use is inconsistent with "
 
14135
                                    "its correspondent in the %s %s",
 
14136
                                    WXS_ACTION_STR(action),
 
14137
                                    xmlSchemaGetComponentDesignation(&str,
 
14138
                                        baseItem),
 
14139
                                    NULL, NULL);
 
14140
                                FREE_AND_NULL(str);
 
14141
                                /* err = pctxt->err; */
 
14142
                            }
 
14143
                        }
 
14144
                    }
 
14145
                    break;
 
14146
                }
 
14147
            }
 
14148
not_found:      
 
14149
            if (!found) {
 
14150
                /*
 
14151
                * (2.2) "otherwise the {base type definition} must have an
 
14152
                * {attribute wildcard} and the {target namespace} of the
 
14153
                * R's {attribute declaration} must be ļæ½validļæ½ with respect
 
14154
                * to that wildcard, as defined in Wildcard allows Namespace
 
14155
                * Name (ļæ½3.10.4)."
 
14156
                */
 
14157
                if ((baseWild == NULL) ||
 
14158
                    (xmlSchemaCheckCVCWildcardNamespace(baseWild,
 
14159
                    (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
 
14160
                {
 
14161
                    xmlChar *str = NULL;
 
14162
                    
 
14163
                    xmlSchemaPAttrUseErr4(pctxt,
 
14164
                        XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
 
14165
                        WXS_ITEM_NODE(item), item, cur,
 
14166
                        "Neither a matching attribute use, "
 
14167
                        "nor a matching wildcard exists in the %s %s",
 
14168
                        WXS_ACTION_STR(action),
 
14169
                        xmlSchemaGetComponentDesignation(&str, baseItem),
 
14170
                        NULL, NULL);
 
14171
                    FREE_AND_NULL(str);
 
14172
                    /* err = pctxt->err; */
 
14173
                }
 
14174
            }
 
14175
        }
 
14176
    }
 
14177
    /*
 
14178
    * SPEC derivation-ok-restriction (3):    
 
14179
    * (3) "For each attribute use in the {attribute uses} of the {base type
 
14180
    * definition} whose {required} is true, there must be an attribute
 
14181
    * use with an {attribute declaration} with the same {name} and
 
14182
    * {target namespace} as its {attribute declaration} in the {attribute
 
14183
    * uses} of the complex type definition itself whose {required} is true.
 
14184
    */
 
14185
    if (baseUses != NULL) {
 
14186
        for (j = 0; j < baseUses->nbItems; j++) {
 
14187
            bcur = baseUses->items[j];
 
14188
            if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
 
14189
                continue;
 
14190
            found = 0;
 
14191
            if (uses != NULL) {
 
14192
                for (i = 0; i < uses->nbItems; i++) {
 
14193
                    cur = uses->items[i];       
 
14194
                    if ((WXS_ATTRUSE_DECL_NAME(cur) ==
 
14195
                        WXS_ATTRUSE_DECL_NAME(bcur)) &&
 
14196
                        (WXS_ATTRUSE_DECL_TNS(cur) ==
 
14197
                        WXS_ATTRUSE_DECL_TNS(bcur))) {
 
14198
                        found = 1;
 
14199
                        break;
 
14200
                    }
 
14201
                }
 
14202
            }
 
14203
            if (!found) {
 
14204
                xmlChar *strA = NULL, *strB = NULL;
 
14205
                
 
14206
                xmlSchemaCustomErr4(ACTXT_CAST pctxt,
 
14207
                    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
 
14208
                    NULL, item,
 
14209
                    "A matching attribute use for the "
 
14210
                    "'required' %s of the %s %s is missing",
 
14211
                    xmlSchemaGetComponentDesignation(&strA, bcur),
 
14212
                    WXS_ACTION_STR(action),
 
14213
                    xmlSchemaGetComponentDesignation(&strB, baseItem),
 
14214
                    NULL);
 
14215
                FREE_AND_NULL(strA);
 
14216
                FREE_AND_NULL(strB);
 
14217
            }
 
14218
        }
 
14219
    }
 
14220
    /*
 
14221
    * derivation-ok-restriction (4)
 
14222
    */
 
14223
    if (wild != NULL) {
 
14224
        /*
 
14225
        * (4) "If there is an {attribute wildcard}, all of the
 
14226
        * following must be true:"
 
14227
        */   
 
14228
        if (baseWild == NULL) {
 
14229
            xmlChar *str = NULL;
 
14230
 
 
14231
            /*
 
14232
            * (4.1) "The {base type definition} must also have one."
 
14233
            */      
 
14234
            xmlSchemaCustomErr4(ACTXT_CAST pctxt,
 
14235
                XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
 
14236
                NULL, item,
 
14237
                "The %s has an attribute wildcard, "
 
14238
                "but the %s %s '%s' does not have one",
 
14239
                WXS_ITEM_TYPE_NAME(item),                   
 
14240
                WXS_ACTION_STR(action),
 
14241
                WXS_ITEM_TYPE_NAME(baseItem),
 
14242
                xmlSchemaGetComponentQName(&str, baseItem));
 
14243
            FREE_AND_NULL(str);
 
14244
            return(pctxt->err);
 
14245
        } else if ((baseWild->any == 0) &&
 
14246
                xmlSchemaCheckCOSNSSubset(wild, baseWild))
 
14247
        {
 
14248
            xmlChar *str = NULL;
 
14249
            /*
 
14250
            * (4.2) "The complex type definition's {attribute wildcard}'s
 
14251
            * {namespace constraint} must be a subset of the {base type
 
14252
            * definition}'s {attribute wildcard}'s {namespace constraint},
 
14253
            * as defined by Wildcard Subset (ļæ½3.10.6)."
 
14254
            */
 
14255
            xmlSchemaCustomErr4(ACTXT_CAST pctxt,
 
14256
                XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
 
14257
                NULL, item,
 
14258
                "The attribute wildcard is not a valid "
 
14259
                "subset of the wildcard in the %s %s '%s'",
 
14260
                WXS_ACTION_STR(action),
 
14261
                WXS_ITEM_TYPE_NAME(baseItem),
 
14262
                xmlSchemaGetComponentQName(&str, baseItem),
 
14263
                NULL);
 
14264
            FREE_AND_NULL(str);
 
14265
            return(pctxt->err);
 
14266
        }
 
14267
        /* 4.3 Unless the {base type definition} is the ļæ½ur-type
 
14268
        * definitionļæ½, the complex type definition's {attribute
 
14269
        * wildcard}'s {process contents} must be identical to or
 
14270
        * stronger than the {base type definition}'s {attribute
 
14271
        * wildcard}'s {process contents}, where strict is stronger
 
14272
        * than lax is stronger than skip.
 
14273
        */
 
14274
        if ((! WXS_IS_ANYTYPE(baseItem)) &&
 
14275
            (wild->processContents < baseWild->processContents)) {
 
14276
            xmlChar *str = NULL;
 
14277
            xmlSchemaCustomErr4(ACTXT_CAST pctxt,
 
14278
                XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
 
14279
                NULL, baseItem,
 
14280
                "The {process contents} of the attribute wildcard is "
 
14281
                "weaker than the one in the %s %s '%s'",
 
14282
                WXS_ACTION_STR(action),
 
14283
                WXS_ITEM_TYPE_NAME(baseItem),
 
14284
                xmlSchemaGetComponentQName(&str, baseItem),
 
14285
                NULL);
 
14286
            FREE_AND_NULL(str)
 
14287
                return(pctxt->err);
 
14288
        }
 
14289
    }
 
14290
    return(0);
 
14291
}
 
14292
 
 
14293
 
 
14294
static int
 
14295
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
 
14296
                                  xmlSchemaBasicItemPtr item,
 
14297
                                  xmlSchemaWildcardPtr *completeWild,
 
14298
                                  xmlSchemaItemListPtr list,
 
14299
                                  xmlSchemaItemListPtr prohibs);
 
14300
/**
 
14301
 * xmlSchemaFixupTypeAttributeUses:
 
14302
 * @ctxt:  the schema parser context
 
14303
 * @type:  the complex type definition
 
14304
 *
 
14305
 *
 
14306
 * Builds the wildcard and the attribute uses on the given complex type.
 
14307
 * Returns -1 if an internal error occurs, 0 otherwise.
 
14308
 *
 
14309
 * ATTENTION TODO: Experimantally this uses pointer comparisons for
 
14310
 * strings, so recheck this if we start to hardcode some schemata, since
 
14311
 * they might not be in the same dict.
 
14312
 * NOTE: It is allowed to "extend" the xs:anyType type.
 
14313
 */
 
14314
static int
 
14315
xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
 
14316
                                  xmlSchemaTypePtr type)
 
14317
{
 
14318
    xmlSchemaTypePtr baseType = NULL;
 
14319
    xmlSchemaAttributeUsePtr use;    
 
14320
    xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
 
14321
 
 
14322
    if (type->baseType == NULL) {
 
14323
        PERROR_INT("xmlSchemaFixupTypeAttributeUses",
 
14324
            "no base type");
 
14325
        return (-1);
 
14326
    }
 
14327
    baseType = type->baseType;        
 
14328
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
 
14329
        if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
 
14330
            return(-1);
 
14331
 
 
14332
    uses = type->attrUses;
 
14333
    baseUses = baseType->attrUses;
 
14334
    /*
 
14335
    * Expand attribute group references. And build the 'complete'
 
14336
    * wildcard, i.e. intersect multiple wildcards.
 
14337
    * Move attribute prohibitions into a separate list.
 
14338
    */
 
14339
    if (uses != NULL) { 
 
14340
        if (WXS_IS_RESTRICTION(type)) {
 
14341
            /*
 
14342
            * This one will transfer all attr. prohibitions
 
14343
            * into pctxt->attrProhibs.
 
14344
            */
 
14345
            if (xmlSchemaExpandAttributeGroupRefs(pctxt,
 
14346
                WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
 
14347
                pctxt->attrProhibs) == -1)
 
14348
            {
 
14349
                PERROR_INT("xmlSchemaFixupTypeAttributeUses",
 
14350
                "failed to expand attributes");
 
14351
            }
 
14352
            if (pctxt->attrProhibs->nbItems != 0)
 
14353
                prohibs = pctxt->attrProhibs;
 
14354
        } else {
 
14355
            if (xmlSchemaExpandAttributeGroupRefs(pctxt,
 
14356
                WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
 
14357
                NULL) == -1)
 
14358
            {
 
14359
                PERROR_INT("xmlSchemaFixupTypeAttributeUses",
 
14360
                "failed to expand attributes");
 
14361
            }
 
14362
        }
 
14363
    }
 
14364
    /*
 
14365
    * Inherit the attribute uses of the base type.
 
14366
    */
 
14367
    if (baseUses != NULL) {
 
14368
        int i, j;
 
14369
        xmlSchemaAttributeUseProhibPtr pro;
 
14370
 
 
14371
        if (WXS_IS_RESTRICTION(type)) {
 
14372
            int usesCount;
 
14373
            xmlSchemaAttributeUsePtr tmp; 
 
14374
 
 
14375
            if (uses != NULL)
 
14376
                usesCount = uses->nbItems;
 
14377
            else
 
14378
                usesCount = 0;
 
14379
 
 
14380
            /* Restriction. */
 
14381
            for (i = 0; i < baseUses->nbItems; i++) {
 
14382
                use = baseUses->items[i];
 
14383
                if (prohibs) {
 
14384
                    /*
 
14385
                    * Filter out prohibited uses.
 
14386
                    */
 
14387
                    for (j = 0; j < prohibs->nbItems; j++) {
 
14388
                        pro = prohibs->items[j];
 
14389
                        if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
 
14390
                            (WXS_ATTRUSE_DECL_TNS(use) ==
 
14391
                                pro->targetNamespace))
 
14392
                        {
 
14393
                            goto inherit_next;
 
14394
                        }
 
14395
                    }
 
14396
                }
 
14397
                if (usesCount) {
 
14398
                    /*
 
14399
                    * Filter out existing uses.
 
14400
                    */
 
14401
                    for (j = 0; j < usesCount; j++) {
 
14402
                        tmp = uses->items[j];
 
14403
                        if ((WXS_ATTRUSE_DECL_NAME(use) ==
 
14404
                                WXS_ATTRUSE_DECL_NAME(tmp)) &&
 
14405
                            (WXS_ATTRUSE_DECL_TNS(use) ==
 
14406
                                WXS_ATTRUSE_DECL_TNS(tmp)))
 
14407
                        {
 
14408
                            goto inherit_next;
 
14409
                        }
 
14410
                    }
 
14411
                }
 
14412
                if (uses == NULL) {
 
14413
                    type->attrUses = xmlSchemaItemListCreate();
 
14414
                    if (type->attrUses == NULL)
 
14415
                        goto exit_failure;
 
14416
                    uses = type->attrUses;
 
14417
                }
 
14418
                xmlSchemaItemListAddSize(uses, 2, use);
 
14419
inherit_next: {}
 
14420
            }
 
14421
        } else {
 
14422
            /* Extension. */
 
14423
            for (i = 0; i < baseUses->nbItems; i++) {       
 
14424
                use = baseUses->items[i];               
 
14425
                if (uses == NULL) {
 
14426
                    type->attrUses = xmlSchemaItemListCreate();
 
14427
                    if (type->attrUses == NULL)
 
14428
                        goto exit_failure;
 
14429
                    uses = type->attrUses;
 
14430
                }
 
14431
                xmlSchemaItemListAddSize(uses, baseUses->nbItems, use); 
 
14432
            }
 
14433
        }
 
14434
    }
 
14435
    /*
 
14436
    * Shrink attr. uses.
 
14437
    */
 
14438
    if (uses) {
 
14439
        if (uses->nbItems == 0) {
 
14440
            xmlSchemaItemListFree(uses);
 
14441
            type->attrUses = NULL;
 
14442
        }
 
14443
        /*
 
14444
        * TODO: We could shrink the size of the array
 
14445
        * to fit the actual number of items.
 
14446
        */
 
14447
    }
 
14448
    /*
 
14449
    * Compute the complete wildcard.
 
14450
    */
 
14451
    if (WXS_IS_EXTENSION(type)) {       
 
14452
        if (baseType->attributeWildcard != NULL) {
 
14453
            /*
 
14454
            * (3.2.2.1) "If the ļæ½base wildcardļæ½ is non-ļæ½absentļæ½, then
 
14455
            * the appropriate case among the following:"
 
14456
            */
 
14457
            if (type->attributeWildcard != NULL) {
 
14458
                /*
 
14459
                * Union the complete wildcard with the base wildcard.
 
14460
                * SPEC {attribute wildcard}
 
14461
                * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
 
14462
                * and {annotation} are those of the ļæ½complete wildcardļæ½,
 
14463
                * and whose {namespace constraint} is the intensional union
 
14464
                * of the {namespace constraint} of the ļæ½complete wildcardļæ½
 
14465
                * and of the ļæ½base wildcardļæ½, as defined in Attribute
 
14466
                * Wildcard Union (ļæ½3.10.6)."
 
14467
                */
 
14468
                if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
 
14469
                    baseType->attributeWildcard) == -1)
 
14470
                    goto exit_failure;          
 
14471
            } else {
 
14472
                /*
 
14473
                * (3.2.2.1.1) "If the ļæ½complete wildcardļæ½ is ļæ½absentļæ½,
 
14474
                * then the ļæ½base wildcardļæ½."
 
14475
                */
 
14476
                type->attributeWildcard = baseType->attributeWildcard;
 
14477
            }    
 
14478
        } else {
 
14479
            /*
 
14480
            * (3.2.2.2) "otherwise (the ļæ½base wildcardļæ½ is ļæ½absentļæ½) the
 
14481
            * ļæ½complete wildcard"
 
14482
            * NOOP
 
14483
            */
 
14484
        }
 
14485
    } else {
 
14486
        /*
 
14487
        * SPEC {attribute wildcard}
 
14488
        * (3.1) "If the <restriction> alternative is chosen, then the
 
14489
        * ļæ½complete wildcardļæ½;"
 
14490
        * NOOP
 
14491
        */
 
14492
    }
 
14493
    
 
14494
    return (0);
 
14495
 
 
14496
exit_failure:
 
14497
    return(-1);
 
14498
}
 
14499
 
 
14500
/**
 
14501
 * xmlSchemaTypeFinalContains:
 
14502
 * @schema:  the schema
 
14503
 * @type:  the type definition
 
14504
 * @final: the final
 
14505
 *
 
14506
 * Evaluates if a type definition contains the given "final".
 
14507
 * This does take "finalDefault" into account as well.
 
14508
 *
 
14509
 * Returns 1 if the type does containt the given "final",
 
14510
 * 0 otherwise.
 
14511
 */
 
14512
static int
 
14513
xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
 
14514
{
 
14515
    if (type == NULL)
 
14516
        return (0);
 
14517
    if (type->flags & final)
 
14518
        return (1);
 
14519
    else
 
14520
        return (0);
 
14521
}
 
14522
 
 
14523
/**
 
14524
 * xmlSchemaGetUnionSimpleTypeMemberTypes:
 
14525
 * @type:  the Union Simple Type
 
14526
 *
 
14527
 * Returns a list of member types of @type if existing,
 
14528
 * returns NULL otherwise.
 
14529
 */
 
14530
static xmlSchemaTypeLinkPtr
 
14531
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
 
14532
{
 
14533
    while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
 
14534
        if (type->memberTypes != NULL)
 
14535
            return (type->memberTypes);
 
14536
        else
 
14537
            type = type->baseType;
 
14538
    }
 
14539
    return (NULL);
 
14540
}
 
14541
 
 
14542
/**
 
14543
 * xmlSchemaGetParticleTotalRangeMin:
 
14544
 * @particle: the particle
 
14545
 *
 
14546
 * Schema Component Constraint: Effective Total Range
 
14547
 * (all and sequence) + (choice)
 
14548
 *
 
14549
 * Returns the minimun Effective Total Range.
 
14550
 */
 
14551
static int
 
14552
xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
 
14553
{
 
14554
    if ((particle->children == NULL) ||
 
14555
        (particle->minOccurs == 0))
 
14556
        return (0);
 
14557
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
 
14558
        int min = -1, cur;
 
14559
        xmlSchemaParticlePtr part =
 
14560
            (xmlSchemaParticlePtr) particle->children->children;
 
14561
 
 
14562
        if (part == NULL)
 
14563
            return (0);
 
14564
        while (part != NULL) {
 
14565
            if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
 
14566
                (part->children->type == XML_SCHEMA_TYPE_ANY))
 
14567
                cur = part->minOccurs;
 
14568
            else
 
14569
                cur = xmlSchemaGetParticleTotalRangeMin(part);
 
14570
            if (cur == 0)
 
14571
                return (0);
 
14572
            if ((min > cur) || (min == -1))
 
14573
                min = cur;
 
14574
            part = (xmlSchemaParticlePtr) part->next;
 
14575
        }
 
14576
        return (particle->minOccurs * min);
 
14577
    } else {
 
14578
        /* <all> and <sequence> */
 
14579
        int sum = 0;
 
14580
        xmlSchemaParticlePtr part =
 
14581
            (xmlSchemaParticlePtr) particle->children->children;
 
14582
 
 
14583
        if (part == NULL)
 
14584
            return (0);
 
14585
        do {
 
14586
            if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
 
14587
                (part->children->type == XML_SCHEMA_TYPE_ANY))
 
14588
                sum += part->minOccurs;
 
14589
            else
 
14590
                sum += xmlSchemaGetParticleTotalRangeMin(part);
 
14591
            part = (xmlSchemaParticlePtr) part->next;
 
14592
        } while (part != NULL);
 
14593
        return (particle->minOccurs * sum);
 
14594
    }
 
14595
}
 
14596
 
 
14597
/**
 
14598
 * xmlSchemaGetParticleTotalRangeMax:
 
14599
 * @particle: the particle
 
14600
 *
 
14601
 * Schema Component Constraint: Effective Total Range
 
14602
 * (all and sequence) + (choice)
 
14603
 *
 
14604
 * Returns the maximum Effective Total Range.
 
14605
 */
 
14606
static int
 
14607
xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
 
14608
{
 
14609
    if ((particle->children == NULL) ||
 
14610
        (particle->children->children == NULL))
 
14611
        return (0);
 
14612
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
 
14613
        int max = -1, cur;
 
14614
        xmlSchemaParticlePtr part =
 
14615
            (xmlSchemaParticlePtr) particle->children->children;
 
14616
 
 
14617
        for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
 
14618
            if (part->children == NULL)
 
14619
                continue;
 
14620
            if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
 
14621
                (part->children->type == XML_SCHEMA_TYPE_ANY))
 
14622
                cur = part->maxOccurs;
 
14623
            else
 
14624
                cur = xmlSchemaGetParticleTotalRangeMax(part);
 
14625
            if (cur == UNBOUNDED)
 
14626
                return (UNBOUNDED);
 
14627
            if ((max < cur) || (max == -1))
 
14628
                max = cur;
 
14629
        }
 
14630
        /* TODO: Handle overflows? */
 
14631
        return (particle->maxOccurs * max);
 
14632
    } else {
 
14633
        /* <all> and <sequence> */
 
14634
        int sum = 0, cur;
 
14635
        xmlSchemaParticlePtr part =
 
14636
            (xmlSchemaParticlePtr) particle->children->children;
 
14637
 
 
14638
        for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
 
14639
            if (part->children == NULL)
 
14640
                continue;
 
14641
            if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
 
14642
                (part->children->type == XML_SCHEMA_TYPE_ANY))
 
14643
                cur = part->maxOccurs;
 
14644
            else
 
14645
                cur = xmlSchemaGetParticleTotalRangeMax(part);
 
14646
            if (cur == UNBOUNDED)
 
14647
                return (UNBOUNDED);
 
14648
            if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
 
14649
                return (UNBOUNDED);
 
14650
            sum += cur;
 
14651
        }
 
14652
        /* TODO: Handle overflows? */
 
14653
        return (particle->maxOccurs * sum);
 
14654
    }
 
14655
}
 
14656
 
 
14657
/**
 
14658
 * xmlSchemaIsParticleEmptiable:
 
14659
 * @particle: the particle
 
14660
 *
 
14661
 * Schema Component Constraint: Particle Emptiable
 
14662
 * Checks whether the given particle is emptiable.
 
14663
 *
 
14664
 * Returns 1 if emptiable, 0 otherwise.
 
14665
 */
 
14666
static int
 
14667
xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
 
14668
{
 
14669
    /*
 
14670
    * SPEC (1) "Its {min occurs} is 0."
 
14671
    */
 
14672
    if ((particle == NULL) || (particle->minOccurs == 0) ||
 
14673
        (particle->children == NULL))
 
14674
        return (1);
 
14675
    /*
 
14676
    * SPEC (2) "Its {term} is a group and the minimum part of the
 
14677
    * effective total range of that group, [...] is 0."
 
14678
    */
 
14679
    if (WXS_IS_MODEL_GROUP(particle->children)) {
 
14680
        if (xmlSchemaGetParticleTotalRangeMin(particle) == 0)
 
14681
            return (1);
 
14682
    }
 
14683
    return (0);
 
14684
}
 
14685
 
 
14686
/**
 
14687
 * xmlSchemaCheckCOSSTDerivedOK:
 
14688
 * @actxt: a context
 
14689
 * @type:  the derived simple type definition
 
14690
 * @baseType:  the base type definition
 
14691
 * @subset: the subset of ('restriction', ect.)
 
14692
 *
 
14693
 * Schema Component Constraint:
 
14694
 * Type Derivation OK (Simple) (cos-st-derived-OK)
 
14695
 *
 
14696
 * Checks wheter @type can be validly
 
14697
 * derived from @baseType.
 
14698
 *
 
14699
 * Returns 0 on success, an positive error code otherwise.
 
14700
 */
 
14701
static int
 
14702
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
 
14703
                             xmlSchemaTypePtr type,
 
14704
                             xmlSchemaTypePtr baseType,
 
14705
                             int subset)
 
14706
{
 
14707
    /*
 
14708
    * 1 They are the same type definition.
 
14709
    * TODO: The identy check might have to be more complex than this.
 
14710
    */
 
14711
    if (type == baseType)
 
14712
        return (0);
 
14713
    /*
 
14714
    * 2.1 restriction is not in the subset, or in the {final}
 
14715
    * of its own {base type definition};
 
14716
    *
 
14717
    * NOTE that this will be used also via "xsi:type".
 
14718
    *
 
14719
    * TODO: Revise this, it looks strange. How can the "type"
 
14720
    * not be fixed or *in* fixing?
 
14721
    */
 
14722
    if (WXS_IS_TYPE_NOT_FIXED(type))
 
14723
        if (xmlSchemaTypeFixup(type, actxt) == -1)
 
14724
            return(-1);
 
14725
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
 
14726
        if (xmlSchemaTypeFixup(baseType, actxt) == -1)
 
14727
            return(-1);
 
14728
    if ((subset & SUBSET_RESTRICTION) ||
 
14729
        (xmlSchemaTypeFinalContains(type->baseType,
 
14730
            XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
 
14731
        return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
 
14732
    }
 
14733
    /* 2.2 */
 
14734
    if (type->baseType == baseType) {
 
14735
        /*
 
14736
        * 2.2.1 D's ļæ½base type definitionļæ½ is B.
 
14737
        */
 
14738
        return (0);
 
14739
    }
 
14740
    /*
 
14741
    * 2.2.2 D's ļæ½base type definitionļæ½ is not the ļæ½ur-type definitionļæ½
 
14742
    * and is validly derived from B given the subset, as defined by this
 
14743
    * constraint.
 
14744
    */
 
14745
    if ((! WXS_IS_ANYTYPE(type->baseType)) &&
 
14746
        (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
 
14747
            baseType, subset) == 0)) {
 
14748
        return (0);
 
14749
    }
 
14750
    /*
 
14751
    * 2.2.3 D's {variety} is list or union and B is the ļæ½simple ur-type
 
14752
    * definitionļæ½.
 
14753
    */
 
14754
    if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
 
14755
        (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
 
14756
        return (0);
 
14757
    }
 
14758
    /*
 
14759
    * 2.2.4 B's {variety} is union and D is validly derived from a type
 
14760
    * definition in B's {member type definitions} given the subset, as
 
14761
    * defined by this constraint.
 
14762
    *
 
14763
    * NOTE: This seems not to involve built-in types, since there is no
 
14764
    * built-in Union Simple Type.
 
14765
    */
 
14766
    if (WXS_IS_UNION(baseType)) {
 
14767
        xmlSchemaTypeLinkPtr cur;
 
14768
 
 
14769
        cur = baseType->memberTypes;
 
14770
        while (cur != NULL) {
 
14771
            if (WXS_IS_TYPE_NOT_FIXED(cur->type))
 
14772
                if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
 
14773
                    return(-1);
 
14774
            if (xmlSchemaCheckCOSSTDerivedOK(actxt,
 
14775
                    type, cur->type, subset) == 0)
 
14776
            {
 
14777
                /*
 
14778
                * It just has to be validly derived from at least one
 
14779
                * member-type.
 
14780
                */
 
14781
                return (0);
 
14782
            }
 
14783
            cur = cur->next;
 
14784
        }
 
14785
    }
 
14786
    return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
 
14787
}
 
14788
 
 
14789
/**
 
14790
 * xmlSchemaCheckTypeDefCircularInternal:
 
14791
 * @pctxt:  the schema parser context
 
14792
 * @ctxtType:  the type definition
 
14793
 * @ancestor: an ancestor of @ctxtType
 
14794
 *
 
14795
 * Checks st-props-correct (2) + ct-props-correct (3).
 
14796
 * Circular type definitions are not allowed.
 
14797
 *
 
14798
 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
 
14799
 * circular, 0 otherwise.
 
14800
 */
 
14801
static int
 
14802
xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
 
14803
                           xmlSchemaTypePtr ctxtType,
 
14804
                           xmlSchemaTypePtr ancestor)
 
14805
{
 
14806
    int ret;
 
14807
 
 
14808
    if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
 
14809
        return (0);
 
14810
 
 
14811
    if (ctxtType == ancestor) {
 
14812
        xmlSchemaPCustomErr(pctxt,
 
14813
            XML_SCHEMAP_ST_PROPS_CORRECT_2,
 
14814
            WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
 
14815
            "The definition is circular", NULL);
 
14816
        return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
 
14817
    }
 
14818
    if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
 
14819
        /*
 
14820
        * Avoid inifinite recursion on circular types not yet checked.
 
14821
        */
 
14822
        return (0);
 
14823
    }
 
14824
    ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
 
14825
    ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
 
14826
        ancestor->baseType);
 
14827
    ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
 
14828
    return (ret);
 
14829
}
 
14830
 
 
14831
/**
 
14832
 * xmlSchemaCheckTypeDefCircular:
 
14833
 * @item:  the complex/simple type definition
 
14834
 * @ctxt:  the parser context
 
14835
 * @name:  the name
 
14836
 *
 
14837
 * Checks for circular type definitions.
 
14838
 */
 
14839
static void
 
14840
xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
 
14841
                              xmlSchemaParserCtxtPtr ctxt)
 
14842
{
 
14843
    if ((item == NULL) ||
 
14844
        (item->type == XML_SCHEMA_TYPE_BASIC) ||
 
14845
        (item->baseType == NULL))
 
14846
        return;
 
14847
    xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
 
14848
        item->baseType);
 
14849
}
 
14850
 
 
14851
/*
 
14852
* Simple Type Definition Representation OK (src-simple-type) 4
 
14853
*
 
14854
* "4 Circular union type definition is disallowed. That is, if the
 
14855
* <union> alternative is chosen, there must not be any entries in the
 
14856
* memberTypes [attribute] at any depth which resolve to the component
 
14857
* corresponding to the <simpleType>."
 
14858
*
 
14859
* Note that this should work on the *representation* of a component,
 
14860
* thus assumes any union types in the member types not being yet
 
14861
* substituted. At this stage we need the variety of the types
 
14862
* to be already computed.
 
14863
*/
 
14864
static int
 
14865
xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
 
14866
                                        xmlSchemaTypePtr ctxType,
 
14867
                                        xmlSchemaTypeLinkPtr members)
 
14868
{    
 
14869
    xmlSchemaTypeLinkPtr member;
 
14870
    xmlSchemaTypePtr memberType;
 
14871
    
 
14872
    member = members;
 
14873
    while (member != NULL) {
 
14874
        memberType = member->type;
 
14875
        while ((memberType != NULL) &&
 
14876
            (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
 
14877
            if (memberType == ctxType) {
 
14878
                xmlSchemaPCustomErr(pctxt,
 
14879
                    XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
 
14880
                    WXS_BASIC_CAST ctxType, NULL,
 
14881
                    "The union type definition is circular", NULL);
 
14882
                return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
 
14883
            }
 
14884
            if ((WXS_IS_UNION(memberType)) &&
 
14885
                ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
 
14886
            {
 
14887
                int res;
 
14888
                memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
 
14889
                res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
 
14890
                    ctxType,
 
14891
                    xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
 
14892
                memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
 
14893
                if (res != 0)
 
14894
                    return(res);
 
14895
            }
 
14896
            memberType = memberType->baseType;
 
14897
        }
 
14898
        member = member->next;
 
14899
    }
 
14900
    return(0);
 
14901
}
 
14902
 
 
14903
static int
 
14904
xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
 
14905
                                   xmlSchemaTypePtr type)
 
14906
{
 
14907
    if (! WXS_IS_UNION(type))
 
14908
        return(0);
 
14909
    return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
 
14910
        type->memberTypes));
 
14911
}
 
14912
 
 
14913
/**
 
14914
 * xmlSchemaResolveTypeReferences:
 
14915
 * @item:  the complex/simple type definition
 
14916
 * @ctxt:  the parser context
 
14917
 * @name:  the name
 
14918
 *
 
14919
 * Resolvese type definition references
 
14920
 */
 
14921
static void
 
14922
xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
 
14923
                         xmlSchemaParserCtxtPtr ctxt)
 
14924
{
 
14925
    if (typeDef == NULL)
 
14926
        return;
 
14927
 
 
14928
    /*
 
14929
    * Resolve the base type.
 
14930
    */
 
14931
    if (typeDef->baseType == NULL) {
 
14932
        typeDef->baseType = xmlSchemaGetType(ctxt->schema,
 
14933
            typeDef->base, typeDef->baseNs);
 
14934
        if (typeDef->baseType == NULL) {
 
14935
            xmlSchemaPResCompAttrErr(ctxt,
 
14936
                XML_SCHEMAP_SRC_RESOLVE,
 
14937
                WXS_BASIC_CAST typeDef, typeDef->node,
 
14938
                "base", typeDef->base, typeDef->baseNs,
 
14939
                XML_SCHEMA_TYPE_SIMPLE, NULL);
 
14940
            return;
 
14941
        }
 
14942
    }
 
14943
    if (WXS_IS_SIMPLE(typeDef)) {
 
14944
        if (WXS_IS_UNION(typeDef)) {
 
14945
            /*
 
14946
            * Resolve the memberTypes.
 
14947
            */
 
14948
            xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
 
14949
            return;
 
14950
        } else if (WXS_IS_LIST(typeDef)) {
 
14951
            /*
 
14952
            * Resolve the itemType.
 
14953
            */
 
14954
            if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
 
14955
 
 
14956
                typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
 
14957
                    typeDef->base, typeDef->baseNs);
 
14958
 
 
14959
                if ((typeDef->subtypes == NULL) ||
 
14960
                    (! WXS_IS_SIMPLE(typeDef->subtypes)))
 
14961
                {
 
14962
                    typeDef->subtypes = NULL;
 
14963
                    xmlSchemaPResCompAttrErr(ctxt,
 
14964
                        XML_SCHEMAP_SRC_RESOLVE,
 
14965
                        WXS_BASIC_CAST typeDef, typeDef->node,
 
14966
                        "itemType", typeDef->base, typeDef->baseNs,
 
14967
                        XML_SCHEMA_TYPE_SIMPLE, NULL);
 
14968
                }
 
14969
            }
 
14970
            return;
 
14971
        }
 
14972
    } 
 
14973
    /*
 
14974
    * The ball of letters below means, that if we have a particle
 
14975
    * which has a QName-helper component as its {term}, we want
 
14976
    * to resolve it...
 
14977
    */
 
14978
    else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
 
14979
        ((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
 
14980
            XML_SCHEMA_TYPE_PARTICLE) &&
 
14981
        (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
 
14982
        ((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
 
14983
            XML_SCHEMA_EXTRA_QNAMEREF))
 
14984
    {
 
14985
        xmlSchemaQNameRefPtr ref =
 
14986
            WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
 
14987
        xmlSchemaModelGroupDefPtr groupDef;
 
14988
 
 
14989
        /*
 
14990
        * URGENT TODO: Test this.
 
14991
        */
 
14992
        WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
 
14993
        /*
 
14994
        * Resolve the MG definition reference.
 
14995
        */
 
14996
        groupDef =
 
14997
            WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
 
14998
                ref->itemType, ref->name, ref->targetNamespace);
 
14999
        if (groupDef == NULL) {
 
15000
            xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
 
15001
                NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
 
15002
                "ref", ref->name, ref->targetNamespace, ref->itemType,
 
15003
                NULL);
 
15004
            /* Remove the particle. */
 
15005
            WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
 
15006
        } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
 
15007
            /* Remove the particle. */
 
15008
            WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
 
15009
        else {
 
15010
            /*
 
15011
            * Assign the MG definition's {model group} to the
 
15012
            * particle's {term}.
 
15013
            */
 
15014
            WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
 
15015
            
 
15016
            if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
 
15017
                /*
 
15018
                * SPEC cos-all-limited (1.2)
 
15019
                * "1.2 the {term} property of a particle with
 
15020
                * {max occurs}=1 which is part of a pair which constitutes
 
15021
                * the {content type} of a complex type definition."
 
15022
                */
 
15023
                if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
 
15024
                    xmlSchemaCustomErr(ACTXT_CAST ctxt,
 
15025
                        /* TODO: error code */
 
15026
                        XML_SCHEMAP_COS_ALL_LIMITED,
 
15027
                        WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
 
15028
                        "The particle's {max occurs} must be 1, since the "
 
15029
                        "reference resolves to an 'all' model group",
 
15030
                        NULL, NULL);
 
15031
                }
 
15032
            }
 
15033
        }
 
15034
    }
 
15035
}
 
15036
 
 
15037
 
 
15038
 
 
15039
/**
 
15040
 * xmlSchemaCheckSTPropsCorrect:
 
15041
 * @ctxt:  the schema parser context
 
15042
 * @type:  the simple type definition
 
15043
 *
 
15044
 * Checks st-props-correct.
 
15045
 *
 
15046
 * Returns 0 if the properties are correct,
 
15047
 * if not, a positive error code and -1 on internal
 
15048
 * errors.
 
15049
 */
 
15050
static int
 
15051
xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
 
15052
                             xmlSchemaTypePtr type)
 
15053
{
 
15054
    xmlSchemaTypePtr baseType = type->baseType;
 
15055
    xmlChar *str = NULL;
 
15056
 
 
15057
    /* STATE: error funcs converted. */
 
15058
    /*
 
15059
    * Schema Component Constraint: Simple Type Definition Properties Correct
 
15060
    *
 
15061
    * NOTE: This is somehow redundant, since we actually built a simple type
 
15062
    * to have all the needed information; this acts as an self test.
 
15063
    */
 
15064
    /* Base type: If the datatype has been ļæ½derivedļæ½ by ļæ½restrictionļæ½
 
15065
    * then the Simple Type Definition component from which it is ļæ½derivedļæ½,
 
15066
    * otherwise the Simple Type Definition for anySimpleType (ļæ½4.1.6).
 
15067
    */
 
15068
    if (baseType == NULL) {
 
15069
        /*
 
15070
        * TODO: Think about: "modulo the impact of Missing
 
15071
        * Sub-components (ļæ½5.3)."
 
15072
        */
 
15073
        xmlSchemaPCustomErr(ctxt,
 
15074
            XML_SCHEMAP_ST_PROPS_CORRECT_1,
 
15075
            WXS_BASIC_CAST type, NULL,
 
15076
            "No base type existent", NULL);
 
15077
        return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
 
15078
 
 
15079
    }
 
15080
    if (! WXS_IS_SIMPLE(baseType)) {
 
15081
        xmlSchemaPCustomErr(ctxt,
 
15082
            XML_SCHEMAP_ST_PROPS_CORRECT_1,
 
15083
            WXS_BASIC_CAST type, NULL,
 
15084
            "The base type '%s' is not a simple type",
 
15085
            xmlSchemaGetComponentQName(&str, baseType));
 
15086
        FREE_AND_NULL(str)
 
15087
        return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
 
15088
    }
 
15089
    if ( (WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
 
15090
         (WXS_IS_RESTRICTION(type) == 0) &&
 
15091
         (! WXS_IS_ANY_SIMPLE_TYPE(baseType))) {
 
15092
        xmlSchemaPCustomErr(ctxt,
 
15093
            XML_SCHEMAP_ST_PROPS_CORRECT_1,
 
15094
            WXS_BASIC_CAST type, NULL,
 
15095
            "A type, derived by list or union, must have"
 
15096
            "the simple ur-type definition as base type, not '%s'",
 
15097
            xmlSchemaGetComponentQName(&str, baseType));
 
15098
        FREE_AND_NULL(str)
 
15099
        return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
 
15100
    }
 
15101
    /*
 
15102
    * Variety: One of {atomic, list, union}.
 
15103
    */
 
15104
    if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
 
15105
        (! WXS_IS_LIST(type))) {
 
15106
        xmlSchemaPCustomErr(ctxt,
 
15107
            XML_SCHEMAP_ST_PROPS_CORRECT_1,
 
15108
            WXS_BASIC_CAST type, NULL,
 
15109
            "The variety is absent", NULL);
 
15110
        return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
 
15111
    }
 
15112
    /* TODO: Finish this. Hmm, is this finished? */
 
15113
 
 
15114
    /*
 
15115
    * 3 The {final} of the {base type definition} must not contain restriction.
 
15116
    */
 
15117
    if (xmlSchemaTypeFinalContains(baseType,
 
15118
        XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
 
15119
        xmlSchemaPCustomErr(ctxt,
 
15120
            XML_SCHEMAP_ST_PROPS_CORRECT_3,
 
15121
            WXS_BASIC_CAST type, NULL,
 
15122
            "The 'final' of its base type '%s' must not contain "
 
15123
            "'restriction'",
 
15124
            xmlSchemaGetComponentQName(&str, baseType));
 
15125
        FREE_AND_NULL(str)
 
15126
        return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
 
15127
    }
 
15128
 
 
15129
    /*
 
15130
    * 2 All simple type definitions must be derived ultimately from the ļæ½simple
 
15131
    * ur-type definition (soļæ½ circular definitions are disallowed). That is, it
 
15132
    * must be possible to reach a built-in primitive datatype or the ļæ½simple
 
15133
    * ur-type definitionļæ½ by repeatedly following the {base type definition}.
 
15134
    *
 
15135
    * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
 
15136
    */
 
15137
    return (0);
 
15138
}
 
15139
 
 
15140
/**
 
15141
 * xmlSchemaCheckCOSSTRestricts:
 
15142
 * @ctxt:  the schema parser context
 
15143
 * @type:  the simple type definition
 
15144
 *
 
15145
 * Schema Component Constraint:
 
15146
 * Derivation Valid (Restriction, Simple) (cos-st-restricts)
 
15147
 
 
15148
 * Checks if the given @type (simpleType) is derived validly by restriction.
 
15149
 * STATUS:
 
15150
 *
 
15151
 * Returns -1 on internal errors, 0 if the type is validly derived,
 
15152
 * a positive error code otherwise.
 
15153
 */
 
15154
static int
 
15155
xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
 
15156
                             xmlSchemaTypePtr type)
 
15157
{
 
15158
    xmlChar *str = NULL;
 
15159
 
 
15160
    if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
 
15161
        PERROR_INT("xmlSchemaCheckCOSSTRestricts",
 
15162
            "given type is not a user-derived simpleType");
 
15163
        return (-1);
 
15164
    }
 
15165
 
 
15166
    if (WXS_IS_ATOMIC(type)) {
 
15167
        xmlSchemaTypePtr primitive;
 
15168
        /*
 
15169
        * 1.1 The {base type definition} must be an atomic simple
 
15170
        * type definition or a built-in primitive datatype.
 
15171
        */
 
15172
        if (! WXS_IS_ATOMIC(type->baseType)) {
 
15173
            xmlSchemaPCustomErr(pctxt,
 
15174
                XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
 
15175
                WXS_BASIC_CAST type, NULL,
 
15176
                "The base type '%s' is not an atomic simple type",
 
15177
                xmlSchemaGetComponentQName(&str, type->baseType));
 
15178
            FREE_AND_NULL(str)
 
15179
            return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
 
15180
        }
 
15181
        /* 1.2 The {final} of the {base type definition} must not contain
 
15182
        * restriction.
 
15183
        */
 
15184
        /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
 
15185
        if (xmlSchemaTypeFinalContains(type->baseType,
 
15186
            XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
 
15187
            xmlSchemaPCustomErr(pctxt,
 
15188
                XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
 
15189
                WXS_BASIC_CAST type, NULL,
 
15190
                "The final of its base type '%s' must not contain 'restriction'",
 
15191
                xmlSchemaGetComponentQName(&str, type->baseType));
 
15192
            FREE_AND_NULL(str)
 
15193
            return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
 
15194
        }
 
15195
 
 
15196
        /*
 
15197
        * 1.3.1 DF must be an allowed constraining facet for the {primitive
 
15198
        * type definition}, as specified in the appropriate subsection of 3.2
 
15199
        * Primitive datatypes.
 
15200
        */
 
15201
        if (type->facets != NULL) {
 
15202
            xmlSchemaFacetPtr facet;
 
15203
            int ok = 1;
 
15204
 
 
15205
            primitive = xmlSchemaGetPrimitiveType(type);
 
15206
            if (primitive == NULL) {
 
15207
                PERROR_INT("xmlSchemaCheckCOSSTRestricts",
 
15208
                    "failed to get primitive type");
 
15209
                return (-1);
 
15210
            }
 
15211
            facet = type->facets;
 
15212
            do {
 
15213
                if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
 
15214
                    ok = 0;
 
15215
                    xmlSchemaPIllegalFacetAtomicErr(pctxt,
 
15216
                        XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
 
15217
                        type, primitive, facet);
 
15218
                }
 
15219
                facet = facet->next;
 
15220
            } while (facet != NULL);
 
15221
            if (ok == 0)
 
15222
                return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
 
15223
        }
 
15224
        /*
 
15225
        * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
 
15226
        * of the {base type definition} (call this BF),then the DF's {value}
 
15227
        * must be a valid restriction of BF's {value} as defined in
 
15228
        * [XML Schemas: Datatypes]."
 
15229
        *
 
15230
        * NOTE (1.3.2) Facet derivation constraints are currently handled in
 
15231
        * xmlSchemaDeriveAndValidateFacets()
 
15232
        */
 
15233
    } else if (WXS_IS_LIST(type)) {
 
15234
        xmlSchemaTypePtr itemType = NULL;
 
15235
 
 
15236
        itemType = type->subtypes;
 
15237
        if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
 
15238
            PERROR_INT("xmlSchemaCheckCOSSTRestricts",
 
15239
                "failed to evaluate the item type");
 
15240
            return (-1);
 
15241
        }
 
15242
        if (WXS_IS_TYPE_NOT_FIXED(itemType))
 
15243
            xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
 
15244
        /*
 
15245
        * 2.1 The {item type definition} must have a {variety} of atomic or
 
15246
        * union (in which case all the {member type definitions}
 
15247
        * must be atomic).
 
15248
        */
 
15249
        if ((! WXS_IS_ATOMIC(itemType)) &&
 
15250
            (! WXS_IS_UNION(itemType))) {
 
15251
            xmlSchemaPCustomErr(pctxt,
 
15252
                XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
 
15253
                WXS_BASIC_CAST type, NULL,
 
15254
                "The item type '%s' does not have a variety of atomic or union",
 
15255
                xmlSchemaGetComponentQName(&str, itemType));
 
15256
            FREE_AND_NULL(str)
 
15257
            return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
 
15258
        } else if (WXS_IS_UNION(itemType)) {
 
15259
            xmlSchemaTypeLinkPtr member;
 
15260
 
 
15261
            member = itemType->memberTypes;
 
15262
            while (member != NULL) {
 
15263
                if (! WXS_IS_ATOMIC(member->type)) {
 
15264
                    xmlSchemaPCustomErr(pctxt,
 
15265
                        XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
 
15266
                        WXS_BASIC_CAST type, NULL,
 
15267
                        "The item type is a union type, but the "
 
15268
                        "member type '%s' of this item type is not atomic",
 
15269
                        xmlSchemaGetComponentQName(&str, member->type));
 
15270
                    FREE_AND_NULL(str)
 
15271
                    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
 
15272
                }
 
15273
                member = member->next;
 
15274
            }
 
15275
        }
 
15276
 
 
15277
        if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
 
15278
            xmlSchemaFacetPtr facet;
 
15279
            /*
 
15280
            * This is the case if we have: <simpleType><list ..
 
15281
            */
 
15282
            /*
 
15283
            * 2.3.1
 
15284
            * 2.3.1.1 The {final} of the {item type definition} must not
 
15285
            * contain list.
 
15286
            */
 
15287
            if (xmlSchemaTypeFinalContains(itemType,
 
15288
                XML_SCHEMAS_TYPE_FINAL_LIST)) {
 
15289
                xmlSchemaPCustomErr(pctxt,
 
15290
                    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
 
15291
                    WXS_BASIC_CAST type, NULL,
 
15292
                    "The final of its item type '%s' must not contain 'list'",
 
15293
                    xmlSchemaGetComponentQName(&str, itemType));
 
15294
                FREE_AND_NULL(str)
 
15295
                return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
 
15296
            }
 
15297
            /*
 
15298
            * 2.3.1.2 The {facets} must only contain the whiteSpace
 
15299
            * facet component.
 
15300
            * OPTIMIZE TODO: the S4S already disallows any facet
 
15301
            * to be specified.
 
15302
            */
 
15303
            if (type->facets != NULL) {
 
15304
                facet = type->facets;
 
15305
                do {
 
15306
                    if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
 
15307
                        xmlSchemaPIllegalFacetListUnionErr(pctxt,
 
15308
                            XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
 
15309
                            type, facet);
 
15310
                        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
 
15311
                    }
 
15312
                    facet = facet->next;
 
15313
                } while (facet != NULL);
 
15314
            }
 
15315
            /*
 
15316
            * MAYBE TODO: (Hmm, not really) Datatypes states:
 
15317
            * A ļæ½listļæ½ datatype can be ļæ½derivedļæ½ from an ļæ½atomicļæ½ datatype
 
15318
            * whose ļæ½lexical spaceļæ½ allows space (such as string or anyURI)or
 
15319
            * a ļæ½unionļæ½ datatype any of whose {member type definitions}'s
 
15320
            * ļæ½lexical spaceļæ½ allows space.
 
15321
            */
 
15322
        } else {
 
15323
            /*
 
15324
            * This is the case if we have: <simpleType><restriction ...
 
15325
            * I.e. the variety of "list" is inherited.
 
15326
            */
 
15327
            /*
 
15328
            * 2.3.2
 
15329
            * 2.3.2.1 The {base type definition} must have a {variety} of list.
 
15330
            */
 
15331
            if (! WXS_IS_LIST(type->baseType)) {
 
15332
                xmlSchemaPCustomErr(pctxt,
 
15333
                    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
 
15334
                    WXS_BASIC_CAST type, NULL,
 
15335
                    "The base type '%s' must be a list type",
 
15336
                    xmlSchemaGetComponentQName(&str, type->baseType));
 
15337
                FREE_AND_NULL(str)
 
15338
                return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
 
15339
            }
 
15340
            /*
 
15341
            * 2.3.2.2 The {final} of the {base type definition} must not
 
15342
            * contain restriction.
 
15343
            */
 
15344
            if (xmlSchemaTypeFinalContains(type->baseType,
 
15345
                XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
 
15346
                xmlSchemaPCustomErr(pctxt,
 
15347
                    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
 
15348
                    WXS_BASIC_CAST type, NULL,
 
15349
                    "The 'final' of the base type '%s' must not contain 'restriction'",
 
15350
                    xmlSchemaGetComponentQName(&str, type->baseType));
 
15351
                FREE_AND_NULL(str)
 
15352
                return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
 
15353
            }
 
15354
            /*
 
15355
            * 2.3.2.3 The {item type definition} must be validly derived
 
15356
            * from the {base type definition}'s {item type definition} given
 
15357
            * the empty set, as defined in Type Derivation OK (Simple) (ļæ½3.14.6).
 
15358
            */
 
15359
            {
 
15360
                xmlSchemaTypePtr baseItemType;
 
15361
 
 
15362
                baseItemType = type->baseType->subtypes;
 
15363
                if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
 
15364
                    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
 
15365
                        "failed to eval the item type of a base type");
 
15366
                    return (-1);
 
15367
                }
 
15368
                if ((itemType != baseItemType) &&
 
15369
                    (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
 
15370
                        baseItemType, 0) != 0)) {
 
15371
                    xmlChar *strBIT = NULL, *strBT = NULL;
 
15372
                    xmlSchemaPCustomErrExt(pctxt,
 
15373
                        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
 
15374
                        WXS_BASIC_CAST type, NULL,
 
15375
                        "The item type '%s' is not validly derived from "
 
15376
                        "the item type '%s' of the base type '%s'",
 
15377
                        xmlSchemaGetComponentQName(&str, itemType),
 
15378
                        xmlSchemaGetComponentQName(&strBIT, baseItemType),
 
15379
                        xmlSchemaGetComponentQName(&strBT, type->baseType));
 
15380
 
 
15381
                    FREE_AND_NULL(str)
 
15382
                    FREE_AND_NULL(strBIT)
 
15383
                    FREE_AND_NULL(strBT)
 
15384
                    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
 
15385
                }
 
15386
            }
 
15387
 
 
15388
            if (type->facets != NULL) {
 
15389
                xmlSchemaFacetPtr facet;
 
15390
                int ok = 1;
 
15391
                /*
 
15392
                * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
 
15393
                * and enumeration facet components are allowed among the {facets}.
 
15394
                */
 
15395
                facet = type->facets;
 
15396
                do {
 
15397
                    switch (facet->type) {
 
15398
                        case XML_SCHEMA_FACET_LENGTH:
 
15399
                        case XML_SCHEMA_FACET_MINLENGTH:
 
15400
                        case XML_SCHEMA_FACET_MAXLENGTH:
 
15401
                        case XML_SCHEMA_FACET_WHITESPACE:
 
15402
                            /*
 
15403
                            * TODO: 2.5.1.2 List datatypes
 
15404
                            * The value of ļæ½whiteSpaceļæ½ is fixed to the value collapse.
 
15405
                            */
 
15406
                        case XML_SCHEMA_FACET_PATTERN:
 
15407
                        case XML_SCHEMA_FACET_ENUMERATION:
 
15408
                            break;
 
15409
                        default: {
 
15410
                            xmlSchemaPIllegalFacetListUnionErr(pctxt,
 
15411
                                XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
 
15412
                                type, facet);
 
15413
                            /*
 
15414
                            * We could return, but it's nicer to report all
 
15415
                            * invalid facets.
 
15416
                            */
 
15417
                            ok = 0;
 
15418
                        }
 
15419
                    }
 
15420
                    facet = facet->next;
 
15421
                } while (facet != NULL);
 
15422
                if (ok == 0)
 
15423
                    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
 
15424
                /*
 
15425
                * SPEC (2.3.2.5) (same as 1.3.2)
 
15426
                *
 
15427
                * NOTE (2.3.2.5) This is currently done in
 
15428
                * xmlSchemaDeriveAndValidateFacets()
 
15429
                */
 
15430
            }
 
15431
        }
 
15432
    } else if (WXS_IS_UNION(type)) {
 
15433
        /*
 
15434
        * 3.1 The {member type definitions} must all have {variety} of
 
15435
        * atomic or list.
 
15436
        */
 
15437
        xmlSchemaTypeLinkPtr member;
 
15438
 
 
15439
        member = type->memberTypes;
 
15440
        while (member != NULL) {
 
15441
            if (WXS_IS_TYPE_NOT_FIXED(member->type))
 
15442
                xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
 
15443
 
 
15444
            if ((! WXS_IS_ATOMIC(member->type)) &&
 
15445
                (! WXS_IS_LIST(member->type))) {
 
15446
                xmlSchemaPCustomErr(pctxt,
 
15447
                    XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
 
15448
                    WXS_BASIC_CAST type, NULL,
 
15449
                    "The member type '%s' is neither an atomic, nor a list type",
 
15450
                    xmlSchemaGetComponentQName(&str, member->type));
 
15451
                FREE_AND_NULL(str)
 
15452
                return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
 
15453
            }
 
15454
            member = member->next;
 
15455
        }
 
15456
        /*
 
15457
        * 3.3.1 If the {base type definition} is the ļæ½simple ur-type
 
15458
        * definitionļæ½
 
15459
        */
 
15460
        if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
 
15461
            /*
 
15462
            * 3.3.1.1 All of the {member type definitions} must have a
 
15463
            * {final} which does not contain union.
 
15464
            */
 
15465
            member = type->memberTypes;
 
15466
            while (member != NULL) {
 
15467
                if (xmlSchemaTypeFinalContains(member->type,
 
15468
                    XML_SCHEMAS_TYPE_FINAL_UNION)) {
 
15469
                    xmlSchemaPCustomErr(pctxt,
 
15470
                        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
 
15471
                        WXS_BASIC_CAST type, NULL,
 
15472
                        "The 'final' of member type '%s' contains 'union'",
 
15473
                        xmlSchemaGetComponentQName(&str, member->type));
 
15474
                    FREE_AND_NULL(str)
 
15475
                    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
 
15476
                }
 
15477
                member = member->next;
 
15478
            }
 
15479
            /*
 
15480
            * 3.3.1.2 The {facets} must be empty.
 
15481
            */
 
15482
            if (type->facetSet != NULL) {
 
15483
                xmlSchemaPCustomErr(pctxt,
 
15484
                    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
 
15485
                    WXS_BASIC_CAST type, NULL,
 
15486
                    "No facets allowed", NULL);
 
15487
                return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
 
15488
            }
 
15489
        } else {
 
15490
            /*
 
15491
            * 3.3.2.1 The {base type definition} must have a {variety} of union.
 
15492
            * I.e. the variety of "list" is inherited.
 
15493
            */
 
15494
            if (! WXS_IS_UNION(type->baseType)) {
 
15495
                xmlSchemaPCustomErr(pctxt,
 
15496
                    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
 
15497
                    WXS_BASIC_CAST type, NULL,
 
15498
                    "The base type '%s' is not a union type",
 
15499
                    xmlSchemaGetComponentQName(&str, type->baseType));
 
15500
                FREE_AND_NULL(str)
 
15501
                return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
 
15502
            }
 
15503
            /*
 
15504
            * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
 
15505
            */
 
15506
            if (xmlSchemaTypeFinalContains(type->baseType,
 
15507
                XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
 
15508
                xmlSchemaPCustomErr(pctxt,
 
15509
                    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
 
15510
                    WXS_BASIC_CAST type, NULL,
 
15511
                    "The 'final' of its base type '%s' must not contain 'restriction'",
 
15512
                    xmlSchemaGetComponentQName(&str, type->baseType));
 
15513
                FREE_AND_NULL(str)
 
15514
                return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
 
15515
            }
 
15516
            /*
 
15517
            * 3.3.2.3 The {member type definitions}, in order, must be validly
 
15518
            * derived from the corresponding type definitions in the {base
 
15519
            * type definition}'s {member type definitions} given the empty set,
 
15520
            * as defined in Type Derivation OK (Simple) (ļæ½3.14.6).
 
15521
            */
 
15522
            {
 
15523
                xmlSchemaTypeLinkPtr baseMember;
 
15524
 
 
15525
                /*
 
15526
                * OPTIMIZE: if the type is restricting, it has no local defined
 
15527
                * member types and inherits the member types of the base type;
 
15528
                * thus a check for equality can be skipped.
 
15529
                */
 
15530
                /*
 
15531
                * Even worse: I cannot see a scenario where a restricting
 
15532
                * union simple type can have other member types as the member
 
15533
                * types of it's base type. This check seems not necessary with
 
15534
                * respect to the derivation process in libxml2.
 
15535
                * But necessary if constructing types with an API.
 
15536
                */
 
15537
                if (type->memberTypes != NULL) {
 
15538
                    member = type->memberTypes;
 
15539
                    baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
 
15540
                    if ((member == NULL) && (baseMember != NULL)) {
 
15541
                        PERROR_INT("xmlSchemaCheckCOSSTRestricts",
 
15542
                            "different number of member types in base");
 
15543
                    }
 
15544
                    while (member != NULL) {
 
15545
                        if (baseMember == NULL) {
 
15546
                            PERROR_INT("xmlSchemaCheckCOSSTRestricts",
 
15547
                            "different number of member types in base");
 
15548
                        } else if ((member->type != baseMember->type) &&
 
15549
                            (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
 
15550
                                member->type, baseMember->type, 0) != 0)) {
 
15551
                            xmlChar *strBMT = NULL, *strBT = NULL;
 
15552
 
 
15553
                            xmlSchemaPCustomErrExt(pctxt,
 
15554
                                XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
 
15555
                                WXS_BASIC_CAST type, NULL,
 
15556
                                "The member type %s is not validly "
 
15557
                                "derived from its corresponding member "
 
15558
                                "type %s of the base type %s",
 
15559
                                xmlSchemaGetComponentQName(&str, member->type),
 
15560
                                xmlSchemaGetComponentQName(&strBMT, baseMember->type),
 
15561
                                xmlSchemaGetComponentQName(&strBT, type->baseType));
 
15562
                            FREE_AND_NULL(str)
 
15563
                            FREE_AND_NULL(strBMT)
 
15564
                            FREE_AND_NULL(strBT)
 
15565
                            return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
 
15566
                        }
 
15567
                        member = member->next;
 
15568
                        baseMember = baseMember->next;
 
15569
                    }
 
15570
                }
 
15571
            }
 
15572
            /*
 
15573
            * 3.3.2.4 Only pattern and enumeration facet components are
 
15574
            * allowed among the {facets}.
 
15575
            */
 
15576
            if (type->facets != NULL) {
 
15577
                xmlSchemaFacetPtr facet;
 
15578
                int ok = 1;
 
15579
 
 
15580
                facet = type->facets;
 
15581
                do {
 
15582
                    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
 
15583
                        (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
 
15584
                        xmlSchemaPIllegalFacetListUnionErr(pctxt,
 
15585
                                XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
 
15586
                                type, facet);
 
15587
                        ok = 0;
 
15588
                    }
 
15589
                    facet = facet->next;
 
15590
                } while (facet != NULL);
 
15591
                if (ok == 0)
 
15592
                    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
 
15593
 
 
15594
            }
 
15595
            /*
 
15596
            * SPEC (3.3.2.5) (same as 1.3.2)
 
15597
            *
 
15598
            * NOTE (3.3.2.5) This is currently done in
 
15599
            * xmlSchemaDeriveAndValidateFacets()
 
15600
            */
 
15601
        }
 
15602
    }
 
15603
 
 
15604
    return (0);
 
15605
}
 
15606
 
 
15607
/**
 
15608
 * xmlSchemaCheckSRCSimpleType:
 
15609
 * @ctxt:  the schema parser context
 
15610
 * @type:  the simple type definition
 
15611
 *
 
15612
 * Checks crc-simple-type constraints. 
 
15613
 *
 
15614
 * Returns 0 if the constraints are satisfied,
 
15615
 * if not a positive error code and -1 on internal
 
15616
 * errors.
 
15617
 */
 
15618
#if 0
 
15619
static int
 
15620
xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
 
15621
                            xmlSchemaTypePtr type)
 
15622
{
 
15623
    /*
 
15624
    * src-simple-type.1 The corresponding simple type definition, if any,
 
15625
    * must satisfy the conditions set out in Constraints on Simple Type
 
15626
    * Definition Schema Components (ļæ½3.14.6).
 
15627
    */    
 
15628
    if (WXS_IS_RESTRICTION(type)) {
 
15629
        /*
 
15630
        * src-simple-type.2 "If the <restriction> alternative is chosen,
 
15631
        * either it must have a base [attribute] or a <simpleType> among its
 
15632
        * [children], but not both."
 
15633
        * NOTE: This is checked in the parse function of <restriction>.
 
15634
        */
 
15635
        /*
 
15636
        * 
 
15637
        */
 
15638
    } else if (WXS_IS_LIST(type)) {
 
15639
        /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
 
15640
        * an itemType [attribute] or a <simpleType> among its [children],
 
15641
        * but not both."
 
15642
        *
 
15643
        * NOTE: This is checked in the parse function of <list>.
 
15644
        */
 
15645
    } else if (WXS_IS_UNION(type)) {    
 
15646
        /* 
 
15647
        * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
 
15648
        */
 
15649
    }
 
15650
    return (0);
 
15651
}
 
15652
#endif
 
15653
 
 
15654
static int
 
15655
xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
 
15656
{
 
15657
   if (ctxt->vctxt == NULL) {
 
15658
        ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
 
15659
        if (ctxt->vctxt == NULL) {
 
15660
            xmlSchemaPErr(ctxt, NULL,
 
15661
                XML_SCHEMAP_INTERNAL,
 
15662
                "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
 
15663
                "failed to create a temp. validation context.\n",
 
15664
                NULL, NULL);
 
15665
            return (-1);
 
15666
        }
 
15667
        /* TODO: Pass user data. */
 
15668
        xmlSchemaSetValidErrors(ctxt->vctxt,
 
15669
            ctxt->error, ctxt->warning, ctxt->errCtxt);
 
15670
        xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
 
15671
            ctxt->serror, ctxt->errCtxt);
 
15672
    }
 
15673
    return (0);
 
15674
}
 
15675
 
 
15676
static int
 
15677
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
 
15678
                             xmlNodePtr node,
 
15679
                             xmlSchemaTypePtr type,
 
15680
                             const xmlChar *value,
 
15681
                             xmlSchemaValPtr *retVal,
 
15682
                             int fireErrors,
 
15683
                             int normalize,
 
15684
                             int isNormalized);
 
15685
 
 
15686
/**
 
15687
 * xmlSchemaParseCheckCOSValidDefault:
 
15688
 * @pctxt:  the schema parser context
 
15689
 * @type:  the simple type definition
 
15690
 * @value: the default value
 
15691
 * @node: an optional node (the holder of the value)
 
15692
 *
 
15693
 * Schema Component Constraint: Element Default Valid (Immediate)
 
15694
 * (cos-valid-default)
 
15695
 * This will be used by the parser only. For the validator there's
 
15696
 * an other version.
 
15697
 *
 
15698
 * Returns 0 if the constraints are satisfied,
 
15699
 * if not, a positive error code and -1 on internal
 
15700
 * errors.
 
15701
 */
 
15702
static int
 
15703
xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
 
15704
                                   xmlNodePtr node,
 
15705
                                   xmlSchemaTypePtr type,
 
15706
                                   const xmlChar *value,
 
15707
                                   xmlSchemaValPtr *val)
 
15708
{
 
15709
    int ret = 0;
 
15710
 
 
15711
    /*
 
15712
    * cos-valid-default:
 
15713
    * Schema Component Constraint: Element Default Valid (Immediate)
 
15714
    * For a string to be a valid default with respect to a type
 
15715
    * definition the appropriate case among the following must be true:
 
15716
    */
 
15717
    if WXS_IS_COMPLEX(type) {
 
15718
        /*
 
15719
        * Complex type.
 
15720
        *
 
15721
        * SPEC (2.1) "its {content type} must be a simple type definition
 
15722
        * or mixed."
 
15723
        * SPEC (2.2.2) "If the {content type} is mixed, then the {content
 
15724
        * type}'s particle must be ļæ½emptiableļæ½ as defined by
 
15725
        * Particle Emptiable (ļæ½3.9.6)."
 
15726
        */
 
15727
        if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
 
15728
            ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
 
15729
            /* NOTE that this covers (2.2.2) as well. */
 
15730
            xmlSchemaPCustomErr(pctxt,
 
15731
                XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
 
15732
                WXS_BASIC_CAST type, type->node,
 
15733
                "For a string to be a valid default, the type definition "
 
15734
                "must be a simple type or a complex type with mixed content "
 
15735
                "and a particle emptiable", NULL);
 
15736
            return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
 
15737
        }
 
15738
    }
 
15739
    /*
 
15740
    * 1 If the type definition is a simple type definition, then the string
 
15741
    * must be ļæ½validļæ½ with respect to that definition as defined by String
 
15742
    * Valid (ļæ½3.14.4).
 
15743
    *
 
15744
    * AND
 
15745
    *
 
15746
    * 2.2.1 If the {content type} is a simple type definition, then the
 
15747
    * string must be ļæ½validļæ½ with respect to that simple type definition
 
15748
    * as defined by String Valid (ļæ½3.14.4).
 
15749
    */
 
15750
    if (WXS_IS_SIMPLE(type))
 
15751
        ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
 
15752
            type, value, val, 1, 1, 0);
 
15753
    else if (WXS_HAS_SIMPLE_CONTENT(type))
 
15754
        ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
 
15755
            type->contentTypeDef, value, val, 1, 1, 0);
 
15756
    else
 
15757
        return (ret);
 
15758
 
 
15759
    if (ret < 0) {
 
15760
        PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
 
15761
            "calling xmlSchemaVCheckCVCSimpleType()");
 
15762
    }
 
15763
 
 
15764
    return (ret);
 
15765
}
 
15766
 
 
15767
/**
 
15768
 * xmlSchemaCheckCTPropsCorrect:
 
15769
 * @ctxt:  the schema parser context
 
15770
 * @type:  the complex type definition
 
15771
 *
 
15772
 *.(4.6) Constraints on Complex Type Definition Schema Components
 
15773
 * Schema Component Constraint:
 
15774
 * Complex Type Definition Properties Correct (ct-props-correct)
 
15775
 * STATUS: (seems) complete
 
15776
 *
 
15777
 * Returns 0 if the constraints are satisfied, a positive
 
15778
 * error code if not and -1 if an internal error occured.
 
15779
 */
 
15780
static int
 
15781
xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
 
15782
                             xmlSchemaTypePtr type)
 
15783
{
 
15784
    /*
 
15785
    * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
 
15786
    *
 
15787
    * SPEC (1) "The values of the properties of a complex type definition must
 
15788
    * be as described in the property tableau in The Complex Type Definition
 
15789
    * Schema Component (ļæ½3.4.1), modulo the impact of Missing
 
15790
    * Sub-components (ļæ½5.3)."
 
15791
    */
 
15792
    if ((type->baseType != NULL) &&
 
15793
        (WXS_IS_SIMPLE(type->baseType)) &&
 
15794
        (WXS_IS_EXTENSION(type) == 0)) {
 
15795
        /*
 
15796
        * SPEC (2) "If the {base type definition} is a simple type definition,
 
15797
        * the {derivation method} must be extension."
 
15798
        */
 
15799
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
15800
            XML_SCHEMAP_SRC_CT_1,
 
15801
            NULL, WXS_BASIC_CAST type, 
 
15802
            "If the base type is a simple type, the derivation method must be "
 
15803
            "'extension'", NULL, NULL);
 
15804
        return (XML_SCHEMAP_SRC_CT_1);
 
15805
    }
 
15806
    /*
 
15807
    * SPEC (3) "Circular definitions are disallowed, except for the ļæ½ur-type
 
15808
    * definitionļæ½. That is, it must be possible to reach the ļæ½ur-type
 
15809
    * definition by repeatedly following the {base type definition}."
 
15810
    *
 
15811
    * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
 
15812
    */
 
15813
    /*
 
15814
    * NOTE that (4) and (5) need the following:
 
15815
    *   - attribute uses need to be already inherited (apply attr. prohibitions)
 
15816
    *   - attribute group references need to be expanded already
 
15817
    *   - simple types need to be typefixed already
 
15818
    */    
 
15819
    if (type->attrUses &&
 
15820
        (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
 
15821
    {
 
15822
        xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
 
15823
        xmlSchemaAttributeUsePtr use, tmp;
 
15824
        int i, j, hasId = 0;
 
15825
 
 
15826
        for (i = uses->nbItems -1; i >= 0; i--) {
 
15827
            use = uses->items[i];
 
15828
            
 
15829
            /* 
 
15830
            * SPEC ct-props-correct
 
15831
            * (4) "Two distinct attribute declarations in the
 
15832
            * {attribute uses} must not have identical {name}s and
 
15833
            * {target namespace}s."
 
15834
            */
 
15835
            if (i > 0) {
 
15836
                for (j = i -1; j >= 0; j--) {
 
15837
                    tmp = uses->items[j];
 
15838
                    if ((WXS_ATTRUSE_DECL_NAME(use) ==
 
15839
                        WXS_ATTRUSE_DECL_NAME(tmp)) &&
 
15840
                        (WXS_ATTRUSE_DECL_TNS(use) ==
 
15841
                        WXS_ATTRUSE_DECL_TNS(tmp)))
 
15842
                    {
 
15843
                        xmlChar *str = NULL;
 
15844
 
 
15845
                        xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
15846
                            XML_SCHEMAP_AG_PROPS_CORRECT,
 
15847
                            NULL, WXS_BASIC_CAST type,
 
15848
                            "Duplicate %s",
 
15849
                            xmlSchemaGetComponentDesignation(&str, use),
 
15850
                            NULL);
 
15851
                        FREE_AND_NULL(str);
 
15852
                        /*
 
15853
                        * Remove the duplicate.
 
15854
                        */
 
15855
                        if (xmlSchemaItemListRemove(uses, i) == -1)
 
15856
                            goto exit_failure;
 
15857
                        goto next_use;
 
15858
                    }
 
15859
                }
 
15860
            }
 
15861
            /*
 
15862
            * SPEC ct-props-correct
 
15863
            * (5) "Two distinct attribute declarations in the
 
15864
            * {attribute uses} must not have {type definition}s which
 
15865
            * are or are derived from ID."
 
15866
            */
 
15867
            if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
 
15868
                if (xmlSchemaIsDerivedFromBuiltInType(
 
15869
                    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
 
15870
                {               
 
15871
                    if (hasId) {
 
15872
                        xmlChar *str = NULL;
 
15873
                        
 
15874
                        xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
15875
                            XML_SCHEMAP_AG_PROPS_CORRECT,
 
15876
                            NULL, WXS_BASIC_CAST type,
 
15877
                            "There must not exist more than one attribute "
 
15878
                            "declaration of type 'xs:ID' "
 
15879
                            "(or derived from 'xs:ID'). The %s violates this "
 
15880
                            "constraint",
 
15881
                            xmlSchemaGetComponentDesignation(&str, use),
 
15882
                            NULL);
 
15883
                        FREE_AND_NULL(str);
 
15884
                        if (xmlSchemaItemListRemove(uses, i) == -1)
 
15885
                            goto exit_failure;
 
15886
                    }
 
15887
                    
 
15888
                    hasId = 1;
 
15889
                }
 
15890
            }
 
15891
next_use: {}
 
15892
        }
 
15893
    }
 
15894
    return (0);
 
15895
exit_failure:
 
15896
    return(-1);
 
15897
}
 
15898
 
 
15899
static int
 
15900
xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
 
15901
                       xmlSchemaTypePtr typeB)
 
15902
{
 
15903
    /*
 
15904
    * TODO: This should implement component-identity
 
15905
    * in the future.
 
15906
    */
 
15907
    if ((typeA == NULL) || (typeB == NULL))
 
15908
        return (0);
 
15909
    return (typeA == typeB);
 
15910
}
 
15911
 
 
15912
/**
 
15913
 * xmlSchemaCheckCOSCTDerivedOK:
 
15914
 * @ctxt:  the schema parser context
 
15915
 * @type:  the to-be derived complex type definition
 
15916
 * @baseType:  the base complex type definition
 
15917
 * @set: the given set
 
15918
 *
 
15919
 * Schema Component Constraint:
 
15920
 * Type Derivation OK (Complex) (cos-ct-derived-ok)
 
15921
 *
 
15922
 * STATUS: completed
 
15923
 *
 
15924
 * Returns 0 if the constraints are satisfied, or 1
 
15925
 * if not.
 
15926
 */
 
15927
static int
 
15928
xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
 
15929
                             xmlSchemaTypePtr type,
 
15930
                             xmlSchemaTypePtr baseType,
 
15931
                             int set)
 
15932
{
 
15933
    int equal = xmlSchemaAreEqualTypes(type, baseType);
 
15934
    /* TODO: Error codes. */
 
15935
    /*
 
15936
    * SPEC "For a complex type definition (call it D, for derived)
 
15937
    * to be validly derived from a type definition (call this
 
15938
    * B, for base) given a subset of {extension, restriction}
 
15939
    * all of the following must be true:"
 
15940
    */
 
15941
    if (! equal) {
 
15942
        /*
 
15943
        * SPEC (1) "If B and D are not the same type definition, then the
 
15944
        * {derivation method} of D must not be in the subset."
 
15945
        */
 
15946
        if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
 
15947
            ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
 
15948
            return (1);
 
15949
    } else {
 
15950
        /*
 
15951
        * SPEC (2.1) "B and D must be the same type definition."
 
15952
        */
 
15953
        return (0);
 
15954
    }
 
15955
    /*
 
15956
    * SPEC (2.2) "B must be D's {base type definition}."
 
15957
    */
 
15958
    if (type->baseType == baseType)
 
15959
        return (0);
 
15960
    /*
 
15961
    * SPEC (2.3.1) "D's {base type definition} must not be the ļæ½ur-type
 
15962
    * definitionļæ½."
 
15963
    */
 
15964
    if (WXS_IS_ANYTYPE(type->baseType))
 
15965
        return (1);
 
15966
 
 
15967
    if (WXS_IS_COMPLEX(type->baseType)) {
 
15968
        /*
 
15969
        * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
 
15970
        * must be validly derived from B given the subset as defined by this
 
15971
        * constraint."
 
15972
        */
 
15973
        return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
 
15974
            baseType, set));
 
15975
    } else {
 
15976
        /*
 
15977
        * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
 
15978
        * must be validly derived from B given the subset as defined in Type
 
15979
        * Derivation OK (Simple) (ļæ½3.14.6).
 
15980
        */
 
15981
        return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
 
15982
            baseType, set));
 
15983
    }
 
15984
}
 
15985
 
 
15986
/**
 
15987
 * xmlSchemaCheckCOSDerivedOK:
 
15988
 * @type:  the derived simple type definition
 
15989
 * @baseType:  the base type definition
 
15990
 *
 
15991
 * Calls:
 
15992
 * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
 
15993
 *
 
15994
 * Checks wheter @type can be validly derived from @baseType.
 
15995
 *
 
15996
 * Returns 0 on success, an positive error code otherwise.
 
15997
 */
 
15998
static int
 
15999
xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
 
16000
                           xmlSchemaTypePtr type,
 
16001
                           xmlSchemaTypePtr baseType,
 
16002
                           int set)
 
16003
{
 
16004
    if (WXS_IS_SIMPLE(type))
 
16005
        return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
 
16006
    else
 
16007
        return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
 
16008
}
 
16009
 
 
16010
/**
 
16011
 * xmlSchemaCheckCOSCTExtends:
 
16012
 * @ctxt:  the schema parser context
 
16013
 * @type:  the complex type definition
 
16014
 *
 
16015
 * (3.4.6) Constraints on Complex Type Definition Schema Components
 
16016
 * Schema Component Constraint:
 
16017
 * Derivation Valid (Extension) (cos-ct-extends)
 
16018
 *
 
16019
 * STATUS:
 
16020
 *   missing:
 
16021
 *     (1.5)
 
16022
 *     (1.4.3.2.2.2) "Particle Valid (Extension)"
 
16023
 *
 
16024
 * Returns 0 if the constraints are satisfied, a positive
 
16025
 * error code if not and -1 if an internal error occured.
 
16026
 */
 
16027
static int
 
16028
xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
 
16029
                           xmlSchemaTypePtr type)
 
16030
{
 
16031
    xmlSchemaTypePtr base = type->baseType;
 
16032
    /*
 
16033
    * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
 
16034
    * temporarily only.
 
16035
    */
 
16036
    /*
 
16037
    * SPEC (1) "If the {base type definition} is a complex type definition,
 
16038
    * then all of the following must be true:"
 
16039
    */
 
16040
    if (WXS_IS_COMPLEX(base)) { 
 
16041
        /*
 
16042
        * SPEC (1.1) "The {final} of the {base type definition} must not
 
16043
        * contain extension."
 
16044
        */
 
16045
        if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
 
16046
            xmlSchemaPCustomErr(ctxt,
 
16047
                XML_SCHEMAP_COS_CT_EXTENDS_1_1,
 
16048
                WXS_BASIC_CAST type, NULL,
 
16049
                "The 'final' of the base type definition "
 
16050
                "contains 'extension'", NULL);
 
16051
            return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
 
16052
        }
 
16053
        
 
16054
        /*
 
16055
        * ATTENTION: The constrains (1.2) and (1.3) are not applied,
 
16056
        * since they are automatically satisfied through the
 
16057
        * inheriting mechanism.
 
16058
        * Note that even if redefining components, the inheriting mechanism
 
16059
        * is used.
 
16060
        */
 
16061
#if 0
 
16062
        /*
 
16063
        * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
 
16064
        * uses}
 
16065
        * of the complex type definition itself, that is, for every attribute
 
16066
        * use in the {attribute uses} of the {base type definition}, there
 
16067
        * must be an attribute use in the {attribute uses} of the complex
 
16068
        * type definition itself whose {attribute declaration} has the same
 
16069
        * {name}, {target namespace} and {type definition} as its attribute
 
16070
        * declaration"
 
16071
        */
 
16072
        if (base->attrUses != NULL) {
 
16073
            int i, j, found;
 
16074
            xmlSchemaAttributeUsePtr use, buse;
 
16075
 
 
16076
            for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
 
16077
                buse = (WXS_LIST_CAST base->attrUses)->items[i];
 
16078
                found = 0;
 
16079
                if (type->attrUses != NULL) {
 
16080
                    use = (WXS_LIST_CAST type->attrUses)->items[j];
 
16081
                    for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
 
16082
                    {
 
16083
                        if ((WXS_ATTRUSE_DECL_NAME(use) ==
 
16084
                                WXS_ATTRUSE_DECL_NAME(buse)) &&
 
16085
                            (WXS_ATTRUSE_DECL_TNS(use) ==
 
16086
                                WXS_ATTRUSE_DECL_TNS(buse)) &&
 
16087
                            (WXS_ATTRUSE_TYPEDEF(use) ==
 
16088
                                WXS_ATTRUSE_TYPEDEF(buse))
 
16089
                        {
 
16090
                            found = 1;
 
16091
                            break;
 
16092
                        }
 
16093
                    }
 
16094
                }
 
16095
                if (! found) {
 
16096
                    xmlChar *str = NULL;
 
16097
                
 
16098
                    xmlSchemaCustomErr(ACTXT_CAST ctxt,
 
16099
                        XML_SCHEMAP_COS_CT_EXTENDS_1_2,
 
16100
                        NULL, WXS_BASIC_CAST type,
 
16101
                        /* 
 
16102
                        * TODO: The report does not indicate that also the
 
16103
                        * type needs to be the same.
 
16104
                        */
 
16105
                        "This type is missing a matching correspondent "
 
16106
                        "for its {base type}'s %s in its {attribute uses}",
 
16107
                        xmlSchemaGetComponentDesignation(&str,
 
16108
                            buse->children),
 
16109
                        NULL);
 
16110
                    FREE_AND_NULL(str)
 
16111
                }
 
16112
            }
 
16113
        }
 
16114
        /*
 
16115
        * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
 
16116
        * definition must also have one, and the base type definition's
 
16117
        * {attribute  wildcard}'s {namespace constraint} must be a subset
 
16118
        * of the complex  type definition's {attribute wildcard}'s {namespace
 
16119
        * constraint}, as defined by Wildcard Subset (ļæ½3.10.6)."
 
16120
        */
 
16121
  
 
16122
        /*
 
16123
        * MAYBE TODO: Enable if ever needed. But this will be needed only
 
16124
        * if created the type via a schema construction API.
 
16125
        */
 
16126
        if (base->attributeWildcard != NULL) {
 
16127
            if (type->attributeWilcard == NULL) {
 
16128
                xmlChar *str = NULL;
 
16129
                
 
16130
                xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
16131
                    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
 
16132
                    NULL, type,
 
16133
                    "The base %s has an attribute wildcard, "
 
16134
                    "but this type is missing an attribute wildcard",
 
16135
                    xmlSchemaGetComponentDesignation(&str, base));
 
16136
                FREE_AND_NULL(str)
 
16137
 
 
16138
            } else if (xmlSchemaCheckCOSNSSubset(
 
16139
                base->attributeWildcard, type->attributeWildcard))
 
16140
            {
 
16141
                xmlChar *str = NULL;
 
16142
                
 
16143
                xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
16144
                    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
 
16145
                    NULL, type,
 
16146
                    "The attribute wildcard is not a valid "
 
16147
                    "superset of the one in the base %s",
 
16148
                    xmlSchemaGetComponentDesignation(&str, base));
 
16149
                FREE_AND_NULL(str)
 
16150
            }
 
16151
        }
 
16152
#endif
 
16153
        /*
 
16154
        * SPEC (1.4) "One of the following must be true:"
 
16155
        */
 
16156
        if ((type->contentTypeDef != NULL) &&
 
16157
            (type->contentTypeDef == base->contentTypeDef)) {
 
16158
            /*
 
16159
            * SPEC (1.4.1) "The {content type} of the {base type definition}
 
16160
            * and the {content type} of the complex type definition itself
 
16161
            * must be the same simple type definition"
 
16162
            * PASS
 
16163
            */
 
16164
        } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
 
16165
            (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
 
16166
            /*
 
16167
            * SPEC (1.4.2) "The {content type} of both the {base type
 
16168
            * definition} and the complex type definition itself must
 
16169
            * be empty."
 
16170
            * PASS
 
16171
            */
 
16172
        } else {
 
16173
            /*
 
16174
            * SPEC (1.4.3) "All of the following must be true:"
 
16175
            */
 
16176
            if (type->subtypes == NULL) {
 
16177
                /*
 
16178
                * SPEC 1.4.3.1 The {content type} of the complex type
 
16179
                * definition itself must specify a particle.
 
16180
                */
 
16181
                xmlSchemaPCustomErr(ctxt,
 
16182
                    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
 
16183
                    WXS_BASIC_CAST type, NULL,
 
16184
                    "The content type must specify a particle", NULL);
 
16185
                return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
 
16186
            }
 
16187
            /*
 
16188
            * SPEC (1.4.3.2) "One of the following must be true:"
 
16189
            */
 
16190
            if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
 
16191
                /*
 
16192
                * SPEC (1.4.3.2.1) "The {content type} of the {base type
 
16193
                * definition} must be empty.
 
16194
                * PASS
 
16195
                */
 
16196
            } else {
 
16197
                /*
 
16198
                * SPEC (1.4.3.2.2) "All of the following must be true:"
 
16199
                */
 
16200
                if ((type->contentType != base->contentType) ||
 
16201
                    ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
 
16202
                    (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
 
16203
                    /*
 
16204
                    * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
 
16205
                    * or both must be element-only."
 
16206
                    */
 
16207
                    xmlSchemaPCustomErr(ctxt,
 
16208
                        XML_SCHEMAP_COS_CT_EXTENDS_1_1,
 
16209
                        WXS_BASIC_CAST type, NULL,
 
16210
                        "The content type of both, the type and its base "
 
16211
                        "type, must either 'mixed' or 'element-only'", NULL);
 
16212
                    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
 
16213
                }
 
16214
                /*
 
16215
                * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
 
16216
                * complex type definition must be a ļæ½valid extensionļæ½
 
16217
                * of the {base type definition}'s particle, as defined
 
16218
                * in Particle Valid (Extension) (ļæ½3.9.6)."
 
16219
                *
 
16220
                * NOTE that we won't check "Particle Valid (Extension)",
 
16221
                * since it is ensured by the derivation process in
 
16222
                * xmlSchemaTypeFixup(). We need to implement this when heading
 
16223
                * for a construction API
 
16224
                * TODO: !! This is needed to be checked if redefining a type !!
 
16225
                */
 
16226
            }
 
16227
            /*
 
16228
            * URGENT TODO (1.5)
 
16229
            */
 
16230
        }
 
16231
    } else {
 
16232
        /*
 
16233
        * SPEC (2) "If the {base type definition} is a simple type definition,
 
16234
        * then all of the following must be true:"
 
16235
        */
 
16236
        if (type->contentTypeDef != base) {
 
16237
            /*
 
16238
            * SPEC (2.1) "The {content type} must be the same simple type
 
16239
            * definition."
 
16240
            */
 
16241
            xmlSchemaPCustomErr(ctxt,
 
16242
                XML_SCHEMAP_COS_CT_EXTENDS_1_1,
 
16243
                WXS_BASIC_CAST type, NULL,
 
16244
                "The content type must be the simple base type", NULL);
 
16245
            return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
 
16246
        }
 
16247
        if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
 
16248
            /*
 
16249
            * SPEC (2.2) "The {final} of the {base type definition} must not
 
16250
            * contain extension"
 
16251
            * NOTE that this is the same as (1.1).
 
16252
            */
 
16253
            xmlSchemaPCustomErr(ctxt,
 
16254
                XML_SCHEMAP_COS_CT_EXTENDS_1_1,
 
16255
                WXS_BASIC_CAST type, NULL,
 
16256
                "The 'final' of the base type definition "
 
16257
                "contains 'extension'", NULL);
 
16258
            return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
 
16259
        }
 
16260
    }
 
16261
    return (0);
 
16262
}
 
16263
 
 
16264
/**
 
16265
 * xmlSchemaCheckDerivationOKRestriction:
 
16266
 * @ctxt:  the schema parser context
 
16267
 * @type:  the complex type definition
 
16268
 *
 
16269
 * (3.4.6) Constraints on Complex Type Definition Schema Components
 
16270
 * Schema Component Constraint:
 
16271
 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
 
16272
 *
 
16273
 * STATUS:
 
16274
 *   missing:
 
16275
 *     (5.4.2) ???
 
16276
 *
 
16277
 * ATTENTION:
 
16278
 * In XML Schema 1.1 this will be:
 
16279
 * Validation Rule: Checking complex type subsumption
 
16280
 *
 
16281
 * Returns 0 if the constraints are satisfied, a positive
 
16282
 * error code if not and -1 if an internal error occured.
 
16283
 */
 
16284
static int
 
16285
xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
 
16286
                                      xmlSchemaTypePtr type)
 
16287
{
 
16288
    xmlSchemaTypePtr base;
 
16289
 
 
16290
    /*
 
16291
    * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
 
16292
    * temporarily only.
 
16293
    */
 
16294
    base = type->baseType;
 
16295
    if (! WXS_IS_COMPLEX(base)) {
 
16296
        xmlSchemaCustomErr(ACTXT_CAST ctxt,         
 
16297
            XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
 
16298
            type->node, WXS_BASIC_CAST type,
 
16299
            "The base type must be a complex type", NULL, NULL);
 
16300
        return(ctxt->err);
 
16301
    }
 
16302
    if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
 
16303
        /*
 
16304
        * SPEC (1) "The {base type definition} must be a complex type
 
16305
        * definition whose {final} does not contain restriction."
 
16306
        */
 
16307
        xmlSchemaCustomErr(ACTXT_CAST ctxt,         
 
16308
            XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
 
16309
            type->node, WXS_BASIC_CAST type,
 
16310
            "The 'final' of the base type definition "
 
16311
            "contains 'restriction'", NULL, NULL);
 
16312
        return (ctxt->err);
 
16313
    }
 
16314
    /*
 
16315
    * SPEC (2), (3) and (4)
 
16316
    * Those are handled in a separate function, since the
 
16317
    * same constraints are needed for redefinition of
 
16318
    * attribute groups as well.
 
16319
    */
 
16320
    if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
 
16321
        XML_SCHEMA_ACTION_DERIVE,
 
16322
        WXS_BASIC_CAST type, WXS_BASIC_CAST base,
 
16323
        type->attrUses, base->attrUses,
 
16324
        type->attributeWildcard,
 
16325
        base->attributeWildcard) == -1)
 
16326
    {
 
16327
        return(-1);
 
16328
    }
 
16329
    /*
 
16330
    * SPEC (5) "One of the following must be true:"
 
16331
    */
 
16332
    if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
 
16333
        /*
 
16334
        * SPEC (5.1) "The {base type definition} must be the
 
16335
        * ļæ½ur-type definitionļæ½."
 
16336
        * PASS
 
16337
        */
 
16338
    } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
 
16339
            (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
 
16340
        /*
 
16341
        * SPEC (5.2.1) "The {content type} of the complex type definition
 
16342
        * must be a simple type definition"
 
16343
        *
 
16344
        * SPEC (5.2.2) "One of the following must be true:"
 
16345
        */
 
16346
        if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
 
16347
            (base->contentType == XML_SCHEMA_CONTENT_BASIC))
 
16348
        {
 
16349
            int err;
 
16350
            /*
 
16351
            * SPEC (5.2.2.1) "The {content type} of the {base type
 
16352
            * definition} must be a simple type definition from which
 
16353
            * the {content type} is validly derived given the empty
 
16354
            * set as defined in Type Derivation OK (Simple) (ļæ½3.14.6)."
 
16355
            *
 
16356
            * ATTENTION TODO: This seems not needed if the type implicitely
 
16357
            * derived from the base type.
 
16358
            * 
 
16359
            */
 
16360
            err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
 
16361
                type->contentTypeDef, base->contentTypeDef, 0);
 
16362
            if (err != 0) {
 
16363
                xmlChar *strA = NULL, *strB = NULL;
 
16364
 
 
16365
                if (err == -1)
 
16366
                    return(-1);
 
16367
                xmlSchemaCustomErr(ACTXT_CAST ctxt,
 
16368
                    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
 
16369
                    NULL, WXS_BASIC_CAST type,
 
16370
                    "The {content type} %s is not validly derived from the "
 
16371
                    "base type's {content type} %s",
 
16372
                    xmlSchemaGetComponentDesignation(&strA,
 
16373
                        type->contentTypeDef),
 
16374
                    xmlSchemaGetComponentDesignation(&strB,
 
16375
                        base->contentTypeDef));
 
16376
                FREE_AND_NULL(strA);
 
16377
                FREE_AND_NULL(strB);
 
16378
                return(ctxt->err);
 
16379
            }
 
16380
        } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
 
16381
            (xmlSchemaIsParticleEmptiable(
 
16382
                (xmlSchemaParticlePtr) base->subtypes))) {
 
16383
            /*
 
16384
            * SPEC (5.2.2.2) "The {base type definition} must be mixed
 
16385
            * and have a particle which is ļæ½emptiableļæ½ as defined in
 
16386
            * Particle Emptiable (ļæ½3.9.6)."
 
16387
            * PASS
 
16388
            */
 
16389
        } else {
 
16390
            xmlSchemaPCustomErr(ctxt,
 
16391
                XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
 
16392
                WXS_BASIC_CAST type, NULL,
 
16393
                "The content type of the base type must be either "
 
16394
                "a simple type or 'mixed' and an emptiable particle", NULL);
 
16395
            return (ctxt->err);
 
16396
        }
 
16397
    } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
 
16398
        /*
 
16399
        * SPEC (5.3.1) "The {content type} of the complex type itself must
 
16400
        * be empty"
 
16401
        */
 
16402
        if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
 
16403
            /*
 
16404
            * SPEC (5.3.2.1) "The {content type} of the {base type
 
16405
            * definition} must also be empty."
 
16406
            * PASS
 
16407
            */
 
16408
        } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
 
16409
            (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
 
16410
            xmlSchemaIsParticleEmptiable(
 
16411
                (xmlSchemaParticlePtr) base->subtypes)) {
 
16412
            /*
 
16413
            * SPEC (5.3.2.2) "The {content type} of the {base type
 
16414
            * definition} must be elementOnly or mixed and have a particle
 
16415
            * which is ļæ½emptiableļæ½ as defined in Particle Emptiable (ļæ½3.9.6)."
 
16416
            * PASS
 
16417
            */
 
16418
        } else {
 
16419
            xmlSchemaPCustomErr(ctxt,
 
16420
                XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
 
16421
                WXS_BASIC_CAST type, NULL,
 
16422
                "The content type of the base type must be either "
 
16423
                "empty or 'mixed' (or 'elements-only') and an emptiable "
 
16424
                "particle", NULL);
 
16425
            return (ctxt->err);
 
16426
        }
 
16427
    } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
 
16428
        WXS_HAS_MIXED_CONTENT(type)) {
 
16429
        /*
 
16430
        * SPEC (5.4.1.1) "The {content type} of the complex type definition
 
16431
        * itself must be element-only"
 
16432
        */       
 
16433
        if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
 
16434
            /*
 
16435
            * SPEC (5.4.1.2) "The {content type} of the complex type
 
16436
            * definition itself and of the {base type definition} must be
 
16437
            * mixed"
 
16438
            */
 
16439
            xmlSchemaPCustomErr(ctxt,
 
16440
                XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
 
16441
                WXS_BASIC_CAST type, NULL,
 
16442
                "If the content type is 'mixed', then the content type of the "
 
16443
                "base type must also be 'mixed'", NULL);
 
16444
            return (ctxt->err);
 
16445
        }
 
16446
        /*
 
16447
        * SPEC (5.4.2) "The particle of the complex type definition itself
 
16448
        * must be a ļæ½valid restrictionļæ½ of the particle of the {content
 
16449
        * type} of the {base type definition} as defined in Particle Valid
 
16450
        * (Restriction) (ļæ½3.9.6).
 
16451
        *
 
16452
        * URGENT TODO: (5.4.2)
 
16453
        */
 
16454
    } else {
 
16455
        xmlSchemaPCustomErr(ctxt,
 
16456
            XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
 
16457
            WXS_BASIC_CAST type, NULL,
 
16458
            "The type is not a valid restriction of its base type", NULL);
 
16459
        return (ctxt->err);
 
16460
    }
 
16461
    return (0);
 
16462
}
 
16463
 
 
16464
/**
 
16465
 * xmlSchemaCheckCTComponent:
 
16466
 * @ctxt:  the schema parser context
 
16467
 * @type:  the complex type definition
 
16468
 *
 
16469
 * (3.4.6) Constraints on Complex Type Definition Schema Components
 
16470
 *
 
16471
 * Returns 0 if the constraints are satisfied, a positive
 
16472
 * error code if not and -1 if an internal error occured.
 
16473
 */
 
16474
static int
 
16475
xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
 
16476
                          xmlSchemaTypePtr type)
 
16477
{
 
16478
    int ret;
 
16479
    /*
 
16480
    * Complex Type Definition Properties Correct
 
16481
    */
 
16482
    ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
 
16483
    if (ret != 0)
 
16484
        return (ret);
 
16485
    if (WXS_IS_EXTENSION(type))
 
16486
        ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
 
16487
    else
 
16488
        ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
 
16489
    return (ret);
 
16490
}
 
16491
 
 
16492
/**
 
16493
 * xmlSchemaCheckSRCCT:
 
16494
 * @ctxt:  the schema parser context
 
16495
 * @type:  the complex type definition
 
16496
 *
 
16497
 * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
 
16498
 * Schema Representation Constraint:
 
16499
 * Complex Type Definition Representation OK (src-ct)
 
16500
 *
 
16501
 * Returns 0 if the constraints are satisfied, a positive
 
16502
 * error code if not and -1 if an internal error occured.
 
16503
 */
 
16504
static int
 
16505
xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
 
16506
                    xmlSchemaTypePtr type)
 
16507
{
 
16508
    xmlSchemaTypePtr base;
 
16509
    int ret = 0;
 
16510
 
 
16511
    /*
 
16512
    * TODO: Adjust the error codes here, as I used
 
16513
    * XML_SCHEMAP_SRC_CT_1 only yet.
 
16514
    */
 
16515
    base = type->baseType;
 
16516
    if (! WXS_HAS_SIMPLE_CONTENT(type)) {
 
16517
        /*
 
16518
        * 1 If the <complexContent> alternative is chosen, the type definition
 
16519
        * ļæ½resolvedļæ½ to by the ļæ½actual valueļæ½ of the base [attribute]
 
16520
        * must be a complex type definition;
 
16521
        */
 
16522
        if (! WXS_IS_COMPLEX(base)) {
 
16523
            xmlChar *str = NULL;
 
16524
            xmlSchemaPCustomErr(ctxt,
 
16525
                XML_SCHEMAP_SRC_CT_1,
 
16526
                WXS_BASIC_CAST type, type->node,
 
16527
                "If using <complexContent>, the base type is expected to be "
 
16528
                "a complex type. The base type '%s' is a simple type",
 
16529
                xmlSchemaFormatQName(&str, base->targetNamespace,
 
16530
                base->name));
 
16531
            FREE_AND_NULL(str)
 
16532
            return (XML_SCHEMAP_SRC_CT_1);
 
16533
        }
 
16534
    } else {
 
16535
        /*
 
16536
        * SPEC
 
16537
        * 2 If the <simpleContent> alternative is chosen, all of the
 
16538
        * following must be true:
 
16539
        * 2.1 The type definition ļæ½resolvedļæ½ to by the ļæ½actual valueļæ½ of the
 
16540
        * base [attribute] must be one of the following:
 
16541
        */
 
16542
        if (WXS_IS_SIMPLE(base)) {
 
16543
            if (WXS_IS_EXTENSION(type) == 0) {
 
16544
                xmlChar *str = NULL;
 
16545
                /*
 
16546
                * 2.1.3 only if the <extension> alternative is also
 
16547
                * chosen, a simple type definition.
 
16548
                */
 
16549
                /* TODO: Change error code to ..._SRC_CT_2_1_3. */
 
16550
                xmlSchemaPCustomErr(ctxt,
 
16551
                    XML_SCHEMAP_SRC_CT_1,
 
16552
                    WXS_BASIC_CAST type, NULL,
 
16553
                    "If using <simpleContent> and <restriction>, the base "
 
16554
                    "type must be a complex type. The base type '%s' is "
 
16555
                    "a simple type",
 
16556
                    xmlSchemaFormatQName(&str, base->targetNamespace,
 
16557
                        base->name));
 
16558
                FREE_AND_NULL(str)
 
16559
                return (XML_SCHEMAP_SRC_CT_1);
 
16560
            }
 
16561
        } else {
 
16562
            /* Base type is a complex type. */
 
16563
            if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
 
16564
                (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
 
16565
                /*
 
16566
                * 2.1.1 a complex type definition whose {content type} is a
 
16567
                * simple type definition;
 
16568
                * PASS
 
16569
                */
 
16570
                if (base->contentTypeDef == NULL) {
 
16571
                    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
 
16572
                        WXS_BASIC_CAST type, NULL,
 
16573
                        "Internal error: xmlSchemaCheckSRCCT, "
 
16574
                        "'%s', base type has no content type",
 
16575
                        type->name);
 
16576
                    return (-1);
 
16577
                }
 
16578
            } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
 
16579
                (WXS_IS_RESTRICTION(type))) {
 
16580
 
 
16581
                /*
 
16582
                * 2.1.2 only if the <restriction> alternative is also
 
16583
                * chosen, a complex type definition whose {content type}
 
16584
                * is mixed and a particle emptiable.
 
16585
                */
 
16586
                if (! xmlSchemaIsParticleEmptiable(
 
16587
                    (xmlSchemaParticlePtr) base->subtypes)) {
 
16588
                    ret = XML_SCHEMAP_SRC_CT_1;
 
16589
                } else 
 
16590
                    /*
 
16591
                    * Attention: at this point the <simpleType> child is in
 
16592
                    * ->contentTypeDef (put there during parsing).
 
16593
                    */              
 
16594
                    if (type->contentTypeDef == NULL) {
 
16595
                    xmlChar *str = NULL;
 
16596
                    /*
 
16597
                    * 2.2 If clause 2.1.2 above is satisfied, then there
 
16598
                    * must be a <simpleType> among the [children] of
 
16599
                    * <restriction>.
 
16600
                    */
 
16601
                    /* TODO: Change error code to ..._SRC_CT_2_2. */
 
16602
                    xmlSchemaPCustomErr(ctxt,
 
16603
                        XML_SCHEMAP_SRC_CT_1,
 
16604
                        WXS_BASIC_CAST type, NULL,
 
16605
                        "A <simpleType> is expected among the children "
 
16606
                        "of <restriction>, if <simpleContent> is used and "
 
16607
                        "the base type '%s' is a complex type",
 
16608
                        xmlSchemaFormatQName(&str, base->targetNamespace,
 
16609
                        base->name));
 
16610
                    FREE_AND_NULL(str)
 
16611
                    return (XML_SCHEMAP_SRC_CT_1);
 
16612
                }
 
16613
            } else {
 
16614
                ret = XML_SCHEMAP_SRC_CT_1;
 
16615
            }
 
16616
        }
 
16617
        if (ret > 0) {
 
16618
            xmlChar *str = NULL;
 
16619
            if (WXS_IS_RESTRICTION(type)) {
 
16620
                xmlSchemaPCustomErr(ctxt,
 
16621
                    XML_SCHEMAP_SRC_CT_1,
 
16622
                    WXS_BASIC_CAST type, NULL,
 
16623
                    "If <simpleContent> and <restriction> is used, the "
 
16624
                    "base type must be a simple type or a complex type with "
 
16625
                    "mixed content and particle emptiable. The base type "
 
16626
                    "'%s' is none of those",
 
16627
                    xmlSchemaFormatQName(&str, base->targetNamespace,
 
16628
                    base->name));
 
16629
            } else {
 
16630
                xmlSchemaPCustomErr(ctxt,
 
16631
                    XML_SCHEMAP_SRC_CT_1,
 
16632
                    WXS_BASIC_CAST type, NULL,
 
16633
                    "If <simpleContent> and <extension> is used, the "
 
16634
                    "base type must be a simple type. The base type '%s' "
 
16635
                    "is a complex type",
 
16636
                    xmlSchemaFormatQName(&str, base->targetNamespace,
 
16637
                    base->name));
 
16638
            }
 
16639
            FREE_AND_NULL(str)
 
16640
        }
 
16641
    }
 
16642
    /*
 
16643
    * SPEC (3) "The corresponding complex type definition component must
 
16644
    * satisfy the conditions set out in Constraints on Complex Type
 
16645
    * Definition Schema Components (ļæ½3.4.6);"
 
16646
    * NOTE (3) will be done in xmlSchemaTypeFixup().
 
16647
    */
 
16648
    /*
 
16649
    * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
 
16650
    * above for {attribute wildcard} is satisfied, the intensional
 
16651
    * intersection must be expressible, as defined in Attribute Wildcard
 
16652
    * Intersection (ļæ½3.10.6).
 
16653
    * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
 
16654
    */
 
16655
    return (ret);
 
16656
}
 
16657
 
 
16658
#ifdef ENABLE_PARTICLE_RESTRICTION
 
16659
/**
 
16660
 * xmlSchemaCheckParticleRangeOK:
 
16661
 * @ctxt:  the schema parser context
 
16662
 * @type:  the complex type definition
 
16663
 *
 
16664
 * (3.9.6) Constraints on Particle Schema Components
 
16665
 * Schema Component Constraint:
 
16666
 * Occurrence Range OK (range-ok)
 
16667
 *
 
16668
 * STATUS: complete
 
16669
 *
 
16670
 * Returns 0 if the constraints are satisfied, a positive
 
16671
 * error code if not and -1 if an internal error occured.
 
16672
 */
 
16673
static int
 
16674
xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
 
16675
                              int bmin, int bmax)
 
16676
{
 
16677
    if (rmin < bmin)
 
16678
        return (1);
 
16679
    if ((bmax != UNBOUNDED) &&
 
16680
        (rmax > bmax))
 
16681
        return (1);
 
16682
    return (0);
 
16683
}
 
16684
 
 
16685
/**
 
16686
 * xmlSchemaCheckRCaseNameAndTypeOK:
 
16687
 * @ctxt:  the schema parser context
 
16688
 * @r: the restricting element declaration particle
 
16689
 * @b: the base element declaration particle
 
16690
 *
 
16691
 * (3.9.6) Constraints on Particle Schema Components
 
16692
 * Schema Component Constraint:
 
16693
 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
 
16694
 * (rcase-NameAndTypeOK)
 
16695
 *
 
16696
 * STATUS:
 
16697
 *   MISSING (3.2.3)
 
16698
 *   CLARIFY: (3.2.2)
 
16699
 *
 
16700
 * Returns 0 if the constraints are satisfied, a positive
 
16701
 * error code if not and -1 if an internal error occured.
 
16702
 */
 
16703
static int
 
16704
xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
 
16705
                                 xmlSchemaParticlePtr r,
 
16706
                                 xmlSchemaParticlePtr b)
 
16707
{
 
16708
    xmlSchemaElementPtr elemR, elemB;
 
16709
 
 
16710
    /* TODO: Error codes (rcase-NameAndTypeOK). */
 
16711
    elemR = (xmlSchemaElementPtr) r->children;
 
16712
    elemB = (xmlSchemaElementPtr) b->children;
 
16713
    /*
 
16714
    * SPEC (1) "The declarations' {name}s and {target namespace}s are
 
16715
    * the same."
 
16716
    */
 
16717
    if ((elemR != elemB) &&
 
16718
        ((! xmlStrEqual(elemR->name, elemB->name)) ||
 
16719
        (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
 
16720
        return (1);
 
16721
    /*
 
16722
    * SPEC (2) "R's occurrence range is a valid restriction of B's
 
16723
    * occurrence range as defined by Occurrence Range OK (ļæ½3.9.6)."
 
16724
    */
 
16725
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
 
16726
            b->minOccurs, b->maxOccurs) != 0)
 
16727
        return (1);
 
16728
    /*
 
16729
    * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
 
16730
    * {scope} are global."
 
16731
    */
 
16732
    if (elemR == elemB)
 
16733
        return (0);
 
16734
    /*
 
16735
    * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
 
16736
    */
 
16737
    if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
 
16738
        (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
 
16739
         return (1);
 
16740
    /*
 
16741
    * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
 
16742
    * or is not fixed, or R's declaration's {value constraint} is fixed
 
16743
    * with the same value."
 
16744
    */
 
16745
    if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
 
16746
        ((elemR->value == NULL) ||
 
16747
         ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
 
16748
         /* TODO: Equality of the initial value or normalized or canonical? */
 
16749
         (! xmlStrEqual(elemR->value, elemB->value))))
 
16750
         return (1);
 
16751
    /*
 
16752
    * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
 
16753
    * definitions} is a subset of B's declaration's {identity-constraint
 
16754
    * definitions}, if any."
 
16755
    */
 
16756
    if (elemB->idcs != NULL) {
 
16757
        /* TODO */
 
16758
    }
 
16759
    /*
 
16760
    * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
 
16761
    * superset of B's declaration's {disallowed substitutions}."
 
16762
    */
 
16763
    if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
 
16764
         ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
 
16765
        ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
 
16766
         ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
 
16767
        ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
 
16768
         ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
 
16769
         return (1);
 
16770
    /*
 
16771
    * SPEC (3.2.5) "R's {type definition} is validly derived given
 
16772
    * {extension, list, union} from B's {type definition}"
 
16773
    *
 
16774
    * BADSPEC TODO: What's the point of adding "list" and "union" to the
 
16775
    * set, if the corresponding constraints handle "restriction" and
 
16776
    * "extension" only?
 
16777
    *
 
16778
    */
 
16779
    {
 
16780
        int set = 0;
 
16781
 
 
16782
        set |= SUBSET_EXTENSION;
 
16783
        set |= SUBSET_LIST;
 
16784
        set |= SUBSET_UNION;
 
16785
        if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
 
16786
            elemB->subtypes, set) != 0)
 
16787
            return (1);
 
16788
    }
 
16789
    return (0);
 
16790
}
 
16791
 
 
16792
/**
 
16793
 * xmlSchemaCheckRCaseNSCompat:
 
16794
 * @ctxt:  the schema parser context
 
16795
 * @r: the restricting element declaration particle
 
16796
 * @b: the base wildcard particle
 
16797
 *
 
16798
 * (3.9.6) Constraints on Particle Schema Components
 
16799
 * Schema Component Constraint:
 
16800
 * Particle Derivation OK (Elt:Any -- NSCompat)
 
16801
 * (rcase-NSCompat)
 
16802
 *
 
16803
 * STATUS: complete
 
16804
 *
 
16805
 * Returns 0 if the constraints are satisfied, a positive
 
16806
 * error code if not and -1 if an internal error occured.
 
16807
 */
 
16808
static int
 
16809
xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
 
16810
                            xmlSchemaParticlePtr r,
 
16811
                            xmlSchemaParticlePtr b)
 
16812
{
 
16813
    /* TODO:Error codes (rcase-NSCompat). */
 
16814
    /*
 
16815
    * SPEC "For an element declaration particle to be a ļæ½valid restrictionļæ½
 
16816
    * of a wildcard particle all of the following must be true:"
 
16817
    *
 
16818
    * SPEC (1) "The element declaration's {target namespace} is ļæ½validļæ½
 
16819
    * with respect to the wildcard's {namespace constraint} as defined by
 
16820
    * Wildcard allows Namespace Name (ļæ½3.10.4)."
 
16821
    */
 
16822
    if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
 
16823
        ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
 
16824
        return (1);
 
16825
    /*
 
16826
    * SPEC (2) "R's occurrence range is a valid restriction of B's
 
16827
    * occurrence range as defined by Occurrence Range OK (ļæ½3.9.6)."
 
16828
    */
 
16829
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
 
16830
            b->minOccurs, b->maxOccurs) != 0)
 
16831
        return (1);
 
16832
 
 
16833
    return (0);
 
16834
}
 
16835
 
 
16836
/**
 
16837
 * xmlSchemaCheckRCaseRecurseAsIfGroup:
 
16838
 * @ctxt:  the schema parser context
 
16839
 * @r: the restricting element declaration particle
 
16840
 * @b: the base model group particle
 
16841
 *
 
16842
 * (3.9.6) Constraints on Particle Schema Components
 
16843
 * Schema Component Constraint:
 
16844
 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
 
16845
 * (rcase-RecurseAsIfGroup)
 
16846
 *
 
16847
 * STATUS: TODO
 
16848
 *
 
16849
 * Returns 0 if the constraints are satisfied, a positive
 
16850
 * error code if not and -1 if an internal error occured.
 
16851
 */
 
16852
static int
 
16853
xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
 
16854
                                    xmlSchemaParticlePtr r,
 
16855
                                    xmlSchemaParticlePtr b)
 
16856
{
 
16857
    /* TODO: Error codes (rcase-RecurseAsIfGroup). */
 
16858
    TODO
 
16859
    return (0);
 
16860
}
 
16861
 
 
16862
/**
 
16863
 * xmlSchemaCheckRCaseNSSubset:
 
16864
 * @ctxt:  the schema parser context
 
16865
 * @r: the restricting wildcard particle
 
16866
 * @b: the base wildcard particle
 
16867
 *
 
16868
 * (3.9.6) Constraints on Particle Schema Components
 
16869
 * Schema Component Constraint:
 
16870
 * Particle Derivation OK (Any:Any -- NSSubset)
 
16871
 * (rcase-NSSubset)
 
16872
 *
 
16873
 * STATUS: complete
 
16874
 *
 
16875
 * Returns 0 if the constraints are satisfied, a positive
 
16876
 * error code if not and -1 if an internal error occured.
 
16877
 */
 
16878
static int
 
16879
xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
 
16880
                                    xmlSchemaParticlePtr r,
 
16881
                                    xmlSchemaParticlePtr b,
 
16882
                                    int isAnyTypeBase)
 
16883
{
 
16884
    /* TODO: Error codes (rcase-NSSubset). */
 
16885
    /*
 
16886
    * SPEC (1) "R's occurrence range is a valid restriction of B's
 
16887
    * occurrence range as defined by Occurrence Range OK (ļæ½3.9.6)."
 
16888
    */
 
16889
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
 
16890
            b->minOccurs, b->maxOccurs))
 
16891
        return (1);
 
16892
    /*
 
16893
    * SPEC (2) "R's {namespace constraint} must be an intensional subset
 
16894
    * of B's {namespace constraint} as defined by Wildcard Subset (ļæ½3.10.6)."
 
16895
    */
 
16896
    if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
 
16897
        (xmlSchemaWildcardPtr) b->children))
 
16898
        return (1);
 
16899
    /*
 
16900
    * SPEC (3) "Unless B is the content model wildcard of the ļæ½ur-type
 
16901
    * definitionļæ½, R's {process contents} must be identical to or stronger
 
16902
    * than B's {process contents}, where strict is stronger than lax is
 
16903
    * stronger than skip."
 
16904
    */
 
16905
    if (! isAnyTypeBase) {
 
16906
        if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
 
16907
            ((xmlSchemaWildcardPtr) b->children)->processContents)
 
16908
            return (1);
 
16909
    }
 
16910
 
 
16911
    return (0);
 
16912
}
 
16913
 
 
16914
/**
 
16915
 * xmlSchemaCheckCOSParticleRestrict:
 
16916
 * @ctxt:  the schema parser context
 
16917
 * @type:  the complex type definition
 
16918
 *
 
16919
 * (3.9.6) Constraints on Particle Schema Components
 
16920
 * Schema Component Constraint:
 
16921
 * Particle Valid (Restriction) (cos-particle-restrict)
 
16922
 *
 
16923
 * STATUS: TODO
 
16924
 *
 
16925
 * Returns 0 if the constraints are satisfied, a positive
 
16926
 * error code if not and -1 if an internal error occured.
 
16927
 */
 
16928
static int
 
16929
xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
 
16930
                                  xmlSchemaParticlePtr r,
 
16931
                                  xmlSchemaParticlePtr b)
 
16932
{
 
16933
    int ret = 0;
 
16934
 
 
16935
    /*part = WXS_TYPE_PARTICLE(type);
 
16936
    basePart = WXS_TYPE_PARTICLE(base);
 
16937
    */
 
16938
 
 
16939
    TODO
 
16940
 
 
16941
    /*
 
16942
    * SPEC (1) "They are the same particle."
 
16943
    */
 
16944
    if (r == b)
 
16945
        return (0);
 
16946
 
 
16947
 
 
16948
    return (0);
 
16949
}
 
16950
 
 
16951
/**
 
16952
 * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
 
16953
 * @ctxt:  the schema parser context
 
16954
 * @r: the model group particle
 
16955
 * @b: the base wildcard particle
 
16956
 *
 
16957
 * (3.9.6) Constraints on Particle Schema Components
 
16958
 * Schema Component Constraint:
 
16959
 * Particle Derivation OK (All/Choice/Sequence:Any --
 
16960
 *                         NSRecurseCheckCardinality)
 
16961
 * (rcase-NSRecurseCheckCardinality)
 
16962
 *
 
16963
 * STATUS: TODO: subst-groups
 
16964
 *
 
16965
 * Returns 0 if the constraints are satisfied, a positive
 
16966
 * error code if not and -1 if an internal error occured.
 
16967
 */
 
16968
static int
 
16969
xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
 
16970
                                             xmlSchemaParticlePtr r,
 
16971
                                             xmlSchemaParticlePtr b)
 
16972
{
 
16973
    xmlSchemaParticlePtr part;
 
16974
    /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
 
16975
    if ((r->children == NULL) || (r->children->children == NULL))
 
16976
        return (-1);
 
16977
    /*
 
16978
    * SPEC "For a group particle to be a ļæ½valid restrictionļæ½ of a
 
16979
    * wildcard particle..."
 
16980
    *
 
16981
    * SPEC (1) "Every member of the {particles} of the group is a ļæ½valid
 
16982
    * restrictionļæ½ of the wildcard as defined by
 
16983
    * Particle Valid (Restriction) (ļæ½3.9.6)."
 
16984
    */
 
16985
    part = (xmlSchemaParticlePtr) r->children->children;
 
16986
    do {
 
16987
        if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
 
16988
            return (1);
 
16989
        part = (xmlSchemaParticlePtr) part->next;
 
16990
    } while (part != NULL);
 
16991
    /*
 
16992
    * SPEC (2) "The effective total range of the group [...] is a
 
16993
    * valid restriction of B's occurrence range as defined by
 
16994
    * Occurrence Range OK (ļæ½3.9.6)."
 
16995
    */
 
16996
    if (xmlSchemaCheckParticleRangeOK(
 
16997
            xmlSchemaGetParticleTotalRangeMin(r),
 
16998
            xmlSchemaGetParticleTotalRangeMax(r),
 
16999
            b->minOccurs, b->maxOccurs) != 0)
 
17000
        return (1);
 
17001
    return (0);
 
17002
}
 
17003
 
 
17004
/**
 
17005
 * xmlSchemaCheckRCaseRecurse:
 
17006
 * @ctxt:  the schema parser context
 
17007
 * @r: the <all> or <sequence> model group particle
 
17008
 * @b: the base <all> or <sequence> model group particle
 
17009
 *
 
17010
 * (3.9.6) Constraints on Particle Schema Components
 
17011
 * Schema Component Constraint:
 
17012
 * Particle Derivation OK (All:All,Sequence:Sequence --
 
17013
                           Recurse)
 
17014
 * (rcase-Recurse)
 
17015
 *
 
17016
 * STATUS:  ?
 
17017
 * TODO: subst-groups
 
17018
 *
 
17019
 * Returns 0 if the constraints are satisfied, a positive
 
17020
 * error code if not and -1 if an internal error occured.
 
17021
 */
 
17022
static int
 
17023
xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
 
17024
                           xmlSchemaParticlePtr r,
 
17025
                           xmlSchemaParticlePtr b)
 
17026
{
 
17027
    /* xmlSchemaParticlePtr part; */
 
17028
    /* TODO: Error codes (rcase-Recurse). */
 
17029
    if ((r->children == NULL) || (b->children == NULL) ||
 
17030
        (r->children->type != b->children->type))
 
17031
        return (-1);
 
17032
    /*
 
17033
    * SPEC "For an all or sequence group particle to be a ļæ½valid
 
17034
    * restrictionļæ½ of another group particle with the same {compositor}..."
 
17035
    *
 
17036
    * SPEC (1) "R's occurrence range is a valid restriction of B's
 
17037
    * occurrence range as defined by Occurrence Range OK (ļæ½3.9.6)."
 
17038
    */
 
17039
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
 
17040
            b->minOccurs, b->maxOccurs))
 
17041
        return (1);
 
17042
 
 
17043
 
 
17044
    return (0);
 
17045
}
 
17046
 
 
17047
#endif
 
17048
 
 
17049
#define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
 
17050
    xmlSchemaPCustomErrExt(pctxt,      \
 
17051
        XML_SCHEMAP_INVALID_FACET_VALUE, \
 
17052
        WXS_BASIC_CAST fac1, fac1->node, \
 
17053
        "It is an error for both '%s' and '%s' to be specified on the "\
 
17054
        "same type definition", \
 
17055
        BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
 
17056
        BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
 
17057
 
 
17058
#define FACET_RESTR_ERR(fac1, msg) \
 
17059
    xmlSchemaPCustomErr(pctxt,      \
 
17060
        XML_SCHEMAP_INVALID_FACET_VALUE, \
 
17061
        WXS_BASIC_CAST fac1, fac1->node, \
 
17062
        msg, NULL);
 
17063
 
 
17064
#define FACET_RESTR_FIXED_ERR(fac) \
 
17065
    xmlSchemaPCustomErr(pctxt, \
 
17066
        XML_SCHEMAP_INVALID_FACET_VALUE, \
 
17067
        WXS_BASIC_CAST fac, fac->node, \
 
17068
        "The base type's facet is 'fixed', thus the value must not " \
 
17069
        "differ", NULL);
 
17070
 
 
17071
static void
 
17072
xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
 
17073
                        xmlSchemaFacetPtr facet1,
 
17074
                        xmlSchemaFacetPtr facet2,
 
17075
                        int lessGreater,
 
17076
                        int orEqual,
 
17077
                        int ofBase)
 
17078
{
 
17079
    xmlChar *msg = NULL;
 
17080
 
 
17081
    msg = xmlStrdup(BAD_CAST "'");
 
17082
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
 
17083
    msg = xmlStrcat(msg, BAD_CAST "' has to be");
 
17084
    if (lessGreater == 0)
 
17085
        msg = xmlStrcat(msg, BAD_CAST " equal to");
 
17086
    if (lessGreater == 1)
 
17087
        msg = xmlStrcat(msg, BAD_CAST " greater than");
 
17088
    else
 
17089
        msg = xmlStrcat(msg, BAD_CAST " less than");
 
17090
 
 
17091
    if (orEqual)
 
17092
        msg = xmlStrcat(msg, BAD_CAST " or equal to");
 
17093
    msg = xmlStrcat(msg, BAD_CAST " '");
 
17094
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
 
17095
    if (ofBase)
 
17096
        msg = xmlStrcat(msg, BAD_CAST "' of the base type");
 
17097
    else
 
17098
        msg = xmlStrcat(msg, BAD_CAST "'");
 
17099
 
 
17100
    xmlSchemaPCustomErr(pctxt,
 
17101
        XML_SCHEMAP_INVALID_FACET_VALUE,
 
17102
        WXS_BASIC_CAST facet1, NULL,
 
17103
        (const char *) msg, NULL);
 
17104
 
 
17105
    if (msg != NULL)
 
17106
        xmlFree(msg);
 
17107
}
 
17108
 
 
17109
/*
 
17110
* xmlSchemaDeriveAndValidateFacets:
 
17111
*
 
17112
* Schema Component Constraint: Simple Type Restriction (Facets)
 
17113
* (st-restrict-facets)
 
17114
*/
 
17115
static int
 
17116
xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
 
17117
                                 xmlSchemaTypePtr type)
 
17118
{
 
17119
    xmlSchemaTypePtr base = type->baseType;
 
17120
    xmlSchemaFacetLinkPtr link, cur, last = NULL;
 
17121
    xmlSchemaFacetPtr facet, bfacet,
 
17122
        flength = NULL, ftotdig = NULL, ffracdig = NULL,
 
17123
        fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
 
17124
        fmininc = NULL, fmaxinc = NULL,
 
17125
        fminexc = NULL, fmaxexc = NULL,
 
17126
        bflength = NULL, bftotdig = NULL, bffracdig = NULL,
 
17127
        bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
 
17128
        bfmininc = NULL, bfmaxinc = NULL,
 
17129
        bfminexc = NULL, bfmaxexc = NULL;
 
17130
    int res; /* err = 0, fixedErr; */
 
17131
 
 
17132
    /*
 
17133
    * SPEC st-restrict-facets 1:
 
17134
    * "The {variety} of R is the same as that of B."    
 
17135
    */
 
17136
    /*
 
17137
    * SPEC st-restrict-facets 2:
 
17138
    * "If {variety} is atomic, the {primitive type definition}
 
17139
    * of R is the same as that of B."
 
17140
    *
 
17141
    * NOTE: we leave 1 & 2 out for now, since this will be
 
17142
    * satisfied by the derivation process.
 
17143
    * CONSTRUCTION TODO: Maybe needed if using a construction API.
 
17144
    */
 
17145
    /*
 
17146
    * SPEC st-restrict-facets 3:
 
17147
    * "The {facets} of R are the union of S and the {facets}
 
17148
    * of B, eliminating duplicates. To eliminate duplicates,
 
17149
    * when a facet of the same kind occurs in both S and the
 
17150
    * {facets} of B, the one in the {facets} of B is not
 
17151
    * included, with the exception of enumeration and pattern
 
17152
    * facets, for which multiple occurrences with distinct values
 
17153
    * are allowed."
 
17154
    */
 
17155
 
 
17156
    if ((type->facetSet == NULL) && (base->facetSet == NULL))
 
17157
        return (0);
 
17158
 
 
17159
    last = type->facetSet;
 
17160
    if (last != NULL)
 
17161
        while (last->next != NULL)
 
17162
            last = last->next;
 
17163
 
 
17164
    for (cur = type->facetSet; cur != NULL; cur = cur->next) {
 
17165
        facet = cur->facet;
 
17166
        switch (facet->type) {
 
17167
            case XML_SCHEMA_FACET_LENGTH:
 
17168
                flength = facet; break;
 
17169
            case XML_SCHEMA_FACET_MINLENGTH:
 
17170
                fminlen = facet; break;
 
17171
            case XML_SCHEMA_FACET_MININCLUSIVE:
 
17172
                fmininc = facet; break;
 
17173
            case XML_SCHEMA_FACET_MINEXCLUSIVE:
 
17174
                fminexc = facet; break;
 
17175
            case XML_SCHEMA_FACET_MAXLENGTH:
 
17176
                fmaxlen = facet; break;
 
17177
            case XML_SCHEMA_FACET_MAXINCLUSIVE:
 
17178
                fmaxinc = facet; break;
 
17179
            case XML_SCHEMA_FACET_MAXEXCLUSIVE:
 
17180
                fmaxexc = facet; break;
 
17181
            case XML_SCHEMA_FACET_TOTALDIGITS:
 
17182
                ftotdig = facet; break;
 
17183
            case XML_SCHEMA_FACET_FRACTIONDIGITS:
 
17184
                ffracdig = facet; break;
 
17185
            default:
 
17186
                break;
 
17187
        }
 
17188
    }
 
17189
    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
 
17190
        facet = cur->facet;
 
17191
        switch (facet->type) {
 
17192
            case XML_SCHEMA_FACET_LENGTH:
 
17193
                bflength = facet; break;
 
17194
            case XML_SCHEMA_FACET_MINLENGTH:
 
17195
                bfminlen = facet; break;
 
17196
            case XML_SCHEMA_FACET_MININCLUSIVE:
 
17197
                bfmininc = facet; break;
 
17198
            case XML_SCHEMA_FACET_MINEXCLUSIVE:
 
17199
                bfminexc = facet; break;
 
17200
            case XML_SCHEMA_FACET_MAXLENGTH:
 
17201
                bfmaxlen = facet; break;
 
17202
            case XML_SCHEMA_FACET_MAXINCLUSIVE:
 
17203
                bfmaxinc = facet; break;
 
17204
            case XML_SCHEMA_FACET_MAXEXCLUSIVE:
 
17205
                bfmaxexc = facet; break;
 
17206
            case XML_SCHEMA_FACET_TOTALDIGITS:
 
17207
                bftotdig = facet; break;
 
17208
            case XML_SCHEMA_FACET_FRACTIONDIGITS:
 
17209
                bffracdig = facet; break;
 
17210
            default:
 
17211
                break;
 
17212
        }
 
17213
    }
 
17214
    /*
 
17215
    * length and minLength or maxLength (2.2) + (3.2)
 
17216
    */
 
17217
    if (flength && (fminlen || fmaxlen)) {
 
17218
        FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
 
17219
            "either of 'minLength' or 'maxLength' to be specified on "
 
17220
            "the same type definition")
 
17221
    }
 
17222
    /*
 
17223
    * Mutual exclusions in the same derivation step.
 
17224
    */
 
17225
    if ((fmaxinc) && (fmaxexc)) {
 
17226
        /*
 
17227
        * SCC "maxInclusive and maxExclusive"
 
17228
        */
 
17229
        FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
 
17230
    }
 
17231
    if ((fmininc) && (fminexc)) {
 
17232
        /*
 
17233
        * SCC "minInclusive and minExclusive"
 
17234
        */
 
17235
        FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
 
17236
    }
 
17237
 
 
17238
    if (flength && bflength) {
 
17239
        /*
 
17240
        * SCC "length valid restriction"
 
17241
        * The values have to be equal.
 
17242
        */
 
17243
        res = xmlSchemaCompareValues(flength->val, bflength->val);
 
17244
        if (res == -2)
 
17245
            goto internal_error;
 
17246
        if (res != 0)
 
17247
            xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
 
17248
        if ((res != 0) && (bflength->fixed)) {
 
17249
            FACET_RESTR_FIXED_ERR(flength)
 
17250
        }
 
17251
 
 
17252
    }
 
17253
    if (fminlen && bfminlen) {
 
17254
        /*
 
17255
        * SCC "minLength valid restriction"
 
17256
        * minLength >= BASE minLength
 
17257
        */
 
17258
        res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
 
17259
        if (res == -2)
 
17260
            goto internal_error;
 
17261
        if (res == -1)
 
17262
            xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
 
17263
        if ((res != 0) && (bfminlen->fixed)) {
 
17264
            FACET_RESTR_FIXED_ERR(fminlen)
 
17265
        }
 
17266
    }
 
17267
    if (fmaxlen && bfmaxlen) {
 
17268
        /*
 
17269
        * SCC "maxLength valid restriction"
 
17270
        * maxLength <= BASE minLength
 
17271
        */
 
17272
        res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
 
17273
        if (res == -2)
 
17274
            goto internal_error;
 
17275
        if (res == 1)
 
17276
            xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
 
17277
        if ((res != 0) && (bfmaxlen->fixed)) {
 
17278
            FACET_RESTR_FIXED_ERR(fmaxlen)
 
17279
        }
 
17280
    }
 
17281
    /*
 
17282
    * SCC "length and minLength or maxLength"
 
17283
    */
 
17284
    if (! flength)
 
17285
        flength = bflength;
 
17286
    if (flength) {
 
17287
        if (! fminlen)
 
17288
            flength = bflength;
 
17289
        if (fminlen) {
 
17290
            /* (1.1) length >= minLength */
 
17291
            res = xmlSchemaCompareValues(flength->val, fminlen->val);
 
17292
            if (res == -2)
 
17293
                goto internal_error;
 
17294
            if (res == -1)
 
17295
                xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
 
17296
        }
 
17297
        if (! fmaxlen)
 
17298
            fmaxlen = bfmaxlen;
 
17299
        if (fmaxlen) {
 
17300
            /* (2.1) length <= maxLength */
 
17301
            res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
 
17302
            if (res == -2)
 
17303
                goto internal_error;
 
17304
            if (res == 1)
 
17305
                xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
 
17306
        }
 
17307
    }
 
17308
    if (fmaxinc) {
 
17309
        /*
 
17310
        * "maxInclusive"
 
17311
        */
 
17312
        if (fmininc) {
 
17313
            /* SCC "maxInclusive >= minInclusive" */
 
17314
            res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
 
17315
            if (res == -2)
 
17316
                goto internal_error;
 
17317
            if (res == -1) {
 
17318
                xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
 
17319
            }
 
17320
        }
 
17321
        /*
 
17322
        * SCC "maxInclusive valid restriction"
 
17323
        */
 
17324
        if (bfmaxinc) {
 
17325
            /* maxInclusive <= BASE maxInclusive */
 
17326
            res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
 
17327
            if (res == -2)
 
17328
                goto internal_error;
 
17329
            if (res == 1)
 
17330
                xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
 
17331
            if ((res != 0) && (bfmaxinc->fixed)) {
 
17332
                FACET_RESTR_FIXED_ERR(fmaxinc)
 
17333
            }
 
17334
        }
 
17335
        if (bfmaxexc) {
 
17336
            /* maxInclusive < BASE maxExclusive */
 
17337
            res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
 
17338
            if (res == -2)
 
17339
                goto internal_error;
 
17340
            if (res != -1) {
 
17341
                xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
 
17342
            }
 
17343
        }
 
17344
        if (bfmininc) {
 
17345
            /* maxInclusive >= BASE minInclusive */
 
17346
            res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
 
17347
            if (res == -2)
 
17348
                goto internal_error;
 
17349
            if (res == -1) {
 
17350
                xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
 
17351
            }
 
17352
        }
 
17353
        if (bfminexc) {
 
17354
            /* maxInclusive > BASE minExclusive */
 
17355
            res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
 
17356
            if (res == -2)
 
17357
                goto internal_error;
 
17358
            if (res != 1) {
 
17359
                xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
 
17360
            }
 
17361
        }
 
17362
    }
 
17363
    if (fmaxexc) {
 
17364
        /*
 
17365
        * "maxExclusive >= minExclusive"
 
17366
        */
 
17367
        if (fminexc) {
 
17368
            res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
 
17369
            if (res == -2)
 
17370
                goto internal_error;
 
17371
            if (res == -1) {
 
17372
                xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
 
17373
            }
 
17374
        }
 
17375
        /*
 
17376
        * "maxExclusive valid restriction"
 
17377
        */
 
17378
        if (bfmaxexc) {
 
17379
            /* maxExclusive <= BASE maxExclusive */
 
17380
            res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
 
17381
            if (res == -2)
 
17382
                goto internal_error;
 
17383
            if (res == 1) {
 
17384
                xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
 
17385
            }
 
17386
            if ((res != 0) && (bfmaxexc->fixed)) {
 
17387
                FACET_RESTR_FIXED_ERR(fmaxexc)
 
17388
            }
 
17389
        }
 
17390
        if (bfmaxinc) {
 
17391
            /* maxExclusive <= BASE maxInclusive */
 
17392
            res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
 
17393
            if (res == -2)
 
17394
                goto internal_error;
 
17395
            if (res == 1) {
 
17396
                xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
 
17397
            }
 
17398
        }
 
17399
        if (bfmininc) {
 
17400
            /* maxExclusive > BASE minInclusive */
 
17401
            res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
 
17402
            if (res == -2)
 
17403
                goto internal_error;
 
17404
            if (res != 1) {
 
17405
                xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
 
17406
            }
 
17407
        }
 
17408
        if (bfminexc) {
 
17409
            /* maxExclusive > BASE minExclusive */
 
17410
            res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
 
17411
            if (res == -2)
 
17412
                goto internal_error;
 
17413
            if (res != 1) {
 
17414
                xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
 
17415
            }
 
17416
        }
 
17417
    }
 
17418
    if (fminexc) {
 
17419
        /*
 
17420
        * "minExclusive < maxInclusive"
 
17421
        */
 
17422
        if (fmaxinc) {
 
17423
            res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
 
17424
            if (res == -2)
 
17425
                goto internal_error;
 
17426
            if (res != -1) {
 
17427
                xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
 
17428
            }
 
17429
        }
 
17430
        /*
 
17431
        * "minExclusive valid restriction"
 
17432
        */
 
17433
        if (bfminexc) {
 
17434
            /* minExclusive >= BASE minExclusive */
 
17435
            res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
 
17436
            if (res == -2)
 
17437
                goto internal_error;
 
17438
            if (res == -1) {
 
17439
                xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
 
17440
            }
 
17441
            if ((res != 0) && (bfminexc->fixed)) {
 
17442
                FACET_RESTR_FIXED_ERR(fminexc)
 
17443
            }
 
17444
        }
 
17445
        if (bfmaxinc) {
 
17446
            /* minExclusive <= BASE maxInclusive */
 
17447
            res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
 
17448
            if (res == -2)
 
17449
                goto internal_error;
 
17450
            if (res == 1) {
 
17451
                xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
 
17452
            }
 
17453
        }
 
17454
        if (bfmininc) {
 
17455
            /* minExclusive >= BASE minInclusive */
 
17456
            res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
 
17457
            if (res == -2)
 
17458
                goto internal_error;
 
17459
            if (res == -1) {
 
17460
                xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
 
17461
            }
 
17462
        }
 
17463
        if (bfmaxexc) {
 
17464
            /* minExclusive < BASE maxExclusive */
 
17465
            res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
 
17466
            if (res == -2)
 
17467
                goto internal_error;
 
17468
            if (res != -1) {
 
17469
                xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
 
17470
            }
 
17471
        }
 
17472
    }
 
17473
    if (fmininc) {
 
17474
        /*
 
17475
        * "minInclusive < maxExclusive"
 
17476
        */
 
17477
        if (fmaxexc) {
 
17478
            res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
 
17479
            if (res == -2)
 
17480
                goto internal_error;
 
17481
            if (res != -1) {
 
17482
                xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
 
17483
            }
 
17484
        }
 
17485
        /*
 
17486
        * "minExclusive valid restriction"
 
17487
        */
 
17488
        if (bfmininc) {
 
17489
            /* minInclusive >= BASE minInclusive */
 
17490
            res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
 
17491
            if (res == -2)
 
17492
                goto internal_error;
 
17493
            if (res == -1) {
 
17494
                xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
 
17495
            }
 
17496
            if ((res != 0) && (bfmininc->fixed)) {
 
17497
                FACET_RESTR_FIXED_ERR(fmininc)
 
17498
            }
 
17499
        }
 
17500
        if (bfmaxinc) {
 
17501
            /* minInclusive <= BASE maxInclusive */
 
17502
            res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
 
17503
            if (res == -2)
 
17504
                goto internal_error;
 
17505
            if (res == 1) {
 
17506
                xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
 
17507
            }
 
17508
        }
 
17509
        if (bfminexc) {
 
17510
            /* minInclusive > BASE minExclusive */
 
17511
            res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
 
17512
            if (res == -2)
 
17513
                goto internal_error;
 
17514
            if (res != 1)
 
17515
                xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
 
17516
        }
 
17517
        if (bfmaxexc) {
 
17518
            /* minInclusive < BASE maxExclusive */
 
17519
            res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
 
17520
            if (res == -2)
 
17521
                goto internal_error;
 
17522
            if (res != -1)
 
17523
                xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
 
17524
        }
 
17525
    }
 
17526
    if (ftotdig && bftotdig) {
 
17527
        /*
 
17528
        * SCC " totalDigits valid restriction"
 
17529
        * totalDigits <= BASE totalDigits
 
17530
        */
 
17531
        res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
 
17532
        if (res == -2)
 
17533
            goto internal_error;
 
17534
        if (res == 1)
 
17535
            xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
 
17536
            -1, 1, 1);
 
17537
        if ((res != 0) && (bftotdig->fixed)) {
 
17538
            FACET_RESTR_FIXED_ERR(ftotdig)
 
17539
        }
 
17540
    }
 
17541
    if (ffracdig && bffracdig) {
 
17542
        /*
 
17543
        * SCC  "fractionDigits valid restriction"
 
17544
        * fractionDigits <= BASE fractionDigits
 
17545
        */
 
17546
        res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
 
17547
        if (res == -2)
 
17548
            goto internal_error;
 
17549
        if (res == 1)
 
17550
            xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
 
17551
            -1, 1, 1);
 
17552
        if ((res != 0) && (bffracdig->fixed)) {
 
17553
            FACET_RESTR_FIXED_ERR(ffracdig)
 
17554
        }
 
17555
    }
 
17556
    /*
 
17557
    * SCC "fractionDigits less than or equal to totalDigits"
 
17558
    */
 
17559
    if (! ftotdig)
 
17560
        ftotdig = bftotdig;
 
17561
    if (! ffracdig)
 
17562
        ffracdig = bffracdig;
 
17563
    if (ftotdig && ffracdig) {
 
17564
        res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
 
17565
        if (res == -2)
 
17566
            goto internal_error;
 
17567
        if (res == 1)
 
17568
            xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
 
17569
                -1, 1, 0);
 
17570
    }
 
17571
    /*
 
17572
    * *Enumerations* won' be added here, since only the first set
 
17573
    * of enumerations in the ancestor-or-self axis is used
 
17574
    * for validation, plus we need to use the base type of those
 
17575
    * enumerations for whitespace.
 
17576
    *
 
17577
    * *Patterns*: won't be add here, since they are ORed at
 
17578
    * type level and ANDed at ancestor level. This will
 
17579
    * happed during validation by walking the base axis
 
17580
    * of the type.
 
17581
    */
 
17582
    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
 
17583
        bfacet = cur->facet;
 
17584
        /*
 
17585
        * Special handling of enumerations and patterns.
 
17586
        * TODO: hmm, they should not appear in the set, so remove this.
 
17587
        */
 
17588
        if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
 
17589
            (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
 
17590
            continue;
 
17591
        /*
 
17592
        * Search for a duplicate facet in the current type.
 
17593
        */
 
17594
        link = type->facetSet;
 
17595
        /* err = 0; */
 
17596
        /* fixedErr = 0; */
 
17597
        while (link != NULL) {
 
17598
            facet = link->facet;
 
17599
            if (facet->type == bfacet->type) {
 
17600
                switch (facet->type) {
 
17601
                    case XML_SCHEMA_FACET_WHITESPACE:
 
17602
                        /*
 
17603
                        * The whitespace must be stronger.
 
17604
                        */
 
17605
                        if (facet->whitespace < bfacet->whitespace) {
 
17606
                            FACET_RESTR_ERR(flength,
 
17607
                                "The 'whitespace' value has to be equal to "
 
17608
                                "or stronger than the 'whitespace' value of "
 
17609
                                "the base type")
 
17610
                        }
 
17611
                        if ((bfacet->fixed) &&
 
17612
                            (facet->whitespace != bfacet->whitespace)) {
 
17613
                            FACET_RESTR_FIXED_ERR(facet)
 
17614
                        }
 
17615
                        break;
 
17616
                    default:
 
17617
                        break;
 
17618
                }
 
17619
                /* Duplicate found. */
 
17620
                break;
 
17621
            }
 
17622
            link = link->next;
 
17623
        }
 
17624
        /*
 
17625
        * If no duplicate was found: add the base types's facet
 
17626
        * to the set.
 
17627
        */
 
17628
        if (link == NULL) {
 
17629
            link = (xmlSchemaFacetLinkPtr)
 
17630
                xmlMalloc(sizeof(xmlSchemaFacetLink));
 
17631
            if (link == NULL) {
 
17632
                xmlSchemaPErrMemory(pctxt,
 
17633
                    "deriving facets, creating a facet link", NULL);
 
17634
                return (-1);
 
17635
            }
 
17636
            link->facet = cur->facet;
 
17637
            link->next = NULL;
 
17638
            if (last == NULL)
 
17639
                type->facetSet = link;
 
17640
            else
 
17641
                last->next = link;
 
17642
            last = link;
 
17643
        }
 
17644
 
 
17645
    }
 
17646
 
 
17647
    return (0);
 
17648
internal_error:
 
17649
    PERROR_INT("xmlSchemaDeriveAndValidateFacets",
 
17650
        "an error occured");
 
17651
    return (-1);
 
17652
}
 
17653
 
 
17654
static int
 
17655
xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
 
17656
                                             xmlSchemaTypePtr type)
 
17657
{
 
17658
    xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
 
17659
    /*
 
17660
    * The actual value is then formed by replacing any union type
 
17661
    * definition in the ļæ½explicit membersļæ½ with the members of their
 
17662
    * {member type definitions}, in order.
 
17663
    *
 
17664
    * TODO: There's a bug entry at
 
17665
    * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
 
17666
    * which indicates that we'll keep the union types the future.
 
17667
    */
 
17668
    link = type->memberTypes;
 
17669
    while (link != NULL) {
 
17670
 
 
17671
        if (WXS_IS_TYPE_NOT_FIXED(link->type))
 
17672
            xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
 
17673
 
 
17674
        if (WXS_IS_UNION(link->type)) {
 
17675
            subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
 
17676
            if (subLink != NULL) {
 
17677
                link->type = subLink->type;
 
17678
                if (subLink->next != NULL) {
 
17679
                    lastLink = link->next;
 
17680
                    subLink = subLink->next;
 
17681
                    prevLink = link;
 
17682
                    while (subLink != NULL) {
 
17683
                        newLink = (xmlSchemaTypeLinkPtr)
 
17684
                            xmlMalloc(sizeof(xmlSchemaTypeLink));
 
17685
                        if (newLink == NULL) {
 
17686
                            xmlSchemaPErrMemory(pctxt, "allocating a type link",
 
17687
                                NULL);
 
17688
                            return (-1);
 
17689
                        }
 
17690
                        newLink->type = subLink->type;
 
17691
                        prevLink->next = newLink;
 
17692
                        prevLink = newLink;
 
17693
                        newLink->next = lastLink;
 
17694
 
 
17695
                        subLink = subLink->next;
 
17696
                    }
 
17697
                }
 
17698
            }
 
17699
        }
 
17700
        link = link->next;
 
17701
    }
 
17702
    return (0);
 
17703
}
 
17704
 
 
17705
static void
 
17706
xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
 
17707
{       
 
17708
    int has = 0, needVal = 0, normVal = 0;
 
17709
 
 
17710
    has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
 
17711
    if (has) {
 
17712
        needVal = (type->baseType->flags &
 
17713
            XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
 
17714
        normVal = (type->baseType->flags &
 
17715
            XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
 
17716
    }
 
17717
    if (type->facets != NULL) {
 
17718
        xmlSchemaFacetPtr fac;
 
17719
        
 
17720
        for (fac = type->facets; fac != NULL; fac = fac->next) {
 
17721
            switch (fac->type) {
 
17722
                case XML_SCHEMA_FACET_WHITESPACE:
 
17723
                    break;
 
17724
                case XML_SCHEMA_FACET_PATTERN:
 
17725
                    normVal = 1;
 
17726
                    has = 1;
 
17727
                    break;
 
17728
                case XML_SCHEMA_FACET_ENUMERATION:
 
17729
                    needVal = 1;
 
17730
                    normVal = 1;
 
17731
                    has = 1;
 
17732
                    break;
 
17733
                default:
 
17734
                    has = 1;
 
17735
                    break;
 
17736
            }
 
17737
        }       
 
17738
    }
 
17739
    if (normVal)
 
17740
        type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
 
17741
    if (needVal)
 
17742
        type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
 
17743
    if (has)
 
17744
        type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
 
17745
 
 
17746
    if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
 
17747
        xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
 
17748
        /*
 
17749
        * OPTIMIZE VAL TODO: Some facets need a computed value.
 
17750
        */
 
17751
        if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
 
17752
            (prim->builtInType != XML_SCHEMAS_STRING)) {
 
17753
            type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
 
17754
        }       
 
17755
    }       
 
17756
}
 
17757
 
 
17758
static int
 
17759
xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
 
17760
{
 
17761
    
 
17762
    
 
17763
    /*
 
17764
    * Evaluate the whitespace-facet value.
 
17765
    */    
 
17766
    if (WXS_IS_LIST(type)) {
 
17767
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
 
17768
        return (0);
 
17769
    } else if (WXS_IS_UNION(type))
 
17770
        return (0);
 
17771
    
 
17772
    if (type->facetSet != NULL) {
 
17773
        xmlSchemaFacetLinkPtr lin;
 
17774
 
 
17775
        for (lin = type->facetSet; lin != NULL; lin = lin->next) {
 
17776
            if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
 
17777
                switch (lin->facet->whitespace) {
 
17778
                case XML_SCHEMAS_FACET_PRESERVE:
 
17779
                    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
 
17780
                    break;
 
17781
                case XML_SCHEMAS_FACET_REPLACE:
 
17782
                    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
 
17783
                    break;
 
17784
                case XML_SCHEMAS_FACET_COLLAPSE:
 
17785
                    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
 
17786
                    break;
 
17787
                default:
 
17788
                    return (-1);
 
17789
                }
 
17790
                return (0);
 
17791
            }
 
17792
        }
 
17793
    }
 
17794
    /*
 
17795
    * For all ļæ½atomicļæ½ datatypes other than string (and types ļæ½derivedļæ½ 
 
17796
    * by ļæ½restrictionļæ½ from it) the value of whiteSpace is fixed to 
 
17797
    * collapse
 
17798
    */
 
17799
    {
 
17800
        xmlSchemaTypePtr anc;
 
17801
 
 
17802
        for (anc = type->baseType; anc != NULL && 
 
17803
                anc->builtInType != XML_SCHEMAS_ANYTYPE;
 
17804
                anc = anc->baseType) {
 
17805
 
 
17806
            if (anc->type == XML_SCHEMA_TYPE_BASIC) {
 
17807
                if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {           
 
17808
                    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
 
17809
 
 
17810
                } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
 
17811
                    (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {              
 
17812
                    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
 
17813
 
 
17814
                } else
 
17815
                    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
 
17816
                break;
 
17817
            }
 
17818
        }
 
17819
    }
 
17820
    return (0);
 
17821
}
 
17822
 
 
17823
static int
 
17824
xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
 
17825
                          xmlSchemaTypePtr type)
 
17826
{
 
17827
    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
 
17828
        return(0);
 
17829
    if (! WXS_IS_TYPE_NOT_FIXED_1(type))
 
17830
        return(0);
 
17831
    type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
 
17832
 
 
17833
    if (WXS_IS_LIST(type)) {
 
17834
        /*
 
17835
        * Corresponds to <simpleType><list>...
 
17836
        */
 
17837
        if (type->subtypes == NULL) {
 
17838
            /*
 
17839
            * This one is really needed, so get out.
 
17840
            */
 
17841
            PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
 
17842
                "list type has no item-type assigned");
 
17843
            return(-1);
 
17844
        }
 
17845
    } else if (WXS_IS_UNION(type)) {
 
17846
        /*
 
17847
        * Corresponds to <simpleType><union>...
 
17848
        */      
 
17849
        if (type->memberTypes == NULL) {
 
17850
            /*
 
17851
            * This one is really needed, so get out.
 
17852
            */
 
17853
            PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
 
17854
                "union type has no member-types assigned");
 
17855
            return(-1);
 
17856
        }           
 
17857
    } else {    
 
17858
        /*
 
17859
        * Corresponds to <simpleType><restriction>...
 
17860
        */
 
17861
        if (type->baseType == NULL) {
 
17862
            PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
 
17863
                "type has no base-type assigned");
 
17864
            return(-1);
 
17865
        }
 
17866
        if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
 
17867
            if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
 
17868
                return(-1);
 
17869
        /*
 
17870
        * Variety
 
17871
        * If the <restriction> alternative is chosen, then the
 
17872
        * {variety} of the {base type definition}.
 
17873
        */
 
17874
        if (WXS_IS_ATOMIC(type->baseType))
 
17875
            type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
 
17876
        else if (WXS_IS_LIST(type->baseType)) {
 
17877
            type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
 
17878
            /*
 
17879
            * Inherit the itemType.
 
17880
            */
 
17881
            type->subtypes = type->baseType->subtypes;
 
17882
        } else if (WXS_IS_UNION(type->baseType)) {
 
17883
            type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
 
17884
            /*
 
17885
            * NOTE that we won't assign the memberTypes of the base,
 
17886
            * since this will make trouble when freeing them; we will
 
17887
            * use a lookup function to access them instead.
 
17888
            */
 
17889
        }
 
17890
    }
 
17891
    return(0);
 
17892
}
 
17893
 
 
17894
#ifdef DEBUG_TYPE
 
17895
static void
 
17896
xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
 
17897
                       xmlSchemaTypePtr type)
 
17898
{
 
17899
    if (type->node != NULL) {
 
17900
        xmlGenericError(xmlGenericErrorContext,
 
17901
                        "Type of %s : %s:%d :", name,
 
17902
                        type->node->doc->URL,
 
17903
                        xmlGetLineNo(type->node));
 
17904
    } else {
 
17905
        xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
 
17906
    }
 
17907
    if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
 
17908
        switch (type->contentType) {
 
17909
            case XML_SCHEMA_CONTENT_SIMPLE:
 
17910
                xmlGenericError(xmlGenericErrorContext, "simple\n");
 
17911
                break;
 
17912
            case XML_SCHEMA_CONTENT_ELEMENTS:
 
17913
                xmlGenericError(xmlGenericErrorContext, "elements\n");
 
17914
                break;
 
17915
            case XML_SCHEMA_CONTENT_UNKNOWN:
 
17916
                xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
 
17917
                break;
 
17918
            case XML_SCHEMA_CONTENT_EMPTY:
 
17919
                xmlGenericError(xmlGenericErrorContext, "empty\n");
 
17920
                break;
 
17921
            case XML_SCHEMA_CONTENT_MIXED:
 
17922
                if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
 
17923
                    type->subtypes))
 
17924
                    xmlGenericError(xmlGenericErrorContext,
 
17925
                        "mixed as emptiable particle\n");
 
17926
                else
 
17927
                    xmlGenericError(xmlGenericErrorContext, "mixed\n");
 
17928
                break;
 
17929
                /* Removed, since not used. */
 
17930
                /*
 
17931
                case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
 
17932
                xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
 
17933
                break;
 
17934
                */
 
17935
            case XML_SCHEMA_CONTENT_BASIC:
 
17936
                xmlGenericError(xmlGenericErrorContext, "basic\n");
 
17937
                break;
 
17938
            default:
 
17939
                xmlGenericError(xmlGenericErrorContext,
 
17940
                    "not registered !!!\n");
 
17941
                break;
 
17942
        }
 
17943
    }
 
17944
}
 
17945
#endif
 
17946
 
 
17947
/*
 
17948
* 3.14.6 Constraints on Simple Type Definition Schema Components
 
17949
*/
 
17950
static int
 
17951
xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
 
17952
                                 xmlSchemaTypePtr type)
 
17953
{
 
17954
    int res, olderrs = pctxt->nberrors;
 
17955
 
 
17956
    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
 
17957
        return(-1);
 
17958
 
 
17959
    if (! WXS_IS_TYPE_NOT_FIXED(type))
 
17960
        return(0);
 
17961
 
 
17962
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
 
17963
    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
 
17964
 
 
17965
    if (type->baseType == NULL) {
 
17966
        PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
 
17967
            "missing baseType");
 
17968
        goto exit_failure;
 
17969
    }
 
17970
    if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
 
17971
        xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
 
17972
    /* 
 
17973
    * If a member type of a union is a union itself, we need to substitute
 
17974
    * that member type for its member types.
 
17975
    * NOTE that this might change in WXS 1.1; i.e. we will keep the union
 
17976
    * types in WXS 1.1.
 
17977
    */
 
17978
    if ((type->memberTypes != NULL) &&
 
17979
        (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
 
17980
        return(-1);        
 
17981
    /*
 
17982
    * SPEC src-simple-type 1 
 
17983
    * "The corresponding simple type definition, if any, must satisfy
 
17984
    * the conditions set out in Constraints on Simple Type Definition
 
17985
    * Schema Components (ļæ½3.14.6)."
 
17986
    */
 
17987
    /*
 
17988
    * Schema Component Constraint: Simple Type Definition Properties Correct
 
17989
    * (st-props-correct)
 
17990
    */
 
17991
    res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
 
17992
    HFAILURE HERROR
 
17993
    /* 
 
17994
    * Schema Component Constraint: Derivation Valid (Restriction, Simple)
 
17995
    * (cos-st-restricts)
 
17996
    */
 
17997
    res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
 
17998
    HFAILURE HERROR
 
17999
    /*
 
18000
    * TODO: Removed the error report, since it got annoying to get an
 
18001
    * extra error report, if anything failed until now.
 
18002
    * Enable this if needed.
 
18003
    *
 
18004
    * xmlSchemaPErr(ctxt, type->node,
 
18005
    *    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
 
18006
    *    "Simple type '%s' does not satisfy the constraints "
 
18007
    *    "on simple type definitions.\n",
 
18008
    *    type->name, NULL);
 
18009
    */
 
18010
    /*
 
18011
    * Schema Component Constraint: Simple Type Restriction (Facets)
 
18012
    * (st-restrict-facets)
 
18013
    */
 
18014
    res = xmlSchemaCheckFacetValues(type, pctxt);
 
18015
    HFAILURE HERROR
 
18016
    if ((type->facetSet != NULL) ||
 
18017
        (type->baseType->facetSet != NULL)) {
 
18018
        res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
 
18019
        HFAILURE HERROR
 
18020
    }
 
18021
    /*
 
18022
    * Whitespace value.
 
18023
    */
 
18024
    res = xmlSchemaTypeFixupWhitespace(type);
 
18025
    HFAILURE HERROR
 
18026
    xmlSchemaTypeFixupOptimFacets(type);    
 
18027
 
 
18028
exit_error:
 
18029
#ifdef DEBUG_TYPE
 
18030
    xmlSchemaDebugFixedType(pctxt, type);
 
18031
#endif
 
18032
    if (olderrs != pctxt->nberrors)
 
18033
        return(pctxt->err);
 
18034
    return(0);
 
18035
 
 
18036
exit_failure:
 
18037
#ifdef DEBUG_TYPE
 
18038
    xmlSchemaDebugFixedType(pctxt, type);
 
18039
#endif
 
18040
    return(-1);
 
18041
}
 
18042
 
 
18043
static int
 
18044
xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
 
18045
                          xmlSchemaTypePtr type)
 
18046
{
 
18047
    int res = 0, olderrs = pctxt->nberrors;
 
18048
    xmlSchemaTypePtr baseType = type->baseType;
 
18049
 
 
18050
    if (! WXS_IS_TYPE_NOT_FIXED(type))
 
18051
        return(0);
 
18052
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
 
18053
    if (baseType == NULL) {
 
18054
        PERROR_INT("xmlSchemaFixupComplexType",
 
18055
            "missing baseType");
 
18056
        goto exit_failure;
 
18057
    }    
 
18058
    /*
 
18059
    * Fixup the base type.
 
18060
    */
 
18061
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
 
18062
        xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
 
18063
    if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
 
18064
        /*
 
18065
        * Skip fixup if the base type is invalid.
 
18066
        * TODO: Generate a warning!
 
18067
        */
 
18068
        return(0);
 
18069
    }   
 
18070
    /*
 
18071
    * This basically checks if the base type can be derived.
 
18072
    */
 
18073
    res = xmlSchemaCheckSRCCT(pctxt, type);
 
18074
    HFAILURE HERROR   
 
18075
    /*
 
18076
    * Fixup the content type.
 
18077
    */
 
18078
    if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
 
18079
        /*
 
18080
        * Corresponds to <complexType><simpleContent>...
 
18081
        */
 
18082
        if ((WXS_IS_COMPLEX(baseType)) &&
 
18083
            (baseType->contentTypeDef != NULL) &&
 
18084
            (WXS_IS_RESTRICTION(type))) {
 
18085
            xmlSchemaTypePtr contentBase, content;
 
18086
#ifdef ENABLE_NAMED_LOCALS
 
18087
            char buf[30];
 
18088
            const xmlChar *tmpname;
 
18089
#endif
 
18090
            /*
 
18091
            * SPEC (1) If <restriction> + base type is <complexType>,
 
18092
            * "whose own {content type} is a simple type..."
 
18093
            */
 
18094
            if (type->contentTypeDef != NULL) {
 
18095
                /*
 
18096
                * SPEC (1.1) "the simple type definition corresponding to the
 
18097
                * <simpleType> among the [children] of <restriction> if there
 
18098
                * is one;"
 
18099
                * Note that this "<simpleType> among the [children]" was put
 
18100
                * into ->contentTypeDef during parsing.
 
18101
                */
 
18102
                contentBase = type->contentTypeDef;
 
18103
                type->contentTypeDef = NULL;
 
18104
            } else {
 
18105
                /*
 
18106
                * (1.2) "...otherwise (<restriction> has no <simpleType>
 
18107
                * among its [children]), the simple type definition which
 
18108
                * is the {content type} of the ... base type."
 
18109
                */
 
18110
                contentBase = baseType->contentTypeDef;
 
18111
            }
 
18112
            /*
 
18113
            * SPEC
 
18114
            * "... a simple type definition which restricts the simple
 
18115
            * type definition identified in clause 1.1 or clause 1.2
 
18116
            * with a set of facet components"
 
18117
            *
 
18118
            * Create the anonymous simple type, which will be the content
 
18119
            * type of the complex type.
 
18120
            */
 
18121
#ifdef ENABLE_NAMED_LOCALS
 
18122
            snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
 
18123
            tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
 
18124
            content = xmlSchemaAddType(pctxt, pctxt->schema,
 
18125
                XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
 
18126
                type->node, 0);
 
18127
#else
 
18128
            content = xmlSchemaAddType(pctxt, pctxt->schema,
 
18129
                XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
 
18130
                type->node, 0);
 
18131
#endif
 
18132
            if (content == NULL)
 
18133
                goto exit_failure;
 
18134
            /*
 
18135
            * We will use the same node as for the <complexType>
 
18136
            * to have it somehow anchored in the schema doc.
 
18137
            */
 
18138
            content->type = XML_SCHEMA_TYPE_SIMPLE;
 
18139
            content->baseType = contentBase;
 
18140
            /*
 
18141
            * Move the facets, previously anchored on the
 
18142
            * complexType during parsing.
 
18143
            */
 
18144
            content->facets = type->facets;
 
18145
            type->facets = NULL;
 
18146
            content->facetSet = type->facetSet;
 
18147
            type->facetSet = NULL;
 
18148
            
 
18149
            type->contentTypeDef = content;
 
18150
            if (WXS_IS_TYPE_NOT_FIXED(contentBase))
 
18151
                xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
 
18152
            /*
 
18153
            * Fixup the newly created type. We don't need to check
 
18154
            * for circularity here.
 
18155
            */
 
18156
            res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
 
18157
            HFAILURE HERROR 
 
18158
            res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
 
18159
            HFAILURE HERROR 
 
18160
                
 
18161
        } else if ((WXS_IS_COMPLEX(baseType)) &&
 
18162
            (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
 
18163
            (WXS_IS_RESTRICTION(type))) {
 
18164
            /*
 
18165
            * SPEC (2) If <restriction> + base is a mixed <complexType> with
 
18166
            * an emptiable particle, then a simple type definition which
 
18167
            * restricts the <restriction>'s <simpleType> child.
 
18168
            */
 
18169
            if ((type->contentTypeDef == NULL) ||
 
18170
                (type->contentTypeDef->baseType == NULL)) {
 
18171
                /*
 
18172
                * TODO: Check if this ever happens.
 
18173
                */
 
18174
                xmlSchemaPCustomErr(pctxt,
 
18175
                    XML_SCHEMAP_INTERNAL,
 
18176
                    WXS_BASIC_CAST type, NULL,
 
18177
                    "Internal error: xmlSchemaTypeFixup, "
 
18178
                    "complex type '%s': the <simpleContent><restriction> "
 
18179
                    "is missing a <simpleType> child, but was not catched "
 
18180
                    "by xmlSchemaCheckSRCCT()", type->name);
 
18181
                goto exit_failure;
 
18182
            }
 
18183
        } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
 
18184
            /*
 
18185
            * SPEC (3) If <extension> + base is <complexType> with
 
18186
            * <simpleType> content, "...then the {content type} of that
 
18187
            * complex type definition"
 
18188
            */
 
18189
            if (baseType->contentTypeDef == NULL) {
 
18190
                /*
 
18191
                * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
 
18192
                * should have catched this already.
 
18193
                */
 
18194
                xmlSchemaPCustomErr(pctxt,
 
18195
                    XML_SCHEMAP_INTERNAL,
 
18196
                    WXS_BASIC_CAST type, NULL,
 
18197
                    "Internal error: xmlSchemaTypeFixup, "
 
18198
                    "complex type '%s': the <extension>ed base type is "
 
18199
                    "a complex type with no simple content type",
 
18200
                    type->name);
 
18201
                goto exit_failure;
 
18202
            }
 
18203
            type->contentTypeDef = baseType->contentTypeDef;
 
18204
        } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
 
18205
            /*
 
18206
            * SPEC (4) <extension> + base is <simpleType>
 
18207
            * "... then that simple type definition"
 
18208
            */
 
18209
            type->contentTypeDef = baseType;
 
18210
        } else {
 
18211
            /*
 
18212
            * TODO: Check if this ever happens.
 
18213
            */
 
18214
            xmlSchemaPCustomErr(pctxt,
 
18215
                XML_SCHEMAP_INTERNAL,
 
18216
                WXS_BASIC_CAST type, NULL,
 
18217
                "Internal error: xmlSchemaTypeFixup, "
 
18218
                "complex type '%s' with <simpleContent>: unhandled "
 
18219
                "derivation case", type->name);
 
18220
            goto exit_failure;
 
18221
        }
 
18222
    } else {
 
18223
        int dummySequence = 0;
 
18224
        xmlSchemaParticlePtr particle =
 
18225
            (xmlSchemaParticlePtr) type->subtypes;
 
18226
        /*
 
18227
        * Corresponds to <complexType><complexContent>...
 
18228
        *
 
18229
        * NOTE that the effective mixed was already set during parsing of
 
18230
        * <complexType> and <complexContent>; its flag value is
 
18231
        * XML_SCHEMAS_TYPE_MIXED.
 
18232
        *
 
18233
        * Compute the "effective content":
 
18234
        * (2.1.1) + (2.1.2) + (2.1.3)
 
18235
        */
 
18236
        if ((particle == NULL) ||
 
18237
            ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
 
18238
            ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
 
18239
            (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
 
18240
            ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
 
18241
            (particle->minOccurs == 0))) &&
 
18242
            ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
 
18243
            if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
 
18244
                /*
 
18245
                * SPEC (2.1.4) "If the ļæ½effective mixedļæ½ is true, then
 
18246
                * a particle whose properties are as follows:..."
 
18247
                *
 
18248
                * Empty sequence model group with
 
18249
                * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
 
18250
                * NOTE that we sill assign it the <complexType> node to
 
18251
                * somehow anchor it in the doc.
 
18252
                */
 
18253
                if ((particle == NULL) ||
 
18254
                    (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
 
18255
                    /*
 
18256
                    * Create the particle.
 
18257
                    */
 
18258
                    particle = xmlSchemaAddParticle(pctxt,
 
18259
                        type->node, 1, 1);
 
18260
                    if (particle == NULL)
 
18261
                        goto exit_failure;
 
18262
                    /*
 
18263
                    * Create the model group.
 
18264
                    */ /* URGENT TODO: avoid adding to pending items. */
 
18265
                    particle->children = (xmlSchemaTreeItemPtr)
 
18266
                        xmlSchemaAddModelGroup(pctxt, pctxt->schema,
 
18267
                        XML_SCHEMA_TYPE_SEQUENCE, type->node);
 
18268
                    if (particle->children == NULL)
 
18269
                        goto exit_failure;
 
18270
                    
 
18271
                    type->subtypes = (xmlSchemaTypePtr) particle;
 
18272
                }
 
18273
                dummySequence = 1;
 
18274
                type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
 
18275
            } else {
 
18276
                /*
 
18277
                * SPEC (2.1.5) "otherwise empty"
 
18278
                */
 
18279
                type->contentType = XML_SCHEMA_CONTENT_EMPTY;
 
18280
            }
 
18281
        } else {
 
18282
            /*
 
18283
            * SPEC (2.2) "otherwise the particle corresponding to the
 
18284
            * <all>, <choice>, <group> or <sequence> among the
 
18285
            * [children]."
 
18286
            */
 
18287
            type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
 
18288
        }
 
18289
        /*
 
18290
        * Compute the "content type".
 
18291
        */
 
18292
        if (WXS_IS_RESTRICTION(type)) {
 
18293
            /*
 
18294
            * SPEC (3.1) "If <restriction>..."
 
18295
            * (3.1.1) + (3.1.2) */
 
18296
            if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
 
18297
                if (type->flags & XML_SCHEMAS_TYPE_MIXED)
 
18298
                    type->contentType = XML_SCHEMA_CONTENT_MIXED;
 
18299
            }
 
18300
        } else {
 
18301
            /*
 
18302
            * SPEC (3.2) "If <extension>..."
 
18303
            */
 
18304
            if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
 
18305
                /*
 
18306
                * SPEC (3.2.1)
 
18307
                * "If the ļæ½effective contentļæ½ is empty, then the
 
18308
                *  {content type} of the [...] base ..."
 
18309
                */
 
18310
                type->contentType = baseType->contentType;
 
18311
                type->subtypes = baseType->subtypes;
 
18312
                /*
 
18313
                * Fixes bug #347316:
 
18314
                * This is the case when the base type has a simple
 
18315
                * type definition as content.
 
18316
                */
 
18317
                type->contentTypeDef = baseType->contentTypeDef;
 
18318
                /*
 
18319
                * NOTE that the effective mixed is ignored here.
 
18320
                */
 
18321
            } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
 
18322
                /*
 
18323
                * SPEC (3.2.2)
 
18324
                */
 
18325
                if (type->flags & XML_SCHEMAS_TYPE_MIXED)
 
18326
                    type->contentType = XML_SCHEMA_CONTENT_MIXED;
 
18327
            } else {
 
18328
                /*
 
18329
                * SPEC (3.2.3)
 
18330
                */
 
18331
                if (type->flags & XML_SCHEMAS_TYPE_MIXED)
 
18332
                    type->contentType = XML_SCHEMA_CONTENT_MIXED;
 
18333
                    /*
 
18334
                    * "A model group whose {compositor} is sequence and whose
 
18335
                    * {particles} are..."
 
18336
                    */
 
18337
                if ((WXS_TYPE_PARTICLE(type) != NULL) &&
 
18338
                    (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
 
18339
                    ((WXS_TYPE_PARTICLE_TERM(type))->type ==
 
18340
                        XML_SCHEMA_TYPE_ALL))
 
18341
                {
 
18342
                    /*
 
18343
                    * SPEC cos-all-limited (1)
 
18344
                    */
 
18345
                    xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
18346
                        /* TODO: error code */
 
18347
                        XML_SCHEMAP_COS_ALL_LIMITED,
 
18348
                        WXS_ITEM_NODE(type), NULL,
 
18349
                        "The type has an 'all' model group in its "
 
18350
                        "{content type} and thus cannot be derived from "
 
18351
                        "a non-empty type, since this would produce a "
 
18352
                        "'sequence' model group containing the 'all' "
 
18353
                        "model group; 'all' model groups are not "
 
18354
                        "allowed to appear inside other model groups",
 
18355
                        NULL, NULL);
 
18356
 
 
18357
                } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
 
18358
                    (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
 
18359
                    ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
 
18360
                        XML_SCHEMA_TYPE_ALL))
 
18361
                {
 
18362
                    /*
 
18363
                    * SPEC cos-all-limited (1)
 
18364
                    */
 
18365
                    xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
18366
                        /* TODO: error code */
 
18367
                        XML_SCHEMAP_COS_ALL_LIMITED,
 
18368
                        WXS_ITEM_NODE(type), NULL,
 
18369
                        "A type cannot be derived by extension from a type "
 
18370
                        "which has an 'all' model group in its "
 
18371
                        "{content type}, since this would produce a "
 
18372
                        "'sequence' model group containing the 'all' "
 
18373
                        "model group; 'all' model groups are not "
 
18374
                        "allowed to appear inside other model groups",
 
18375
                        NULL, NULL);
 
18376
 
 
18377
                } else if (! dummySequence) {
 
18378
                    xmlSchemaTreeItemPtr effectiveContent =
 
18379
                        (xmlSchemaTreeItemPtr) type->subtypes;
 
18380
                    /*
 
18381
                    * Create the particle.
 
18382
                    */
 
18383
                    particle = xmlSchemaAddParticle(pctxt,
 
18384
                        type->node, 1, 1);
 
18385
                    if (particle == NULL)
 
18386
                        goto exit_failure;
 
18387
                    /*
 
18388
                    * Create the "sequence" model group.
 
18389
                    */
 
18390
                    particle->children = (xmlSchemaTreeItemPtr)
 
18391
                        xmlSchemaAddModelGroup(pctxt, pctxt->schema,
 
18392
                        XML_SCHEMA_TYPE_SEQUENCE, type->node);
 
18393
                    if (particle->children == NULL)
 
18394
                        goto exit_failure;
 
18395
                    WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
 
18396
                    /*
 
18397
                    * SPEC "the particle of the {content type} of
 
18398
                    * the ... base ..."
 
18399
                    * Create a duplicate of the base type's particle
 
18400
                    * and assign its "term" to it.
 
18401
                    */
 
18402
                    particle->children->children =
 
18403
                        (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
 
18404
                        type->node,
 
18405
                        ((xmlSchemaParticlePtr) type->subtypes)->minOccurs,
 
18406
                        ((xmlSchemaParticlePtr) type->subtypes)->maxOccurs);
 
18407
                    if (particle->children->children == NULL)
 
18408
                        goto exit_failure;
 
18409
                    particle = (xmlSchemaParticlePtr)
 
18410
                        particle->children->children;
 
18411
                    particle->children =
 
18412
                        ((xmlSchemaParticlePtr) baseType->subtypes)->children;
 
18413
                    /*
 
18414
                    * SPEC "followed by the ļæ½effective contentļæ½."
 
18415
                    */
 
18416
                    particle->next = effectiveContent;
 
18417
                    /*
 
18418
                    * This all will result in:
 
18419
                    * new-particle
 
18420
                    *   --> new-sequence(
 
18421
                    *         new-particle
 
18422
                    *           --> base-model,
 
18423
                    *         this-particle
 
18424
                    *           --> this-model
 
18425
                    *       )
 
18426
                    */
 
18427
                } else {
 
18428
                    /*
 
18429
                    * This is the case when there is already an empty
 
18430
                    * <sequence> with minOccurs==maxOccurs==1.
 
18431
                    * Just add the base types's content type.
 
18432
                    * NOTE that, although we miss to add an intermediate
 
18433
                    * <sequence>, this should produce no difference to
 
18434
                    * neither the regex compilation of the content model,
 
18435
                    * nor to the complex type contraints.
 
18436
                    */
 
18437
                    particle->children->children =
 
18438
                        (xmlSchemaTreeItemPtr) baseType->subtypes;
 
18439
                }
 
18440
            }
 
18441
        }
 
18442
    }
 
18443
    /*
 
18444
    * Now fixup attribute uses:
 
18445
    *   - expand attr. group references
 
18446
    *     - intersect attribute wildcards
 
18447
    *   - inherit attribute uses of the base type
 
18448
    *   - inherit or union attr. wildcards if extending
 
18449
    *   - apply attr. use prohibitions if restricting
 
18450
    */
 
18451
    res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
 
18452
    HFAILURE HERROR
 
18453
    /*
 
18454
    * Apply the complex type component constraints; this will not
 
18455
    * check attributes, since this is done in
 
18456
    * xmlSchemaFixupTypeAttributeUses().
 
18457
    */
 
18458
    res = xmlSchemaCheckCTComponent(pctxt, type);
 
18459
    HFAILURE HERROR
 
18460
 
 
18461
#ifdef DEBUG_TYPE
 
18462
    xmlSchemaDebugFixedType(pctxt, type);
 
18463
#endif
 
18464
    if (olderrs != pctxt->nberrors)
 
18465
        return(pctxt->err);
 
18466
    else
 
18467
        return(0);
 
18468
 
 
18469
exit_error:
 
18470
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
 
18471
#ifdef DEBUG_TYPE
 
18472
    xmlSchemaDebugFixedType(pctxt, type);
 
18473
#endif
 
18474
    return(pctxt->err);
 
18475
 
 
18476
exit_failure:
 
18477
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
 
18478
#ifdef DEBUG_TYPE
 
18479
    xmlSchemaDebugFixedType(pctxt, type);
 
18480
#endif
 
18481
    return(-1);
 
18482
}
 
18483
 
 
18484
 
 
18485
/**
 
18486
 * xmlSchemaTypeFixup:
 
18487
 * @typeDecl:  the schema type definition
 
18488
 * @ctxt:  the schema parser context
 
18489
 *
 
18490
 * Fixes the content model of the type.
 
18491
 * URGENT TODO: We need an int result!
 
18492
 */
 
18493
static int
 
18494
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
 
18495
                   xmlSchemaAbstractCtxtPtr actxt)
 
18496
{
 
18497
    if (type == NULL)
 
18498
        return(0);
 
18499
    if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
 
18500
        AERROR_INT("xmlSchemaTypeFixup",
 
18501
            "this function needs a parser context");
 
18502
        return(-1);
 
18503
    }
 
18504
    if (! WXS_IS_TYPE_NOT_FIXED(type))
 
18505
        return(0);
 
18506
    if (type->type == XML_SCHEMA_TYPE_COMPLEX)
 
18507
        return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
 
18508
    else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
 
18509
        return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
 
18510
    return(0);
 
18511
}
 
18512
 
 
18513
/**
 
18514
 * xmlSchemaCheckFacet:
 
18515
 * @facet:  the facet
 
18516
 * @typeDecl:  the schema type definition
 
18517
 * @pctxt:  the schema parser context or NULL
 
18518
 * @name: the optional name of the type
 
18519
 *
 
18520
 * Checks and computes the values of facets.
 
18521
 *
 
18522
 * Returns 0 if valid, a positive error code if not valid and
 
18523
 *         -1 in case of an internal or API error.
 
18524
 */
 
18525
int
 
18526
xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
 
18527
                    xmlSchemaTypePtr typeDecl,
 
18528
                    xmlSchemaParserCtxtPtr pctxt,
 
18529
                    const xmlChar * name ATTRIBUTE_UNUSED)
 
18530
{
 
18531
    int ret = 0, ctxtGiven;
 
18532
 
 
18533
    if ((facet == NULL) || (typeDecl == NULL))
 
18534
        return(-1);
 
18535
    /*
 
18536
    * TODO: will the parser context be given if used from
 
18537
    * the relaxNG module?
 
18538
    */
 
18539
    if (pctxt == NULL)
 
18540
        ctxtGiven = 0;
 
18541
    else
 
18542
        ctxtGiven = 1;
 
18543
 
 
18544
    switch (facet->type) {
 
18545
        case XML_SCHEMA_FACET_MININCLUSIVE:
 
18546
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
 
18547
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
 
18548
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
 
18549
        case XML_SCHEMA_FACET_ENUMERATION: {
 
18550
                /*
 
18551
                 * Okay we need to validate the value
 
18552
                 * at that point.
 
18553
                 */
 
18554
                xmlSchemaTypePtr base;
 
18555
 
 
18556
                /* 4.3.5.5 Constraints on enumeration Schema Components
 
18557
                * Schema Component Constraint: enumeration valid restriction
 
18558
                * It is an ļæ½errorļæ½ if any member of {value} is not in the
 
18559
                * ļæ½value spaceļæ½ of {base type definition}.
 
18560
                *
 
18561
                * minInclusive, maxInclusive, minExclusive, maxExclusive:
 
18562
                * The value ļæ½mustļæ½ be in the
 
18563
                * ļæ½value spaceļæ½ of the ļæ½base typeļæ½.
 
18564
                */
 
18565
                /*
 
18566
                * This function is intended to deliver a compiled value
 
18567
                * on the facet. In this implementation of XML Schemata the
 
18568
                * type holding a facet, won't be a built-in type.
 
18569
                * Thus to ensure that other API
 
18570
                * calls (relaxng) do work, if the given type is a built-in
 
18571
                * type, we will assume that the given built-in type *is
 
18572
                * already* the base type.
 
18573
                */
 
18574
                if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
 
18575
                    base = typeDecl->baseType;
 
18576
                    if (base == NULL) {
 
18577
                        PERROR_INT("xmlSchemaCheckFacet",
 
18578
                            "a type user derived type has no base type");
 
18579
                        return (-1);
 
18580
                    }
 
18581
                } else
 
18582
                    base = typeDecl;
 
18583
                         
 
18584
                if (! ctxtGiven) {
 
18585
                    /*
 
18586
                    * A context is needed if called from RelaxNG.
 
18587
                    */              
 
18588
                    pctxt = xmlSchemaNewParserCtxt("*");
 
18589
                    if (pctxt == NULL)
 
18590
                        return (-1);
 
18591
                }
 
18592
                /*
 
18593
                * NOTE: This call does not check the content nodes,
 
18594
                * since they are not available:
 
18595
                * facet->node is just the node holding the facet
 
18596
                * definition, *not* the attribute holding the *value*
 
18597
                * of the facet.
 
18598
                */              
 
18599
                ret = xmlSchemaVCheckCVCSimpleType(
 
18600
                    ACTXT_CAST pctxt, facet->node, base,
 
18601
                    facet->value, &(facet->val), 1, 1, 0);
 
18602
                if (ret != 0) {
 
18603
                    if (ret < 0) {
 
18604
                        /* No error message for RelaxNG. */
 
18605
                        if (ctxtGiven) {                            
 
18606
                            xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
18607
                                XML_SCHEMAP_INTERNAL, facet->node, NULL,
 
18608
                                "Internal error: xmlSchemaCheckFacet, " 
 
18609
                                "failed to validate the value '%s' of the "
 
18610
                                "facet '%s' against the base type",
 
18611
                                facet->value, xmlSchemaFacetTypeToString(facet->type));
 
18612
                        }
 
18613
                        goto internal_error;
 
18614
                    }
 
18615
                    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
 
18616
                    /* No error message for RelaxNG. */
 
18617
                    if (ctxtGiven) {
 
18618
                        xmlChar *str = NULL;
 
18619
 
 
18620
                        xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
18621
                            ret, facet->node, WXS_BASIC_CAST facet,
 
18622
                            "The value '%s' of the facet does not validate "
 
18623
                            "against the base type '%s'",
 
18624
                            facet->value,
 
18625
                            xmlSchemaFormatQName(&str,
 
18626
                                base->targetNamespace, base->name));
 
18627
                        FREE_AND_NULL(str);
 
18628
                    }
 
18629
                    goto exit;
 
18630
                } else if (facet->val == NULL) {
 
18631
                    if (ctxtGiven) {
 
18632
                        PERROR_INT("xmlSchemaCheckFacet",
 
18633
                            "value was not computed");
 
18634
                    }
 
18635
                    TODO
 
18636
                }
 
18637
                break;
 
18638
            }
 
18639
        case XML_SCHEMA_FACET_PATTERN:
 
18640
            facet->regexp = xmlRegexpCompile(facet->value);
 
18641
            if (facet->regexp == NULL) {
 
18642
                ret = XML_SCHEMAP_REGEXP_INVALID;
 
18643
                /* No error message for RelaxNG. */
 
18644
                if (ctxtGiven) {
 
18645
                    xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
18646
                        ret, facet->node, WXS_BASIC_CAST typeDecl,
 
18647
                        "The value '%s' of the facet 'pattern' is not a "
 
18648
                        "valid regular expression",
 
18649
                        facet->value, NULL);
 
18650
                }
 
18651
            }
 
18652
            break;
 
18653
        case XML_SCHEMA_FACET_TOTALDIGITS:
 
18654
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
 
18655
        case XML_SCHEMA_FACET_LENGTH:
 
18656
        case XML_SCHEMA_FACET_MAXLENGTH:
 
18657
        case XML_SCHEMA_FACET_MINLENGTH:
 
18658
 
 
18659
            if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
 
18660
                ret = xmlSchemaValidatePredefinedType(
 
18661
                    xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
 
18662
                    facet->value, &(facet->val));
 
18663
            } else {
 
18664
                ret = xmlSchemaValidatePredefinedType(
 
18665
                    xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
 
18666
                    facet->value, &(facet->val));
 
18667
            }
 
18668
            if (ret != 0) {
 
18669
                if (ret < 0) {
 
18670
                    /* No error message for RelaxNG. */
 
18671
                    if (ctxtGiven) {
 
18672
                        PERROR_INT("xmlSchemaCheckFacet",
 
18673
                            "validating facet value");
 
18674
                    }
 
18675
                    goto internal_error;
 
18676
                }
 
18677
                ret = XML_SCHEMAP_INVALID_FACET_VALUE;
 
18678
                /* No error message for RelaxNG. */
 
18679
                if (ctxtGiven) {
 
18680
                    /* error code */
 
18681
                    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
 
18682
                        ret, facet->node, WXS_BASIC_CAST typeDecl,
 
18683
                        "The value '%s' of the facet '%s' is not a valid '%s'",                 
 
18684
                        facet->value,
 
18685
                        xmlSchemaFacetTypeToString(facet->type),
 
18686
                        (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ? 
 
18687
                            BAD_CAST "nonNegativeInteger" :
 
18688
                            BAD_CAST "positiveInteger",
 
18689
                        NULL);
 
18690
                }
 
18691
            }
 
18692
            break;
 
18693
            
 
18694
        case XML_SCHEMA_FACET_WHITESPACE:{
 
18695
                if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
 
18696
                    facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
 
18697
                } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
 
18698
                    facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
 
18699
                } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
 
18700
                    facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
 
18701
                } else {
 
18702
                    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
 
18703
                    /* No error message for RelaxNG. */
 
18704
                    if (ctxtGiven) {
 
18705
                        /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
 
18706
                        xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
18707
                            ret, facet->node, WXS_BASIC_CAST typeDecl,
 
18708
                            "The value '%s' of the facet 'whitespace' is not "
 
18709
                            "valid", facet->value, NULL);
 
18710
                    }
 
18711
                }
 
18712
            }
 
18713
        default:
 
18714
            break;
 
18715
    }
 
18716
exit:
 
18717
    if ((! ctxtGiven) && (pctxt != NULL))
 
18718
        xmlSchemaFreeParserCtxt(pctxt);
 
18719
    return (ret);
 
18720
internal_error:
 
18721
    if ((! ctxtGiven) && (pctxt != NULL))
 
18722
        xmlSchemaFreeParserCtxt(pctxt);
 
18723
    return (-1);
 
18724
}
 
18725
 
 
18726
/**
 
18727
 * xmlSchemaCheckFacetValues:
 
18728
 * @typeDecl:  the schema type definition
 
18729
 * @ctxt:  the schema parser context
 
18730
 *
 
18731
 * Checks the default values types, especially for facets
 
18732
 */
 
18733
static int
 
18734
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
 
18735
                          xmlSchemaParserCtxtPtr pctxt)
 
18736
{
 
18737
    int res, olderrs = pctxt->nberrors;
 
18738
    const xmlChar *name = typeDecl->name;
 
18739
    /*
 
18740
    * NOTE: It is intended to use the facets list, instead
 
18741
    * of facetSet.
 
18742
    */
 
18743
    if (typeDecl->facets != NULL) {
 
18744
        xmlSchemaFacetPtr facet = typeDecl->facets;
 
18745
 
 
18746
        /*
 
18747
        * Temporarily assign the "schema" to the validation context
 
18748
        * of the parser context. This is needed for NOTATION validation.
 
18749
        */
 
18750
        if (pctxt->vctxt == NULL) {
 
18751
            if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
 
18752
                return(-1);
 
18753
        }
 
18754
        pctxt->vctxt->schema = pctxt->schema;
 
18755
        while (facet != NULL) {
 
18756
            res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
 
18757
            HFAILURE
 
18758
            facet = facet->next;
 
18759
        }
 
18760
        pctxt->vctxt->schema = NULL;
 
18761
    }
 
18762
    if (olderrs != pctxt->nberrors)
 
18763
        return(pctxt->err);
 
18764
    return(0);
 
18765
exit_failure:
 
18766
    return(-1);
 
18767
}
 
18768
 
 
18769
/**
 
18770
 * xmlSchemaGetCircModelGrDefRef:
 
18771
 * @ctxtMGroup: the searched model group
 
18772
 * @selfMGroup: the second searched model group
 
18773
 * @particle: the first particle
 
18774
 *
 
18775
 * This one is intended to be used by
 
18776
 * xmlSchemaCheckGroupDefCircular only.
 
18777
 *
 
18778
 * Returns the particle with the circular model group definition reference,
 
18779
 * otherwise NULL.
 
18780
 */
 
18781
static xmlSchemaTreeItemPtr
 
18782
xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
 
18783
                              xmlSchemaTreeItemPtr particle)
 
18784
{
 
18785
    xmlSchemaTreeItemPtr circ = NULL;
 
18786
    xmlSchemaTreeItemPtr term;
 
18787
    xmlSchemaModelGroupDefPtr gdef;
 
18788
 
 
18789
    for (; particle != NULL; particle = particle->next) {
 
18790
        term = particle->children;
 
18791
        if (term == NULL)
 
18792
            continue;
 
18793
        switch (term->type) {
 
18794
            case XML_SCHEMA_TYPE_GROUP:
 
18795
                gdef = (xmlSchemaModelGroupDefPtr) term;
 
18796
                if (gdef == groupDef)
 
18797
                    return (particle);
 
18798
                /*
 
18799
                * Mark this model group definition to avoid infinite
 
18800
                * recursion on circular references not yet examined.
 
18801
                */
 
18802
                if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
 
18803
                    continue;
 
18804
                if (gdef->children != NULL) {
 
18805
                    gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
 
18806
                    circ = xmlSchemaGetCircModelGrDefRef(groupDef,
 
18807
                        gdef->children->children);
 
18808
                    gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
 
18809
                    if (circ != NULL)
 
18810
                        return (circ);
 
18811
                }
 
18812
                break;
 
18813
            case XML_SCHEMA_TYPE_SEQUENCE:
 
18814
            case XML_SCHEMA_TYPE_CHOICE:
 
18815
            case XML_SCHEMA_TYPE_ALL:
 
18816
                circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
 
18817
                if (circ != NULL)
 
18818
                    return (circ);
 
18819
                break;
 
18820
            default:
 
18821
                break;
 
18822
        }
 
18823
    }
 
18824
    return (NULL);
 
18825
}
 
18826
 
 
18827
/**
 
18828
 * xmlSchemaCheckGroupDefCircular:
 
18829
 * @item:  the model group definition
 
18830
 * @ctxt:  the parser context
 
18831
 * @name:  the name
 
18832
 *
 
18833
 * Checks for circular references to model group definitions.
 
18834
 */
 
18835
static void
 
18836
xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
 
18837
                               xmlSchemaParserCtxtPtr ctxt)
 
18838
{
 
18839
    /*
 
18840
    * Schema Component Constraint: Model Group Correct
 
18841
    * 2 Circular groups are disallowed. That is, within the {particles}
 
18842
    * of a group there must not be at any depth a particle whose {term}
 
18843
    * is the group itself.
 
18844
    */
 
18845
    if ((item == NULL) ||
 
18846
        (item->type != XML_SCHEMA_TYPE_GROUP) ||
 
18847
        (item->children == NULL))
 
18848
        return;
 
18849
    {
 
18850
        xmlSchemaTreeItemPtr circ;
 
18851
 
 
18852
        circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
 
18853
        if (circ != NULL) {
 
18854
            xmlChar *str = NULL;
 
18855
            /*
 
18856
            * TODO: The error report is not adequate: this constraint
 
18857
            * is defined for model groups but not definitions, but since
 
18858
            * there cannot be any circular model groups without a model group
 
18859
            * definition (if not using a construction API), we check those
 
18860
            * defintions only.
 
18861
            */
 
18862
            xmlSchemaPCustomErr(ctxt,
 
18863
                XML_SCHEMAP_MG_PROPS_CORRECT_2,
 
18864
                NULL, WXS_ITEM_NODE(circ),
 
18865
                "Circular reference to the model group definition '%s' "
 
18866
                "defined", xmlSchemaFormatQName(&str,
 
18867
                    item->targetNamespace, item->name));
 
18868
            FREE_AND_NULL(str)
 
18869
            /*
 
18870
            * NOTE: We will cut the reference to avoid further
 
18871
            * confusion of the processor. This is a fatal error.
 
18872
            */
 
18873
            circ->children = NULL;
 
18874
        }
 
18875
    }
 
18876
}
 
18877
 
 
18878
/**
 
18879
 * xmlSchemaModelGroupToModelGroupDefFixup:
 
18880
 * @ctxt:  the parser context
 
18881
 * @mg:  the model group
 
18882
 *
 
18883
 * Assigns the model group of model group definitions to the "term"
 
18884
 * of the referencing particle.
 
18885
 * In xmlSchemaResolveModelGroupParticleReferences the model group
 
18886
 * definitions were assigned to the "term", since needed for the
 
18887
 * circularity check.
 
18888
 *
 
18889
 * Schema Component Constraint:
 
18890
 *     All Group Limited (cos-all-limited) (1.2)
 
18891
 */
 
18892
static void
 
18893
xmlSchemaModelGroupToModelGroupDefFixup(
 
18894
    xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
 
18895
    xmlSchemaModelGroupPtr mg)
 
18896
{
 
18897
    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
 
18898
 
 
18899
    while (particle != NULL) {
 
18900
        if ((WXS_PARTICLE_TERM(particle) == NULL) ||
 
18901
            ((WXS_PARTICLE_TERM(particle))->type !=
 
18902
                XML_SCHEMA_TYPE_GROUP))
 
18903
        {
 
18904
            particle = WXS_PTC_CAST particle->next;
 
18905
            continue;
 
18906
        } 
 
18907
        if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
 
18908
            /*
 
18909
            * TODO: Remove the particle.
 
18910
            */
 
18911
            WXS_PARTICLE_TERM(particle) = NULL;
 
18912
            particle = WXS_PTC_CAST particle->next;
 
18913
            continue;
 
18914
        }
 
18915
        /*
 
18916
        * Assign the model group to the {term} of the particle.
 
18917
        */
 
18918
        WXS_PARTICLE_TERM(particle) =
 
18919
            WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
 
18920
 
 
18921
        particle = WXS_PTC_CAST particle->next;
 
18922
    }
 
18923
}
 
18924
 
 
18925
/**
 
18926
 * xmlSchemaCheckAttrGroupCircularRecur:
 
18927
 * @ctxtGr: the searched attribute group
 
18928
 * @attr: the current attribute list to be processed
 
18929
 *
 
18930
 * This one is intended to be used by
 
18931
 * xmlSchemaCheckAttrGroupCircular only.
 
18932
 *
 
18933
 * Returns the circular attribute grou reference, otherwise NULL.
 
18934
 */
 
18935
static xmlSchemaQNameRefPtr
 
18936
xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
 
18937
                                     xmlSchemaItemListPtr list)
 
18938
{
 
18939
    xmlSchemaAttributeGroupPtr gr;
 
18940
    xmlSchemaQNameRefPtr ref, circ;
 
18941
    int i;
 
18942
    /*
 
18943
    * We will search for an attribute group reference which
 
18944
    * references the context attribute group.
 
18945
    */
 
18946
    for (i = 0; i < list->nbItems; i++) {
 
18947
        ref = list->items[i];
 
18948
        if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
 
18949
            (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
 
18950
            (ref->item != NULL))
 
18951
        {
 
18952
            gr = WXS_ATTR_GROUP_CAST ref->item;
 
18953
            if (gr == ctxtGr)
 
18954
                return(ref);
 
18955
            if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
 
18956
                continue;           
 
18957
            /*
 
18958
            * Mark as visited to avoid infinite recursion on
 
18959
            * circular references not yet examined.
 
18960
            */
 
18961
            if ((gr->attrUses) &&
 
18962
                (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
 
18963
            {
 
18964
                gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
 
18965
                circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
 
18966
                    (xmlSchemaItemListPtr) gr->attrUses);               
 
18967
                gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
 
18968
                if (circ != NULL)
 
18969
                    return (circ);
 
18970
            }
 
18971
            
 
18972
        }
 
18973
    }
 
18974
    return (NULL);
 
18975
}
 
18976
 
 
18977
/**
 
18978
 * xmlSchemaCheckAttrGroupCircular:
 
18979
 * attrGr:  the attribute group definition
 
18980
 * @ctxt:  the parser context
 
18981
 * @name:  the name
 
18982
 *
 
18983
 * Checks for circular references of attribute groups.
 
18984
 */
 
18985
static int
 
18986
xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
 
18987
                                xmlSchemaParserCtxtPtr ctxt)
 
18988
{
 
18989
    /*
 
18990
    * Schema Representation Constraint:
 
18991
    * Attribute Group Definition Representation OK
 
18992
    * 3 Circular group reference is disallowed outside <redefine>.
 
18993
    * That is, unless this element information item's parent is
 
18994
    * <redefine>, then among the [children], if any, there must
 
18995
    * not be an <attributeGroup> with ref [attribute] which resolves
 
18996
    * to the component corresponding to this <attributeGroup>. Indirect
 
18997
    * circularity is also ruled out. That is, when QName resolution
 
18998
    * (Schema Document) (ļæ½3.15.3) is applied to a ļæ½QNameļæ½ arising from
 
18999
    * any <attributeGroup>s with a ref [attribute] among the [children],
 
19000
    * it must not be the case that a ļæ½QNameļæ½ is encountered at any depth
 
19001
    * which resolves to the component corresponding to this <attributeGroup>.
 
19002
    */
 
19003
    if (attrGr->attrUses == NULL)
 
19004
        return(0);
 
19005
    else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
 
19006
        return(0);
 
19007
    else {
 
19008
        xmlSchemaQNameRefPtr circ;
 
19009
        
 
19010
        circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
 
19011
            (xmlSchemaItemListPtr) attrGr->attrUses);   
 
19012
        if (circ != NULL) {
 
19013
            xmlChar *str = NULL;
 
19014
            /*
 
19015
            * TODO: Report the referenced attr group as QName.
 
19016
            */
 
19017
            xmlSchemaPCustomErr(ctxt,
 
19018
                XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
 
19019
                NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
 
19020
                "Circular reference to the attribute group '%s' "
 
19021
                "defined", xmlSchemaGetComponentQName(&str, attrGr));
 
19022
            FREE_AND_NULL(str);
 
19023
            /*
 
19024
            * NOTE: We will cut the reference to avoid further
 
19025
            * confusion of the processor.
 
19026
            * BADSPEC TODO: The spec should define how to process in this case.
 
19027
            */
 
19028
            circ->item = NULL;
 
19029
            return(ctxt->err);
 
19030
        }
 
19031
    }
 
19032
    return(0);
 
19033
}
 
19034
 
 
19035
static int
 
19036
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
 
19037
                                  xmlSchemaAttributeGroupPtr attrGr);
 
19038
 
 
19039
/**
 
19040
 * xmlSchemaExpandAttributeGroupRefs:
 
19041
 * @pctxt: the parser context
 
19042
 * @node: the node of the component holding the attribute uses
 
19043
 * @completeWild: the intersected wildcard to be returned 
 
19044
 * @list: the attribute uses
 
19045
 *
 
19046
 * Substitutes contained attribute group references
 
19047
 * for their attribute uses. Wilcards are intersected.
 
19048
 * Attribute use prohibitions are removed from the list
 
19049
 * and returned via the @prohibs list.
 
19050
 * Pointlessness of attr. prohibs, if a matching attr. decl
 
19051
 * is existent a well, are checked.
 
19052
 */
 
19053
static int
 
19054
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
 
19055
                                  xmlSchemaBasicItemPtr item,
 
19056
                                  xmlSchemaWildcardPtr *completeWild,
 
19057
                                  xmlSchemaItemListPtr list,
 
19058
                                  xmlSchemaItemListPtr prohibs)
 
19059
{
 
19060
    xmlSchemaAttributeGroupPtr gr;
 
19061
    xmlSchemaAttributeUsePtr use;
 
19062
    xmlSchemaItemListPtr sublist;
 
19063
    int i, j;
 
19064
    int created = (*completeWild == NULL) ? 0 : 1;
 
19065
 
 
19066
    if (prohibs)
 
19067
        prohibs->nbItems = 0;
 
19068
 
 
19069
    for (i = 0; i < list->nbItems; i++) {
 
19070
        use = list->items[i];
 
19071
 
 
19072
        if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {        
 
19073
            if (prohibs == NULL) {
 
19074
                PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
 
19075
                    "unexpected attr prohibition found");
 
19076
                return(-1);
 
19077
            }
 
19078
            /*
 
19079
            * Remove from attribute uses.
 
19080
            */
 
19081
            if (xmlSchemaItemListRemove(list, i) == -1)
 
19082
                return(-1);
 
19083
            i--;
 
19084
            /*
 
19085
            * Note that duplicate prohibitions were already
 
19086
            * handled at parsing time.
 
19087
            */      
 
19088
            /*
 
19089
            * Add to list of prohibitions.
 
19090
            */
 
19091
            xmlSchemaItemListAddSize(prohibs, 2, use);
 
19092
            continue;
 
19093
        }
 
19094
        if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
 
19095
            ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
 
19096
        {
 
19097
            if ((WXS_QNAME_CAST use)->item == NULL)
 
19098
                return(-1);
 
19099
            gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
 
19100
            /*
 
19101
            * Expand the referenced attr. group.
 
19102
            * TODO: remove this, this is done in a previous step, so
 
19103
            * already done here.
 
19104
            */
 
19105
            if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
 
19106
                if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
 
19107
                    return(-1);
 
19108
            }
 
19109
            /*
 
19110
            * Build the 'complete' wildcard; i.e. intersect multiple
 
19111
            * wildcards.
 
19112
            */
 
19113
            if (gr->attributeWildcard != NULL) {
 
19114
                if (*completeWild == NULL) {
 
19115
                    *completeWild = gr->attributeWildcard;
 
19116
                } else {
 
19117
                    if (! created) {
 
19118
                        xmlSchemaWildcardPtr tmpWild;
 
19119
 
 
19120
                         /*
 
19121
                        * Copy the first encountered wildcard as context,
 
19122
                        * except for the annotation.
 
19123
                        *
 
19124
                        * Although the complete wildcard might not correspond
 
19125
                        * to any node in the schema, we will anchor it on
 
19126
                        * the node of the owner component.
 
19127
                        */
 
19128
                        tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
 
19129
                            XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
 
19130
                            WXS_ITEM_NODE(item));
 
19131
                        if (tmpWild == NULL)
 
19132
                            return(-1);
 
19133
                        if (xmlSchemaCloneWildcardNsConstraints(pctxt,
 
19134
                            tmpWild, *completeWild) == -1)
 
19135
                            return (-1);
 
19136
                        tmpWild->processContents = (*completeWild)->processContents;
 
19137
                        *completeWild = tmpWild;
 
19138
                        created = 1;
 
19139
                    }
 
19140
                    
 
19141
                    if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
 
19142
                        gr->attributeWildcard) == -1)
 
19143
                        return(-1);
 
19144
                }
 
19145
            }
 
19146
            /*
 
19147
            * Just remove the reference if the referenced group does not
 
19148
            * contain any attribute uses.
 
19149
            */
 
19150
            sublist = ((xmlSchemaItemListPtr) gr->attrUses);
 
19151
            if ((sublist == NULL) || sublist->nbItems == 0) {
 
19152
                if (xmlSchemaItemListRemove(list, i) == -1)
 
19153
                    return(-1);
 
19154
                i--;
 
19155
                continue;
 
19156
            }
 
19157
            /*
 
19158
            * Add the attribute uses.
 
19159
            */
 
19160
            list->items[i] = sublist->items[0];
 
19161
            if (sublist->nbItems != 1) {
 
19162
                for (j = 1; j < sublist->nbItems; j++) {
 
19163
                    i++;
 
19164
                    if (xmlSchemaItemListInsert(list,
 
19165
                            sublist->items[j], i) == -1)
 
19166
                        return(-1);
 
19167
                }
 
19168
            }
 
19169
        }
 
19170
 
 
19171
    }
 
19172
    /*
 
19173
    * Handle pointless prohibitions of declared attributes.
 
19174
    */
 
19175
    if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
 
19176
        xmlSchemaAttributeUseProhibPtr prohib;
 
19177
 
 
19178
        for (i = prohibs->nbItems -1; i >= 0; i--) {
 
19179
            prohib = prohibs->items[i];
 
19180
            for (j = 0; j < list->nbItems; j++) {
 
19181
                use = list->items[j];
 
19182
 
 
19183
                if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
 
19184
                    (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
 
19185
                {
 
19186
                    xmlChar *str = NULL;
 
19187
 
 
19188
                    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
 
19189
                        XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
 
19190
                        prohib->node, NULL,
 
19191
                        "Skipping pointless attribute use prohibition "
 
19192
                        "'%s', since a corresponding attribute use "
 
19193
                        "exists already in the type definition",
 
19194
                        xmlSchemaFormatQName(&str,
 
19195
                            prohib->targetNamespace, prohib->name),
 
19196
                        NULL, NULL);
 
19197
                    FREE_AND_NULL(str);
 
19198
                    /*
 
19199
                    * Remove the prohibition.
 
19200
                    */
 
19201
                    if (xmlSchemaItemListRemove(prohibs, i) == -1)
 
19202
                        return(-1);
 
19203
                    break;
 
19204
                }
 
19205
            }
 
19206
        }
 
19207
    }
 
19208
    return(0);
 
19209
}
 
19210
 
 
19211
/**
 
19212
 * xmlSchemaAttributeGroupExpandRefs:
 
19213
 * @pctxt:  the parser context
 
19214
 * @attrGr:  the attribute group definition 
 
19215
 *
 
19216
 * Computation of:
 
19217
 * {attribute uses} property
 
19218
 * {attribute wildcard} property
 
19219
 *
 
19220
 * Substitutes contained attribute group references
 
19221
 * for their attribute uses. Wilcards are intersected.
 
19222
 */
 
19223
static int
 
19224
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
 
19225
                                  xmlSchemaAttributeGroupPtr attrGr)
 
19226
{  
 
19227
    if ((attrGr->attrUses == NULL) ||
 
19228
        (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
 
19229
        return(0);
 
19230
 
 
19231
    attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
 
19232
    if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
 
19233
        &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
 
19234
        return(-1);    
 
19235
    return(0);
 
19236
}
 
19237
 
 
19238
/**
 
19239
 * xmlSchemaAttributeGroupExpandRefs:
 
19240
 * @pctxt:  the parser context
 
19241
 * @attrGr:  the attribute group definition 
 
19242
 *
 
19243
 * Substitutes contained attribute group references
 
19244
 * for their attribute uses. Wilcards are intersected.
 
19245
 * 
 
19246
 * Schema Component Constraint:
 
19247
 *    Attribute Group Definition Properties Correct (ag-props-correct) 
 
19248
 */
 
19249
static int
 
19250
xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
 
19251
                                  xmlSchemaAttributeGroupPtr attrGr)
 
19252
{  
 
19253
    /*
 
19254
    * SPEC ag-props-correct
 
19255
    * (1) "The values of the properties of an attribute group definition
 
19256
    * must be as described in the property tableau in The Attribute
 
19257
    * Group Definition Schema Component (ļæ½3.6.1), modulo the impact of
 
19258
    * Missing Sub-components (ļæ½5.3);"
 
19259
    */
 
19260
    
 
19261
    if ((attrGr->attrUses != NULL) &&
 
19262
        (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
 
19263
    {
 
19264
        xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
 
19265
        xmlSchemaAttributeUsePtr use, tmp;
 
19266
        int i, j, hasId = 0;
 
19267
 
 
19268
        for (i = uses->nbItems -1; i >= 0; i--) {
 
19269
            use = uses->items[i];           
 
19270
            /*
 
19271
            * SPEC ag-props-correct
 
19272
            * (2) "Two distinct members of the {attribute uses} must not have
 
19273
            * {attribute declaration}s both of whose {name}s match and whose
 
19274
            * {target namespace}s are identical."
 
19275
            */
 
19276
            if (i > 0) {
 
19277
                for (j = i -1; j >= 0; j--) {
 
19278
                    tmp = uses->items[j];
 
19279
                    if ((WXS_ATTRUSE_DECL_NAME(use) ==
 
19280
                        WXS_ATTRUSE_DECL_NAME(tmp)) &&
 
19281
                        (WXS_ATTRUSE_DECL_TNS(use) ==
 
19282
                        WXS_ATTRUSE_DECL_TNS(tmp)))
 
19283
                    {
 
19284
                        xmlChar *str = NULL;
 
19285
                        
 
19286
                        xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
19287
                            XML_SCHEMAP_AG_PROPS_CORRECT,
 
19288
                            attrGr->node, WXS_BASIC_CAST attrGr,
 
19289
                            "Duplicate %s",
 
19290
                            xmlSchemaGetComponentDesignation(&str, use),
 
19291
                            NULL);
 
19292
                        FREE_AND_NULL(str);
 
19293
                        /*
 
19294
                        * Remove the duplicate.
 
19295
                        */
 
19296
                        if (xmlSchemaItemListRemove(uses, i) == -1)
 
19297
                            return(-1);
 
19298
                        goto next_use;
 
19299
                    }
 
19300
                }
 
19301
            }
 
19302
            /*
 
19303
            * SPEC ag-props-correct
 
19304
            * (3) "Two distinct members of the {attribute uses} must not have
 
19305
            * {attribute declaration}s both of whose {type definition}s are or
 
19306
            * are derived from ID."
 
19307
            * TODO: Does 'derived' include member-types of unions?
 
19308
            */
 
19309
            if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {             
 
19310
                if (xmlSchemaIsDerivedFromBuiltInType(
 
19311
                    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
 
19312
                {               
 
19313
                    if (hasId) {
 
19314
                        xmlChar *str = NULL;
 
19315
                        
 
19316
                        xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
19317
                            XML_SCHEMAP_AG_PROPS_CORRECT,
 
19318
                            attrGr->node, WXS_BASIC_CAST attrGr,
 
19319
                            "There must not exist more than one attribute "
 
19320
                            "declaration of type 'xs:ID' "
 
19321
                            "(or derived from 'xs:ID'). The %s violates this "
 
19322
                            "constraint",
 
19323
                            xmlSchemaGetComponentDesignation(&str, use),
 
19324
                            NULL);
 
19325
                        FREE_AND_NULL(str);
 
19326
                        if (xmlSchemaItemListRemove(uses, i) == -1)
 
19327
                            return(-1);
 
19328
                    }               
 
19329
                    hasId = 1;
 
19330
                }
 
19331
            }
 
19332
next_use: {}
 
19333
        }
 
19334
    }
 
19335
    return(0);
 
19336
}
 
19337
 
 
19338
/**
 
19339
 * xmlSchemaResolveAttrGroupReferences:
 
19340
 * @attrgrpDecl:  the schema attribute definition
 
19341
 * @ctxt:  the schema parser context
 
19342
 * @name:  the attribute name
 
19343
 *
 
19344
 * Resolves references to attribute group definitions.
 
19345
 */
 
19346
static int
 
19347
xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
 
19348
                                    xmlSchemaParserCtxtPtr ctxt)
 
19349
{
 
19350
    xmlSchemaAttributeGroupPtr group;
 
19351
 
 
19352
    if (ref->item != NULL)
 
19353
        return(0);
 
19354
    group = xmlSchemaGetAttributeGroup(ctxt->schema,
 
19355
        ref->name,
 
19356
        ref->targetNamespace);
 
19357
    if (group == NULL) {
 
19358
        xmlSchemaPResCompAttrErr(ctxt,
 
19359
            XML_SCHEMAP_SRC_RESOLVE,
 
19360
            NULL, ref->node,
 
19361
            "ref", ref->name, ref->targetNamespace,
 
19362
            ref->itemType, NULL);
 
19363
        return(ctxt->err);
 
19364
    }
 
19365
    ref->item = WXS_BASIC_CAST group;
 
19366
    return(0);
 
19367
}
 
19368
 
 
19369
/**
 
19370
 * xmlSchemaCheckAttrPropsCorrect:
 
19371
 * @item:  an schema attribute declaration/use
 
19372
 * @ctxt:  a schema parser context
 
19373
 * @name:  the name of the attribute
 
19374
 *
 
19375
 *
 
19376
 * Schema Component Constraint:
 
19377
 *    Attribute Declaration Properties Correct (a-props-correct)
 
19378
 *
 
19379
 * Validates the value constraints of an attribute declaration/use.
 
19380
 * NOTE that this needs the simle type definitions to be already
 
19381
 *   builded and checked.
 
19382
 */
 
19383
static int
 
19384
xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
 
19385
                               xmlSchemaAttributePtr attr)
 
19386
{
 
19387
 
 
19388
    /*
 
19389
    * SPEC a-props-correct (1)
 
19390
    * "The values of the properties of an attribute declaration must
 
19391
    * be as described in the property tableau in The Attribute
 
19392
    * Declaration Schema Component (ļæ½3.2.1), modulo the impact of
 
19393
    * Missing Sub-components (ļæ½5.3)."
 
19394
    */
 
19395
    
 
19396
    if (WXS_ATTR_TYPEDEF(attr) == NULL)
 
19397
        return(0);
 
19398
 
 
19399
    if (attr->defValue != NULL) {
 
19400
        int ret;
 
19401
 
 
19402
        /*
 
19403
        * SPEC a-props-correct (3)
 
19404
        * "If the {type definition} is or is derived from ID then there
 
19405
        * must not be a {value constraint}."
 
19406
        */
 
19407
        if (xmlSchemaIsDerivedFromBuiltInType(
 
19408
            WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
 
19409
        {
 
19410
            xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
19411
                XML_SCHEMAP_A_PROPS_CORRECT_3,
 
19412
                NULL, WXS_BASIC_CAST attr,
 
19413
                "Value constraints are not allowed if the type definition "
 
19414
                "is or is derived from xs:ID",
 
19415
                NULL, NULL);
 
19416
            return(pctxt->err);
 
19417
        }
 
19418
        /*
 
19419
        * SPEC a-props-correct (2)
 
19420
        * "if there is a {value constraint}, the canonical lexical
 
19421
        * representation of its value must be ļæ½validļæ½ with respect
 
19422
        * to the {type definition} as defined in String Valid (ļæ½3.14.4)."
 
19423
        * TODO: Don't care about the *cononical* stuff here, this requirement
 
19424
        * will be removed in WXS 1.1 anyway.
 
19425
        */
 
19426
        ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
 
19427
            attr->node, WXS_ATTR_TYPEDEF(attr),
 
19428
            attr->defValue, &(attr->defVal),
 
19429
            1, 1, 0);
 
19430
        if (ret != 0) {
 
19431
            if (ret < 0) {
 
19432
                PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
 
19433
                    "calling xmlSchemaVCheckCVCSimpleType()");
 
19434
                return(-1);
 
19435
            }
 
19436
            xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
19437
                XML_SCHEMAP_A_PROPS_CORRECT_2,
 
19438
                NULL, WXS_BASIC_CAST attr,
 
19439
                "The value of the value constraint is not valid",
 
19440
                NULL, NULL);
 
19441
            return(pctxt->err);
 
19442
        }
 
19443
    }
 
19444
   
 
19445
    return(0);
 
19446
}
 
19447
 
 
19448
static xmlSchemaElementPtr
 
19449
xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
 
19450
                                 xmlSchemaElementPtr ancestor)
 
19451
{
 
19452
    xmlSchemaElementPtr ret;
 
19453
 
 
19454
    if (WXS_SUBST_HEAD(ancestor) == NULL)
 
19455
        return (NULL);
 
19456
    if (WXS_SUBST_HEAD(ancestor) == elemDecl)
 
19457
        return (ancestor);
 
19458
 
 
19459
    if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
 
19460
        return (NULL);
 
19461
    WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
 
19462
    ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
 
19463
        WXS_SUBST_HEAD(ancestor));
 
19464
    WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
 
19465
 
 
19466
    return (ret);
 
19467
}
 
19468
 
 
19469
/**
 
19470
 * xmlSchemaCheckElemPropsCorrect:
 
19471
 * @ctxt:  a schema parser context
 
19472
 * @decl: the element declaration
 
19473
 * @name:  the name of the attribute
 
19474
 *
 
19475
 * Schema Component Constraint:
 
19476
 * Element Declaration Properties Correct (e-props-correct)
 
19477
 *
 
19478
 * STATUS:
 
19479
 *   missing: (6)
 
19480
 */
 
19481
static int
 
19482
xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
 
19483
                               xmlSchemaElementPtr elemDecl)
 
19484
{
 
19485
    int ret = 0;
 
19486
    xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
 
19487
    /*
 
19488
    * SPEC (1) "The values of the properties of an element declaration
 
19489
    * must be as described in the property tableau in The Element
 
19490
    * Declaration Schema Component (ļæ½3.3.1), modulo the impact of Missing
 
19491
    * Sub-components (ļæ½5.3)."
 
19492
    */
 
19493
    if (WXS_SUBST_HEAD(elemDecl) != NULL) {
 
19494
        xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
 
19495
 
 
19496
        xmlSchemaCheckElementDeclComponent(head, pctxt);
 
19497
        /*
 
19498
        * SPEC (3) "If there is a non-ļæ½absentļæ½ {substitution group
 
19499
        * affiliation}, then {scope} must be global."
 
19500
        */
 
19501
        if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
 
19502
            xmlSchemaPCustomErr(pctxt,
 
19503
                XML_SCHEMAP_E_PROPS_CORRECT_3,
 
19504
                WXS_BASIC_CAST elemDecl, NULL,
 
19505
                "Only global element declarations can have a "
 
19506
                "substitution group affiliation", NULL);
 
19507
            ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
 
19508
        }
 
19509
        /*
 
19510
        * TODO: SPEC (6) "Circular substitution groups are disallowed.
 
19511
        * That is, it must not be possible to return to an element declaration
 
19512
        * by repeatedly following the {substitution group affiliation}
 
19513
        * property."
 
19514
        */
 
19515
        if (head == elemDecl)
 
19516
            circ = head;
 
19517
        else if (WXS_SUBST_HEAD(head) != NULL)
 
19518
            circ = xmlSchemaCheckSubstGroupCircular(head, head);
 
19519
        else
 
19520
            circ = NULL;
 
19521
        if (circ != NULL) {
 
19522
            xmlChar *strA = NULL, *strB = NULL;
 
19523
 
 
19524
            xmlSchemaPCustomErrExt(pctxt,
 
19525
                XML_SCHEMAP_E_PROPS_CORRECT_6,
 
19526
                WXS_BASIC_CAST circ, NULL,
 
19527
                "The element declaration '%s' defines a circular "
 
19528
                "substitution group to element declaration '%s'",
 
19529
                xmlSchemaGetComponentQName(&strA, circ),
 
19530
                xmlSchemaGetComponentQName(&strB, head),
 
19531
                NULL);
 
19532
            FREE_AND_NULL(strA)
 
19533
            FREE_AND_NULL(strB)
 
19534
            ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
 
19535
        }
 
19536
        /*
 
19537
        * SPEC (4) "If there is a {substitution group affiliation},
 
19538
        * the {type definition}
 
19539
        * of the element declaration must be validly derived from the {type
 
19540
        * definition} of the {substitution group affiliation}, given the value
 
19541
        * of the {substitution group exclusions} of the {substitution group
 
19542
        * affiliation}, as defined in Type Derivation OK (Complex) (ļæ½3.4.6)
 
19543
        * (if the {type definition} is complex) or as defined in
 
19544
        * Type Derivation OK (Simple) (ļæ½3.14.6) (if the {type definition} is
 
19545
        * simple)."
 
19546
        *
 
19547
        * NOTE: {substitution group exclusions} means the values of the
 
19548
        * attribute "final".
 
19549
        */
 
19550
 
 
19551
        if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
 
19552
            int set = 0;
 
19553
 
 
19554
            if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
 
19555
                set |= SUBSET_EXTENSION;
 
19556
            if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
 
19557
                set |= SUBSET_RESTRICTION;
 
19558
 
 
19559
            if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
 
19560
                WXS_ELEM_TYPEDEF(head), set) != 0) {
 
19561
                xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
 
19562
 
 
19563
                ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
 
19564
                xmlSchemaPCustomErrExt(pctxt,
 
19565
                    XML_SCHEMAP_E_PROPS_CORRECT_4,
 
19566
                    WXS_BASIC_CAST elemDecl, NULL,
 
19567
                    "The type definition '%s' was "
 
19568
                    "either rejected by the substitution group "
 
19569
                    "affiliation '%s', or not validly derived from its type "
 
19570
                    "definition '%s'",
 
19571
                    xmlSchemaGetComponentQName(&strA, typeDef),
 
19572
                    xmlSchemaGetComponentQName(&strB, head),
 
19573
                    xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
 
19574
                FREE_AND_NULL(strA)
 
19575
                FREE_AND_NULL(strB)
 
19576
                FREE_AND_NULL(strC)
 
19577
            }
 
19578
        }
 
19579
    }
 
19580
    /*
 
19581
    * SPEC (5) "If the {type definition} or {type definition}'s
 
19582
    * {content type}
 
19583
    * is or is derived from ID then there must not be a {value constraint}.
 
19584
    * Note: The use of ID as a type definition for elements goes beyond
 
19585
    * XML 1.0, and should be avoided if backwards compatibility is desired"
 
19586
    */
 
19587
    if ((elemDecl->value != NULL) &&
 
19588
        ((WXS_IS_SIMPLE(typeDef) &&
 
19589
          xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
 
19590
         (WXS_IS_COMPLEX(typeDef) &&
 
19591
          WXS_HAS_SIMPLE_CONTENT(typeDef) &&
 
19592
          xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
 
19593
            XML_SCHEMAS_ID)))) {
 
19594
 
 
19595
        ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
 
19596
        xmlSchemaPCustomErr(pctxt,
 
19597
            XML_SCHEMAP_E_PROPS_CORRECT_5,
 
19598
            WXS_BASIC_CAST elemDecl, NULL,
 
19599
            "The type definition (or type definition's content type) is or "
 
19600
            "is derived from ID; value constraints are not allowed in "
 
19601
            "conjunction with such a type definition", NULL);
 
19602
    } else if (elemDecl->value != NULL) {
 
19603
        int vcret;
 
19604
        xmlNodePtr node = NULL;
 
19605
 
 
19606
        /*
 
19607
        * SPEC (2) "If there is a {value constraint}, the canonical lexical
 
19608
        * representation of its value must be ļæ½validļæ½ with respect to the
 
19609
        * {type definition} as defined in Element Default Valid (Immediate)
 
19610
        * (ļæ½3.3.6)."
 
19611
        */
 
19612
        if (typeDef == NULL) {
 
19613
            xmlSchemaPErr(pctxt, elemDecl->node,
 
19614
                XML_SCHEMAP_INTERNAL,
 
19615
                "Internal error: xmlSchemaCheckElemPropsCorrect, "
 
19616
                "type is missing... skipping validation of "
 
19617
                "the value constraint", NULL, NULL);
 
19618
            return (-1);
 
19619
        }
 
19620
        if (elemDecl->node != NULL) {
 
19621
            if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
 
19622
                node = (xmlNodePtr) xmlHasProp(elemDecl->node,
 
19623
                    BAD_CAST "fixed");
 
19624
            else
 
19625
                node = (xmlNodePtr) xmlHasProp(elemDecl->node,
 
19626
                    BAD_CAST "default");
 
19627
        }
 
19628
        vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
 
19629
            typeDef, elemDecl->value, &(elemDecl->defVal));
 
19630
        if (vcret != 0) {
 
19631
            if (vcret < 0) {
 
19632
                PERROR_INT("xmlSchemaElemCheckValConstr",
 
19633
                    "failed to validate the value constraint of an "
 
19634
                    "element declaration");
 
19635
                return (-1);
 
19636
            }
 
19637
            return (vcret);
 
19638
        }
 
19639
    }
 
19640
 
 
19641
    return (ret);
 
19642
}
 
19643
 
 
19644
/**
 
19645
 * xmlSchemaCheckElemSubstGroup:
 
19646
 * @ctxt:  a schema parser context
 
19647
 * @decl: the element declaration
 
19648
 * @name:  the name of the attribute
 
19649
 *
 
19650
 * Schema Component Constraint:
 
19651
 * Substitution Group (cos-equiv-class)
 
19652
 *
 
19653
 * In Libxml2 the subst. groups will be precomputed, in terms of that
 
19654
 * a list will be built for each subst. group head, holding all direct
 
19655
 * referents to this head.
 
19656
 * NOTE that this function needs:
 
19657
 *   1. circular subst. groups to be checked beforehand
 
19658
 *   2. the declaration's type to be derived from the head's type
 
19659
 *
 
19660
 * STATUS:
 
19661
 *
 
19662
 */
 
19663
static void
 
19664
xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
 
19665
                             xmlSchemaElementPtr elemDecl)
 
19666
{
 
19667
    if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
 
19668
        /* SPEC (1) "Its {abstract} is false." */
 
19669
        (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
 
19670
        return;
 
19671
    {
 
19672
        xmlSchemaElementPtr head;
 
19673
        xmlSchemaTypePtr headType, type;
 
19674
        int set, methSet;
 
19675
        /*
 
19676
        * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
 
19677
        * {disallowed substitutions} as the blocking constraint, as defined in
 
19678
        * Substitution Group OK (Transitive) (ļæ½3.3.6)."
 
19679
        */
 
19680
        for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
 
19681
            head = WXS_SUBST_HEAD(head)) {
 
19682
            set = 0;
 
19683
            methSet = 0;
 
19684
            /*
 
19685
            * The blocking constraints.
 
19686
            */
 
19687
            if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
 
19688
                continue;
 
19689
            headType = head->subtypes;
 
19690
            type = elemDecl->subtypes;
 
19691
            if (headType == type)
 
19692
                goto add_member;
 
19693
            if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
 
19694
                set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
 
19695
            if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
 
19696
                set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
 
19697
            /*
 
19698
            * SPEC: Substitution Group OK (Transitive) (2.3)
 
19699
            * "The set of all {derivation method}s involved in the
 
19700
            * derivation of D's {type definition} from C's {type definition}
 
19701
            * does not intersect with the union of the blocking constraint,
 
19702
            * C's {prohibited substitutions} (if C is complex, otherwise the
 
19703
            * empty set) and the {prohibited substitutions} (respectively the
 
19704
            * empty set) of any intermediate {type definition}s in the
 
19705
            * derivation of D's {type definition} from C's {type definition}."
 
19706
            */
 
19707
            /*
 
19708
            * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
 
19709
            * subst.head axis, the methSet does not need to be computed for
 
19710
            * the full depth over and over.
 
19711
            */
 
19712
            /*
 
19713
            * The set of all {derivation method}s involved in the derivation
 
19714
            */
 
19715
            while ((type != NULL) && (type != headType)) {
 
19716
                if ((WXS_IS_EXTENSION(type)) &&
 
19717
                    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
 
19718
                    methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
 
19719
 
 
19720
                if (WXS_IS_RESTRICTION(type) &&
 
19721
                    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
 
19722
                    methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
 
19723
 
 
19724
                type = type->baseType;
 
19725
            }
 
19726
            /*
 
19727
            * The {prohibited substitutions} of all intermediate types +
 
19728
            * the head's type.
 
19729
            */
 
19730
            type = elemDecl->subtypes->baseType;
 
19731
            while (type != NULL) {
 
19732
                if (WXS_IS_COMPLEX(type)) {
 
19733
                    if ((type->flags &
 
19734
                            XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
 
19735
                        ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
 
19736
                    set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
 
19737
                    if ((type->flags &
 
19738
                            XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
 
19739
                        ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
 
19740
                    set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
 
19741
                } else
 
19742
                    break;
 
19743
                if (type == headType)
 
19744
                    break;
 
19745
                type = type->baseType;
 
19746
            }
 
19747
            if ((set != 0) &&
 
19748
                (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
 
19749
                (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
 
19750
                ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
 
19751
                (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
 
19752
                continue;
 
19753
            }
 
19754
add_member:
 
19755
            xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
 
19756
            if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
 
19757
                head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
 
19758
        }
 
19759
    }
 
19760
}
 
19761
 
 
19762
#ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
 
19763
/**
 
19764
 * xmlSchemaCheckElementDeclComponent
 
19765
 * @pctxt: the schema parser context
 
19766
 * @ctxtComponent: the context component (an element declaration)
 
19767
 * @ctxtParticle: the first particle of the context component
 
19768
 * @searchParticle: the element declaration particle to be analysed
 
19769
 *
 
19770
 * Schema Component Constraint: Element Declarations Consistent 
 
19771
 */
 
19772
static int
 
19773
xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
 
19774
                                    xmlSchemaBasicItemPtr ctxtComponent,
 
19775
                                    xmlSchemaParticlePtr ctxtParticle,                              
 
19776
                                    xmlSchemaParticlePtr searchParticle,
 
19777
                                    xmlSchemaParticlePtr curParticle,
 
19778
                                    int search)
 
19779
{
 
19780
    return(0);
 
19781
 
 
19782
    int ret = 0;
 
19783
    xmlSchemaParticlePtr cur = curParticle;
 
19784
    if (curParticle == NULL) {  
 
19785
        return(0);
 
19786
    }
 
19787
    if (WXS_PARTICLE_TERM(curParticle) == NULL) {
 
19788
        /*
 
19789
        * Just return in this case. A missing "term" of the particle
 
19790
        * might arise due to an invalid "term" component.
 
19791
        */
 
19792
        return(0);
 
19793
    }    
 
19794
    while (cur != NULL) {
 
19795
        switch (WXS_PARTICLE_TERM(cur)->type) {
 
19796
            case XML_SCHEMA_TYPE_ANY:
 
19797
                break;
 
19798
            case XML_SCHEMA_TYPE_ELEMENT:
 
19799
                if (search == 0) {
 
19800
                    ret = xmlSchemaCheckElementDeclConsistent(pctxt,
 
19801
                        ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
 
19802
                    if (ret != 0)
 
19803
                        return(ret);                
 
19804
                } else {
 
19805
                    xmlSchemaElementPtr elem =
 
19806
                        WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
 
19807
                    /*
 
19808
                    * SPEC Element Declarations Consistent:
 
19809
                    * "If the {particles} contains, either directly,
 
19810
                    * indirectly (that is, within the {particles} of a
 
19811
                    * contained model group, recursively) or ļæ½implicitlyļæ½
 
19812
                    * two or more element declaration particles with
 
19813
                    * the same {name} and {target namespace}, then
 
19814
                    * all their type definitions must be the same
 
19815
                    * top-level definition [...]"
 
19816
                    */
 
19817
                    if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
 
19818
                            WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
 
19819
                        xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
 
19820
                            WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
 
19821
                    {
 
19822
                        xmlChar *strA = NULL, *strB = NULL;
 
19823
                        
 
19824
                        xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
19825
                            /* TODO: error code */
 
19826
                            XML_SCHEMAP_COS_NONAMBIG,
 
19827
                            WXS_ITEM_NODE(cur), NULL,
 
19828
                            "In the content model of %s, there are multiple "
 
19829
                            "element declarations for '%s' with different "
 
19830
                            "type definitions",
 
19831
                            xmlSchemaGetComponentDesignation(&strA,
 
19832
                                ctxtComponent),
 
19833
                            xmlSchemaFormatQName(&strB,
 
19834
                                WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
 
19835
                                WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
 
19836
                        FREE_AND_NULL(strA);
 
19837
                        FREE_AND_NULL(strB);
 
19838
                        return(XML_SCHEMAP_COS_NONAMBIG);
 
19839
                    }
 
19840
                }           
 
19841
                break;
 
19842
            case XML_SCHEMA_TYPE_SEQUENCE: {            
 
19843
                break;
 
19844
                }
 
19845
            case XML_SCHEMA_TYPE_CHOICE:{
 
19846
                /*
 
19847
                xmlSchemaTreeItemPtr sub;
 
19848
                
 
19849
                sub = WXS_PARTICLE_TERM(particle)->children;  (xmlSchemaParticlePtr) 
 
19850
                while (sub != NULL) {
 
19851
                    ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
 
19852
                        ctxtParticle, ctxtElem);
 
19853
                    if (ret != 0)
 
19854
                        return(ret);
 
19855
                    sub = sub->next;
 
19856
                }
 
19857
                */
 
19858
                break;
 
19859
                }
 
19860
            case XML_SCHEMA_TYPE_ALL:
 
19861
                break;
 
19862
            case XML_SCHEMA_TYPE_GROUP:
 
19863
                break;
 
19864
            default:
 
19865
                xmlSchemaInternalErr2(ACTXT_CAST pctxt,
 
19866
                    "xmlSchemaCheckElementDeclConsistent",
 
19867
                    "found unexpected term of type '%s' in content model",
 
19868
                    WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
 
19869
                return(-1);
 
19870
        }
 
19871
        cur = (xmlSchemaParticlePtr) cur->next;
 
19872
    }
 
19873
 
 
19874
exit:
 
19875
    return(ret);
 
19876
}
 
19877
#endif
 
19878
 
 
19879
/**
 
19880
 * xmlSchemaCheckElementDeclComponent
 
19881
 * @item:  an schema element declaration/particle
 
19882
 * @ctxt:  a schema parser context
 
19883
 * @name:  the name of the attribute
 
19884
 *
 
19885
 * Validates the value constraints of an element declaration.
 
19886
 * Adds substitution group members. 
 
19887
 */
 
19888
static void
 
19889
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
 
19890
                                   xmlSchemaParserCtxtPtr ctxt)
 
19891
{
 
19892
    if (elemDecl == NULL)
 
19893
        return;
 
19894
    if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
 
19895
        return;
 
19896
    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
 
19897
    if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
 
19898
        /*
 
19899
        * Adds substitution group members.
 
19900
        */
 
19901
        xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);   
 
19902
    }
 
19903
}
 
19904
 
 
19905
/**
 
19906
 * xmlSchemaResolveModelGroupParticleReferences:
 
19907
 * @particle:  a particle component
 
19908
 * @ctxt:  a parser context
 
19909
 *
 
19910
 * Resolves references of a model group's {particles} to
 
19911
 * model group definitions and to element declarations.
 
19912
 */
 
19913
static void
 
19914
xmlSchemaResolveModelGroupParticleReferences(
 
19915
    xmlSchemaParserCtxtPtr ctxt,
 
19916
    xmlSchemaModelGroupPtr mg)
 
19917
{
 
19918
    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
 
19919
    xmlSchemaQNameRefPtr ref;
 
19920
    xmlSchemaBasicItemPtr refItem;
 
19921
 
 
19922
    /*
 
19923
    * URGENT TODO: Test this.
 
19924
    */
 
19925
    while (particle != NULL) {
 
19926
        if ((WXS_PARTICLE_TERM(particle) == NULL) ||
 
19927
            ((WXS_PARTICLE_TERM(particle))->type !=
 
19928
                XML_SCHEMA_EXTRA_QNAMEREF))
 
19929
        {
 
19930
            goto next_particle;
 
19931
        } 
 
19932
        ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
 
19933
        /*
 
19934
        * Resolve the reference.
 
19935
        * NULL the {term} by default.
 
19936
        */
 
19937
        particle->children = NULL;
 
19938
 
 
19939
        refItem = xmlSchemaGetNamedComponent(ctxt->schema,
 
19940
            ref->itemType, ref->name, ref->targetNamespace);
 
19941
        if (refItem == NULL) {
 
19942
            xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
 
19943
                NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
 
19944
                ref->targetNamespace, ref->itemType, NULL);
 
19945
            /* TODO: remove the particle. */
 
19946
            goto next_particle;
 
19947
        } 
 
19948
        if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
 
19949
            if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
 
19950
                /* TODO: remove the particle. */
 
19951
                goto next_particle;
 
19952
            /*
 
19953
            * NOTE that we will assign the model group definition
 
19954
            * itself to the "term" of the particle. This will ease
 
19955
            * the check for circular model group definitions. After
 
19956
            * that the "term" will be assigned the model group of the
 
19957
            * model group definition.
 
19958
            */
 
19959
            if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
 
19960
                    XML_SCHEMA_TYPE_ALL) {
 
19961
                /*
 
19962
                * SPEC cos-all-limited (1)
 
19963
                * SPEC cos-all-limited (1.2)
 
19964
                * "It appears only as the value of one or both of the
 
19965
                * following properties:"
 
19966
                * (1.1) "the {model group} property of a model group
 
19967
                *        definition."
 
19968
                * (1.2) "the {term} property of a particle [... of] the "
 
19969
                * {content type} of a complex type definition."
 
19970
                */
 
19971
                xmlSchemaCustomErr(ACTXT_CAST ctxt,
 
19972
                    /* TODO: error code */
 
19973
                    XML_SCHEMAP_COS_ALL_LIMITED,
 
19974
                    WXS_ITEM_NODE(particle), NULL,
 
19975
                    "A model group definition is referenced, but "
 
19976
                    "it contains an 'all' model group, which "
 
19977
                    "cannot be contained by model groups",
 
19978
                    NULL, NULL);
 
19979
                /* TODO: remove the particle. */
 
19980
                goto next_particle;
 
19981
            }
 
19982
            particle->children = (xmlSchemaTreeItemPtr) refItem;
 
19983
        } else {
 
19984
            /*
 
19985
            * TODO: Are referenced element declarations the only
 
19986
            * other components we expect here?
 
19987
            */
 
19988
            particle->children = (xmlSchemaTreeItemPtr) refItem;
 
19989
        }
 
19990
next_particle:
 
19991
        particle = WXS_PTC_CAST particle->next;
 
19992
    }
 
19993
}
 
19994
 
 
19995
static int
 
19996
xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
 
19997
                       xmlSchemaValPtr y) 
 
19998
{   
 
19999
    xmlSchemaTypePtr tx, ty, ptx, pty;    
 
20000
    int ret;
 
20001
 
 
20002
    while (x != NULL) {
 
20003
        /* Same types. */
 
20004
        tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
 
20005
        ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
 
20006
        ptx = xmlSchemaGetPrimitiveType(tx);
 
20007
        pty = xmlSchemaGetPrimitiveType(ty);
 
20008
        /*
 
20009
        * (1) if a datatype T' is ļæ½derivedļæ½ by ļæ½restrictionļæ½ from an
 
20010
        * atomic datatype T then the ļæ½value spaceļæ½ of T' is a subset of
 
20011
        * the ļæ½value spaceļæ½ of T. */
 
20012
        /*
 
20013
        * (2) if datatypes T' and T'' are ļæ½derivedļæ½ by ļæ½restrictionļæ½
 
20014
        * from a common atomic ancestor T then the ļæ½value spaceļæ½s of T'
 
20015
        * and T'' may overlap.
 
20016
        */
 
20017
        if (ptx != pty)
 
20018
            return(0);
 
20019
        /*
 
20020
        * We assume computed values to be normalized, so do a fast
 
20021
        * string comparison for string based types.
 
20022
        */
 
20023
        if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
 
20024
            WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
 
20025
            if (! xmlStrEqual(
 
20026
                xmlSchemaValueGetAsString(x),
 
20027
                xmlSchemaValueGetAsString(y)))
 
20028
                return (0);
 
20029
        } else {
 
20030
            ret = xmlSchemaCompareValuesWhtsp(
 
20031
                x, XML_SCHEMA_WHITESPACE_PRESERVE,
 
20032
                y, XML_SCHEMA_WHITESPACE_PRESERVE);
 
20033
            if (ret == -2)
 
20034
                return(-1);
 
20035
            if (ret != 0)
 
20036
                return(0);
 
20037
        }
 
20038
        /*
 
20039
        * Lists.
 
20040
        */
 
20041
        x = xmlSchemaValueGetNext(x);
 
20042
        if (x != NULL) {
 
20043
            y = xmlSchemaValueGetNext(y);
 
20044
            if (y == NULL)
 
20045
                return (0);         
 
20046
        } else if (xmlSchemaValueGetNext(y) != NULL)
 
20047
            return (0);
 
20048
        else
 
20049
            return (1);
 
20050
    }
 
20051
    return (0);
 
20052
}
 
20053
 
 
20054
/**
 
20055
 * xmlSchemaResolveAttrUseReferences:
 
20056
 * @item:  an attribute use
 
20057
 * @ctxt:  a parser context
 
20058
 *
 
20059
 * Resolves the referenced attribute declaration.
 
20060
 */
 
20061
static int
 
20062
xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
 
20063
                                  xmlSchemaParserCtxtPtr ctxt)
 
20064
{
 
20065
    if ((ctxt == NULL) || (ause == NULL))
 
20066
        return(-1);
 
20067
    if ((ause->attrDecl == NULL) ||
 
20068
        (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
 
20069
        return(0);
 
20070
 
 
20071
    {
 
20072
        xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
 
20073
 
 
20074
        /*
 
20075
        * TODO: Evaluate, what errors could occur if the declaration is not
 
20076
        * found.
 
20077
        */
 
20078
        ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
 
20079
            ref->name, ref->targetNamespace);
 
20080
        if (ause->attrDecl == NULL) {
 
20081
            xmlSchemaPResCompAttrErr(ctxt,
 
20082
                XML_SCHEMAP_SRC_RESOLVE,
 
20083
                WXS_BASIC_CAST ause, ause->node,
 
20084
                "ref", ref->name, ref->targetNamespace,
 
20085
                XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
 
20086
            return(ctxt->err);;
 
20087
        }
 
20088
    }
 
20089
    return(0);
 
20090
}
 
20091
 
 
20092
/**
 
20093
 * xmlSchemaCheckAttrUsePropsCorrect:
 
20094
 * @ctxt:  a parser context
 
20095
 * @use:  an attribute use 
 
20096
 *
 
20097
 * Schema Component Constraint:
 
20098
 * Attribute Use Correct (au-props-correct)
 
20099
 * 
 
20100
 */
 
20101
static int
 
20102
xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
 
20103
                             xmlSchemaAttributeUsePtr use)
 
20104
{
 
20105
    if ((ctxt == NULL) || (use == NULL))
 
20106
        return(-1);
 
20107
    if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
 
20108
        ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
 
20109
        return(0);      
 
20110
 
 
20111
    /*
 
20112
    * SPEC au-props-correct (1)
 
20113
    * "The values of the properties of an attribute use must be as
 
20114
    * described in the property tableau in The Attribute Use Schema
 
20115
    * Component (ļæ½3.5.1), modulo the impact of Missing
 
20116
    * Sub-components (ļæ½5.3)."
 
20117
    */
 
20118
    
 
20119
    if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
 
20120
        ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
 
20121
        ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
 
20122
    {
 
20123
        xmlSchemaPCustomErr(ctxt,
 
20124
            XML_SCHEMAP_AU_PROPS_CORRECT_2,
 
20125
            WXS_BASIC_CAST use, NULL,
 
20126
            "The attribute declaration has a 'fixed' value constraint "
 
20127
            ", thus the attribute use must also have a 'fixed' value "
 
20128
            "constraint",
 
20129
            NULL);
 
20130
        return(ctxt->err);
 
20131
    }
 
20132
    /*
 
20133
    * Compute and check the value constraint's value.
 
20134
    */
 
20135
    if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
 
20136
        int ret;
 
20137
        /*
 
20138
        * TODO: The spec seems to be missing a check of the 
 
20139
        * value constraint of the attribute use. We will do it here.
 
20140
        */
 
20141
        /*
 
20142
        * SPEC a-props-correct (3)
 
20143
        */
 
20144
        if (xmlSchemaIsDerivedFromBuiltInType(
 
20145
            WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
 
20146
        {
 
20147
            xmlSchemaCustomErr(ACTXT_CAST ctxt,
 
20148
                XML_SCHEMAP_AU_PROPS_CORRECT,
 
20149
                NULL, WXS_BASIC_CAST use,
 
20150
                "Value constraints are not allowed if the type definition "
 
20151
                "is or is derived from xs:ID",
 
20152
                NULL, NULL);
 
20153
            return(ctxt->err);
 
20154
        }
 
20155
        
 
20156
        ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
 
20157
            use->node, WXS_ATTRUSE_TYPEDEF(use),
 
20158
            use->defValue, &(use->defVal),
 
20159
            1, 1, 0);
 
20160
        if (ret != 0) {
 
20161
            if (ret < 0) {
 
20162
                PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
 
20163
                    "calling xmlSchemaVCheckCVCSimpleType()");
 
20164
                return(-1);
 
20165
            }
 
20166
            xmlSchemaCustomErr(ACTXT_CAST ctxt,
 
20167
                XML_SCHEMAP_AU_PROPS_CORRECT,
 
20168
                NULL, WXS_BASIC_CAST use,
 
20169
                "The value of the value constraint is not valid",
 
20170
                NULL, NULL);
 
20171
            return(ctxt->err);
 
20172
        }
 
20173
    }
 
20174
    /*
 
20175
    * SPEC au-props-correct (2)
 
20176
    * "If the {attribute declaration} has a fixed
 
20177
    * {value constraint}, then if the attribute use itself has a
 
20178
    * {value constraint}, it must also be fixed and its value must match
 
20179
    * that of the {attribute declaration}'s {value constraint}."
 
20180
    */
 
20181
    if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
 
20182
        (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
 
20183
    {
 
20184
        if (! xmlSchemaAreValuesEqual(use->defVal,
 
20185
                (WXS_ATTRUSE_DECL(use))->defVal))
 
20186
        {
 
20187
            xmlSchemaPCustomErr(ctxt,
 
20188
                XML_SCHEMAP_AU_PROPS_CORRECT_2,
 
20189
                WXS_BASIC_CAST use, NULL,
 
20190
                "The 'fixed' value constraint of the attribute use "
 
20191
                "must match the attribute declaration's value "
 
20192
                "constraint '%s'",
 
20193
                (WXS_ATTRUSE_DECL(use))->defValue);
 
20194
        }
 
20195
        return(ctxt->err);
 
20196
    }
 
20197
    return(0);
 
20198
}
 
20199
 
 
20200
 
 
20201
 
 
20202
 
 
20203
/**
 
20204
 * xmlSchemaResolveAttrTypeReferences:
 
20205
 * @item:  an attribute declaration
 
20206
 * @ctxt:  a parser context 
 
20207
 *
 
20208
 * Resolves the referenced type definition component.
 
20209
 */
 
20210
static int
 
20211
xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
 
20212
                                   xmlSchemaParserCtxtPtr ctxt)
 
20213
{
 
20214
    /*
 
20215
    * The simple type definition corresponding to the <simpleType> element
 
20216
    * information item in the [children], if present, otherwise the simple
 
20217
    * type definition ļæ½resolvedļæ½ to by the ļæ½actual valueļæ½ of the type
 
20218
    * [attribute], if present, otherwise the ļæ½simple ur-type definitionļæ½.
 
20219
    */
 
20220
    if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
 
20221
        return(0);
 
20222
    item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
 
20223
    if (item->subtypes != NULL)
 
20224
        return(0);
 
20225
    if (item->typeName != NULL) {
 
20226
        xmlSchemaTypePtr type;
 
20227
 
 
20228
        type = xmlSchemaGetType(ctxt->schema, item->typeName,
 
20229
            item->typeNs);
 
20230
        if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
 
20231
            xmlSchemaPResCompAttrErr(ctxt,
 
20232
                XML_SCHEMAP_SRC_RESOLVE,
 
20233
                WXS_BASIC_CAST item, item->node,
 
20234
                "type", item->typeName, item->typeNs,
 
20235
                XML_SCHEMA_TYPE_SIMPLE, NULL);
 
20236
            return(ctxt->err);
 
20237
        } else
 
20238
            item->subtypes = type;
 
20239
 
 
20240
    } else {
 
20241
        /*
 
20242
        * The type defaults to the xs:anySimpleType.
 
20243
        */
 
20244
        item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
 
20245
    }
 
20246
    return(0);
 
20247
}
 
20248
 
 
20249
/**
 
20250
 * xmlSchemaResolveIDCKeyReferences:
 
20251
 * @idc:  the identity-constraint definition
 
20252
 * @ctxt:  the schema parser context
 
20253
 * @name:  the attribute name
 
20254
 *
 
20255
 * Resolve keyRef references to key/unique IDCs.
 
20256
 * Schema Component Constraint:
 
20257
 *   Identity-constraint Definition Properties Correct (c-props-correct)
 
20258
 */
 
20259
static int
 
20260
xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
 
20261
                          xmlSchemaParserCtxtPtr pctxt)
 
20262
{
 
20263
    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
 
20264
        return(0);
 
20265
    if (idc->ref->name != NULL) {
 
20266
        idc->ref->item = (xmlSchemaBasicItemPtr)
 
20267
            xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
 
20268
                idc->ref->targetNamespace);
 
20269
        if (idc->ref->item == NULL) {
 
20270
            /*
 
20271
            * TODO: It is actually not an error to fail to resolve
 
20272
            * at this stage. BUT we need to be that strict!
 
20273
            */
 
20274
            xmlSchemaPResCompAttrErr(pctxt,
 
20275
                XML_SCHEMAP_SRC_RESOLVE,
 
20276
                WXS_BASIC_CAST idc, idc->node,
 
20277
                "refer", idc->ref->name,
 
20278
                idc->ref->targetNamespace,
 
20279
                XML_SCHEMA_TYPE_IDC_KEY, NULL);
 
20280
            return(pctxt->err);
 
20281
        } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
 
20282
            /*
 
20283
            * SPEC c-props-correct (1)
 
20284
            */
 
20285
            xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
20286
                XML_SCHEMAP_C_PROPS_CORRECT,
 
20287
                NULL, WXS_BASIC_CAST idc,
 
20288
                "The keyref references a keyref",
 
20289
                NULL, NULL);
 
20290
            idc->ref->item = NULL;
 
20291
            return(pctxt->err);
 
20292
        } else {
 
20293
            if (idc->nbFields !=
 
20294
                ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
 
20295
                xmlChar *str = NULL;
 
20296
                xmlSchemaIDCPtr refer;
 
20297
                
 
20298
                refer = (xmlSchemaIDCPtr) idc->ref->item;
 
20299
                /*
 
20300
                * SPEC c-props-correct(2)
 
20301
                * "If the {identity-constraint category} is keyref,
 
20302
                * the cardinality of the {fields} must equal that of
 
20303
                * the {fields} of the {referenced key}.
 
20304
                */
 
20305
                xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
20306
                    XML_SCHEMAP_C_PROPS_CORRECT,
 
20307
                    NULL, WXS_BASIC_CAST idc,
 
20308
                    "The cardinality of the keyref differs from the "
 
20309
                    "cardinality of the referenced key/unique '%s'",
 
20310
                    xmlSchemaFormatQName(&str, refer->targetNamespace,
 
20311
                        refer->name),
 
20312
                    NULL);
 
20313
                FREE_AND_NULL(str)
 
20314
                return(pctxt->err);
 
20315
            }
 
20316
        }
 
20317
    }
 
20318
    return(0);
 
20319
}
 
20320
 
 
20321
static int
 
20322
xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
 
20323
                                       xmlSchemaParserCtxtPtr pctxt)
 
20324
{
 
20325
    if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
 
20326
        prohib->targetNamespace) == NULL) {
 
20327
 
 
20328
        xmlSchemaPResCompAttrErr(pctxt,
 
20329
            XML_SCHEMAP_SRC_RESOLVE,
 
20330
            NULL, prohib->node,
 
20331
            "ref", prohib->name, prohib->targetNamespace,
 
20332
            XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
 
20333
        return(XML_SCHEMAP_SRC_RESOLVE);
 
20334
    }
 
20335
    return(0);
 
20336
}
 
20337
 
 
20338
#define WXS_REDEFINED_TYPE(c) \
 
20339
(((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
 
20340
 
 
20341
#define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
 
20342
(((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
 
20343
 
 
20344
#define WXS_REDEFINED_ATTR_GROUP(c) \
 
20345
(((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
 
20346
 
 
20347
static int
 
20348
xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
 
20349
{
 
20350
    int err = 0;
 
20351
    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
 
20352
    xmlSchemaBasicItemPtr prev, item;
 
20353
    int wasRedefined;
 
20354
 
 
20355
    if (redef == NULL)
 
20356
        return(0);      
 
20357
 
 
20358
    do {
 
20359
        item = redef->item;
 
20360
        /*
 
20361
        * First try to locate the redefined component in the
 
20362
        * schema graph starting with the redefined schema.
 
20363
        * NOTE: According to this schema bug entry:
 
20364
        *   http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
 
20365
        *   it's not clear if the referenced component needs to originate
 
20366
        *   from the <redefine>d schema _document_ or the schema; the latter
 
20367
        *   would include all imported and included sub-schemas of the
 
20368
        *   <redefine>d schema. Currenlty we latter approach is used.
 
20369
        *   SUPPLEMENT: It seems that the WG moves towards the latter
 
20370
        *   approach, so we are doing it right.
 
20371
        *   
 
20372
        */
 
20373
        prev = xmlSchemaFindRedefCompInGraph(
 
20374
            redef->targetBucket, item->type,
 
20375
            redef->refName, redef->refTargetNs);
 
20376
        if (prev == NULL) {
 
20377
            xmlChar *str = NULL;
 
20378
            xmlNodePtr node;
 
20379
 
 
20380
            /*
 
20381
            * SPEC src-redefine:
 
20382
            * (6.2.1) "The ļæ½actual valueļæ½ of its own name attribute plus
 
20383
            * target namespace must successfully ļæ½resolveļæ½ to a model
 
20384
            * group definition in I."
 
20385
            * (7.2.1) "The ļæ½actual valueļæ½ of its own name attribute plus
 
20386
            * target namespace must successfully ļæ½resolveļæ½ to an attribute
 
20387
            * group definition in I."
 
20388
 
 
20389
            *
 
20390
            * Note that, if we are redefining with the use of references
 
20391
            * to components, the spec assumes the src-resolve to be used;
 
20392
            * but this won't assure that we search only *inside* the
 
20393
            * redefined schema.
 
20394
            */
 
20395
            if (redef->reference)
 
20396
                node = WXS_ITEM_NODE(redef->reference);
 
20397
            else
 
20398
                node = WXS_ITEM_NODE(item);
 
20399
            xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
20400
                /*
 
20401
                * TODO: error code.
 
20402
                * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
 
20403
                * reference kind.               
 
20404
                */
 
20405
                XML_SCHEMAP_SRC_REDEFINE, node, NULL,
 
20406
                "The %s '%s' to be redefined could not be found in "
 
20407
                "the redefined schema",
 
20408
                WXS_ITEM_TYPE_NAME(item),
 
20409
                xmlSchemaFormatQName(&str, redef->refTargetNs,
 
20410
                    redef->refName));
 
20411
            FREE_AND_NULL(str);     
 
20412
            err = pctxt->err;
 
20413
            redef = redef->next;
 
20414
            continue;
 
20415
        }
 
20416
        /*
 
20417
        * TODO: Obtaining and setting the redefinition state is really
 
20418
        * clumsy.
 
20419
        */
 
20420
        wasRedefined = 0;
 
20421
        switch (item->type) {
 
20422
            case XML_SCHEMA_TYPE_COMPLEX:
 
20423
            case XML_SCHEMA_TYPE_SIMPLE:
 
20424
                if ((WXS_TYPE_CAST prev)->flags &
 
20425
                    XML_SCHEMAS_TYPE_REDEFINED)
 
20426
                {
 
20427
                    wasRedefined = 1;
 
20428
                    break;
 
20429
                }
 
20430
                /* Mark it as redefined. */
 
20431
                (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
 
20432
                /*
 
20433
                * Assign the redefined type to the
 
20434
                * base type of the redefining type.
 
20435
                * TODO: How
 
20436
                */
 
20437
                ((xmlSchemaTypePtr) item)->baseType = 
 
20438
                    (xmlSchemaTypePtr) prev;
 
20439
                break;
 
20440
            case XML_SCHEMA_TYPE_GROUP:
 
20441
                if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
 
20442
                    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
 
20443
                {
 
20444
                    wasRedefined = 1;
 
20445
                    break;
 
20446
                }
 
20447
                /* Mark it as redefined. */
 
20448
                (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
 
20449
                    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
 
20450
                if (redef->reference != NULL) {
 
20451
                    /*
 
20452
                    * Overwrite the QName-reference with the
 
20453
                    * referenced model group def.
 
20454
                    */
 
20455
                    (WXS_PTC_CAST redef->reference)->children =
 
20456
                        WXS_TREE_CAST prev;
 
20457
                }
 
20458
                redef->target = prev;
 
20459
                break;
 
20460
            case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 
20461
                if ((WXS_ATTR_GROUP_CAST prev)->flags &
 
20462
                    XML_SCHEMAS_ATTRGROUP_REDEFINED)
 
20463
                {
 
20464
                    wasRedefined = 1;
 
20465
                    break;
 
20466
                }
 
20467
                (WXS_ATTR_GROUP_CAST prev)->flags |=
 
20468
                    XML_SCHEMAS_ATTRGROUP_REDEFINED;
 
20469
                if (redef->reference != NULL) {
 
20470
                    /*
 
20471
                    * Assign the redefined attribute group to the
 
20472
                    * QName-reference component.
 
20473
                    * This is the easy case, since we will just
 
20474
                    * expand the redefined group.
 
20475
                    */
 
20476
                    (WXS_QNAME_CAST redef->reference)->item = prev;
 
20477
                    redef->target = NULL;
 
20478
                } else {
 
20479
                    /*
 
20480
                    * This is the complicated case: we need
 
20481
                    * to apply src-redefine (7.2.2) at a later
 
20482
                    * stage, i.e. when attribute group references
 
20483
                    * have beed expanded and simple types have
 
20484
                    * beed fixed.
 
20485
                    */
 
20486
                    redef->target = prev;
 
20487
                }
 
20488
                break;
 
20489
            default:
 
20490
                PERROR_INT("xmlSchemaResolveRedefReferences",
 
20491
                    "Unexpected redefined component type");
 
20492
                return(-1);     
 
20493
        }
 
20494
        if (wasRedefined) {
 
20495
            xmlChar *str = NULL;
 
20496
            xmlNodePtr node;
 
20497
 
 
20498
            if (redef->reference)
 
20499
                node = WXS_ITEM_NODE(redef->reference);
 
20500
            else
 
20501
                node = WXS_ITEM_NODE(redef->item);
 
20502
            
 
20503
            xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
20504
                /* TODO: error code. */
 
20505
                XML_SCHEMAP_SRC_REDEFINE,
 
20506
                node, NULL,
 
20507
                "The referenced %s was already redefined. Multiple "
 
20508
                "redefinition of the same component is not supported",
 
20509
                xmlSchemaGetComponentDesignation(&str, prev),
 
20510
                NULL);
 
20511
            FREE_AND_NULL(str)      
 
20512
            err = pctxt->err;
 
20513
            redef = redef->next;
 
20514
            continue;
 
20515
        }
 
20516
        redef = redef->next;    
 
20517
    } while (redef != NULL);
 
20518
 
 
20519
    return(err);
 
20520
}
 
20521
 
 
20522
static int
 
20523
xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
 
20524
{
 
20525
    int err = 0;
 
20526
    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
 
20527
    xmlSchemaBasicItemPtr item;
 
20528
 
 
20529
    if (redef == NULL)
 
20530
        return(0);      
 
20531
 
 
20532
    do {
 
20533
        if (redef->target == NULL) {
 
20534
            redef = redef->next;
 
20535
            continue;
 
20536
        }
 
20537
        item = redef->item;
 
20538
                
 
20539
        switch (item->type) {
 
20540
            case XML_SCHEMA_TYPE_SIMPLE:
 
20541
            case XML_SCHEMA_TYPE_COMPLEX:
 
20542
                /*
 
20543
                * Since the spec wants the {name} of the redefined
 
20544
                * type to be 'absent', we'll NULL it.
 
20545
                */
 
20546
                (WXS_TYPE_CAST redef->target)->name = NULL;
 
20547
                
 
20548
                /*
 
20549
                * TODO: Seems like there's nothing more to do. The normal
 
20550
                * inheritance mechanism is used. But not 100% sure.
 
20551
                */
 
20552
                break;
 
20553
            case XML_SCHEMA_TYPE_GROUP:
 
20554
                /*
 
20555
                * URGENT TODO:
 
20556
                * SPEC src-redefine:
 
20557
                * (6.2.2) "The {model group} of the model group definition
 
20558
                * which corresponds to it per XML Representation of Model
 
20559
                * Group Definition Schema Components (ļæ½3.7.2) must be a
 
20560
                * ļæ½valid restrictionļæ½ of the {model group} of that model
 
20561
                * group definition in I, as defined in Particle Valid
 
20562
                * (Restriction) (ļæ½3.9.6)."
 
20563
                */
 
20564
                break;
 
20565
            case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 
20566
                /*
 
20567
                * SPEC src-redefine:
 
20568
                * (7.2.2) "The {attribute uses} and {attribute wildcard} of
 
20569
                * the attribute group definition which corresponds to it
 
20570
                * per XML Representation of Attribute Group Definition Schema
 
20571
                * Components (ļæ½3.6.2) must be ļæ½valid restrictionsļæ½ of the
 
20572
                * {attribute uses} and {attribute wildcard} of that attribute
 
20573
                * group definition in I, as defined in clause 2, clause 3 and
 
20574
                * clause 4 of Derivation Valid (Restriction, Complex)
 
20575
                * (ļæ½3.4.6) (where references to the base type definition are
 
20576
                * understood as references to the attribute group definition
 
20577
                * in I)."
 
20578
                */
 
20579
                err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
 
20580
                    XML_SCHEMA_ACTION_REDEFINE,
 
20581
                    item, redef->target,
 
20582
                    (WXS_ATTR_GROUP_CAST item)->attrUses,
 
20583
                    (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
 
20584
                    (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
 
20585
                    (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
 
20586
                if (err == -1)
 
20587
                    return(-1);
 
20588
                break;
 
20589
            default:
 
20590
                break;
 
20591
        }
 
20592
        redef = redef->next;
 
20593
    } while (redef != NULL);
 
20594
    return(0);
 
20595
}
 
20596
        
 
20597
 
 
20598
static int
 
20599
xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
 
20600
                       xmlSchemaBucketPtr bucket)
 
20601
{
 
20602
    xmlSchemaBasicItemPtr item;
 
20603
    int err;
 
20604
    xmlHashTablePtr *table;
 
20605
    const xmlChar *name;
 
20606
    int i;
 
20607
 
 
20608
#define WXS_GET_GLOBAL_HASH(c, slot) { \
 
20609
    if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
 
20610
        table = &(WXS_IMPBUCKET((c))->schema->slot); \
 
20611
    else \
 
20612
        table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
 
20613
 
 
20614
    /*
 
20615
    * Add global components to the schema's hash tables.
 
20616
    * This is the place where duplicate components will be
 
20617
    * detected.
 
20618
    * TODO: I think normally we should support imports of the
 
20619
    *   same namespace from multiple locations. We don't do currently,
 
20620
    *   but if we do then according to:
 
20621
    *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
 
20622
    *   we would need, if imported directly, to import redefined
 
20623
    *   components as well to be able to catch clashing components.
 
20624
    *   (I hope I'll still know what this means after some months :-()
 
20625
    */
 
20626
    if (bucket == NULL)
 
20627
        return(-1);
 
20628
    if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
 
20629
        return(0);
 
20630
    bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED; 
 
20631
    
 
20632
    for (i = 0; i < bucket->globals->nbItems; i++) {
 
20633
        item = bucket->globals->items[i];
 
20634
        table = NULL;
 
20635
        switch (item->type) {
 
20636
            case XML_SCHEMA_TYPE_COMPLEX:
 
20637
            case XML_SCHEMA_TYPE_SIMPLE:
 
20638
                if (WXS_REDEFINED_TYPE(item))
 
20639
                    continue;
 
20640
                name = (WXS_TYPE_CAST item)->name;
 
20641
                WXS_GET_GLOBAL_HASH(bucket, typeDecl)
 
20642
                break;
 
20643
            case XML_SCHEMA_TYPE_ELEMENT:
 
20644
                name = (WXS_ELEM_CAST item)->name;
 
20645
                WXS_GET_GLOBAL_HASH(bucket, elemDecl)
 
20646
                break;
 
20647
            case XML_SCHEMA_TYPE_ATTRIBUTE:
 
20648
                name = (WXS_ATTR_CAST item)->name;
 
20649
                WXS_GET_GLOBAL_HASH(bucket, attrDecl)
 
20650
                break;
 
20651
            case XML_SCHEMA_TYPE_GROUP:
 
20652
                if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
 
20653
                    continue;
 
20654
                name = (WXS_MODEL_GROUPDEF_CAST item)->name;
 
20655
                WXS_GET_GLOBAL_HASH(bucket, groupDecl)
 
20656
                break;
 
20657
            case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 
20658
                if (WXS_REDEFINED_ATTR_GROUP(item))
 
20659
                    continue;
 
20660
                name = (WXS_ATTR_GROUP_CAST item)->name;
 
20661
                WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
 
20662
                break;
 
20663
            case XML_SCHEMA_TYPE_IDC_KEY:
 
20664
            case XML_SCHEMA_TYPE_IDC_UNIQUE:
 
20665
            case XML_SCHEMA_TYPE_IDC_KEYREF:
 
20666
                name = (WXS_IDC_CAST item)->name;
 
20667
                WXS_GET_GLOBAL_HASH(bucket, idcDef)
 
20668
                break;
 
20669
            case XML_SCHEMA_TYPE_NOTATION:
 
20670
                name = ((xmlSchemaNotationPtr) item)->name;
 
20671
                WXS_GET_GLOBAL_HASH(bucket, notaDecl)
 
20672
                break;      
 
20673
            default:
 
20674
                PERROR_INT("xmlSchemaAddComponents",
 
20675
                    "Unexpected global component type");
 
20676
                continue;               
 
20677
        }       
 
20678
        if (*table == NULL) {
 
20679
            *table = xmlHashCreateDict(10, pctxt->dict);
 
20680
            if (*table == NULL) {
 
20681
                PERROR_INT("xmlSchemaAddComponents",
 
20682
                    "failed to create a component hash table");
 
20683
                return(-1);
 
20684
            }
 
20685
        }       
 
20686
        err = xmlHashAddEntry(*table, name, item);
 
20687
        if (err != 0) { 
 
20688
            xmlChar *str = NULL;
 
20689
            
 
20690
            xmlSchemaCustomErr(ACTXT_CAST pctxt,
 
20691
                XML_SCHEMAP_REDEFINED_TYPE,
 
20692
                WXS_ITEM_NODE(item),
 
20693
                WXS_BASIC_CAST item,
 
20694
                "A global %s '%s' does already exist",
 
20695
                WXS_ITEM_TYPE_NAME(item),
 
20696
                xmlSchemaGetComponentQName(&str, item));
 
20697
            FREE_AND_NULL(str);  
 
20698
        }
 
20699
    }
 
20700
    /*
 
20701
    * Process imported/included schemas.
 
20702
    */
 
20703
    if (bucket->relations != NULL) {
 
20704
        xmlSchemaSchemaRelationPtr rel = bucket->relations;
 
20705
        do {
 
20706
            if ((rel->bucket != NULL) &&
 
20707
                ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
 
20708
                if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
 
20709
                    return(-1);
 
20710
            }
 
20711
            rel = rel->next;
 
20712
        } while (rel != NULL);
 
20713
    }
 
20714
    return(0);
 
20715
}
 
20716
 
 
20717
static int
 
20718
xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
 
20719
                         xmlSchemaBucketPtr rootBucket)
 
20720
{
 
20721
    xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
 
20722
    xmlSchemaTreeItemPtr item, *items;
 
20723
    int nbItems, i, ret = 0;
 
20724
    xmlSchemaBucketPtr oldbucket = con->bucket;
 
20725
    xmlSchemaElementPtr elemDecl;
 
20726
 
 
20727
#define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
 
20728
 
 
20729
    if ((con->pending == NULL) ||
 
20730
        (con->pending->nbItems == 0))
 
20731
        return(0);    
 
20732
 
 
20733
    /*
 
20734
    * Since xmlSchemaFixupComplexType() will create new particles
 
20735
    * (local components), and those particle components need a bucket
 
20736
    * on the constructor, we'll assure here that the constructor has
 
20737
    * a bucket.
 
20738
    * TODO: Think about storing locals _only_ on the main bucket.    
 
20739
    */    
 
20740
    if (con->bucket == NULL)
 
20741
        con->bucket = rootBucket;    
 
20742
 
 
20743
    /* TODO:
 
20744
    * SPEC (src-redefine):
 
20745
    * (6.2) "If it has no such self-reference, then all of the
 
20746
    * following must be true:"
 
20747
    
 
20748
    * (6.2.2) The {model group} of the model group definition which
 
20749
    * corresponds to it per XML Representation of Model Group
 
20750
    * Definition Schema Components (ļæ½3.7.2) must be a ļæ½valid
 
20751
    * restrictionļæ½ of the {model group} of that model group definition
 
20752
    * in I, as defined in Particle Valid (Restriction) (ļæ½3.9.6)."
 
20753
    */
 
20754
    xmlSchemaCheckSRCRedefineFirst(pctxt);
 
20755
 
 
20756
    /*
 
20757
    * Add global components to the schemata's hash tables.
 
20758
    */    
 
20759
    xmlSchemaAddComponents(pctxt, rootBucket);
 
20760
 
 
20761
    pctxt->ctxtType = NULL;
 
20762
    items = (xmlSchemaTreeItemPtr *) con->pending->items;
 
20763
    nbItems = con->pending->nbItems;
 
20764
    /*
 
20765
    * Now that we have parsed *all* the schema document(s) and converted
 
20766
    * them to schema components, we can resolve references, apply component
 
20767
    * constraints, create the FSA from the content model, etc.
 
20768
    */    
 
20769
    /*
 
20770
    * Resolve references of..
 
20771
    *
 
20772
    * 1. element declarations:
 
20773
    *   - the type definition
 
20774
    *   - the substitution group affiliation
 
20775
    * 2. simple/complex types:
 
20776
    *   - the base type definition
 
20777
    *   - the memberTypes of union types
 
20778
    *   - the itemType of list types
 
20779
    * 3. attributes declarations and attribute uses:
 
20780
    *   - the type definition
 
20781
    *   - if an attribute use, then the attribute declaration
 
20782
    * 4. attribute group references:
 
20783
    *   - the attribute group definition
 
20784
    * 5. particles:
 
20785
    *   - the term of the particle (e.g. a model group)
 
20786
    * 6. IDC key-references:
 
20787
    *   - the referenced IDC 'key' or 'unique' definition
 
20788
    * 7. Attribute prohibitions which had a "ref" attribute.
 
20789
    */        
 
20790
    for (i = 0; i < nbItems; i++) {
 
20791
        item = items[i];
 
20792
        switch (item->type) {
 
20793
            case XML_SCHEMA_TYPE_ELEMENT:
 
20794
                xmlSchemaResolveElementReferences(
 
20795
                    (xmlSchemaElementPtr) item, pctxt);
 
20796
                FIXHFAILURE;
 
20797
                break;
 
20798
            case XML_SCHEMA_TYPE_COMPLEX:
 
20799
            case XML_SCHEMA_TYPE_SIMPLE:
 
20800
                xmlSchemaResolveTypeReferences(
 
20801
                    (xmlSchemaTypePtr) item, pctxt);
 
20802
                FIXHFAILURE;
 
20803
                break;
 
20804
            case XML_SCHEMA_TYPE_ATTRIBUTE:
 
20805
                xmlSchemaResolveAttrTypeReferences(
 
20806
                    (xmlSchemaAttributePtr) item, pctxt);
 
20807
                FIXHFAILURE;
 
20808
                break;
 
20809
            case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 
20810
                xmlSchemaResolveAttrUseReferences(
 
20811
                    (xmlSchemaAttributeUsePtr) item, pctxt);
 
20812
                FIXHFAILURE;
 
20813
                break;
 
20814
            case XML_SCHEMA_EXTRA_QNAMEREF:
 
20815
                if ((WXS_QNAME_CAST item)->itemType == 
 
20816
                    XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
 
20817
                {
 
20818
                    xmlSchemaResolveAttrGroupReferences(
 
20819
                        WXS_QNAME_CAST item, pctxt);
 
20820
                }
 
20821
                FIXHFAILURE;
 
20822
                break;
 
20823
            case XML_SCHEMA_TYPE_SEQUENCE:
 
20824
            case XML_SCHEMA_TYPE_CHOICE:
 
20825
            case XML_SCHEMA_TYPE_ALL:
 
20826
                xmlSchemaResolveModelGroupParticleReferences(pctxt,
 
20827
                    WXS_MODEL_GROUP_CAST item);
 
20828
                FIXHFAILURE;
 
20829
                break;
 
20830
            case XML_SCHEMA_TYPE_IDC_KEY:
 
20831
            case XML_SCHEMA_TYPE_IDC_UNIQUE:
 
20832
            case XML_SCHEMA_TYPE_IDC_KEYREF:
 
20833
                xmlSchemaResolveIDCKeyReferences(
 
20834
                    (xmlSchemaIDCPtr) item, pctxt);
 
20835
                FIXHFAILURE;
 
20836
                break;
 
20837
            case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
 
20838
                /*
 
20839
                * Handle attribue prohibition which had a
 
20840
                * "ref" attribute.
 
20841
                */
 
20842
                xmlSchemaResolveAttrUseProhibReferences(
 
20843
                    WXS_ATTR_PROHIB_CAST item, pctxt);
 
20844
                FIXHFAILURE;
 
20845
                break;
 
20846
            default:
 
20847
                break;
 
20848
        }
 
20849
    }
 
20850
    if (pctxt->nberrors != 0)
 
20851
        goto exit_error;
 
20852
    
 
20853
    /*
 
20854
    * Now that all references are resolved we
 
20855
    * can check for circularity of...
 
20856
    * 1. the base axis of type definitions 
 
20857
    * 2. nested model group definitions
 
20858
    * 3. nested attribute group definitions
 
20859
    * TODO: check for circual substitution groups.
 
20860
    */
 
20861
    for (i = 0; i < nbItems; i++) {
 
20862
        item = items[i];
 
20863
        /*
 
20864
        * Let's better stop on the first error here.
 
20865
        */
 
20866
        switch (item->type) {
 
20867
            case XML_SCHEMA_TYPE_COMPLEX:
 
20868
            case XML_SCHEMA_TYPE_SIMPLE:
 
20869
                xmlSchemaCheckTypeDefCircular(
 
20870
                    (xmlSchemaTypePtr) item, pctxt);
 
20871
                FIXHFAILURE;
 
20872
                if (pctxt->nberrors != 0)
 
20873
                    goto exit_error;
 
20874
                break;
 
20875
            case XML_SCHEMA_TYPE_GROUP:
 
20876
                xmlSchemaCheckGroupDefCircular(
 
20877
                    (xmlSchemaModelGroupDefPtr) item, pctxt);
 
20878
                FIXHFAILURE;
 
20879
                if (pctxt->nberrors != 0)
 
20880
                    goto exit_error;
 
20881
                break;
 
20882
            case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 
20883
                xmlSchemaCheckAttrGroupCircular(
 
20884
                    (xmlSchemaAttributeGroupPtr) item, pctxt);
 
20885
                FIXHFAILURE;
 
20886
                if (pctxt->nberrors != 0)
 
20887
                    goto exit_error;
 
20888
                break;
 
20889
            default:
 
20890
                break;
 
20891
        }       
 
20892
    }
 
20893
    if (pctxt->nberrors != 0)
 
20894
        goto exit_error;
 
20895
    /*
 
20896
    * Model group definition references:
 
20897
    * Such a reference is reflected by a particle at the component
 
20898
    * level. Until now the 'term' of such particles pointed
 
20899
    * to the model group definition; this was done, in order to
 
20900
    * ease circularity checks. Now we need to set the 'term' of
 
20901
    * such particles to the model group of the model group definition.
 
20902
    */
 
20903
    for (i = 0; i < nbItems; i++) {
 
20904
        item = items[i];
 
20905
        switch (item->type) {
 
20906
            case XML_SCHEMA_TYPE_SEQUENCE:
 
20907
            case XML_SCHEMA_TYPE_CHOICE:        
 
20908
                xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
 
20909
                    WXS_MODEL_GROUP_CAST item);
 
20910
                break;
 
20911
            default:
 
20912
                break;
 
20913
        }
 
20914
    }
 
20915
    if (pctxt->nberrors != 0)
 
20916
        goto exit_error;
 
20917
    /*
 
20918
    * Expand attribute group references of attribute group definitions.
 
20919
    */
 
20920
    for (i = 0; i < nbItems; i++) {
 
20921
        item = items[i];
 
20922
        switch (item->type) {
 
20923
            case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 
20924
                if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
 
20925
                    WXS_ATTR_GROUP_HAS_REFS(item))
 
20926
                {
 
20927
                    xmlSchemaAttributeGroupExpandRefs(pctxt,
 
20928
                        WXS_ATTR_GROUP_CAST item);
 
20929
                    FIXHFAILURE;
 
20930
                }
 
20931
                break;
 
20932
            default:
 
20933
                break;
 
20934
        }
 
20935
    }
 
20936
    if (pctxt->nberrors != 0)
 
20937
        goto exit_error;
 
20938
    /* 
 
20939
    * First compute the variety of simple types. This is needed as
 
20940
    * a seperate step, since otherwise we won't be able to detect
 
20941
    * circular union types in all cases.
 
20942
    */
 
20943
    for (i = 0; i < nbItems; i++) {
 
20944
        item = items[i];
 
20945
        switch (item->type) {
 
20946
            case XML_SCHEMA_TYPE_SIMPLE:
 
20947
                if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
 
20948
                    xmlSchemaFixupSimpleTypeStageOne(pctxt,
 
20949
                        (xmlSchemaTypePtr) item);
 
20950
                    FIXHFAILURE;
 
20951
                }
 
20952
                break;
 
20953
            default:
 
20954
                break;
 
20955
        }
 
20956
    }
 
20957
    if (pctxt->nberrors != 0)
 
20958
        goto exit_error;
 
20959
    /*
 
20960
    * Detect circular union types. Note that this needs the variety to
 
20961
    * be already computed.
 
20962
    */
 
20963
    for (i = 0; i < nbItems; i++) {
 
20964
        item = items[i];
 
20965
        switch (item->type) {
 
20966
            case XML_SCHEMA_TYPE_SIMPLE:
 
20967
                if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
 
20968
                    xmlSchemaCheckUnionTypeDefCircular(pctxt,   
 
20969
                        (xmlSchemaTypePtr) item);
 
20970
                    FIXHFAILURE;
 
20971
                }
 
20972
                break;
 
20973
            default:
 
20974
                break;
 
20975
        }
 
20976
    }
 
20977
    if (pctxt->nberrors != 0)
 
20978
        goto exit_error;
 
20979
    
 
20980
    /*
 
20981
    * Do the complete type fixup for simple types.
 
20982
    */
 
20983
    for (i = 0; i < nbItems; i++) {
 
20984
        item = items[i];
 
20985
        switch (item->type) {
 
20986
            case XML_SCHEMA_TYPE_SIMPLE:
 
20987
                if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
 
20988
                    xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
 
20989
                    FIXHFAILURE;
 
20990
                }
 
20991
                break;
 
20992
            default:
 
20993
                break;
 
20994
        }
 
20995
    }
 
20996
    if (pctxt->nberrors != 0)
 
20997
        goto exit_error;
 
20998
    /*
 
20999
    * At this point we need build and check all simple types.
 
21000
    */
 
21001
    /*
 
21002
    * Apply contraints for attribute declarations.
 
21003
    */
 
21004
    for (i = 0; i < nbItems; i++) {
 
21005
        item = items[i];
 
21006
        switch (item->type) {
 
21007
            case XML_SCHEMA_TYPE_ATTRIBUTE:             
 
21008
                xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
 
21009
                FIXHFAILURE;
 
21010
                break;      
 
21011
            default:
 
21012
                break;
 
21013
        }
 
21014
    }
 
21015
    if (pctxt->nberrors != 0)
 
21016
        goto exit_error;
 
21017
    /*
 
21018
    * Apply constraints for attribute uses.
 
21019
    */    
 
21020
    for (i = 0; i < nbItems; i++) {
 
21021
        item = items[i];
 
21022
        switch (item->type) {
 
21023
            case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 
21024
                if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
 
21025
                    xmlSchemaCheckAttrUsePropsCorrect(pctxt,
 
21026
                        WXS_ATTR_USE_CAST item);
 
21027
                    FIXHFAILURE;
 
21028
                }
 
21029
                break;
 
21030
            default:
 
21031
                break;
 
21032
        }
 
21033
    }
 
21034
    if (pctxt->nberrors != 0)
 
21035
        goto exit_error;
 
21036
 
 
21037
    /*
 
21038
    * Apply constraints for attribute group definitions.
 
21039
    */
 
21040
    for (i = 0; i < nbItems; i++) {
 
21041
        item = items[i];
 
21042
        switch (item->type) {
 
21043
        case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 
21044
            if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
 
21045
                ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
 
21046
            {
 
21047
                xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
 
21048
                FIXHFAILURE;
 
21049
            }
 
21050
            break;
 
21051
        default:
 
21052
            break;
 
21053
        }
 
21054
    }
 
21055
    if (pctxt->nberrors != 0)
 
21056
        goto exit_error;
 
21057
 
 
21058
    /*
 
21059
    * Apply constraints for redefinitions.
 
21060
    */
 
21061
    if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
 
21062
        xmlSchemaCheckSRCRedefineSecond(pctxt);
 
21063
    if (pctxt->nberrors != 0)
 
21064
        goto exit_error;
 
21065
 
 
21066
    /*    
 
21067
    * Complex types are builded and checked.
 
21068
    */
 
21069
    for (i = 0; i < nbItems; i++) {
 
21070
        item = con->pending->items[i];
 
21071
        switch (item->type) {
 
21072
            case XML_SCHEMA_TYPE_COMPLEX:
 
21073
                if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
 
21074
                    xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
 
21075
                    FIXHFAILURE;
 
21076
                }
 
21077
                break;
 
21078
            default:
 
21079
                break;
 
21080
        }
 
21081
    }
 
21082
    if (pctxt->nberrors != 0)
 
21083
        goto exit_error;
 
21084
 
 
21085
    /*
 
21086
    * The list could have changed, since xmlSchemaFixupComplexType()
 
21087
    * will create particles and model groups in some cases.
 
21088
    */
 
21089
    items = (xmlSchemaTreeItemPtr *) con->pending->items;
 
21090
    nbItems = con->pending->nbItems;    
 
21091
    
 
21092
    /*
 
21093
    * Apply some constraints for element declarations.
 
21094
    */
 
21095
    for (i = 0; i < nbItems; i++) {
 
21096
        item = items[i];
 
21097
        switch (item->type) {
 
21098
            case XML_SCHEMA_TYPE_ELEMENT:
 
21099
                elemDecl = (xmlSchemaElementPtr) item;
 
21100
                
 
21101
                if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
 
21102
                {
 
21103
                    xmlSchemaCheckElementDeclComponent(
 
21104
                        (xmlSchemaElementPtr) elemDecl, pctxt);
 
21105
                    FIXHFAILURE;
 
21106
                }
 
21107
 
 
21108
#ifdef WXS_ELEM_DECL_CONS_ENABLED
 
21109
                /*
 
21110
                * Schema Component Constraint: Element Declarations Consistent
 
21111
                * Apply this constraint to local types of element declarations.
 
21112
                */
 
21113
                if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
 
21114
                    (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
 
21115
                    (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
 
21116
                {
 
21117
                    xmlSchemaCheckElementDeclConsistent(pctxt,
 
21118
                        WXS_BASIC_CAST elemDecl,
 
21119
                        WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
 
21120
                        NULL, NULL, 0);
 
21121
                }
 
21122
#endif
 
21123
                break;
 
21124
            default:
 
21125
                break;
 
21126
        }
 
21127
    }
 
21128
    if (pctxt->nberrors != 0)
 
21129
        goto exit_error;
 
21130
 
 
21131
    /*
 
21132
    * Finally we can build the automaton from the content model of
 
21133
    * complex types.
 
21134
    */
 
21135
 
 
21136
    for (i = 0; i < nbItems; i++) {
 
21137
        item = items[i];
 
21138
        switch (item->type) {
 
21139
            case XML_SCHEMA_TYPE_COMPLEX:
 
21140
                xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
 
21141
                /* FIXHFAILURE; */
 
21142
                break;
 
21143
            default:
 
21144
                break;
 
21145
        }
 
21146
    }
 
21147
    if (pctxt->nberrors != 0)
 
21148
        goto exit_error;
 
21149
    /*
 
21150
    * URGENT TODO: cos-element-consistent
 
21151
    */        
 
21152
    goto exit;    
 
21153
 
 
21154
exit_error:    
 
21155
    ret = pctxt->err;
 
21156
    goto exit;
 
21157
 
 
21158
exit_failure:
 
21159
    ret = -1;
 
21160
 
 
21161
exit:
 
21162
    /*
 
21163
    * Reset the constructor. This is needed for XSI acquisition, since
 
21164
    * those items will be processed over and over again for every XSI
 
21165
    * if not cleared here.
 
21166
    */
 
21167
    con->bucket = oldbucket;
 
21168
    con->pending->nbItems = 0;    
 
21169
    if (con->substGroups != NULL) {
 
21170
        xmlHashFree(con->substGroups,
 
21171
            (xmlHashDeallocator) xmlSchemaSubstGroupFree);
 
21172
        con->substGroups = NULL;
 
21173
    }    
 
21174
    if (con->redefs != NULL) {
 
21175
        xmlSchemaRedefListFree(con->redefs);
 
21176
        con->redefs = NULL;
 
21177
    }
 
21178
    return(ret);
 
21179
}
 
21180
/**
 
21181
 * xmlSchemaParse:
 
21182
 * @ctxt:  a schema validation context
 
21183
 *
 
21184
 * parse a schema definition resource and build an internal
 
21185
 * XML Shema struture which can be used to validate instances.
 
21186
 *
 
21187
 * Returns the internal XML Schema structure built from the resource or
 
21188
 *         NULL in case of error
 
21189
 */
 
21190
xmlSchemaPtr
 
21191
xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
 
21192
{
 
21193
    xmlSchemaPtr mainSchema = NULL;
 
21194
    xmlSchemaBucketPtr bucket = NULL;
 
21195
    int res;
 
21196
 
 
21197
    /*
 
21198
    * This one is used if the schema to be parsed was specified via
 
21199
    * the API; i.e. not automatically by the validated instance document.
 
21200
    */
 
21201
 
 
21202
    xmlSchemaInitTypes();
 
21203
 
 
21204
    if (ctxt == NULL)
 
21205
        return (NULL);
 
21206
 
 
21207
    /* TODO: Init the context. Is this all we need?*/
 
21208
    ctxt->nberrors = 0;
 
21209
    ctxt->err = 0;
 
21210
    ctxt->counter = 0;
 
21211
 
 
21212
    /* Create the *main* schema. */
 
21213
    mainSchema = xmlSchemaNewSchema(ctxt);
 
21214
    if (mainSchema == NULL)
 
21215
        goto exit_failure;
 
21216
    /*
 
21217
    * Create the schema constructor.
 
21218
    */
 
21219
    if (ctxt->constructor == NULL) {
 
21220
        ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
 
21221
        if (ctxt->constructor == NULL)
 
21222
            return(NULL);
 
21223
        /* Take ownership of the constructor to be able to free it. */
 
21224
        ctxt->ownsConstructor = 1;
 
21225
    }
 
21226
    ctxt->constructor->mainSchema = mainSchema;
 
21227
    /*
 
21228
    * Locate and add the schema document.
 
21229
    */
 
21230
    res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
 
21231
        ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
 
21232
        NULL, NULL, &bucket);
 
21233
    if (res == -1)
 
21234
        goto exit_failure;
 
21235
    if (res != 0)
 
21236
        goto exit;   
 
21237
 
 
21238
    if (bucket == NULL) {
 
21239
        /* TODO: Error code, actually we failed to *locate* the schema. */
 
21240
        if (ctxt->URL) 
 
21241
            xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
 
21242
                NULL, NULL,
 
21243
                "Failed to locate the main schema resource at '%s'",
 
21244
                ctxt->URL, NULL);
 
21245
        else
 
21246
            xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
 
21247
                NULL, NULL,
 
21248
                "Failed to locate the main schema resource",
 
21249
                    NULL, NULL);
 
21250
        goto exit;
 
21251
    }        
 
21252
    /* Then do the parsing for good. */
 
21253
    if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
 
21254
        goto exit_failure;
 
21255
    if (ctxt->nberrors != 0)
 
21256
        goto exit;
 
21257
    
 
21258
    mainSchema->doc = bucket->doc;
 
21259
    mainSchema->preserve = ctxt->preserve;
 
21260
    
 
21261
    ctxt->schema = mainSchema;
 
21262
 
 
21263
    if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
 
21264
        goto exit_failure;
 
21265
 
 
21266
    /*
 
21267
    * TODO: This is not nice, since we cannot distinguish from the
 
21268
    * result if there was an internal error or not.
 
21269
    */
 
21270
exit:       
 
21271
    if (ctxt->nberrors != 0) {  
 
21272
        if (mainSchema) {
 
21273
            xmlSchemaFree(mainSchema);
 
21274
            mainSchema = NULL;
 
21275
        }
 
21276
        if (ctxt->constructor) {
 
21277
            xmlSchemaConstructionCtxtFree(ctxt->constructor);
 
21278
            ctxt->constructor = NULL;
 
21279
            ctxt->ownsConstructor = 0;
 
21280
        }
 
21281
    }
 
21282
    ctxt->schema = NULL;
 
21283
    return(mainSchema);
 
21284
exit_failure:
 
21285
    /* 
 
21286
    * Quite verbose, but should catch internal errors, which were
 
21287
    * not communitated.
 
21288
    */
 
21289
    if (mainSchema) {
 
21290
        xmlSchemaFree(mainSchema);
 
21291
        mainSchema = NULL;
 
21292
    }
 
21293
    if (ctxt->constructor) {
 
21294
        xmlSchemaConstructionCtxtFree(ctxt->constructor);
 
21295
        ctxt->constructor = NULL;
 
21296
        ctxt->ownsConstructor = 0;
 
21297
    }
 
21298
    PERROR_INT2("xmlSchemaParse",
 
21299
        "An internal error occured");    
 
21300
    ctxt->schema = NULL;
 
21301
    return(NULL);
 
21302
}
 
21303
 
 
21304
/**
 
21305
 * xmlSchemaSetParserErrors:
 
21306
 * @ctxt:  a schema validation context
 
21307
 * @err:  the error callback
 
21308
 * @warn:  the warning callback
 
21309
 * @ctx:  contextual data for the callbacks
 
21310
 *
 
21311
 * Set the callback functions used to handle errors for a validation context
 
21312
 */
 
21313
void
 
21314
xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
 
21315
                         xmlSchemaValidityErrorFunc err,
 
21316
                         xmlSchemaValidityWarningFunc warn, void *ctx)
 
21317
{
 
21318
    if (ctxt == NULL)
 
21319
        return;
 
21320
    ctxt->error = err;
 
21321
    ctxt->warning = warn;
 
21322
    ctxt->errCtxt = ctx;
 
21323
    if (ctxt->vctxt != NULL)
 
21324
        xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
 
21325
}
 
21326
 
 
21327
/**
 
21328
 * xmlSchemaSetParserStructuredErrors:
 
21329
 * @ctxt:  a schema parser context
 
21330
 * @serror:  the structured error function
 
21331
 * @ctx: the functions context
 
21332
 *
 
21333
 * Set the structured error callback
 
21334
 */
 
21335
void
 
21336
xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
 
21337
                                   xmlStructuredErrorFunc serror,
 
21338
                                   void *ctx)
 
21339
{
 
21340
    if (ctxt == NULL)
 
21341
        return;
 
21342
    ctxt->serror = serror;
 
21343
    ctxt->errCtxt = ctx;
 
21344
    if (ctxt->vctxt != NULL)
 
21345
        xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
 
21346
}
 
21347
 
 
21348
/**
 
21349
 * xmlSchemaGetParserErrors:
 
21350
 * @ctxt:  a XMl-Schema parser context
 
21351
 * @err: the error callback result
 
21352
 * @warn: the warning callback result
 
21353
 * @ctx: contextual data for the callbacks result
 
21354
 *
 
21355
 * Get the callback information used to handle errors for a parser context
 
21356
 *
 
21357
 * Returns -1 in case of failure, 0 otherwise
 
21358
 */
 
21359
int
 
21360
xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
 
21361
                         xmlSchemaValidityErrorFunc * err,
 
21362
                         xmlSchemaValidityWarningFunc * warn, void **ctx)
 
21363
{
 
21364
        if (ctxt == NULL)
 
21365
                return(-1);
 
21366
        if (err != NULL)
 
21367
                *err = ctxt->error;
 
21368
        if (warn != NULL)
 
21369
                *warn = ctxt->warning;
 
21370
        if (ctx != NULL)
 
21371
                *ctx = ctxt->errCtxt;
 
21372
        return(0);
 
21373
}
 
21374
 
 
21375
/**
 
21376
 * xmlSchemaFacetTypeToString:
 
21377
 * @type:  the facet type
 
21378
 *
 
21379
 * Convert the xmlSchemaTypeType to a char string.
 
21380
 *
 
21381
 * Returns the char string representation of the facet type if the
 
21382
 *     type is a facet and an "Internal Error" string otherwise.
 
21383
 */
 
21384
static const xmlChar *
 
21385
xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
 
21386
{
 
21387
    switch (type) {
 
21388
        case XML_SCHEMA_FACET_PATTERN:
 
21389
            return (BAD_CAST "pattern");
 
21390
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
 
21391
            return (BAD_CAST "maxExclusive");
 
21392
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
 
21393
            return (BAD_CAST "maxInclusive");
 
21394
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
 
21395
            return (BAD_CAST "minExclusive");
 
21396
        case XML_SCHEMA_FACET_MININCLUSIVE:
 
21397
            return (BAD_CAST "minInclusive");
 
21398
        case XML_SCHEMA_FACET_WHITESPACE:
 
21399
            return (BAD_CAST "whiteSpace");
 
21400
        case XML_SCHEMA_FACET_ENUMERATION:
 
21401
            return (BAD_CAST "enumeration");
 
21402
        case XML_SCHEMA_FACET_LENGTH:
 
21403
            return (BAD_CAST "length");
 
21404
        case XML_SCHEMA_FACET_MAXLENGTH:
 
21405
            return (BAD_CAST "maxLength");
 
21406
        case XML_SCHEMA_FACET_MINLENGTH:
 
21407
            return (BAD_CAST "minLength");
 
21408
        case XML_SCHEMA_FACET_TOTALDIGITS:
 
21409
            return (BAD_CAST "totalDigits");
 
21410
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
 
21411
            return (BAD_CAST "fractionDigits");
 
21412
        default:
 
21413
            break;
 
21414
    }
 
21415
    return (BAD_CAST "Internal Error");
 
21416
}
 
21417
 
 
21418
static xmlSchemaWhitespaceValueType
 
21419
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
 
21420
{
 
21421
    /*
 
21422
    * The normalization type can be changed only for types which are derived
 
21423
    * from xsd:string.
 
21424
    */
 
21425
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
 
21426
        /*
 
21427
        * Note that we assume a whitespace of preserve for anySimpleType.
 
21428
        */
 
21429
        if ((type->builtInType == XML_SCHEMAS_STRING) ||
 
21430
            (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
 
21431
            return(XML_SCHEMA_WHITESPACE_PRESERVE);
 
21432
        else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
 
21433
            return(XML_SCHEMA_WHITESPACE_REPLACE);
 
21434
        else {
 
21435
            /*
 
21436
            * For all ļæ½atomicļæ½ datatypes other than string (and types ļæ½derivedļæ½
 
21437
            * by ļæ½restrictionļæ½ from it) the value of whiteSpace is fixed to
 
21438
            * collapse
 
21439
            * Note that this includes built-in list datatypes.
 
21440
            */
 
21441
            return(XML_SCHEMA_WHITESPACE_COLLAPSE);
 
21442
        }
 
21443
    } else if (WXS_IS_LIST(type)) {
 
21444
        /*
 
21445
        * For list types the facet "whiteSpace" is fixed to "collapse".
 
21446
        */
 
21447
        return (XML_SCHEMA_WHITESPACE_COLLAPSE);
 
21448
    } else if (WXS_IS_UNION(type)) {
 
21449
        return (XML_SCHEMA_WHITESPACE_UNKNOWN);
 
21450
    } else if (WXS_IS_ATOMIC(type)) {
 
21451
        if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
 
21452
            return (XML_SCHEMA_WHITESPACE_PRESERVE);
 
21453
        else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
 
21454
            return (XML_SCHEMA_WHITESPACE_REPLACE);
 
21455
        else
 
21456
            return (XML_SCHEMA_WHITESPACE_COLLAPSE);
 
21457
    }
 
21458
    return (-1);
 
21459
}
 
21460
 
 
21461
/************************************************************************
 
21462
 *                                                                      *
 
21463
 *                      Simple type validation                          *
 
21464
 *                                                                      *
 
21465
 ************************************************************************/
 
21466
 
 
21467
 
 
21468
/************************************************************************
 
21469
 *                                                                      *
 
21470
 *                      DOM Validation code                             *
 
21471
 *                                                                      *
 
21472
 ************************************************************************/
 
21473
 
 
21474
/**
 
21475
 * xmlSchemaAssembleByLocation:
 
21476
 * @pctxt:  a schema parser context
 
21477
 * @vctxt:  a schema validation context
 
21478
 * @schema: the existing schema
 
21479
 * @node: the node that fired the assembling
 
21480
 * @nsName: the namespace name of the new schema
 
21481
 * @location: the location of the schema
 
21482
 *
 
21483
 * Expands an existing schema by an additional schema.
 
21484
 *
 
21485
 * Returns 0 if the new schema is correct, a positive error code
 
21486
 * number otherwise and -1 in case of an internal or API error.
 
21487
 */
 
21488
static int
 
21489
xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
 
21490
                            xmlSchemaPtr schema,
 
21491
                            xmlNodePtr node,
 
21492
                            const xmlChar *nsName,
 
21493
                            const xmlChar *location)
 
21494
{
 
21495
    int ret = 0;
 
21496
    xmlSchemaParserCtxtPtr pctxt;
 
21497
    xmlSchemaBucketPtr bucket = NULL;
 
21498
 
 
21499
    if ((vctxt == NULL) || (schema == NULL))
 
21500
        return (-1);
 
21501
 
 
21502
    if (vctxt->pctxt == NULL) {
 
21503
        VERROR_INT("xmlSchemaAssembleByLocation",
 
21504
            "no parser context available");
 
21505
        return(-1);
 
21506
    }
 
21507
    pctxt = vctxt->pctxt;
 
21508
    if (pctxt->constructor == NULL) {
 
21509
        PERROR_INT("xmlSchemaAssembleByLocation",
 
21510
            "no constructor");
 
21511
        return(-1);
 
21512
    }
 
21513
    /*
 
21514
    * Acquire the schema document.
 
21515
    */
 
21516
    location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
 
21517
        location, node);
 
21518
    /*
 
21519
    * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
 
21520
    * the process will automatically change this to
 
21521
    * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
 
21522
    */
 
21523
    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
 
21524
        location, NULL, NULL, 0, node, NULL, nsName, 
 
21525
        &bucket);
 
21526
    if (ret != 0)
 
21527
        return(ret);    
 
21528
    if (bucket == NULL) {       
 
21529
        /*
 
21530
        * Generate a warning that the document could not be located.
 
21531
        */
 
21532
        xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
 
21533
            node, NULL,
 
21534
            "The document at location '%s' could not be acquired",
 
21535
            location, NULL, NULL);
 
21536
        return(ret);
 
21537
    }
 
21538
    /*
 
21539
    * The first located schema will be handled as if all other
 
21540
    * schemas imported by XSI were imported by this first schema.
 
21541
    */
 
21542
    if ((bucket != NULL) &&
 
21543
        (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
 
21544
        WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
 
21545
    /*
 
21546
    * TODO: Is this handled like an import? I.e. is it not an error
 
21547
    * if the schema cannot be located?
 
21548
    */
 
21549
    if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
 
21550
        return(0);
 
21551
    /*
 
21552
    * We will reuse the parser context for every schema imported
 
21553
    * directly via XSI. So reset the context.
 
21554
    */
 
21555
    pctxt->nberrors = 0;
 
21556
    pctxt->err = 0;
 
21557
    pctxt->doc = bucket->doc;
 
21558
    
 
21559
    ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);        
 
21560
    if (ret == -1) {
 
21561
        pctxt->doc = NULL;
 
21562
        goto exit_failure;
 
21563
    }
 
21564
    /* Paranoid error channelling. */
 
21565
    if ((ret == 0) && (pctxt->nberrors != 0))
 
21566
        ret = pctxt->err;    
 
21567
    if (pctxt->nberrors == 0) { 
 
21568
        /* 
 
21569
        * Only bother to fixup pending components, if there was
 
21570
        * no error yet.
 
21571
        * For every XSI acquired schema (and its sub-schemata) we will
 
21572
        * fixup the components.
 
21573
        */
 
21574
        xmlSchemaFixupComponents(pctxt, bucket);
 
21575
        ret = pctxt->err;
 
21576
        /*
 
21577
        * Not nice, but we need somehow to channel the schema parser
 
21578
        * error to the validation context.
 
21579
        */
 
21580
        if ((ret != 0) && (vctxt->err == 0))
 
21581
            vctxt->err = ret;
 
21582
        vctxt->nberrors += pctxt->nberrors;
 
21583
    } else {
 
21584
        /* Add to validation error sum. */ 
 
21585
        vctxt->nberrors += pctxt->nberrors;
 
21586
    }
 
21587
    pctxt->doc = NULL;
 
21588
    return(ret);
 
21589
exit_failure:
 
21590
    pctxt->doc = NULL;
 
21591
    return (-1);
 
21592
}
 
21593
 
 
21594
static xmlSchemaAttrInfoPtr
 
21595
xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,                 
 
21596
                         int metaType)
 
21597
{
 
21598
    if (vctxt->nbAttrInfos == 0)
 
21599
        return (NULL);
 
21600
    {
 
21601
        int i;
 
21602
        xmlSchemaAttrInfoPtr iattr;
 
21603
 
 
21604
        for (i = 0; i < vctxt->nbAttrInfos; i++) {
 
21605
            iattr = vctxt->attrInfos[i];
 
21606
            if (iattr->metaType == metaType)
 
21607
                return (iattr);
 
21608
        }
 
21609
 
 
21610
    }
 
21611
    return (NULL);
 
21612
}
 
21613
 
 
21614
/**
 
21615
 * xmlSchemaAssembleByXSI:
 
21616
 * @vctxt:  a schema validation context
 
21617
 *
 
21618
 * Expands an existing schema by an additional schema using
 
21619
 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
 
21620
 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
 
21621
 * must be set to 1.
 
21622
 *
 
21623
 * Returns 0 if the new schema is correct, a positive error code
 
21624
 * number otherwise and -1 in case of an internal or API error.
 
21625
 */
 
21626
static int
 
21627
xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
 
21628
{
 
21629
    const xmlChar *cur, *end;
 
21630
    const xmlChar *nsname = NULL, *location;
 
21631
    int count = 0;
 
21632
    int ret = 0;
 
21633
    xmlSchemaAttrInfoPtr iattr;
 
21634
 
 
21635
    /*
 
21636
    * Parse the value; we will assume an even number of values
 
21637
    * to be given (this is how Xerces and XSV work).
 
21638
    *
 
21639
    * URGENT TODO: !! This needs to work for both
 
21640
    * @noNamespaceSchemaLocation AND @schemaLocation on the same
 
21641
    * element !!
 
21642
    */
 
21643
    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
 
21644
        XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
 
21645
    if (iattr == NULL)
 
21646
        iattr = xmlSchemaGetMetaAttrInfo(vctxt,
 
21647
        XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
 
21648
    if (iattr == NULL)
 
21649
        return (0);
 
21650
    cur = iattr->value;
 
21651
    do {
 
21652
        /*
 
21653
        * TODO: Move the string parsing mechanism away from here.
 
21654
        */
 
21655
        if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
 
21656
            /*
 
21657
            * Get the namespace name.
 
21658
            */
 
21659
            while (IS_BLANK_CH(*cur))
 
21660
                cur++;
 
21661
            end = cur;
 
21662
            while ((*end != 0) && (!(IS_BLANK_CH(*end))))
 
21663
                end++;
 
21664
            if (end == cur)
 
21665
                break;
 
21666
            count++; /* TODO: Don't use the schema's dict. */
 
21667
            nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
 
21668
            cur = end;
 
21669
        }
 
21670
        /*
 
21671
        * Get the URI.
 
21672
        */
 
21673
        while (IS_BLANK_CH(*cur))
 
21674
            cur++;
 
21675
        end = cur;
 
21676
        while ((*end != 0) && (!(IS_BLANK_CH(*end))))
 
21677
            end++;
 
21678
        if (end == cur) {
 
21679
            if (iattr->metaType ==
 
21680
                XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
 
21681
            {
 
21682
                /*
 
21683
                * If using @schemaLocation then tuples are expected.
 
21684
                * I.e. the namespace name *and* the document's URI.
 
21685
                */              
 
21686
                xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
 
21687
                    iattr->node, NULL,
 
21688
                    "The value must consist of tuples: the target namespace "
 
21689
                    "name and the document's URI", NULL, NULL, NULL);
 
21690
            }
 
21691
            break;
 
21692
        }
 
21693
        count++; /* TODO: Don't use the schema's dict. */
 
21694
        location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
 
21695
        cur = end;
 
21696
        ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
 
21697
            iattr->node, nsname, location);
 
21698
        if (ret == -1) {
 
21699
            VERROR_INT("xmlSchemaAssembleByXSI",
 
21700
                "assembling schemata");
 
21701
            return (-1);
 
21702
        }
 
21703
    } while (*cur != 0);
 
21704
    return (ret);
 
21705
}
 
21706
 
 
21707
static const xmlChar *
 
21708
xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
 
21709
                         const xmlChar *prefix)
 
21710
{
 
21711
    if (vctxt->sax != NULL) {
 
21712
        int i, j;
 
21713
        xmlSchemaNodeInfoPtr inode;
 
21714
        
 
21715
        for (i = vctxt->depth; i >= 0; i--) {
 
21716
            if (vctxt->elemInfos[i]->nbNsBindings != 0) {
 
21717
                inode = vctxt->elemInfos[i];
 
21718
                for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
 
21719
                    if (((prefix == NULL) &&
 
21720
                            (inode->nsBindings[j] == NULL)) ||
 
21721
                        ((prefix != NULL) && xmlStrEqual(prefix,
 
21722
                            inode->nsBindings[j]))) {
 
21723
 
 
21724
                        /*
 
21725
                        * Note that the namespace bindings are already
 
21726
                        * in a string dict.
 
21727
                        */
 
21728
                        return (inode->nsBindings[j+1]);                        
 
21729
                    }
 
21730
                }
 
21731
            }
 
21732
        }
 
21733
        return (NULL);
 
21734
#ifdef LIBXML_WRITER_ENABLED
 
21735
    } else if (vctxt->reader != NULL) {
 
21736
        xmlChar *nsName;
 
21737
        
 
21738
        nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
 
21739
        if (nsName != NULL) {
 
21740
            const xmlChar *ret;
 
21741
 
 
21742
            ret = xmlDictLookup(vctxt->dict, nsName, -1);
 
21743
            xmlFree(nsName);
 
21744
            return (ret);
 
21745
        } else
 
21746
            return (NULL);
 
21747
#endif
 
21748
    } else {
 
21749
        xmlNsPtr ns;
 
21750
 
 
21751
        if ((vctxt->inode->node == NULL) ||
 
21752
            (vctxt->inode->node->doc == NULL)) {
 
21753
            VERROR_INT("xmlSchemaLookupNamespace",
 
21754
                "no node or node's doc avaliable");
 
21755
            return (NULL);
 
21756
        }
 
21757
        ns = xmlSearchNs(vctxt->inode->node->doc,
 
21758
            vctxt->inode->node, prefix);
 
21759
        if (ns != NULL)
 
21760
            return (ns->href);
 
21761
        return (NULL);
 
21762
    }
 
21763
}
 
21764
 
 
21765
/*
 
21766
* This one works on the schema of the validation context.
 
21767
*/
 
21768
static int
 
21769
xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,                    
 
21770
                          xmlSchemaPtr schema,
 
21771
                          xmlNodePtr node,
 
21772
                          const xmlChar *value,
 
21773
                          xmlSchemaValPtr *val,
 
21774
                          int valNeeded)
 
21775
{
 
21776
    int ret;
 
21777
 
 
21778
    if (vctxt && (vctxt->schema == NULL)) {
 
21779
        VERROR_INT("xmlSchemaValidateNotation",
 
21780
            "a schema is needed on the validation context");
 
21781
        return (-1);
 
21782
    }
 
21783
    ret = xmlValidateQName(value, 1);
 
21784
    if (ret != 0)
 
21785
        return (ret);
 
21786
    {
 
21787
        xmlChar *localName = NULL;
 
21788
        xmlChar *prefix = NULL;
 
21789
 
 
21790
        localName = xmlSplitQName2(value, &prefix);
 
21791
        if (prefix != NULL) {
 
21792
            const xmlChar *nsName = NULL;
 
21793
 
 
21794
            if (vctxt != NULL) 
 
21795
                nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
 
21796
            else if (node != NULL) {
 
21797
                xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
 
21798
                if (ns != NULL)
 
21799
                    nsName = ns->href;
 
21800
            } else {
 
21801
                xmlFree(prefix);
 
21802
                xmlFree(localName);
 
21803
                return (1);
 
21804
            }
 
21805
            if (nsName == NULL) {
 
21806
                xmlFree(prefix);
 
21807
                xmlFree(localName);
 
21808
                return (1);
 
21809
            }
 
21810
            if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
 
21811
                if ((valNeeded) && (val != NULL)) {
 
21812
                    (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
 
21813
                                                       xmlStrdup(nsName));
 
21814
                    if (*val == NULL)
 
21815
                        ret = -1;
 
21816
                }
 
21817
            } else
 
21818
                ret = 1;
 
21819
            xmlFree(prefix);
 
21820
            xmlFree(localName);
 
21821
        } else {
 
21822
            if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
 
21823
                if (valNeeded && (val != NULL)) {
 
21824
                    (*val) = xmlSchemaNewNOTATIONValue(
 
21825
                        BAD_CAST xmlStrdup(value), NULL);
 
21826
                    if (*val == NULL)
 
21827
                        ret = -1;
 
21828
                }
 
21829
            } else
 
21830
                return (1);
 
21831
        }
 
21832
    }
 
21833
    return (ret);
 
21834
}
 
21835
 
 
21836
static int
 
21837
xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
 
21838
                       const xmlChar* lname,
 
21839
                       const xmlChar* nsname)
 
21840
{
 
21841
    int i;
 
21842
 
 
21843
    lname = xmlDictLookup(vctxt->dict, lname, -1);
 
21844
    if (lname == NULL)
 
21845
        return(-1);
 
21846
    if (nsname != NULL) {
 
21847
        nsname = xmlDictLookup(vctxt->dict, nsname, -1);
 
21848
        if (nsname == NULL)
 
21849
            return(-1);
 
21850
    }
 
21851
    for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
 
21852
        if ((vctxt->nodeQNames->items [i] == lname) &&
 
21853
            (vctxt->nodeQNames->items[i +1] == nsname))
 
21854
            /* Already there */
 
21855
            return(i);
 
21856
    }
 
21857
    /* Add new entry. */
 
21858
    i = vctxt->nodeQNames->nbItems;
 
21859
    xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
 
21860
    xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
 
21861
    return(i);
 
21862
}
 
21863
 
 
21864
/************************************************************************
 
21865
 *                                                                      *
 
21866
 *  Validation of identity-constraints (IDC)                            *
 
21867
 *                                                                      *
 
21868
 ************************************************************************/
 
21869
 
 
21870
/**
 
21871
 * xmlSchemaAugmentIDC:
 
21872
 * @idcDef: the IDC definition
 
21873
 *
 
21874
 * Creates an augmented IDC definition item.
 
21875
 *
 
21876
 * Returns the item, or NULL on internal errors.
 
21877
 */
 
21878
static void
 
21879
xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef,
 
21880
                    xmlSchemaValidCtxtPtr vctxt)
 
21881
{
 
21882
    xmlSchemaIDCAugPtr aidc;
 
21883
 
 
21884
    aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
 
21885
    if (aidc == NULL) {
 
21886
        xmlSchemaVErrMemory(vctxt,
 
21887
            "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
 
21888
            NULL);
 
21889
        return;
 
21890
    }
 
21891
    aidc->keyrefDepth = -1;
 
21892
    aidc->def = idcDef;
 
21893
    aidc->next = NULL;
 
21894
    if (vctxt->aidcs == NULL)
 
21895
        vctxt->aidcs = aidc;
 
21896
    else {
 
21897
        aidc->next = vctxt->aidcs;
 
21898
        vctxt->aidcs = aidc;
 
21899
    }
 
21900
    /*
 
21901
    * Save if we have keyrefs at all.
 
21902
    */
 
21903
    if ((vctxt->hasKeyrefs == 0) &&
 
21904
        (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
 
21905
        vctxt->hasKeyrefs = 1;
 
21906
}
 
21907
 
 
21908
/**
 
21909
 * xmlSchemaAugmentImportedIDC:
 
21910
 * @imported: the imported schema
 
21911
 *
 
21912
 * Creates an augmented IDC definition for the imported schema.
 
21913
 */
 
21914
static void
 
21915
xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) {
 
21916
    if (imported->schema->idcDef != NULL) {
 
21917
            xmlHashScan(imported->schema->idcDef ,
 
21918
            (xmlHashScanner) xmlSchemaAugmentIDC, vctxt);
 
21919
    }
 
21920
}
 
21921
 
 
21922
/**
 
21923
 * xmlSchemaIDCNewBinding:
 
21924
 * @idcDef: the IDC definition of this binding
 
21925
 *
 
21926
 * Creates a new IDC binding.
 
21927
 *
 
21928
 * Returns the new IDC binding, NULL on internal errors.
 
21929
 */
 
21930
static xmlSchemaPSVIIDCBindingPtr
 
21931
xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
 
21932
{
 
21933
    xmlSchemaPSVIIDCBindingPtr ret;
 
21934
 
 
21935
    ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
 
21936
            sizeof(xmlSchemaPSVIIDCBinding));
 
21937
    if (ret == NULL) {
 
21938
        xmlSchemaVErrMemory(NULL,
 
21939
            "allocating a PSVI IDC binding item", NULL);
 
21940
        return (NULL);
 
21941
    }
 
21942
    memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
 
21943
    ret->definition = idcDef;
 
21944
    return (ret);
 
21945
}
 
21946
 
 
21947
/**
 
21948
 * xmlSchemaIDCStoreNodeTableItem:
 
21949
 * @vctxt: the WXS validation context
 
21950
 * @item: the IDC node table item
 
21951
 *
 
21952
 * The validation context is used to store IDC node table items.
 
21953
 * They are stored to avoid copying them if IDC node-tables are merged
 
21954
 * with corresponding parent IDC node-tables (bubbling).
 
21955
 *
 
21956
 * Returns 0 if succeeded, -1 on internal errors.
 
21957
 */
 
21958
static int
 
21959
xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
 
21960
                               xmlSchemaPSVIIDCNodePtr item)
 
21961
{
 
21962
    /*
 
21963
    * Add to gobal list.
 
21964
    */
 
21965
    if (vctxt->idcNodes == NULL) {
 
21966
        vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
 
21967
            xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
 
21968
        if (vctxt->idcNodes == NULL) {
 
21969
            xmlSchemaVErrMemory(vctxt,
 
21970
                "allocating the IDC node table item list", NULL);
 
21971
            return (-1);
 
21972
        }
 
21973
        vctxt->sizeIdcNodes = 20;
 
21974
    } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
 
21975
        vctxt->sizeIdcNodes *= 2;
 
21976
        vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
 
21977
            xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
 
21978
            sizeof(xmlSchemaPSVIIDCNodePtr));
 
21979
        if (vctxt->idcNodes == NULL) {
 
21980
            xmlSchemaVErrMemory(vctxt,
 
21981
                "re-allocating the IDC node table item list", NULL);
 
21982
            return (-1);
 
21983
        }
 
21984
    }
 
21985
    vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
 
21986
 
 
21987
    return (0);
 
21988
}
 
21989
 
 
21990
/**
 
21991
 * xmlSchemaIDCStoreKey:
 
21992
 * @vctxt: the WXS validation context
 
21993
 * @item: the IDC key
 
21994
 *
 
21995
 * The validation context is used to store an IDC key.
 
21996
 *
 
21997
 * Returns 0 if succeeded, -1 on internal errors.
 
21998
 */
 
21999
static int
 
22000
xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
 
22001
                     xmlSchemaPSVIIDCKeyPtr key)
 
22002
{
 
22003
    /*
 
22004
    * Add to gobal list.
 
22005
    */
 
22006
    if (vctxt->idcKeys == NULL) {
 
22007
        vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
 
22008
            xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
 
22009
        if (vctxt->idcKeys == NULL) {
 
22010
            xmlSchemaVErrMemory(vctxt,
 
22011
                "allocating the IDC key storage list", NULL);
 
22012
            return (-1);
 
22013
        }
 
22014
        vctxt->sizeIdcKeys = 40;
 
22015
    } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
 
22016
        vctxt->sizeIdcKeys *= 2;
 
22017
        vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
 
22018
            xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
 
22019
            sizeof(xmlSchemaPSVIIDCKeyPtr));
 
22020
        if (vctxt->idcKeys == NULL) {
 
22021
            xmlSchemaVErrMemory(vctxt,
 
22022
                "re-allocating the IDC key storage list", NULL);
 
22023
            return (-1);
 
22024
        }
 
22025
    }
 
22026
    vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
 
22027
 
 
22028
    return (0);
 
22029
}
 
22030
 
 
22031
/**
 
22032
 * xmlSchemaIDCAppendNodeTableItem:
 
22033
 * @bind: the IDC binding
 
22034
 * @ntItem: the node-table item
 
22035
 *
 
22036
 * Appends the IDC node-table item to the binding.
 
22037
 *
 
22038
 * Returns 0 on success and -1 on internal errors.
 
22039
 */
 
22040
static int
 
22041
xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
 
22042
                                xmlSchemaPSVIIDCNodePtr ntItem)
 
22043
{
 
22044
    if (bind->nodeTable == NULL) {
 
22045
        bind->sizeNodes = 10;
 
22046
        bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
 
22047
            xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
 
22048
        if (bind->nodeTable == NULL) {
 
22049
            xmlSchemaVErrMemory(NULL,
 
22050
                "allocating an array of IDC node-table items", NULL);
 
22051
            return(-1);
 
22052
        }
 
22053
    } else if (bind->sizeNodes <= bind->nbNodes) {
 
22054
        bind->sizeNodes *= 2;
 
22055
        bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
 
22056
            xmlRealloc(bind->nodeTable, bind->sizeNodes *
 
22057
                sizeof(xmlSchemaPSVIIDCNodePtr));
 
22058
        if (bind->nodeTable == NULL) {
 
22059
            xmlSchemaVErrMemory(NULL,
 
22060
                "re-allocating an array of IDC node-table items", NULL);
 
22061
            return(-1);
 
22062
        }
 
22063
    }
 
22064
    bind->nodeTable[bind->nbNodes++] = ntItem;
 
22065
    return(0);
 
22066
}
 
22067
 
 
22068
/**
 
22069
 * xmlSchemaIDCAcquireBinding:
 
22070
 * @vctxt: the WXS validation context
 
22071
 * @matcher: the IDC matcher
 
22072
 *
 
22073
 * Looks up an PSVI IDC binding, for the IDC definition and
 
22074
 * of the given matcher. If none found, a new one is created
 
22075
 * and added to the IDC table.
 
22076
 *
 
22077
 * Returns an IDC binding or NULL on internal errors.
 
22078
 */
 
22079
static xmlSchemaPSVIIDCBindingPtr
 
22080
xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
 
22081
                          xmlSchemaIDCMatcherPtr matcher)
 
22082
{
 
22083
    xmlSchemaNodeInfoPtr ielem;
 
22084
 
 
22085
    ielem = vctxt->elemInfos[matcher->depth];
 
22086
 
 
22087
    if (ielem->idcTable == NULL) {
 
22088
        ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
 
22089
        if (ielem->idcTable == NULL)
 
22090
            return (NULL);
 
22091
        return(ielem->idcTable);
 
22092
    } else {
 
22093
        xmlSchemaPSVIIDCBindingPtr bind = NULL;
 
22094
 
 
22095
        bind = ielem->idcTable;
 
22096
        do {
 
22097
            if (bind->definition == matcher->aidc->def)
 
22098
                return(bind);
 
22099
            if (bind->next == NULL) {
 
22100
                bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
 
22101
                if (bind->next == NULL)
 
22102
                    return (NULL);
 
22103
                return(bind->next);
 
22104
            }
 
22105
            bind = bind->next;
 
22106
        } while (bind != NULL);
 
22107
    }
 
22108
    return (NULL);
 
22109
}
 
22110
 
 
22111
static xmlSchemaItemListPtr
 
22112
xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
 
22113
                             xmlSchemaIDCMatcherPtr matcher)
 
22114
{
 
22115
    if (matcher->targets == NULL)
 
22116
        matcher->targets = xmlSchemaItemListCreate();
 
22117
    return(matcher->targets);
 
22118
}
 
22119
 
 
22120
/**
 
22121
 * xmlSchemaIDCFreeKey:
 
22122
 * @key: the IDC key
 
22123
 *
 
22124
 * Frees an IDC key together with its compiled value.
 
22125
 */
 
22126
static void
 
22127
xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
 
22128
{
 
22129
    if (key->val != NULL)
 
22130
        xmlSchemaFreeValue(key->val);
 
22131
    xmlFree(key);
 
22132
}
 
22133
 
 
22134
/**
 
22135
 * xmlSchemaIDCFreeBinding:
 
22136
 *
 
22137
 * Frees an IDC binding. Note that the node table-items
 
22138
 * are not freed.
 
22139
 */
 
22140
static void
 
22141
xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
 
22142
{
 
22143
    if (bind->nodeTable != NULL)
 
22144
        xmlFree(bind->nodeTable);
 
22145
    if (bind->dupls != NULL)
 
22146
        xmlSchemaItemListFree(bind->dupls);     
 
22147
    xmlFree(bind);
 
22148
}
 
22149
 
 
22150
/**
 
22151
 * xmlSchemaIDCFreeIDCTable:
 
22152
 * @bind: the first IDC binding in the list
 
22153
 *
 
22154
 * Frees an IDC table, i.e. all the IDC bindings in the list.
 
22155
 */
 
22156
static void
 
22157
xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
 
22158
{
 
22159
    xmlSchemaPSVIIDCBindingPtr prev;
 
22160
 
 
22161
    while (bind != NULL) {
 
22162
        prev = bind;
 
22163
        bind = bind->next;
 
22164
        xmlSchemaIDCFreeBinding(prev);
 
22165
    }
 
22166
}
 
22167
 
 
22168
/**
 
22169
 * xmlSchemaIDCFreeMatcherList:
 
22170
 * @matcher: the first IDC matcher in the list
 
22171
 *
 
22172
 * Frees a list of IDC matchers.
 
22173
 */
 
22174
static void
 
22175
xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
 
22176
{
 
22177
    xmlSchemaIDCMatcherPtr next;
 
22178
 
 
22179
    while (matcher != NULL) {
 
22180
        next = matcher->next;
 
22181
        if (matcher->keySeqs != NULL) {     
 
22182
            int i;
 
22183
            for (i = 0; i < matcher->sizeKeySeqs; i++)
 
22184
                if (matcher->keySeqs[i] != NULL)
 
22185
                    xmlFree(matcher->keySeqs[i]);
 
22186
            xmlFree(matcher->keySeqs);      
 
22187
        }
 
22188
        if (matcher->targets != NULL) {
 
22189
            if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
 
22190
                int i;
 
22191
                xmlSchemaPSVIIDCNodePtr idcNode;
 
22192
                /*
 
22193
                * Node-table items for keyrefs are not stored globally
 
22194
                * to the validation context, since they are not bubbled.
 
22195
                * We need to free them here.
 
22196
                */
 
22197
                for (i = 0; i < matcher->targets->nbItems; i++) {
 
22198
                    idcNode =
 
22199
                        (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
 
22200
                    xmlFree(idcNode->keys);
 
22201
                    xmlFree(idcNode);
 
22202
                }
 
22203
            }
 
22204
            xmlSchemaItemListFree(matcher->targets);
 
22205
        }
 
22206
        xmlFree(matcher);
 
22207
        matcher = next;
 
22208
    }
 
22209
}
 
22210
 
 
22211
/**
 
22212
 * xmlSchemaIDCReleaseMatcherList:
 
22213
 * @vctxt: the WXS validation context
 
22214
 * @matcher: the first IDC matcher in the list
 
22215
 *
 
22216
 * Caches a list of IDC matchers for reuse.
 
22217
 */
 
22218
static void
 
22219
xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
 
22220
                               xmlSchemaIDCMatcherPtr matcher)
 
22221
{
 
22222
    xmlSchemaIDCMatcherPtr next;
 
22223
 
 
22224
    while (matcher != NULL) {
 
22225
        next = matcher->next;
 
22226
        if (matcher->keySeqs != NULL) {     
 
22227
            int i;
 
22228
            /*
 
22229
            * Don't free the array, but only the content.
 
22230
            */
 
22231
            for (i = 0; i < matcher->sizeKeySeqs; i++)
 
22232
                if (matcher->keySeqs[i] != NULL) {
 
22233
                    xmlFree(matcher->keySeqs[i]);
 
22234
                    matcher->keySeqs[i] = NULL;
 
22235
                }
 
22236
        }
 
22237
        if (matcher->targets) {
 
22238
            if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
 
22239
                int i;
 
22240
                xmlSchemaPSVIIDCNodePtr idcNode;
 
22241
                /*
 
22242
                * Node-table items for keyrefs are not stored globally
 
22243
                * to the validation context, since they are not bubbled.
 
22244
                * We need to free them here.
 
22245
                */
 
22246
                for (i = 0; i < matcher->targets->nbItems; i++) {
 
22247
                    idcNode =
 
22248
                        (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
 
22249
                    xmlFree(idcNode->keys);
 
22250
                    xmlFree(idcNode);
 
22251
                }
 
22252
            }
 
22253
            xmlSchemaItemListFree(matcher->targets);
 
22254
            matcher->targets = NULL;
 
22255
        }       
 
22256
        matcher->next = NULL;
 
22257
        /*
 
22258
        * Cache the matcher.
 
22259
        */
 
22260
        if (vctxt->idcMatcherCache != NULL)
 
22261
            matcher->nextCached = vctxt->idcMatcherCache;
 
22262
        vctxt->idcMatcherCache = matcher;
 
22263
 
 
22264
        matcher = next;
 
22265
    }
 
22266
}
 
22267
 
 
22268
/**
 
22269
 * xmlSchemaIDCAddStateObject:
 
22270
 * @vctxt: the WXS validation context
 
22271
 * @matcher: the IDC matcher
 
22272
 * @sel: the XPath information
 
22273
 * @parent: the parent "selector" state object if any
 
22274
 * @type: "selector" or "field"
 
22275
 *
 
22276
 * Creates/reuses and activates state objects for the given
 
22277
 * XPath information; if the XPath expression consists of unions,
 
22278
 * multiple state objects are created for every unioned expression.
 
22279
 *
 
22280
 * Returns 0 on success and -1 on internal errors.
 
22281
 */
 
22282
static int
 
22283
xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
 
22284
                        xmlSchemaIDCMatcherPtr matcher,
 
22285
                        xmlSchemaIDCSelectPtr sel,
 
22286
                        int type)
 
22287
{
 
22288
    xmlSchemaIDCStateObjPtr sto;
 
22289
 
 
22290
    /*
 
22291
    * Reuse the state objects from the pool.
 
22292
    */
 
22293
    if (vctxt->xpathStatePool != NULL) {
 
22294
        sto = vctxt->xpathStatePool;
 
22295
        vctxt->xpathStatePool = sto->next;
 
22296
        sto->next = NULL;
 
22297
    } else {    
 
22298
        /*
 
22299
        * Create a new state object.
 
22300
        */
 
22301
        sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
 
22302
        if (sto == NULL) {
 
22303
            xmlSchemaVErrMemory(NULL,
 
22304
                "allocating an IDC state object", NULL);
 
22305
            return (-1);
 
22306
        }
 
22307
        memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
 
22308
    }   
 
22309
    /*
 
22310
    * Add to global list. 
 
22311
    */  
 
22312
    if (vctxt->xpathStates != NULL)
 
22313
        sto->next = vctxt->xpathStates;
 
22314
    vctxt->xpathStates = sto;
 
22315
 
 
22316
    /*
 
22317
    * Free the old xpath validation context.
 
22318
    */
 
22319
    if (sto->xpathCtxt != NULL)
 
22320
        xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
 
22321
 
 
22322
    /*
 
22323
    * Create a new XPath (pattern) validation context.
 
22324
    */
 
22325
    sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
 
22326
        (xmlPatternPtr) sel->xpathComp);
 
22327
    if (sto->xpathCtxt == NULL) {
 
22328
        VERROR_INT("xmlSchemaIDCAddStateObject",
 
22329
            "failed to create an XPath validation context");
 
22330
        return (-1);
 
22331
    }    
 
22332
    sto->type = type;
 
22333
    sto->depth = vctxt->depth;
 
22334
    sto->matcher = matcher;
 
22335
    sto->sel = sel;
 
22336
    sto->nbHistory = 0;
 
22337
    
 
22338
#ifdef DEBUG_IDC
 
22339
    xmlGenericError(xmlGenericErrorContext, "IDC:   STO push '%s'\n",
 
22340
        sto->sel->xpath);
 
22341
#endif
 
22342
    return (0);
 
22343
}
 
22344
 
 
22345
/**
 
22346
 * xmlSchemaXPathEvaluate:
 
22347
 * @vctxt: the WXS validation context
 
22348
 * @nodeType: the nodeType of the current node
 
22349
 *
 
22350
 * Evaluates all active XPath state objects.
 
22351
 *
 
22352
 * Returns the number of IC "field" state objects which resolved to
 
22353
 * this node, 0 if none resolved and -1 on internal errors.
 
22354
 */
 
22355
static int
 
22356
xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
 
22357
                       xmlElementType nodeType)
 
22358
{
 
22359
    xmlSchemaIDCStateObjPtr sto, head = NULL, first;
 
22360
    int res, resolved = 0, depth = vctxt->depth;
 
22361
        
 
22362
    if (vctxt->xpathStates == NULL)
 
22363
        return (0);
 
22364
 
 
22365
    if (nodeType == XML_ATTRIBUTE_NODE)
 
22366
        depth++;
 
22367
#ifdef DEBUG_IDC
 
22368
    {
 
22369
        xmlChar *str = NULL;
 
22370
        xmlGenericError(xmlGenericErrorContext, 
 
22371
            "IDC: EVAL on %s, depth %d, type %d\n",         
 
22372
            xmlSchemaFormatQName(&str, vctxt->inode->nsName,
 
22373
                vctxt->inode->localName), depth, nodeType);
 
22374
        FREE_AND_NULL(str)
 
22375
    }
 
22376
#endif
 
22377
    /*
 
22378
    * Process all active XPath state objects.
 
22379
    */
 
22380
    first = vctxt->xpathStates;
 
22381
    sto = first;
 
22382
    while (sto != head) {
 
22383
#ifdef DEBUG_IDC
 
22384
        if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
 
22385
            xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] selector '%s'\n", 
 
22386
                sto->matcher->aidc->def->name, sto->sel->xpath);
 
22387
        else
 
22388
            xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] field '%s'\n", 
 
22389
                sto->matcher->aidc->def->name, sto->sel->xpath);
 
22390
#endif
 
22391
        if (nodeType == XML_ELEMENT_NODE)
 
22392
            res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
 
22393
                vctxt->inode->localName, vctxt->inode->nsName);
 
22394
        else
 
22395
            res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
 
22396
                vctxt->inode->localName, vctxt->inode->nsName);
 
22397
 
 
22398
        if (res == -1) {
 
22399
            VERROR_INT("xmlSchemaXPathEvaluate",
 
22400
                "calling xmlStreamPush()");
 
22401
            return (-1);
 
22402
        }
 
22403
        if (res == 0)
 
22404
            goto next_sto;
 
22405
        /*
 
22406
        * Full match.
 
22407
        */
 
22408
#ifdef DEBUG_IDC
 
22409
        xmlGenericError(xmlGenericErrorContext, "IDC:     "
 
22410
            "MATCH\n");
 
22411
#endif
 
22412
        /*
 
22413
        * Register a match in the state object history.
 
22414
        */
 
22415
        if (sto->history == NULL) {
 
22416
            sto->history = (int *) xmlMalloc(5 * sizeof(int));
 
22417
            if (sto->history == NULL) {
 
22418
                xmlSchemaVErrMemory(NULL, 
 
22419
                    "allocating the state object history", NULL);
 
22420
                return(-1);
 
22421
            }
 
22422
            sto->sizeHistory = 5;
 
22423
        } else if (sto->sizeHistory <= sto->nbHistory) {
 
22424
            sto->sizeHistory *= 2;
 
22425
            sto->history = (int *) xmlRealloc(sto->history,
 
22426
                sto->sizeHistory * sizeof(int));
 
22427
            if (sto->history == NULL) {
 
22428
                xmlSchemaVErrMemory(NULL, 
 
22429
                    "re-allocating the state object history", NULL);
 
22430
                return(-1);
 
22431
            }
 
22432
        }               
 
22433
        sto->history[sto->nbHistory++] = depth;
 
22434
 
 
22435
#ifdef DEBUG_IDC
 
22436
        xmlGenericError(xmlGenericErrorContext, "IDC:       push match '%d'\n",
 
22437
            vctxt->depth);
 
22438
#endif
 
22439
 
 
22440
        if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
 
22441
            xmlSchemaIDCSelectPtr sel;
 
22442
            /*
 
22443
            * Activate state objects for the IDC fields of
 
22444
            * the IDC selector.
 
22445
            */
 
22446
#ifdef DEBUG_IDC
 
22447
            xmlGenericError(xmlGenericErrorContext, "IDC:     "
 
22448
                "activating field states\n");
 
22449
#endif
 
22450
            sel = sto->matcher->aidc->def->fields;
 
22451
            while (sel != NULL) {
 
22452
                if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
 
22453
                    sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
 
22454
                    return (-1);
 
22455
                sel = sel->next;
 
22456
            }
 
22457
        } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
 
22458
            /*
 
22459
            * An IDC key node was found by the IDC field.
 
22460
            */
 
22461
#ifdef DEBUG_IDC
 
22462
            xmlGenericError(xmlGenericErrorContext,
 
22463
                "IDC:     key found\n");
 
22464
#endif
 
22465
            /*
 
22466
            * Notify that the character value of this node is
 
22467
            * needed.
 
22468
            */
 
22469
            if (resolved == 0) {
 
22470
                if ((vctxt->inode->flags &
 
22471
                    XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
 
22472
                vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
 
22473
            }
 
22474
            resolved++;
 
22475
        }
 
22476
next_sto:
 
22477
        if (sto->next == NULL) {
 
22478
            /*
 
22479
            * Evaluate field state objects created on this node as well.
 
22480
            */
 
22481
            head = first;
 
22482
            sto = vctxt->xpathStates;
 
22483
        } else
 
22484
            sto = sto->next;
 
22485
    }
 
22486
    return (resolved);
 
22487
}
 
22488
 
 
22489
static const xmlChar *
 
22490
xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
 
22491
                              xmlChar **buf,
 
22492
                              xmlSchemaPSVIIDCKeyPtr *seq,
 
22493
                              int count)
 
22494
{
 
22495
    int i, res;
 
22496
    xmlChar *value = NULL;
 
22497
 
 
22498
    *buf = xmlStrdup(BAD_CAST "[");
 
22499
    for (i = 0; i < count; i++) {
 
22500
        *buf = xmlStrcat(*buf, BAD_CAST "'");
 
22501
        res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val, 
 
22502
            xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
 
22503
            &value);
 
22504
        if (res == 0)
 
22505
            *buf = xmlStrcat(*buf, BAD_CAST value);
 
22506
        else {
 
22507
            VERROR_INT("xmlSchemaFormatIDCKeySequence",
 
22508
                "failed to compute a canonical value");
 
22509
            *buf = xmlStrcat(*buf, BAD_CAST "???");
 
22510
        }
 
22511
        if (i < count -1)
 
22512
            *buf = xmlStrcat(*buf, BAD_CAST "', ");
 
22513
        else
 
22514
            *buf = xmlStrcat(*buf, BAD_CAST "'");
 
22515
        if (value != NULL) {
 
22516
            xmlFree(value);
 
22517
            value = NULL;
 
22518
        }
 
22519
    }
 
22520
    *buf = xmlStrcat(*buf, BAD_CAST "]");
 
22521
 
 
22522
    return (BAD_CAST *buf);
 
22523
}
 
22524
 
 
22525
/**
 
22526
 * xmlSchemaXPathPop:
 
22527
 * @vctxt: the WXS validation context
 
22528
 *
 
22529
 * Pops all XPath states.
 
22530
 *
 
22531
 * Returns 0 on success and -1 on internal errors.
 
22532
 */
 
22533
static int
 
22534
xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
 
22535
{
 
22536
    xmlSchemaIDCStateObjPtr sto;
 
22537
    int res;
 
22538
 
 
22539
    if (vctxt->xpathStates == NULL)
 
22540
        return(0);
 
22541
    sto = vctxt->xpathStates;
 
22542
    do {
 
22543
        res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
 
22544
        if (res == -1)
 
22545
            return (-1);
 
22546
        sto = sto->next;
 
22547
    } while (sto != NULL);
 
22548
    return(0);
 
22549
}
 
22550
 
 
22551
/**
 
22552
 * xmlSchemaXPathProcessHistory:
 
22553
 * @vctxt: the WXS validation context
 
22554
 * @type: the simple/complex type of the current node if any at all
 
22555
 * @val: the precompiled value
 
22556
 *
 
22557
 * Processes and pops the history items of the IDC state objects.
 
22558
 * IDC key-sequences are validated/created on IDC bindings.
 
22559
 * 
 
22560
 * Returns 0 on success and -1 on internal errors.
 
22561
 */
 
22562
static int
 
22563
xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
 
22564
                             int depth)
 
22565
{
 
22566
    xmlSchemaIDCStateObjPtr sto, nextsto;
 
22567
    int res, matchDepth;
 
22568
    xmlSchemaPSVIIDCKeyPtr key = NULL;
 
22569
    xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
 
22570
 
 
22571
    if (vctxt->xpathStates == NULL)
 
22572
        return (0);
 
22573
    sto = vctxt->xpathStates;
 
22574
 
 
22575
#ifdef DEBUG_IDC
 
22576
    {
 
22577
        xmlChar *str = NULL;
 
22578
        xmlGenericError(xmlGenericErrorContext, 
 
22579
            "IDC: BACK on %s, depth %d\n",
 
22580
            xmlSchemaFormatQName(&str, vctxt->inode->nsName,
 
22581
                vctxt->inode->localName), vctxt->depth);
 
22582
        FREE_AND_NULL(str)
 
22583
    }
 
22584
#endif    
 
22585
    /*
 
22586
    * Evaluate the state objects.
 
22587
    */
 
22588
    while (sto != NULL) {
 
22589
        res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
 
22590
        if (res == -1) {
 
22591
            VERROR_INT("xmlSchemaXPathProcessHistory",
 
22592
                "calling xmlStreamPop()");
 
22593
            return (-1);
 
22594
        }
 
22595
#ifdef DEBUG_IDC
 
22596
        xmlGenericError(xmlGenericErrorContext, "IDC:   stream pop '%s'\n",
 
22597
            sto->sel->xpath);
 
22598
#endif
 
22599
        if (sto->nbHistory == 0)
 
22600
            goto deregister_check;
 
22601
 
 
22602
        matchDepth = sto->history[sto->nbHistory -1];
 
22603
 
 
22604
        /*
 
22605
        * Only matches at the current depth are of interest.
 
22606
        */
 
22607
        if (matchDepth != depth) {
 
22608
            sto = sto->next;
 
22609
            continue;
 
22610
        }       
 
22611
        if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
 
22612
            /*
 
22613
            * NOTE: According to
 
22614
            *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
 
22615
            *   ... the simple-content of complex types is also allowed.
 
22616
            */
 
22617
            
 
22618
            if (WXS_IS_COMPLEX(type)) {
 
22619
                if (WXS_HAS_SIMPLE_CONTENT(type)) {
 
22620
                    /*
 
22621
                    * Sanity check for complex types with simple content.
 
22622
                    */
 
22623
                    simpleType = type->contentTypeDef;
 
22624
                    if (simpleType == NULL) {
 
22625
                        VERROR_INT("xmlSchemaXPathProcessHistory",
 
22626
                            "field resolves to a CT with simple content "
 
22627
                            "but the CT is missing the ST definition");
 
22628
                        return (-1);
 
22629
                    }
 
22630
                } else
 
22631
                    simpleType = NULL;
 
22632
            } else 
 
22633
                simpleType = type;
 
22634
            if (simpleType == NULL) {
 
22635
                xmlChar *str = NULL;
 
22636
        
 
22637
                /*
 
22638
                * Not qualified if the field resolves to a node of non
 
22639
                * simple type.
 
22640
                */      
 
22641
                xmlSchemaCustomErr(ACTXT_CAST vctxt,
 
22642
                    XML_SCHEMAV_CVC_IDC, NULL,              
 
22643
                    WXS_BASIC_CAST sto->matcher->aidc->def,
 
22644
                    "The XPath '%s' of a field of %s does evaluate to a node of "
 
22645
                    "non-simple type",
 
22646
                    sto->sel->xpath,
 
22647
                    xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
 
22648
                FREE_AND_NULL(str);
 
22649
                sto->nbHistory--;
 
22650
                goto deregister_check;
 
22651
            }
 
22652
            
 
22653
            if ((key == NULL) && (vctxt->inode->val == NULL)) {
 
22654
                /*
 
22655
                * Failed to provide the normalized value; maybe
 
22656
                * the value was invalid.
 
22657
                */
 
22658
                VERROR(XML_SCHEMAV_CVC_IDC,
 
22659
                    WXS_BASIC_CAST sto->matcher->aidc->def,
 
22660
                    "Warning: No precomputed value available, the value "
 
22661
                    "was either invalid or something strange happend");
 
22662
                sto->nbHistory--;
 
22663
                goto deregister_check;
 
22664
            } else {
 
22665
                xmlSchemaIDCMatcherPtr matcher = sto->matcher;
 
22666
                xmlSchemaPSVIIDCKeyPtr *keySeq;
 
22667
                int pos, idx;
 
22668
                
 
22669
                /*
 
22670
                * The key will be anchored on the matcher's list of
 
22671
                * key-sequences. The position in this list is determined
 
22672
                * by the target node's depth relative to the matcher's
 
22673
                * depth of creation (i.e. the depth of the scope element).
 
22674
                * 
 
22675
                * Element        Depth    Pos   List-entries
 
22676
                * <scope>          0              NULL
 
22677
                *   <bar>          1              NULL
 
22678
                *     <target/>    2       2      target
 
22679
                *   <bar>
 
22680
                * </scope>
 
22681
                *
 
22682
                * The size of the list is only dependant on the depth of
 
22683
                * the tree.
 
22684
                * An entry will be NULLed in selector_leave, i.e. when
 
22685
                * we hit the target's 
 
22686
                */                  
 
22687
                pos = sto->depth - matcher->depth;
 
22688
                idx = sto->sel->index;
 
22689
                
 
22690
                /*
 
22691
                * Create/grow the array of key-sequences.
 
22692
                */
 
22693
                if (matcher->keySeqs == NULL) {
 
22694
                    if (pos > 9) 
 
22695
                        matcher->sizeKeySeqs = pos * 2;
 
22696
                    else
 
22697
                        matcher->sizeKeySeqs = 10;
 
22698
                    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) 
 
22699
                        xmlMalloc(matcher->sizeKeySeqs *
 
22700
                        sizeof(xmlSchemaPSVIIDCKeyPtr *));                      
 
22701
                    if (matcher->keySeqs == NULL) {             
 
22702
                        xmlSchemaVErrMemory(NULL,
 
22703
                            "allocating an array of key-sequences",
 
22704
                            NULL);
 
22705
                        return(-1);
 
22706
                    }
 
22707
                    memset(matcher->keySeqs, 0,
 
22708
                        matcher->sizeKeySeqs *
 
22709
                        sizeof(xmlSchemaPSVIIDCKeyPtr *));
 
22710
                } else if (pos >= matcher->sizeKeySeqs) {       
 
22711
                    int i = matcher->sizeKeySeqs;
 
22712
                    
 
22713
                    matcher->sizeKeySeqs *= 2;
 
22714
                    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
 
22715
                        xmlRealloc(matcher->keySeqs,
 
22716
                        matcher->sizeKeySeqs *
 
22717
                        sizeof(xmlSchemaPSVIIDCKeyPtr *));
 
22718
                    if (matcher->keySeqs == NULL) {
 
22719
                        xmlSchemaVErrMemory(NULL,
 
22720
                            "reallocating an array of key-sequences",
 
22721
                            NULL);
 
22722
                        return (-1);
 
22723
                    }
 
22724
                    /*
 
22725
                    * The array needs to be NULLed.
 
22726
                    * TODO: Use memset?
 
22727
                    */
 
22728
                    for (; i < matcher->sizeKeySeqs; i++) 
 
22729
                        matcher->keySeqs[i] = NULL;                     
 
22730
                }
 
22731
                
 
22732
                /*
 
22733
                * Get/create the key-sequence.
 
22734
                */
 
22735
                keySeq = matcher->keySeqs[pos];             
 
22736
                if (keySeq == NULL) {   
 
22737
                    goto create_sequence;
 
22738
                } else if (keySeq[idx] != NULL) {
 
22739
                    xmlChar *str = NULL;
 
22740
                    /*
 
22741
                    * cvc-identity-constraint:
 
22742
                    * 3 For each node in the ļæ½target node setļæ½ all
 
22743
                    * of the {fields}, with that node as the context
 
22744
                    * node, evaluate to either an empty node-set or
 
22745
                    * a node-set with exactly one member, which must
 
22746
                    * have a simple type.
 
22747
                    * 
 
22748
                    * The key was already set; report an error.
 
22749
                    */
 
22750
                    xmlSchemaCustomErr(ACTXT_CAST vctxt, 
 
22751
                        XML_SCHEMAV_CVC_IDC, NULL,
 
22752
                        WXS_BASIC_CAST matcher->aidc->def,
 
22753
                        "The XPath '%s' of a field of %s evaluates to a "
 
22754
                        "node-set with more than one member",
 
22755
                        sto->sel->xpath,
 
22756
                        xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
 
22757
                    FREE_AND_NULL(str);
 
22758
                    sto->nbHistory--;
 
22759
                    goto deregister_check;
 
22760
                } else
 
22761
                    goto create_key;            
 
22762
                
 
22763
create_sequence:
 
22764
                /*
 
22765
                * Create a key-sequence.
 
22766
                */
 
22767
                keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
 
22768
                    matcher->aidc->def->nbFields * 
 
22769
                    sizeof(xmlSchemaPSVIIDCKeyPtr));
 
22770
                if (keySeq == NULL) {
 
22771
                    xmlSchemaVErrMemory(NULL, 
 
22772
                        "allocating an IDC key-sequence", NULL);
 
22773
                    return(-1);                 
 
22774
                }       
 
22775
                memset(keySeq, 0, matcher->aidc->def->nbFields * 
 
22776
                    sizeof(xmlSchemaPSVIIDCKeyPtr));
 
22777
                matcher->keySeqs[pos] = keySeq;
 
22778
create_key:
 
22779
                /*
 
22780
                * Create a key once per node only.
 
22781
                */  
 
22782
                if (key == NULL) {
 
22783
                    key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
 
22784
                        sizeof(xmlSchemaPSVIIDCKey));
 
22785
                    if (key == NULL) {
 
22786
                        xmlSchemaVErrMemory(NULL,
 
22787
                            "allocating a IDC key", NULL);
 
22788
                        xmlFree(keySeq);
 
22789
                        matcher->keySeqs[pos] = NULL;
 
22790
                        return(-1);                     
 
22791
                    }
 
22792
                    /*
 
22793
                    * Consume the compiled value.
 
22794
                    */
 
22795
                    key->type = simpleType;
 
22796
                    key->val = vctxt->inode->val;
 
22797
                    vctxt->inode->val = NULL;
 
22798
                    /*
 
22799
                    * Store the key in a global list.
 
22800
                    */
 
22801
                    if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
 
22802
                        xmlSchemaIDCFreeKey(key);
 
22803
                        return (-1);
 
22804
                    }
 
22805
                }
 
22806
                keySeq[idx] = key;                  
 
22807
            }
 
22808
        } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
 
22809
                
 
22810
            xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
 
22811
            /* xmlSchemaPSVIIDCBindingPtr bind; */
 
22812
            xmlSchemaPSVIIDCNodePtr ntItem;
 
22813
            xmlSchemaIDCMatcherPtr matcher;
 
22814
            xmlSchemaIDCPtr idc;
 
22815
            xmlSchemaItemListPtr targets;
 
22816
            int pos, i, j, nbKeys;
 
22817
            /*
 
22818
            * Here we have the following scenario:
 
22819
            * An IDC 'selector' state object resolved to a target node,
 
22820
            * during the time this target node was in the 
 
22821
            * ancestor-or-self axis, the 'field' state object(s) looked 
 
22822
            * out for matching nodes to create a key-sequence for this 
 
22823
            * target node. Now we are back to this target node and need
 
22824
            * to put the key-sequence, together with the target node 
 
22825
            * itself, into the node-table of the corresponding IDC 
 
22826
            * binding.
 
22827
            */
 
22828
            matcher = sto->matcher;
 
22829
            idc = matcher->aidc->def;
 
22830
            nbKeys = idc->nbFields;
 
22831
            pos = depth - matcher->depth;               
 
22832
            /*
 
22833
            * Check if the matcher has any key-sequences at all, plus
 
22834
            * if it has a key-sequence for the current target node.
 
22835
            */          
 
22836
            if ((matcher->keySeqs == NULL) ||
 
22837
                (matcher->sizeKeySeqs <= pos)) {
 
22838
                if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
 
22839
                    goto selector_key_error;
 
22840
                else
 
22841
                    goto selector_leave;
 
22842
            }
 
22843
            
 
22844
            keySeq = &(matcher->keySeqs[pos]);          
 
22845
            if (*keySeq == NULL) {
 
22846
                if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
 
22847
                    goto selector_key_error;
 
22848
                else
 
22849
                    goto selector_leave;
 
22850
            }
 
22851
            
 
22852
            for (i = 0; i < nbKeys; i++) {
 
22853
                if ((*keySeq)[i] == NULL) {
 
22854
                    /*
 
22855
                    * Not qualified, if not all fields did resolve.
 
22856
                    */
 
22857
                    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
 
22858
                        /*
 
22859
                        * All fields of a "key" IDC must resolve.
 
22860
                        */
 
22861
                        goto selector_key_error;
 
22862
                    }               
 
22863
                    goto selector_leave;
 
22864
                }
 
22865
            }
 
22866
            /*
 
22867
            * All fields did resolve.
 
22868
            */
 
22869
            
 
22870
            /*
 
22871
            * 4.1 If the {identity-constraint category} is unique(/key),
 
22872
            * then no two members of the ļæ½qualified node setļæ½ have
 
22873
            * ļæ½key-sequencesļæ½ whose members are pairwise equal, as
 
22874
            * defined by Equal in [XML Schemas: Datatypes].
 
22875
            *
 
22876
            * Get the IDC binding from the matcher and check for
 
22877
            * duplicate key-sequences.
 
22878
            */
 
22879
#if 0
 
22880
            bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
 
22881
#endif
 
22882
            targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
 
22883
            if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) && 
 
22884
                (targets->nbItems != 0)) {
 
22885
                xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
 
22886
                
 
22887
                i = 0;
 
22888
                res = 0;
 
22889
                /*
 
22890
                * Compare the key-sequences, key by key.
 
22891
                */
 
22892
                do {
 
22893
                    bkeySeq =
 
22894
                        ((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys;
 
22895
                    for (j = 0; j < nbKeys; j++) {
 
22896
                        ckey = (*keySeq)[j];
 
22897
                        bkey = bkeySeq[j];                                                      
 
22898
                        res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
 
22899
                        if (res == -1) {
 
22900
                            return (-1);
 
22901
                        } else if (res == 0) {
 
22902
                            /*
 
22903
                            * One of the keys differs, so the key-sequence
 
22904
                            * won't be equal; get out.
 
22905
                            */
 
22906
                            break;
 
22907
                        }
 
22908
                    }
 
22909
                    if (res == 1) {
 
22910
                        /*
 
22911
                        * Duplicate key-sequence found.
 
22912
                        */
 
22913
                        break;
 
22914
                    }
 
22915
                    i++;
 
22916
                } while (i < targets->nbItems);
 
22917
                if (i != targets->nbItems) {
 
22918
                    xmlChar *str = NULL, *strB = NULL;
 
22919
                    /*   
 
22920
                    * TODO: Try to report the key-sequence.
 
22921
                    */
 
22922
                    xmlSchemaCustomErr(ACTXT_CAST vctxt, 
 
22923
                        XML_SCHEMAV_CVC_IDC, NULL,
 
22924
                        WXS_BASIC_CAST idc,
 
22925
                        "Duplicate key-sequence %s in %s",
 
22926
                        xmlSchemaFormatIDCKeySequence(vctxt, &str,
 
22927
                            (*keySeq), nbKeys),
 
22928
                        xmlSchemaGetIDCDesignation(&strB, idc));
 
22929
                    FREE_AND_NULL(str);
 
22930
                    FREE_AND_NULL(strB);
 
22931
                    goto selector_leave;
 
22932
                }
 
22933
            }
 
22934
            /*
 
22935
            * Add a node-table item to the IDC binding.
 
22936
            */
 
22937
            ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
 
22938
                sizeof(xmlSchemaPSVIIDCNode));
 
22939
            if (ntItem == NULL) {
 
22940
                xmlSchemaVErrMemory(NULL, 
 
22941
                    "allocating an IDC node-table item", NULL);
 
22942
                xmlFree(*keySeq);
 
22943
                *keySeq = NULL;
 
22944
                return(-1);
 
22945
            }   
 
22946
            memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
 
22947
            
 
22948
            /* 
 
22949
            * Store the node-table item in a global list.
 
22950
            */
 
22951
            if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
 
22952
                if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
 
22953
                    xmlFree(ntItem);
 
22954
                    xmlFree(*keySeq);
 
22955
                    *keySeq = NULL;
 
22956
                    return (-1);
 
22957
                }
 
22958
                ntItem->nodeQNameID = -1;
 
22959
            } else {
 
22960
                /*
 
22961
                * Save a cached QName for this node on the IDC node, to be
 
22962
                * able to report it, even if the node is not saved.
 
22963
                */
 
22964
                ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
 
22965
                    vctxt->inode->localName, vctxt->inode->nsName);
 
22966
                if (ntItem->nodeQNameID == -1) {
 
22967
                    xmlFree(ntItem);
 
22968
                    xmlFree(*keySeq);
 
22969
                    *keySeq = NULL;
 
22970
                    return (-1);                    
 
22971
                }
 
22972
            }
 
22973
            /*
 
22974
            * Init the node-table item: Save the node, position and
 
22975
            * consume the key-sequence.
 
22976
            */
 
22977
            ntItem->node = vctxt->node;
 
22978
            ntItem->nodeLine = vctxt->inode->nodeLine;
 
22979
            ntItem->keys = *keySeq;
 
22980
            *keySeq = NULL;
 
22981
#if 0
 
22982
            if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1) {
 
22983
#endif
 
22984
            if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
 
22985
                if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
 
22986
                    /* 
 
22987
                    * Free the item, since keyref items won't be
 
22988
                    * put on a global list.
 
22989
                    */
 
22990
                    xmlFree(ntItem->keys);
 
22991
                    xmlFree(ntItem);
 
22992
                }
 
22993
                return (-1);
 
22994
            }
 
22995
            
 
22996
            goto selector_leave;
 
22997
selector_key_error:
 
22998
            {
 
22999
                xmlChar *str = NULL;
 
23000
                /*
 
23001
                * 4.2.1 (KEY) The ļæ½target node setļæ½ and the 
 
23002
                * ļæ½qualified node setļæ½ are equal, that is, every 
 
23003
                * member of the ļæ½target node setļæ½ is also a member
 
23004
                * of the ļæ½qualified node setļæ½ and vice versa.
 
23005
                */
 
23006
                xmlSchemaCustomErr(ACTXT_CAST vctxt, 
 
23007
                    XML_SCHEMAV_CVC_IDC, NULL,
 
23008
                    WXS_BASIC_CAST idc,
 
23009
                    "Not all fields of %s evaluate to a node",
 
23010
                    xmlSchemaGetIDCDesignation(&str, idc), NULL);
 
23011
                FREE_AND_NULL(str);
 
23012
            }
 
23013
selector_leave:
 
23014
            /*
 
23015
            * Free the key-sequence if not added to the IDC table.
 
23016
            */
 
23017
            if ((keySeq != NULL) && (*keySeq != NULL)) {
 
23018
                xmlFree(*keySeq);
 
23019
                *keySeq = NULL;
 
23020
            }
 
23021
        } /* if selector */
 
23022
        
 
23023
        sto->nbHistory--;
 
23024
 
 
23025
deregister_check:
 
23026
        /*
 
23027
        * Deregister state objects if they reach the depth of creation.
 
23028
        */
 
23029
        if ((sto->nbHistory == 0) && (sto->depth == depth)) {
 
23030
#ifdef DEBUG_IDC
 
23031
            xmlGenericError(xmlGenericErrorContext, "IDC:   STO pop '%s'\n",
 
23032
                sto->sel->xpath);
 
23033
#endif
 
23034
            if (vctxt->xpathStates != sto) {
 
23035
                VERROR_INT("xmlSchemaXPathProcessHistory",
 
23036
                    "The state object to be removed is not the first "
 
23037
                    "in the list");
 
23038
            }
 
23039
            nextsto = sto->next;
 
23040
            /*
 
23041
            * Unlink from the list of active XPath state objects.
 
23042
            */
 
23043
            vctxt->xpathStates = sto->next;
 
23044
            sto->next = vctxt->xpathStatePool;
 
23045
            /*
 
23046
            * Link it to the pool of reusable state objects.
 
23047
            */
 
23048
            vctxt->xpathStatePool = sto;
 
23049
            sto = nextsto;
 
23050
        } else
 
23051
            sto = sto->next;
 
23052
    } /* while (sto != NULL) */
 
23053
    return (0);
 
23054
}
 
23055
 
 
23056
/**
 
23057
 * xmlSchemaIDCRegisterMatchers:
 
23058
 * @vctxt: the WXS validation context
 
23059
 * @elemDecl: the element declaration
 
23060
 *
 
23061
 * Creates helper objects to evaluate IDC selectors/fields
 
23062
 * successively.
 
23063
 *
 
23064
 * Returns 0 if OK and -1 on internal errors.
 
23065
 */
 
23066
static int
 
23067
xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
 
23068
                             xmlSchemaElementPtr elemDecl)
 
23069
{
 
23070
    xmlSchemaIDCMatcherPtr matcher, last = NULL;
 
23071
    xmlSchemaIDCPtr idc, refIdc;
 
23072
    xmlSchemaIDCAugPtr aidc;
 
23073
        
 
23074
    idc = (xmlSchemaIDCPtr) elemDecl->idcs;
 
23075
    if (idc == NULL)
 
23076
        return (0);
 
23077
    
 
23078
#ifdef DEBUG_IDC
 
23079
    {
 
23080
        xmlChar *str = NULL;
 
23081
        xmlGenericError(xmlGenericErrorContext, 
 
23082
            "IDC: REGISTER on %s, depth %d\n",
 
23083
            (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
 
23084
                vctxt->inode->localName), vctxt->depth);
 
23085
        FREE_AND_NULL(str)
 
23086
    }
 
23087
#endif
 
23088
    if (vctxt->inode->idcMatchers != NULL) {
 
23089
        VERROR_INT("xmlSchemaIDCRegisterMatchers",
 
23090
            "The chain of IDC matchers is expected to be empty");
 
23091
        return (-1);
 
23092
    }
 
23093
    do {
 
23094
        if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
 
23095
            /*
 
23096
            * Since IDCs bubbles are expensive we need to know the
 
23097
            * depth at which the bubbles should stop; this will be
 
23098
            * the depth of the top-most keyref IDC. If no keyref
 
23099
            * references a key/unique IDC, the keyrefDepth will
 
23100
            * be -1, indicating that no bubbles are needed.
 
23101
            */
 
23102
            refIdc = (xmlSchemaIDCPtr) idc->ref->item;
 
23103
            if (refIdc != NULL) {
 
23104
                /*
 
23105
                * Remember that we have keyrefs on this node.
 
23106
                */
 
23107
                vctxt->inode->hasKeyrefs = 1;
 
23108
                /*
 
23109
                * Lookup the referenced augmented IDC info.
 
23110
                */
 
23111
                aidc = vctxt->aidcs;
 
23112
                while (aidc != NULL) {
 
23113
                    if (aidc->def == refIdc)
 
23114
                        break;
 
23115
                    aidc = aidc->next;
 
23116
                }
 
23117
                if (aidc == NULL) {
 
23118
                    VERROR_INT("xmlSchemaIDCRegisterMatchers",
 
23119
                        "Could not find an augmented IDC item for an IDC "
 
23120
                        "definition");
 
23121
                    return (-1);
 
23122
                }               
 
23123
                if ((aidc->keyrefDepth == -1) ||
 
23124
                    (vctxt->depth < aidc->keyrefDepth))
 
23125
                    aidc->keyrefDepth = vctxt->depth;
 
23126
            }
 
23127
        }
 
23128
        /*
 
23129
        * Lookup the augmented IDC item for the IDC definition.
 
23130
        */
 
23131
        aidc = vctxt->aidcs;
 
23132
        while (aidc != NULL) {
 
23133
            if (aidc->def == idc)
 
23134
                break;
 
23135
            aidc = aidc->next;
 
23136
        }
 
23137
        if (aidc == NULL) {
 
23138
            VERROR_INT("xmlSchemaIDCRegisterMatchers",
 
23139
                "Could not find an augmented IDC item for an IDC definition");
 
23140
            return (-1);
 
23141
        }
 
23142
        /*
 
23143
        * Create an IDC matcher for every IDC definition.
 
23144
        */
 
23145
        if (vctxt->idcMatcherCache != NULL) {
 
23146
            /*
 
23147
            * Reuse a cached matcher.
 
23148
            */
 
23149
            matcher = vctxt->idcMatcherCache;
 
23150
            vctxt->idcMatcherCache = matcher->nextCached;
 
23151
            matcher->nextCached = NULL;
 
23152
        } else {
 
23153
            matcher = (xmlSchemaIDCMatcherPtr) 
 
23154
                xmlMalloc(sizeof(xmlSchemaIDCMatcher));
 
23155
            if (matcher == NULL) {
 
23156
                xmlSchemaVErrMemory(vctxt, 
 
23157
                    "allocating an IDC matcher", NULL);
 
23158
                return (-1);
 
23159
            }
 
23160
            memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
 
23161
        }
 
23162
        if (last == NULL)
 
23163
            vctxt->inode->idcMatchers = matcher;
 
23164
        else
 
23165
            last->next = matcher;
 
23166
        last = matcher;
 
23167
 
 
23168
        matcher->type = IDC_MATCHER;
 
23169
        matcher->depth = vctxt->depth;  
 
23170
        matcher->aidc = aidc;
 
23171
        matcher->idcType = aidc->def->type;
 
23172
#ifdef DEBUG_IDC        
 
23173
        xmlGenericError(xmlGenericErrorContext, "IDC:   register matcher\n");
 
23174
#endif 
 
23175
        /*
 
23176
        * Init the automaton state object. 
 
23177
        */
 
23178
        if (xmlSchemaIDCAddStateObject(vctxt, matcher, 
 
23179
            idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
 
23180
            return (-1);
 
23181
 
 
23182
        idc = idc->next;
 
23183
    } while (idc != NULL);
 
23184
    return (0);
 
23185
}
 
23186
 
 
23187
static int
 
23188
xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
 
23189
                           xmlSchemaNodeInfoPtr ielem)
 
23190
{
 
23191
    xmlSchemaPSVIIDCBindingPtr bind;
 
23192
    int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
 
23193
    xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
 
23194
    xmlSchemaPSVIIDCNodePtr *targets, *dupls;
 
23195
    
 
23196
    xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
 
23197
    /* vctxt->createIDCNodeTables */
 
23198
    while (matcher != NULL) {
 
23199
        /*
 
23200
        * Skip keyref IDCs and empty IDC target-lists.
 
23201
        */
 
23202
        if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
 
23203
            WXS_ILIST_IS_EMPTY(matcher->targets))
 
23204
        {
 
23205
            matcher = matcher->next;
 
23206
            continue;
 
23207
        }
 
23208
        /*
 
23209
        * If we _want_ the IDC node-table to be created in any case
 
23210
        * then do so. Otherwise create them only if keyrefs need them.
 
23211
        */
 
23212
        if ((! vctxt->createIDCNodeTables) &&
 
23213
            ((matcher->aidc->keyrefDepth == -1) ||
 
23214
             (matcher->aidc->keyrefDepth > vctxt->depth)))
 
23215
        {
 
23216
            matcher = matcher->next;
 
23217
            continue;
 
23218
        }
 
23219
        /*
 
23220
        * Get/create the IDC binding on this element for the IDC definition.
 
23221
        */
 
23222
        bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
 
23223
 
 
23224
        if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
 
23225
            dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
 
23226
            nbDupls = bind->dupls->nbItems;
 
23227
        } else {
 
23228
            dupls = NULL;
 
23229
            nbDupls = 0;            
 
23230
        }
 
23231
        if (bind->nodeTable != NULL) {
 
23232
            nbNodeTable = bind->nbNodes;
 
23233
        } else {
 
23234
            nbNodeTable = 0;
 
23235
        }
 
23236
 
 
23237
        if ((nbNodeTable == 0) && (nbDupls == 0)) {
 
23238
            /*
 
23239
            * Transfer all IDC target-nodes to the IDC node-table.
 
23240
            */
 
23241
            bind->nodeTable =
 
23242
                (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;            
 
23243
            bind->sizeNodes = matcher->targets->sizeItems;
 
23244
            bind->nbNodes = matcher->targets->nbItems;
 
23245
 
 
23246
            matcher->targets->items = NULL;
 
23247
            matcher->targets->sizeItems = 0;
 
23248
            matcher->targets->nbItems = 0;          
 
23249
        } else {
 
23250
            /*
 
23251
            * Compare the key-sequences and add to the IDC node-table.
 
23252
            */
 
23253
            nbTargets = matcher->targets->nbItems;
 
23254
            targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;      
 
23255
            nbFields = matcher->aidc->def->nbFields;
 
23256
            i = 0;
 
23257
            do {
 
23258
                keys = targets[i]->keys;
 
23259
                if (nbDupls) {                  
 
23260
                    /*
 
23261
                    * Search in already found duplicates first.
 
23262
                    */
 
23263
                    j = 0;
 
23264
                    do {                                                
 
23265
                        if (nbFields == 1) {
 
23266
                            res = xmlSchemaAreValuesEqual(keys[0]->val,
 
23267
                                dupls[j]->keys[0]->val);
 
23268
                            if (res == -1)
 
23269
                                goto internal_error;
 
23270
                            if (res == 1) {
 
23271
                                /*
 
23272
                                * Equal key-sequence.
 
23273
                                */
 
23274
                                goto next_target;
 
23275
                            }
 
23276
                        } else {
 
23277
                            res = 0;
 
23278
                            ntkeys = dupls[j]->keys;
 
23279
                            for (k = 0; k < nbFields; k++) {
 
23280
                                res = xmlSchemaAreValuesEqual(keys[k]->val,
 
23281
                                    ntkeys[k]->val);
 
23282
                                if (res == -1)
 
23283
                                    goto internal_error;
 
23284
                                if (res == 0) {
 
23285
                                    /*
 
23286
                                    * One of the keys differs.
 
23287
                                    */
 
23288
                                    break;
 
23289
                                }
 
23290
                            }
 
23291
                            if (res == 1) {
 
23292
                                /*
 
23293
                                * Equal key-sequence found.
 
23294
                                */
 
23295
                                goto next_target;
 
23296
                            }
 
23297
                        }
 
23298
                        j++;
 
23299
                    } while (j < nbDupls);                  
 
23300
                }
 
23301
                if (nbNodeTable) {
 
23302
                    j = 0;
 
23303
                    do {                                                
 
23304
                        if (nbFields == 1) {
 
23305
                            res = xmlSchemaAreValuesEqual(keys[0]->val,
 
23306
                                bind->nodeTable[j]->keys[0]->val);
 
23307
                            if (res == -1)
 
23308
                                goto internal_error;
 
23309
                            if (res == 0) {
 
23310
                                /*
 
23311
                                * The key-sequence differs.
 
23312
                                */
 
23313
                                goto next_node_table_entry;
 
23314
                            }
 
23315
                        } else {
 
23316
                            res = 0;
 
23317
                            ntkeys = bind->nodeTable[j]->keys;
 
23318
                            for (k = 0; k < nbFields; k++) {
 
23319
                                res = xmlSchemaAreValuesEqual(keys[k]->val,
 
23320
                                    ntkeys[k]->val);
 
23321
                                if (res == -1)
 
23322
                                    goto internal_error;
 
23323
                                if (res == 0) {
 
23324
                                    /*
 
23325
                                    * One of the keys differs.
 
23326
                                    */
 
23327
                                    goto next_node_table_entry;
 
23328
                                }
 
23329
                            }
 
23330
                        }                       
 
23331
                        /*
 
23332
                        * Add the duplicate to the list of duplicates.
 
23333
                        */
 
23334
                        if (bind->dupls == NULL) {
 
23335
                            bind->dupls = xmlSchemaItemListCreate();
 
23336
                            if (bind->dupls == NULL)
 
23337
                                goto internal_error;
 
23338
                        }                   
 
23339
                        if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
 
23340
                            goto internal_error;
 
23341
                        /*
 
23342
                        * Remove the duplicate entry from the IDC node-table.
 
23343
                        */
 
23344
                        bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
 
23345
                        bind->nbNodes--;
 
23346
 
 
23347
                        goto next_target;
 
23348
 
 
23349
next_node_table_entry:
 
23350
                        j++;
 
23351
                    } while (j < nbNodeTable);
 
23352
                }
 
23353
                /*
 
23354
                * If everything is fine, then add the IDC target-node to
 
23355
                * the IDC node-table.
 
23356
                */
 
23357
                if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
 
23358
                    goto internal_error;
 
23359
 
 
23360
next_target:
 
23361
                i++;
 
23362
            } while (i < nbTargets);
 
23363
        }
 
23364
        matcher = matcher->next;
 
23365
    }
 
23366
    return(0);
 
23367
 
 
23368
internal_error:
 
23369
    return(-1);
 
23370
}
 
23371
 
 
23372
/**
 
23373
 * xmlSchemaBubbleIDCNodeTables: 
 
23374
 * @depth: the current tree depth
 
23375
 *
 
23376
 * Merges IDC bindings of an element at @depth into the corresponding IDC 
 
23377
 * bindings of its parent element. If a duplicate note-table entry is found, 
 
23378
 * both, the parent node-table entry and child entry are discarded from the 
 
23379
 * node-table of the parent.
 
23380
 *
 
23381
 * Returns 0 if OK and -1 on internal errors.
 
23382
 */
 
23383
static int
 
23384
xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
 
23385
{
 
23386
    xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
 
23387
    xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
 
23388
    xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
 
23389
    xmlSchemaIDCAugPtr aidc;
 
23390
    int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
 
23391
 
 
23392
    bind = vctxt->inode->idcTable;        
 
23393
    if (bind == NULL) {
 
23394
        /* Fine, no table, no bubbles. */
 
23395
        return (0);
 
23396
    }
 
23397
    
 
23398
    parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
 
23399
    /*
 
23400
    * Walk all bindings; create new or add to existing bindings.
 
23401
    * Remove duplicate key-sequences.
 
23402
    */
 
23403
    while (bind != NULL) {
 
23404
        
 
23405
        if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
 
23406
            goto next_binding;
 
23407
        /*
 
23408
        * Check if the key/unique IDC table needs to be bubbled.
 
23409
        */
 
23410
        if (! vctxt->createIDCNodeTables) {
 
23411
            aidc = vctxt->aidcs;
 
23412
            do {
 
23413
                if (aidc->def == bind->definition) {
 
23414
                    if ((aidc->keyrefDepth == -1) || 
 
23415
                        (aidc->keyrefDepth >= vctxt->depth)) {
 
23416
                        goto next_binding;
 
23417
                    }
 
23418
                    break;
 
23419
                }
 
23420
                aidc = aidc->next;
 
23421
            } while (aidc != NULL);
 
23422
        }
 
23423
 
 
23424
        if (parTable != NULL)
 
23425
            parBind = *parTable;
 
23426
        /*
 
23427
        * Search a matching parent binding for the
 
23428
        * IDC definition.
 
23429
        */
 
23430
        while (parBind != NULL) {           
 
23431
            if (parBind->definition == bind->definition)
 
23432
                break;
 
23433
            parBind = parBind->next;
 
23434
        }
 
23435
 
 
23436
        if (parBind != NULL) {
 
23437
            /*
 
23438
            * Compare every node-table entry of the child node, 
 
23439
            * i.e. the key-sequence within, ...
 
23440
            */
 
23441
            oldNum = parBind->nbNodes; /* Skip newly added items. */
 
23442
 
 
23443
            if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
 
23444
                oldDupls = parBind->dupls->nbItems;
 
23445
                dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
 
23446
            } else {
 
23447
                dupls = NULL;
 
23448
                oldDupls = 0;           
 
23449
            }
 
23450
            
 
23451
            parNodes = parBind->nodeTable;
 
23452
            nbFields = bind->definition->nbFields;
 
23453
            
 
23454
            for (i = 0; i < bind->nbNodes; i++) {
 
23455
                node = bind->nodeTable[i];
 
23456
                if (node == NULL)
 
23457
                    continue;
 
23458
                /*
 
23459
                * ...with every key-sequence of the parent node, already
 
23460
                * evaluated to be a duplicate key-sequence.
 
23461
                */
 
23462
                if (oldDupls) {
 
23463
                    j = 0; 
 
23464
                    while (j < oldDupls) {
 
23465
                        if (nbFields == 1) {
 
23466
                            ret = xmlSchemaAreValuesEqual(
 
23467
                                node->keys[0]->val,
 
23468
                                dupls[j]->keys[0]->val);
 
23469
                            if (ret == -1)
 
23470
                                goto internal_error;
 
23471
                            if (ret == 0) {
 
23472
                                j++;
 
23473
                                continue;
 
23474
                            }
 
23475
                        } else {
 
23476
                            parNode = dupls[j];
 
23477
                            for (k = 0; k < nbFields; k++) {
 
23478
                                ret = xmlSchemaAreValuesEqual(
 
23479
                                    node->keys[k]->val,
 
23480
                                    parNode->keys[k]->val);
 
23481
                                if (ret == -1)
 
23482
                                    goto internal_error;
 
23483
                                if (ret == 0)
 
23484
                                    break;
 
23485
                            }
 
23486
                        }
 
23487
                        if (ret == 1)
 
23488
                            /* Duplicate found. */
 
23489
                            break;
 
23490
                        j++;
 
23491
                    }
 
23492
                    if (j != oldDupls) {
 
23493
                        /* Duplicate found. Skip this entry. */
 
23494
                        continue;
 
23495
                    }
 
23496
                }                   
 
23497
                /*
 
23498
                * ... and with every key-sequence of the parent node.
 
23499
                */
 
23500
                if (oldNum) {
 
23501
                    j = 0; 
 
23502
                    while (j < oldNum) {
 
23503
                        parNode = parNodes[j];
 
23504
                        if (nbFields == 1) {
 
23505
                            ret = xmlSchemaAreValuesEqual(
 
23506
                                node->keys[0]->val,
 
23507
                                parNode->keys[0]->val);
 
23508
                            if (ret == -1)
 
23509
                                goto internal_error;
 
23510
                            if (ret == 0) {
 
23511
                                j++;
 
23512
                                continue;
 
23513
                            }
 
23514
                        } else {                            
 
23515
                            for (k = 0; k < nbFields; k++) {
 
23516
                                ret = xmlSchemaAreValuesEqual(
 
23517
                                    node->keys[k]->val,
 
23518
                                    parNode->keys[k]->val);
 
23519
                                if (ret == -1)
 
23520
                                    goto internal_error;
 
23521
                                if (ret == 0)
 
23522
                                    break;
 
23523
                            }
 
23524
                        }
 
23525
                        if (ret == 1)
 
23526
                            /* Duplicate found. */
 
23527
                            break;
 
23528
                        j++;
 
23529
                    }
 
23530
                    if (j != oldNum) {
 
23531
                        /*
 
23532
                        * Handle duplicates. Move the duplicate in
 
23533
                        * the parent's node-table to the list of
 
23534
                        * duplicates.
 
23535
                        */                      
 
23536
                        oldNum--;
 
23537
                        parBind->nbNodes--;
 
23538
                        /*
 
23539
                        * Move last old item to pos of duplicate.
 
23540
                        */
 
23541
                        parNodes[j] = parNodes[oldNum];
 
23542
                        
 
23543
                        if (parBind->nbNodes != oldNum) {
 
23544
                            /*
 
23545
                            * If new items exist, move last new item to 
 
23546
                            * last of old items.
 
23547
                            */
 
23548
                            parNodes[oldNum] = 
 
23549
                                parNodes[parBind->nbNodes];
 
23550
                        }
 
23551
                        if (parBind->dupls == NULL) {
 
23552
                            parBind->dupls = xmlSchemaItemListCreate();
 
23553
                            if (parBind->dupls == NULL)
 
23554
                                goto internal_error;
 
23555
                        }
 
23556
                        xmlSchemaItemListAdd(parBind->dupls, parNode);                  
 
23557
                    } else {
 
23558
                        /*
 
23559
                        * Add the node-table entry (node and key-sequence) of 
 
23560
                        * the child node to the node table of the parent node.
 
23561
                        */
 
23562
                        if (parBind->nodeTable == NULL) {                       
 
23563
                            parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 
 
23564
                                xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
 
23565
                            if (parBind->nodeTable == NULL) {
 
23566
                                xmlSchemaVErrMemory(NULL, 
 
23567
                                    "allocating IDC list of node-table items", NULL);
 
23568
                                goto internal_error;
 
23569
                            }
 
23570
                            parBind->sizeNodes = 1;
 
23571
                        } else if (parBind->nbNodes >= parBind->sizeNodes) {
 
23572
                            parBind->sizeNodes *= 2;
 
23573
                            parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 
 
23574
                                xmlRealloc(parBind->nodeTable, parBind->sizeNodes * 
 
23575
                                sizeof(xmlSchemaPSVIIDCNodePtr));
 
23576
                            if (parBind->nodeTable == NULL) {
 
23577
                                xmlSchemaVErrMemory(NULL, 
 
23578
                                    "re-allocating IDC list of node-table items", NULL);
 
23579
                                goto internal_error;
 
23580
                            }                       
 
23581
                        }
 
23582
                        parNodes = parBind->nodeTable;
 
23583
                        /*
 
23584
                        * Append the new node-table entry to the 'new node-table
 
23585
                        * entries' section.
 
23586
                        */
 
23587
                        parNodes[parBind->nbNodes++] = node;
 
23588
                    }
 
23589
 
 
23590
                }       
 
23591
                
 
23592
            }   
 
23593
        } else {
 
23594
            /*
 
23595
            * No binding for the IDC was found: create a new one and
 
23596
            * copy all node-tables.
 
23597
            */
 
23598
            parBind = xmlSchemaIDCNewBinding(bind->definition);
 
23599
            if (parBind == NULL)
 
23600
                goto internal_error;
 
23601
            
 
23602
            /*
 
23603
            * TODO: Hmm, how to optimize the initial number of
 
23604
            * allocated entries?
 
23605
            */
 
23606
            if (bind->nbNodes != 0) {
 
23607
                /*
 
23608
                * Add all IDC node-table entries.
 
23609
                */
 
23610
                if (! vctxt->psviExposeIDCNodeTables) {
 
23611
                    /*
 
23612
                    * Just move the entries.
 
23613
                    * NOTE: this is quite save here, since
 
23614
                    * all the keyref lookups have already been
 
23615
                    * performed.
 
23616
                    */
 
23617
                    parBind->nodeTable = bind->nodeTable;
 
23618
                    bind->nodeTable = NULL;
 
23619
                    parBind->sizeNodes = bind->sizeNodes;
 
23620
                    bind->sizeNodes = 0;
 
23621
                    parBind->nbNodes = bind->nbNodes;
 
23622
                    bind->nbNodes = 0;
 
23623
                } else {
 
23624
                    /*
 
23625
                    * Copy the entries.
 
23626
                    */
 
23627
                    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 
 
23628
                        xmlMalloc(bind->nbNodes *
 
23629
                        sizeof(xmlSchemaPSVIIDCNodePtr));
 
23630
                    if (parBind->nodeTable == NULL) {
 
23631
                        xmlSchemaVErrMemory(NULL, 
 
23632
                            "allocating an array of IDC node-table "
 
23633
                            "items", NULL);
 
23634
                        xmlSchemaIDCFreeBinding(parBind);
 
23635
                        goto internal_error;
 
23636
                    }
 
23637
                    parBind->sizeNodes = bind->nbNodes;
 
23638
                    parBind->nbNodes = bind->nbNodes;
 
23639
                    memcpy(parBind->nodeTable, bind->nodeTable,
 
23640
                        bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
 
23641
                }
 
23642
            }
 
23643
            if (bind->dupls) {
 
23644
                /*
 
23645
                * Move the duplicates.
 
23646
                */
 
23647
                if (parBind->dupls != NULL)
 
23648
                    xmlSchemaItemListFree(parBind->dupls);
 
23649
                parBind->dupls = bind->dupls;
 
23650
                bind->dupls = NULL;             
 
23651
            }
 
23652
            if (*parTable == NULL)
 
23653
                *parTable = parBind;
 
23654
            else {
 
23655
                parBind->next = *parTable;
 
23656
                *parTable = parBind;
 
23657
            }      
 
23658
        }       
 
23659
 
 
23660
next_binding:
 
23661
        bind = bind->next;
 
23662
    }
 
23663
    return (0);
 
23664
 
 
23665
internal_error:
 
23666
    return(-1);
 
23667
}
 
23668
 
 
23669
/**
 
23670
 * xmlSchemaCheckCVCIDCKeyRef:
 
23671
 * @vctxt: the WXS validation context
 
23672
 * @elemDecl: the element declaration
 
23673
 *
 
23674
 * Check the cvc-idc-keyref constraints.
 
23675
 */
 
23676
static int
 
23677
xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
 
23678
{
 
23679
    xmlSchemaIDCMatcherPtr matcher;
 
23680
    xmlSchemaPSVIIDCBindingPtr bind;
 
23681
    
 
23682
    matcher = vctxt->inode->idcMatchers;
 
23683
    /*
 
23684
    * Find a keyref.
 
23685
    */
 
23686
    while (matcher != NULL) {
 
23687
        if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
 
23688
            matcher->targets &&
 
23689
            matcher->targets->nbItems)
 
23690
        {
 
23691
            int i, j, k, res, nbFields, hasDupls;
 
23692
            xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
 
23693
            xmlSchemaPSVIIDCNodePtr refNode = NULL;
 
23694
 
 
23695
            nbFields = matcher->aidc->def->nbFields;
 
23696
 
 
23697
            /*
 
23698
            * Find the IDC node-table for the referenced IDC key/unique.
 
23699
            */
 
23700
            bind = vctxt->inode->idcTable;
 
23701
            while (bind != NULL) {
 
23702
                if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item == 
 
23703
                    bind->definition)
 
23704
                    break;
 
23705
                bind = bind->next;
 
23706
            }
 
23707
            hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
 
23708
            /*
 
23709
            * Search for a matching key-sequences.
 
23710
            */
 
23711
            for (i = 0; i < matcher->targets->nbItems; i++) {
 
23712
                res = 0;
 
23713
                refNode = matcher->targets->items[i];
 
23714
                if (bind != NULL) {
 
23715
                    refKeys = refNode->keys;
 
23716
                    for (j = 0; j < bind->nbNodes; j++) {
 
23717
                        keys = bind->nodeTable[j]->keys;
 
23718
                        for (k = 0; k < nbFields; k++) {
 
23719
                            res = xmlSchemaAreValuesEqual(keys[k]->val,
 
23720
                                refKeys[k]->val);
 
23721
                            if (res == 0)
 
23722
                                break;
 
23723
                            else if (res == -1) {
 
23724
                                return (-1);
 
23725
                            }
 
23726
                        }
 
23727
                        if (res == 1) {
 
23728
                            /*
 
23729
                            * Match found.
 
23730
                            */
 
23731
                            break;
 
23732
                        }
 
23733
                    }
 
23734
                    if ((res == 0) && hasDupls) {
 
23735
                        /*
 
23736
                        * Search in duplicates
 
23737
                        */
 
23738
                        for (j = 0; j < bind->dupls->nbItems; j++) {
 
23739
                            keys = ((xmlSchemaPSVIIDCNodePtr)
 
23740
                                bind->dupls->items[j])->keys;
 
23741
                            for (k = 0; k < nbFields; k++) {
 
23742
                                res = xmlSchemaAreValuesEqual(keys[k]->val,
 
23743
                                    refKeys[k]->val);
 
23744
                                if (res == 0)
 
23745
                                    break;
 
23746
                                else if (res == -1) {
 
23747
                                    return (-1);
 
23748
                                }
 
23749
                            }
 
23750
                            if (res == 1) {
 
23751
                                /*
 
23752
                                * Match in duplicates found.
 
23753
                                */
 
23754
                                xmlChar *str = NULL, *strB = NULL;
 
23755
                                xmlSchemaKeyrefErr(vctxt,
 
23756
                                    XML_SCHEMAV_CVC_IDC, refNode,
 
23757
                                    (xmlSchemaTypePtr) matcher->aidc->def,
 
23758
                                    "More than one match found for "
 
23759
                                    "key-sequence %s of keyref '%s'",
 
23760
                                    xmlSchemaFormatIDCKeySequence(vctxt, &str,
 
23761
                                        refNode->keys, nbFields),
 
23762
                                    xmlSchemaGetComponentQName(&strB,
 
23763
                                        matcher->aidc->def));
 
23764
                                FREE_AND_NULL(str);
 
23765
                                FREE_AND_NULL(strB);
 
23766
                                break;
 
23767
                            }
 
23768
                        }
 
23769
                    }
 
23770
                }
 
23771
                
 
23772
                if (res == 0) {
 
23773
                    xmlChar *str = NULL, *strB = NULL;
 
23774
                    xmlSchemaKeyrefErr(vctxt,
 
23775
                        XML_SCHEMAV_CVC_IDC, refNode,
 
23776
                        (xmlSchemaTypePtr) matcher->aidc->def,
 
23777
                        "No match found for key-sequence %s of keyref '%s'",
 
23778
                        xmlSchemaFormatIDCKeySequence(vctxt, &str,
 
23779
                            refNode->keys, nbFields),
 
23780
                        xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
 
23781
                    FREE_AND_NULL(str);
 
23782
                    FREE_AND_NULL(strB);
 
23783
                }
 
23784
            }
 
23785
        }
 
23786
        matcher = matcher->next;
 
23787
    }
 
23788
    /* TODO: Return an error if any error encountered. */
 
23789
    return (0);
 
23790
}
 
23791
 
 
23792
/************************************************************************
 
23793
 *                                                                      *
 
23794
 *                      XML Reader validation code                      *
 
23795
 *                                                                      *
 
23796
 ************************************************************************/
 
23797
 
 
23798
static xmlSchemaAttrInfoPtr
 
23799
xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
 
23800
{
 
23801
    xmlSchemaAttrInfoPtr iattr;
 
23802
    /*
 
23803
    * Grow/create list of attribute infos.
 
23804
    */
 
23805
    if (vctxt->attrInfos == NULL) {
 
23806
        vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
 
23807
            xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
 
23808
        vctxt->sizeAttrInfos = 1;
 
23809
        if (vctxt->attrInfos == NULL) {
 
23810
            xmlSchemaVErrMemory(vctxt,
 
23811
                "allocating attribute info list", NULL);
 
23812
            return (NULL);
 
23813
        }
 
23814
    } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
 
23815
        vctxt->sizeAttrInfos++;
 
23816
        vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
 
23817
            xmlRealloc(vctxt->attrInfos,
 
23818
                vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
 
23819
        if (vctxt->attrInfos == NULL) {
 
23820
            xmlSchemaVErrMemory(vctxt,
 
23821
                "re-allocating attribute info list", NULL);
 
23822
            return (NULL);
 
23823
        }
 
23824
    } else {
 
23825
        iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
 
23826
        if (iattr->localName != NULL) {
 
23827
            VERROR_INT("xmlSchemaGetFreshAttrInfo",
 
23828
                "attr info not cleared");
 
23829
            return (NULL);
 
23830
        }
 
23831
        iattr->nodeType = XML_ATTRIBUTE_NODE;
 
23832
        return (iattr);
 
23833
    }
 
23834
    /*
 
23835
    * Create an attribute info.
 
23836
    */
 
23837
    iattr = (xmlSchemaAttrInfoPtr)
 
23838
        xmlMalloc(sizeof(xmlSchemaAttrInfo));
 
23839
    if (iattr == NULL) {
 
23840
        xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
 
23841
        return (NULL);
 
23842
    }
 
23843
    memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
 
23844
    iattr->nodeType = XML_ATTRIBUTE_NODE;
 
23845
    vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
 
23846
 
 
23847
    return (iattr);
 
23848
}
 
23849
 
 
23850
static int
 
23851
xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
 
23852
                        xmlNodePtr attrNode,
 
23853
                        int nodeLine,
 
23854
                        const xmlChar *localName,
 
23855
                        const xmlChar *nsName,                  
 
23856
                        int ownedNames,
 
23857
                        xmlChar *value,
 
23858
                        int ownedValue)
 
23859
{
 
23860
    xmlSchemaAttrInfoPtr attr;
 
23861
 
 
23862
    attr = xmlSchemaGetFreshAttrInfo(vctxt);
 
23863
    if (attr == NULL) {
 
23864
        VERROR_INT("xmlSchemaPushAttribute",
 
23865
            "calling xmlSchemaGetFreshAttrInfo()");
 
23866
        return (-1);
 
23867
    }
 
23868
    attr->node = attrNode;
 
23869
    attr->nodeLine = nodeLine;
 
23870
    attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
 
23871
    attr->localName = localName;
 
23872
    attr->nsName = nsName;
 
23873
    if (ownedNames)
 
23874
        attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
 
23875
    /*
 
23876
    * Evaluate if it's an XSI attribute.
 
23877
    */
 
23878
    if (nsName != NULL) {
 
23879
        if (xmlStrEqual(localName, BAD_CAST "nil")) {
 
23880
            if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
 
23881
                attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;             
 
23882
            }
 
23883
        } else if (xmlStrEqual(localName, BAD_CAST "type")) {
 
23884
            if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
 
23885
                attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
 
23886
            }
 
23887
        } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
 
23888
            if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
 
23889
                attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
 
23890
            }
 
23891
        } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
 
23892
            if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
 
23893
                attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
 
23894
            }
 
23895
        } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
 
23896
            attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
 
23897
        }
 
23898
    }
 
23899
    attr->value = value;
 
23900
    if (ownedValue)
 
23901
        attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
 
23902
    if (attr->metaType != 0)
 
23903
        attr->state = XML_SCHEMAS_ATTR_META;
 
23904
    return (0);
 
23905
}
 
23906
 
 
23907
/**
 
23908
 * xmlSchemaClearElemInfo:
 
23909
 * @vctxt: the WXS validation context
 
23910
 * @ielem: the element information item
 
23911
 */
 
23912
static void
 
23913
xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
 
23914
                       xmlSchemaNodeInfoPtr ielem)
 
23915
{
 
23916
    ielem->hasKeyrefs = 0;
 
23917
    ielem->appliedXPath = 0;
 
23918
    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
 
23919
        FREE_AND_NULL(ielem->localName);
 
23920
        FREE_AND_NULL(ielem->nsName);
 
23921
    } else {
 
23922
        ielem->localName = NULL;
 
23923
        ielem->nsName = NULL;
 
23924
    }
 
23925
    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
 
23926
        FREE_AND_NULL(ielem->value);
 
23927
    } else {
 
23928
        ielem->value = NULL;
 
23929
    }
 
23930
    if (ielem->val != NULL) {
 
23931
        /*
 
23932
        * PSVI TODO: Be careful not to free it when the value is
 
23933
        * exposed via PSVI.
 
23934
        */
 
23935
        xmlSchemaFreeValue(ielem->val);
 
23936
        ielem->val = NULL;
 
23937
    }
 
23938
    if (ielem->idcMatchers != NULL) {
 
23939
        /*
 
23940
        * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
 
23941
        *   Does it work?
 
23942
        */
 
23943
        xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
 
23944
#if 0
 
23945
        xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
 
23946
#endif
 
23947
        ielem->idcMatchers = NULL;
 
23948
    }
 
23949
    if (ielem->idcTable != NULL) {
 
23950
        /*
 
23951
        * OPTIMIZE TODO: Use a pool of IDC tables??.
 
23952
        */
 
23953
        xmlSchemaIDCFreeIDCTable(ielem->idcTable);
 
23954
        ielem->idcTable = NULL;
 
23955
    }
 
23956
    if (ielem->regexCtxt != NULL) {
 
23957
        xmlRegFreeExecCtxt(ielem->regexCtxt);
 
23958
        ielem->regexCtxt = NULL;
 
23959
    }
 
23960
    if (ielem->nsBindings != NULL) {
 
23961
        xmlFree((xmlChar **)ielem->nsBindings);
 
23962
        ielem->nsBindings = NULL;
 
23963
        ielem->nbNsBindings = 0;
 
23964
        ielem->sizeNsBindings = 0;
 
23965
    }
 
23966
}
 
23967
 
 
23968
/**
 
23969
 * xmlSchemaGetFreshElemInfo:
 
23970
 * @vctxt: the schema validation context
 
23971
 *
 
23972
 * Creates/reuses and initializes the element info item for
 
23973
 * the currect tree depth.
 
23974
 *
 
23975
 * Returns the element info item or NULL on API or internal errors.
 
23976
 */
 
23977
static xmlSchemaNodeInfoPtr
 
23978
xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
 
23979
{
 
23980
    xmlSchemaNodeInfoPtr info = NULL;
 
23981
 
 
23982
    if (vctxt->depth > vctxt->sizeElemInfos) {
 
23983
        VERROR_INT("xmlSchemaGetFreshElemInfo",
 
23984
            "inconsistent depth encountered");
 
23985
        return (NULL);
 
23986
    }
 
23987
    if (vctxt->elemInfos == NULL) {
 
23988
        vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
 
23989
            xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
 
23990
        if (vctxt->elemInfos == NULL) {
 
23991
            xmlSchemaVErrMemory(vctxt,
 
23992
                "allocating the element info array", NULL);
 
23993
            return (NULL);
 
23994
        }
 
23995
        memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
 
23996
        vctxt->sizeElemInfos = 10;
 
23997
    } else if (vctxt->sizeElemInfos <= vctxt->depth) {
 
23998
        int i = vctxt->sizeElemInfos;
 
23999
 
 
24000
        vctxt->sizeElemInfos *= 2;
 
24001
        vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
 
24002
            xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
 
24003
            sizeof(xmlSchemaNodeInfoPtr));
 
24004
        if (vctxt->elemInfos == NULL) {
 
24005
            xmlSchemaVErrMemory(vctxt,
 
24006
                "re-allocating the element info array", NULL);
 
24007
            return (NULL);
 
24008
        }
 
24009
        /*
 
24010
        * We need the new memory to be NULLed.
 
24011
        * TODO: Use memset instead?
 
24012
        */
 
24013
        for (; i < vctxt->sizeElemInfos; i++)
 
24014
            vctxt->elemInfos[i] = NULL;
 
24015
    } else
 
24016
        info = vctxt->elemInfos[vctxt->depth];
 
24017
 
 
24018
    if (info == NULL) {
 
24019
        info = (xmlSchemaNodeInfoPtr)
 
24020
            xmlMalloc(sizeof(xmlSchemaNodeInfo));
 
24021
        if (info == NULL) {
 
24022
            xmlSchemaVErrMemory(vctxt,
 
24023
                "allocating an element info", NULL);
 
24024
            return (NULL);
 
24025
        }
 
24026
        vctxt->elemInfos[vctxt->depth] = info;
 
24027
    } else {
 
24028
        if (info->localName != NULL) {
 
24029
            VERROR_INT("xmlSchemaGetFreshElemInfo",
 
24030
                "elem info has not been cleared");
 
24031
            return (NULL);
 
24032
        }
 
24033
    }
 
24034
    memset(info, 0, sizeof(xmlSchemaNodeInfo));
 
24035
    info->nodeType = XML_ELEMENT_NODE;
 
24036
    info->depth = vctxt->depth;
 
24037
 
 
24038
    return (info);
 
24039
}
 
24040
 
 
24041
#define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
 
24042
#define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
 
24043
#define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
 
24044
 
 
24045
static int
 
24046
xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
 
24047
                        xmlNodePtr node,
 
24048
                        xmlSchemaTypePtr type,
 
24049
                        xmlSchemaValType valType,
 
24050
                        const xmlChar * value,
 
24051
                        xmlSchemaValPtr val,
 
24052
                        unsigned long length,
 
24053
                        int fireErrors)
 
24054
{
 
24055
    int ret, error = 0;
 
24056
 
 
24057
    xmlSchemaTypePtr tmpType;
 
24058
    xmlSchemaFacetLinkPtr facetLink;
 
24059
    xmlSchemaFacetPtr facet;
 
24060
    unsigned long len = 0;
 
24061
    xmlSchemaWhitespaceValueType ws;
 
24062
 
 
24063
    /*
 
24064
    * In Libxml2, derived built-in types have currently no explicit facets.
 
24065
    */
 
24066
    if (type->type == XML_SCHEMA_TYPE_BASIC)
 
24067
        return (0);
 
24068
 
 
24069
    /*
 
24070
    * NOTE: Do not jump away, if the facetSet of the given type is
 
24071
    * empty: until now, "pattern" and "enumeration" facets of the
 
24072
    * *base types* need to be checked as well.
 
24073
    */
 
24074
    if (type->facetSet == NULL)
 
24075
        goto pattern_and_enum;
 
24076
 
 
24077
    if (! WXS_IS_ATOMIC(type)) {
 
24078
        if (WXS_IS_LIST(type))
 
24079
            goto WXS_IS_LIST;
 
24080
        else
 
24081
            goto pattern_and_enum;
 
24082
    }
 
24083
    /*
 
24084
    * Whitespace handling is only of importance for string-based
 
24085
    * types.
 
24086
    */
 
24087
    tmpType = xmlSchemaGetPrimitiveType(type);
 
24088
    if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
 
24089
        WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
 
24090
        ws = xmlSchemaGetWhiteSpaceFacetValue(type);
 
24091
    } else
 
24092
        ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
 
24093
    /*
 
24094
    * If the value was not computed (for string or
 
24095
    * anySimpleType based types), then use the provided
 
24096
    * type.
 
24097
    */
 
24098
    if (val == NULL)
 
24099
        valType = valType;
 
24100
    else
 
24101
        valType = xmlSchemaGetValType(val);
 
24102
    
 
24103
    ret = 0;
 
24104
    for (facetLink = type->facetSet; facetLink != NULL;
 
24105
        facetLink = facetLink->next) {
 
24106
        /*
 
24107
        * Skip the pattern "whiteSpace": it is used to
 
24108
        * format the character content beforehand.
 
24109
        */
 
24110
        switch (facetLink->facet->type) {
 
24111
            case XML_SCHEMA_FACET_WHITESPACE:
 
24112
            case XML_SCHEMA_FACET_PATTERN:
 
24113
            case XML_SCHEMA_FACET_ENUMERATION:
 
24114
                continue;
 
24115
            case XML_SCHEMA_FACET_LENGTH:
 
24116
            case XML_SCHEMA_FACET_MINLENGTH:
 
24117
            case XML_SCHEMA_FACET_MAXLENGTH:
 
24118
                ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
 
24119
                    valType, value, val, &len, ws);
 
24120
                break;
 
24121
            default:
 
24122
                ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
 
24123
                    valType, value, val, ws);
 
24124
                break;
 
24125
        }
 
24126
        if (ret < 0) {
 
24127
            AERROR_INT("xmlSchemaValidateFacets",
 
24128
                "validating against a atomic type facet");
 
24129
            return (-1);
 
24130
        } else if (ret > 0) {
 
24131
            if (fireErrors)
 
24132
                xmlSchemaFacetErr(actxt, ret, node,
 
24133
                value, len, type, facetLink->facet, NULL, NULL, NULL);
 
24134
            else
 
24135
                return (ret);
 
24136
            if (error == 0)
 
24137
                error = ret;
 
24138
        }
 
24139
        ret = 0;
 
24140
    }
 
24141
 
 
24142
WXS_IS_LIST:
 
24143
    if (! WXS_IS_LIST(type))
 
24144
        goto pattern_and_enum;
 
24145
    /*
 
24146
    * "length", "minLength" and "maxLength" of list types.
 
24147
    */
 
24148
    ret = 0;
 
24149
    for (facetLink = type->facetSet; facetLink != NULL;
 
24150
        facetLink = facetLink->next) {
 
24151
        
 
24152
        switch (facetLink->facet->type) {
 
24153
            case XML_SCHEMA_FACET_LENGTH:
 
24154
            case XML_SCHEMA_FACET_MINLENGTH:
 
24155
            case XML_SCHEMA_FACET_MAXLENGTH:                
 
24156
                ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
 
24157
                    value, length, NULL);
 
24158
                break;
 
24159
            default:
 
24160
                continue;
 
24161
        }
 
24162
        if (ret < 0) {
 
24163
            AERROR_INT("xmlSchemaValidateFacets",
 
24164
                "validating against a list type facet");
 
24165
            return (-1);
 
24166
        } else if (ret > 0) {
 
24167
            if (fireErrors)             
 
24168
                xmlSchemaFacetErr(actxt, ret, node,
 
24169
                value, length, type, facetLink->facet, NULL, NULL, NULL);
 
24170
            else
 
24171
                return (ret);
 
24172
            if (error == 0)
 
24173
                error = ret;
 
24174
        }
 
24175
        ret = 0;
 
24176
    }
 
24177
 
 
24178
pattern_and_enum:
 
24179
    if (error >= 0) {
 
24180
        int found = 0;
 
24181
        /*
 
24182
        * Process enumerations. Facet values are in the value space
 
24183
        * of the defining type's base type. This seems to be a bug in the
 
24184
        * XML Schema 1.0 spec. Use the whitespace type of the base type.
 
24185
        * Only the first set of enumerations in the ancestor-or-self axis
 
24186
        * is used for validation.
 
24187
        */
 
24188
        ret = 0;
 
24189
        tmpType = type;
 
24190
        do {
 
24191
            for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
 
24192
                if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
 
24193
                    continue;
 
24194
                found = 1;
 
24195
                ret = xmlSchemaAreValuesEqual(facet->val, val);
 
24196
                if (ret == 1)
 
24197
                    break;
 
24198
                else if (ret < 0) {
 
24199
                    AERROR_INT("xmlSchemaValidateFacets",
 
24200
                        "validating against an enumeration facet");
 
24201
                    return (-1);
 
24202
                }
 
24203
            }
 
24204
            if (ret != 0)
 
24205
                break;
 
24206
            /*
 
24207
            * Break on the first set of enumerations. Any additional
 
24208
            *  enumerations which might be existent on the ancestors
 
24209
            *  of the current type are restricted by this set; thus
 
24210
            *  *must* *not* be taken into account.
 
24211
            */
 
24212
            if (found)
 
24213
                break;
 
24214
            tmpType = tmpType->baseType;
 
24215
        } while ((tmpType != NULL) &&
 
24216
            (tmpType->type != XML_SCHEMA_TYPE_BASIC));
 
24217
        if (found && (ret == 0)) {
 
24218
            ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
 
24219
            if (fireErrors) {
 
24220
                xmlSchemaFacetErr(actxt, ret, node,
 
24221
                    value, 0, type, NULL, NULL, NULL, NULL);
 
24222
            } else
 
24223
                return (ret);
 
24224
            if (error == 0)
 
24225
                error = ret;
 
24226
        }
 
24227
    }
 
24228
 
 
24229
    if (error >= 0) {
 
24230
        int found;
 
24231
        /*
 
24232
        * Process patters. Pattern facets are ORed at type level
 
24233
        * and ANDed if derived. Walk the base type axis.
 
24234
        */
 
24235
        tmpType = type;
 
24236
        facet = NULL;
 
24237
        do {
 
24238
            found = 0;
 
24239
            for (facetLink = tmpType->facetSet; facetLink != NULL;
 
24240
                facetLink = facetLink->next) {
 
24241
                if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
 
24242
                    continue;
 
24243
                found = 1;
 
24244
                /* 
 
24245
                * NOTE that for patterns, @value needs to be the
 
24246
                * normalized vaule.
 
24247
                */
 
24248
                ret = xmlRegexpExec(facetLink->facet->regexp, value);
 
24249
                if (ret == 1)
 
24250
                    break;
 
24251
                else if (ret < 0) {
 
24252
                    AERROR_INT("xmlSchemaValidateFacets",
 
24253
                        "validating against a pattern facet");
 
24254
                    return (-1);
 
24255
                } else {
 
24256
                    /* 
 
24257
                    * Save the last non-validating facet.
 
24258
                    */
 
24259
                    facet = facetLink->facet;
 
24260
                }
 
24261
            }
 
24262
            if (found && (ret != 1)) {
 
24263
                ret = XML_SCHEMAV_CVC_PATTERN_VALID;
 
24264
                if (fireErrors) {
 
24265
                    xmlSchemaFacetErr(actxt, ret, node,
 
24266
                        value, 0, type, facet, NULL, NULL, NULL);
 
24267
                } else
 
24268
                    return (ret);
 
24269
                if (error == 0)
 
24270
                    error = ret;
 
24271
                break;
 
24272
            }
 
24273
            tmpType = tmpType->baseType;
 
24274
        } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
 
24275
    }
 
24276
 
 
24277
    return (error);
 
24278
}
 
24279
 
 
24280
static xmlChar *
 
24281
xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
 
24282
                        const xmlChar *value)
 
24283
{
 
24284
    switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {   
 
24285
        case XML_SCHEMA_WHITESPACE_COLLAPSE:
 
24286
            return (xmlSchemaCollapseString(value));
 
24287
        case XML_SCHEMA_WHITESPACE_REPLACE:
 
24288
            return (xmlSchemaWhiteSpaceReplace(value));
 
24289
        default:
 
24290
            return (NULL);
 
24291
    }
 
24292
}
 
24293
 
 
24294
static int
 
24295
xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
 
24296
                       const xmlChar *value,
 
24297
                       xmlSchemaValPtr *val,
 
24298
                       int valNeeded)
 
24299
{
 
24300
    int ret;
 
24301
    const xmlChar *nsName;
 
24302
    xmlChar *local, *prefix = NULL;
 
24303
    
 
24304
    ret = xmlValidateQName(value, 1);
 
24305
    if (ret != 0) {
 
24306
        if (ret == -1) {
 
24307
            VERROR_INT("xmlSchemaValidateQName",
 
24308
                "calling xmlValidateQName()");
 
24309
            return (-1);
 
24310
        }
 
24311
        return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
 
24312
    }
 
24313
    /*
 
24314
    * NOTE: xmlSplitQName2 will always return a duplicated
 
24315
    * strings.
 
24316
    */
 
24317
    local = xmlSplitQName2(value, &prefix);
 
24318
    if (local == NULL)
 
24319
        local = xmlStrdup(value);
 
24320
    /*
 
24321
    * OPTIMIZE TODO: Use flags for:
 
24322
    *  - is there any namespace binding?
 
24323
    *  - is there a default namespace?
 
24324
    */
 
24325
    nsName = xmlSchemaLookupNamespace(vctxt, prefix);
 
24326
    
 
24327
    if (prefix != NULL) {
 
24328
        xmlFree(prefix);
 
24329
        /*
 
24330
        * A namespace must be found if the prefix is
 
24331
        * NOT NULL.
 
24332
        */
 
24333
        if (nsName == NULL) {
 
24334
            ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
 
24335
            xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
 
24336
                WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
 
24337
                "The QName value '%s' has no "
 
24338
                "corresponding namespace declaration in "
 
24339
                "scope", value, NULL);
 
24340
            if (local != NULL)
 
24341
                xmlFree(local);
 
24342
            return (ret);
 
24343
        }
 
24344
    }
 
24345
    if (valNeeded && val) {
 
24346
        if (nsName != NULL)
 
24347
            *val = xmlSchemaNewQNameValue(
 
24348
                BAD_CAST xmlStrdup(nsName), BAD_CAST local);
 
24349
        else
 
24350
            *val = xmlSchemaNewQNameValue(NULL,
 
24351
                BAD_CAST local);
 
24352
    } else
 
24353
        xmlFree(local);
 
24354
    return (0);
 
24355
}
 
24356
 
 
24357
/*
 
24358
* cvc-simple-type
 
24359
*/
 
24360
static int
 
24361
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
 
24362
                             xmlNodePtr node,
 
24363
                             xmlSchemaTypePtr type,
 
24364
                             const xmlChar *value,
 
24365
                             xmlSchemaValPtr *retVal,
 
24366
                             int fireErrors,
 
24367
                             int normalize,
 
24368
                             int isNormalized)
 
24369
{
 
24370
    int ret = 0, valNeeded = (retVal) ? 1 : 0;
 
24371
    xmlSchemaValPtr val = NULL;
 
24372
    /* xmlSchemaWhitespaceValueType ws; */
 
24373
    xmlChar *normValue = NULL;
 
24374
 
 
24375
#define NORMALIZE(atype) \
 
24376
    if ((! isNormalized) && \
 
24377
    (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
 
24378
        normValue = xmlSchemaNormalizeValue(atype, value); \
 
24379
        if (normValue != NULL) \
 
24380
            value = normValue; \
 
24381
        isNormalized = 1; \
 
24382
    }
 
24383
    
 
24384
    if ((retVal != NULL) && (*retVal != NULL)) {
 
24385
        xmlSchemaFreeValue(*retVal);
 
24386
        *retVal = NULL;
 
24387
    }
 
24388
    /*
 
24389
    * 3.14.4 Simple Type Definition Validation Rules
 
24390
    * Validation Rule: String Valid
 
24391
    */
 
24392
    /*
 
24393
    * 1 It is schema-valid with respect to that definition as defined
 
24394
    * by Datatype Valid in [XML Schemas: Datatypes].
 
24395
    */
 
24396
    /*
 
24397
    * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
 
24398
    * the empty set, as defined in Type Derivation OK (Simple) (ļæ½3.14.6), then
 
24399
    * the string must be a ļæ½declared entity nameļæ½.
 
24400
    */
 
24401
    /*
 
24402
    * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
 
24403
    * given the empty set, as defined in Type Derivation OK (Simple) (ļæ½3.14.6),
 
24404
    * then every whitespace-delimited substring of the string must be a ļæ½declared
 
24405
    * entity nameļæ½.
 
24406
    */
 
24407
    /*
 
24408
    * 2.3 otherwise no further condition applies.
 
24409
    */
 
24410
    if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
 
24411
        valNeeded = 1;
 
24412
    if (value == NULL)
 
24413
        value = BAD_CAST "";
 
24414
    if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
 
24415
        xmlSchemaTypePtr biType; /* The built-in type. */
 
24416
        /*
 
24417
        * SPEC (1.2.1) "if {variety} is ļæ½atomicļæ½ then the string must ļæ½matchļæ½
 
24418
        * a literal in the ļæ½lexical spaceļæ½ of {base type definition}"
 
24419
        */
 
24420
        /*
 
24421
        * Whitespace-normalize.
 
24422
        */
 
24423
        NORMALIZE(type);
 
24424
        if (type->type != XML_SCHEMA_TYPE_BASIC) {
 
24425
            /*
 
24426
            * Get the built-in type.
 
24427
            */
 
24428
            biType = type->baseType;
 
24429
            while ((biType != NULL) &&
 
24430
                (biType->type != XML_SCHEMA_TYPE_BASIC))
 
24431
                biType = biType->baseType;
 
24432
 
 
24433
            if (biType == NULL) {
 
24434
                AERROR_INT("xmlSchemaVCheckCVCSimpleType",
 
24435
                    "could not get the built-in type");
 
24436
                goto internal_error;
 
24437
            }
 
24438
        } else
 
24439
            biType = type;
 
24440
        /*
 
24441
        * NOTATIONs need to be processed here, since they need
 
24442
        * to lookup in the hashtable of NOTATION declarations of the schema.
 
24443
        */
 
24444
        if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {     
 
24445
            switch (biType->builtInType) {              
 
24446
                case XML_SCHEMAS_NOTATION:                  
 
24447
                    ret = xmlSchemaValidateNotation(
 
24448
                        (xmlSchemaValidCtxtPtr) actxt,
 
24449
                        ((xmlSchemaValidCtxtPtr) actxt)->schema,
 
24450
                        NULL, value, &val, valNeeded);
 
24451
                    break;
 
24452
                case XML_SCHEMAS_QNAME:
 
24453
                    ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
 
24454
                        value, &val, valNeeded);
 
24455
                    break;
 
24456
                default:
 
24457
                    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
 
24458
                    if (valNeeded)
 
24459
                        ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
 
24460
                            value, &val, NULL);
 
24461
                    else
 
24462
                        ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
 
24463
                            value, NULL, NULL);
 
24464
                    break;
 
24465
            }
 
24466
        } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {         
 
24467
            switch (biType->builtInType) {                  
 
24468
                case XML_SCHEMAS_NOTATION:
 
24469
                    ret = xmlSchemaValidateNotation(NULL,
 
24470
                        ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
 
24471
                        value, &val, valNeeded);
 
24472
                    break;
 
24473
                default:
 
24474
                    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
 
24475
                    if (valNeeded)
 
24476
                        ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
 
24477
                            value, &val, node);
 
24478
                    else
 
24479
                        ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
 
24480
                            value, NULL, node);
 
24481
                    break;
 
24482
            }      
 
24483
        } else {
 
24484
            /*
 
24485
            * Validation via a public API is not implemented yet.
 
24486
            */
 
24487
            TODO
 
24488
            goto internal_error;
 
24489
        }
 
24490
        if (ret != 0) {
 
24491
            if (ret < 0) {
 
24492
                AERROR_INT("xmlSchemaVCheckCVCSimpleType",
 
24493
                    "validating against a built-in type");
 
24494
                goto internal_error;
 
24495
            }
 
24496
            if (WXS_IS_LIST(type))
 
24497
                ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
 
24498
            else
 
24499
                ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;         
 
24500
        }
 
24501
        if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
 
24502
            /*
 
24503
            * Check facets.
 
24504
            */
 
24505
            ret = xmlSchemaValidateFacets(actxt, node, type,
 
24506
                (xmlSchemaValType) biType->builtInType, value, val,
 
24507
                0, fireErrors);
 
24508
            if (ret != 0) {
 
24509
                if (ret < 0) {
 
24510
                    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
 
24511
                        "validating facets of atomic simple type");
 
24512
                    goto internal_error;
 
24513
                }
 
24514
                if (WXS_IS_LIST(type)) 
 
24515
                    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
 
24516
                else
 
24517
                    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;         
 
24518
            }
 
24519
        }
 
24520
        if (fireErrors && (ret > 0))
 
24521
            xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
 
24522
    } else if (WXS_IS_LIST(type)) {
 
24523
 
 
24524
        xmlSchemaTypePtr itemType;
 
24525
        const xmlChar *cur, *end;
 
24526
        xmlChar *tmpValue = NULL;
 
24527
        unsigned long len = 0;
 
24528
        xmlSchemaValPtr prevVal = NULL, curVal = NULL;
 
24529
        /* 1.2.2 if {variety} is ļæ½listļæ½ then the string must be a sequence
 
24530
        * of white space separated tokens, each of which ļæ½matchļæ½es a literal
 
24531
        * in the ļæ½lexical spaceļæ½ of {item type definition}
 
24532
        */
 
24533
        /*
 
24534
        * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
 
24535
        * the list type has an enum or pattern facet.
 
24536
        */
 
24537
        NORMALIZE(type);
 
24538
        /*
 
24539
        * VAL TODO: Optimize validation of empty values.
 
24540
        * VAL TODO: We do not have computed values for lists.
 
24541
        */
 
24542
        itemType = WXS_LIST_ITEMTYPE(type);     
 
24543
        cur = value;
 
24544
        do {
 
24545
            while (IS_BLANK_CH(*cur))
 
24546
                cur++;
 
24547
            end = cur;
 
24548
            while ((*end != 0) && (!(IS_BLANK_CH(*end))))
 
24549
                end++;
 
24550
            if (end == cur)
 
24551
                break;
 
24552
            tmpValue = xmlStrndup(cur, end - cur);
 
24553
            len++;
 
24554
 
 
24555
            if (valNeeded)
 
24556
                ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
 
24557
                    tmpValue, &curVal, fireErrors, 0, 1);
 
24558
            else
 
24559
                ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
 
24560
                    tmpValue, NULL, fireErrors, 0, 1);
 
24561
            FREE_AND_NULL(tmpValue);
 
24562
            if (curVal != NULL) {
 
24563
                /*
 
24564
                * Add to list of computed values.
 
24565
                */
 
24566
                if (val == NULL)
 
24567
                    val = curVal;
 
24568
                else
 
24569
                    xmlSchemaValueAppend(prevVal, curVal);
 
24570
                prevVal = curVal;
 
24571
                curVal = NULL;
 
24572
            }
 
24573
            if (ret != 0) {
 
24574
                if (ret < 0) {
 
24575
                    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
 
24576
                        "validating an item of list simple type");
 
24577
                    goto internal_error;
 
24578
                }
 
24579
                ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
 
24580
                break;
 
24581
            }       
 
24582
            cur = end;
 
24583
        } while (*cur != 0);
 
24584
        FREE_AND_NULL(tmpValue);
 
24585
        if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
 
24586
            /*
 
24587
            * Apply facets (pattern, enumeration).
 
24588
            */
 
24589
            ret = xmlSchemaValidateFacets(actxt, node, type,
 
24590
                XML_SCHEMAS_UNKNOWN, value, val,
 
24591
                len, fireErrors);
 
24592
            if (ret != 0) {
 
24593
                if (ret < 0) {
 
24594
                    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
 
24595
                        "validating facets of list simple type");
 
24596
                    goto internal_error;
 
24597
                }
 
24598
                ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
 
24599
            }
 
24600
        }
 
24601
        if (fireErrors && (ret > 0)) {
 
24602
            /* 
 
24603
            * Report the normalized value.
 
24604
            */
 
24605
            normalize = 1;
 
24606
            NORMALIZE(type);
 
24607
            xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
 
24608
        }
 
24609
    } else if (WXS_IS_UNION(type)) {
 
24610
        xmlSchemaTypeLinkPtr memberLink;
 
24611
        /*
 
24612
        * TODO: For all datatypes ļæ½derivedļæ½ by ļæ½unionļæ½  whiteSpace does
 
24613
        * not apply directly; however, the normalization behavior of ļæ½unionļæ½
 
24614
        * types is controlled by the value of whiteSpace on that one of the
 
24615
        * ļæ½memberTypesļæ½ against which the ļæ½unionļæ½ is successfully validated.
 
24616
        *
 
24617
        * This means that the value is normalized by the first validating
 
24618
        * member type, then the facets of the union type are applied. This
 
24619
        * needs changing of the value!
 
24620
        */
 
24621
 
 
24622
        /*
 
24623
        * 1.2.3 if {variety} is ļæ½unionļæ½ then the string must ļæ½matchļæ½ a
 
24624
        * literal in the ļæ½lexical spaceļæ½ of at least one member of
 
24625
        * {member type definitions}
 
24626
        */
 
24627
        memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
 
24628
        if (memberLink == NULL) {
 
24629
            AERROR_INT("xmlSchemaVCheckCVCSimpleType",
 
24630
                "union simple type has no member types");
 
24631
            goto internal_error;
 
24632
        }       
 
24633
        /*
 
24634
        * Always normalize union type values, since we currently
 
24635
        * cannot store the whitespace information with the value
 
24636
        * itself; otherwise a later value-comparison would be
 
24637
        * not possible.
 
24638
        */
 
24639
        while (memberLink != NULL) {
 
24640
            if (valNeeded) 
 
24641
                ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
 
24642
                    memberLink->type, value, &val, 0, 1, 0);
 
24643
            else
 
24644
                ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
 
24645
                    memberLink->type, value, NULL, 0, 1, 0);
 
24646
            if (ret <= 0)
 
24647
                break;
 
24648
            memberLink = memberLink->next;
 
24649
        }
 
24650
        if (ret != 0) {
 
24651
            if (ret < 0) {
 
24652
                AERROR_INT("xmlSchemaVCheckCVCSimpleType",
 
24653
                    "validating members of union simple type");
 
24654
                goto internal_error;
 
24655
            }
 
24656
            ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
 
24657
        }
 
24658
        /*
 
24659
        * Apply facets (pattern, enumeration).
 
24660
        */
 
24661
        if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
 
24662
            /*
 
24663
            * The normalization behavior of ļæ½unionļæ½ types is controlled by
 
24664
            * the value of whiteSpace on that one of the ļæ½memberTypesļæ½
 
24665
            * against which the ļæ½unionļæ½ is successfully validated.
 
24666
            */
 
24667
            NORMALIZE(memberLink->type);
 
24668
            ret = xmlSchemaValidateFacets(actxt, node, type,
 
24669
                XML_SCHEMAS_UNKNOWN, value, val,
 
24670
                0, fireErrors);
 
24671
            if (ret != 0) {
 
24672
                if (ret < 0) {
 
24673
                    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
 
24674
                        "validating facets of union simple type");
 
24675
                    goto internal_error;
 
24676
                }
 
24677
                ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;             
 
24678
            }
 
24679
        }
 
24680
        if (fireErrors && (ret > 0))
 
24681
            xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
 
24682
    }
 
24683
 
 
24684
    if (normValue != NULL)
 
24685
        xmlFree(normValue);
 
24686
    if (ret == 0) {
 
24687
        if (retVal != NULL)
 
24688
            *retVal = val;
 
24689
        else if (val != NULL)
 
24690
            xmlSchemaFreeValue(val);
 
24691
    } else if (val != NULL)
 
24692
        xmlSchemaFreeValue(val);
 
24693
    return (ret);
 
24694
internal_error:
 
24695
    if (normValue != NULL)
 
24696
        xmlFree(normValue);
 
24697
    if (val != NULL)
 
24698
        xmlSchemaFreeValue(val);
 
24699
    return (-1);
 
24700
}
 
24701
 
 
24702
static int
 
24703
xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
 
24704
                           const xmlChar *value,
 
24705
                           const xmlChar **nsName,
 
24706
                           const xmlChar **localName)
 
24707
{
 
24708
    int ret = 0;
 
24709
 
 
24710
    if ((nsName == NULL) || (localName == NULL))
 
24711
        return (-1);
 
24712
    *nsName = NULL;
 
24713
    *localName = NULL;
 
24714
 
 
24715
    ret = xmlValidateQName(value, 1);
 
24716
    if (ret == -1)
 
24717
        return (-1);
 
24718
    if (ret > 0) {
 
24719
        xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
 
24720
            XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
 
24721
            value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
 
24722
        return (1);
 
24723
    }
 
24724
    {
 
24725
        xmlChar *local = NULL;
 
24726
        xmlChar *prefix;
 
24727
 
 
24728
        /*
 
24729
        * NOTE: xmlSplitQName2 will return a duplicated
 
24730
        * string.
 
24731
        */
 
24732
        local = xmlSplitQName2(value, &prefix);
 
24733
        if (local == NULL)
 
24734
            *localName = xmlDictLookup(vctxt->dict, value, -1);
 
24735
        else {
 
24736
            *localName = xmlDictLookup(vctxt->dict, local, -1);
 
24737
            xmlFree(local);
 
24738
        }
 
24739
 
 
24740
        *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
 
24741
 
 
24742
        if (prefix != NULL) {
 
24743
            xmlFree(prefix);
 
24744
            /*
 
24745
            * A namespace must be found if the prefix is NOT NULL.
 
24746
            */
 
24747
            if (*nsName == NULL) {
 
24748
                xmlSchemaCustomErr(ACTXT_CAST vctxt,
 
24749
                    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
 
24750
                    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
 
24751
                    "The QName value '%s' has no "
 
24752
                    "corresponding namespace declaration in scope",
 
24753
                    value, NULL);
 
24754
                return (2);
 
24755
            }
 
24756
        }
 
24757
    }
 
24758
    return (0);
 
24759
}
 
24760
 
 
24761
static int
 
24762
xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
 
24763
                        xmlSchemaAttrInfoPtr iattr,
 
24764
                        xmlSchemaTypePtr *localType,
 
24765
                        xmlSchemaElementPtr elemDecl)
 
24766
{
 
24767
    int ret = 0;
 
24768
    /*
 
24769
    * cvc-elt (3.3.4) : (4)
 
24770
    * AND
 
24771
    * Schema-Validity Assessment (Element) (cvc-assess-elt)
 
24772
    *   (1.2.1.2.1) - (1.2.1.2.4)
 
24773
    * Handle 'xsi:type'.
 
24774
    */
 
24775
    if (localType == NULL)
 
24776
        return (-1);
 
24777
    *localType = NULL;
 
24778
    if (iattr == NULL)
 
24779
        return (0);
 
24780
    else {
 
24781
        const xmlChar *nsName = NULL, *local = NULL;
 
24782
        /*
 
24783
        * TODO: We should report a *warning* that the type was overriden
 
24784
        * by the instance.
 
24785
        */
 
24786
        ACTIVATE_ATTRIBUTE(iattr);
 
24787
        /*
 
24788
        * (cvc-elt) (3.3.4) : (4.1)
 
24789
        * (cvc-assess-elt) (1.2.1.2.2)
 
24790
        */
 
24791
        ret = xmlSchemaVExpandQName(vctxt, iattr->value,
 
24792
            &nsName, &local);
 
24793
        if (ret != 0) {
 
24794
            if (ret < 0) {
 
24795
                VERROR_INT("xmlSchemaValidateElementByDeclaration",
 
24796
                    "calling xmlSchemaQNameExpand() to validate the "
 
24797
                    "attribute 'xsi:type'");
 
24798
                goto internal_error;
 
24799
            }
 
24800
            goto exit;
 
24801
        }
 
24802
        /*
 
24803
        * (cvc-elt) (3.3.4) : (4.2)
 
24804
        * (cvc-assess-elt) (1.2.1.2.3)
 
24805
        */
 
24806
        *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
 
24807
        if (*localType == NULL) {
 
24808
            xmlChar *str = NULL;
 
24809
 
 
24810
            xmlSchemaCustomErr(ACTXT_CAST vctxt,
 
24811
                XML_SCHEMAV_CVC_ELT_4_2, NULL,
 
24812
                WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
 
24813
                "The QName value '%s' of the xsi:type attribute does not "
 
24814
                "resolve to a type definition",
 
24815
                xmlSchemaFormatQName(&str, nsName, local), NULL);
 
24816
            FREE_AND_NULL(str);
 
24817
            ret = vctxt->err;
 
24818
            goto exit;
 
24819
        }
 
24820
        if (elemDecl != NULL) {
 
24821
            int set = 0;
 
24822
 
 
24823
            /*
 
24824
            * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
 
24825
            * "The ļæ½local type definitionļæ½ must be validly
 
24826
            * derived from the {type definition} given the union of
 
24827
            * the {disallowed substitutions} and the {type definition}'s
 
24828
            * {prohibited substitutions}, as defined in
 
24829
            * Type Derivation OK (Complex) (ļæ½3.4.6)
 
24830
            * (if it is a complex type definition),
 
24831
            * or given {disallowed substitutions} as defined in Type
 
24832
            * Derivation OK (Simple) (ļæ½3.14.6) (if it is a simple type
 
24833
            * definition)."
 
24834
            *
 
24835
            * {disallowed substitutions}: the "block" on the element decl.
 
24836
            * {prohibited substitutions}: the "block" on the type def.
 
24837
            */
 
24838
            /*
 
24839
            * OPTIMIZE TODO: We could map types already evaluated
 
24840
            * to be validly derived from other types to avoid checking
 
24841
            * this over and over for the same types.
 
24842
            */
 
24843
            if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
 
24844
                (elemDecl->subtypes->flags &
 
24845
                    XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
 
24846
                set |= SUBSET_EXTENSION;
 
24847
 
 
24848
            if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
 
24849
                (elemDecl->subtypes->flags &
 
24850
                    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
 
24851
                set |= SUBSET_RESTRICTION;
 
24852
 
 
24853
            /*
 
24854
            * REMOVED and CHANGED since this produced a parser context
 
24855
            * which adds to the string dict of the schema. So this would
 
24856
            * change the schema and we don't want this. We don't need
 
24857
            * the parser context anymore.
 
24858
            *
 
24859
            * if ((vctxt->pctxt == NULL) &&
 
24860
            *   (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
 
24861
            *       return (-1);
 
24862
            */
 
24863
 
 
24864
            if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
 
24865
                elemDecl->subtypes, set) != 0) {
 
24866
                xmlChar *str = NULL;
 
24867
 
 
24868
                xmlSchemaCustomErr(ACTXT_CAST vctxt,
 
24869
                    XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
 
24870
                    "The type definition '%s', specified by xsi:type, is "
 
24871
                    "blocked or not validly derived from the type definition "
 
24872
                    "of the element declaration",
 
24873
                    xmlSchemaFormatQName(&str,
 
24874
                        (*localType)->targetNamespace,
 
24875
                        (*localType)->name),
 
24876
                    NULL);
 
24877
                FREE_AND_NULL(str);
 
24878
                ret = vctxt->err;
 
24879
                *localType = NULL;
 
24880
            }
 
24881
        }
 
24882
    }
 
24883
exit:
 
24884
    ACTIVATE_ELEM;
 
24885
    return (ret);
 
24886
internal_error:
 
24887
    ACTIVATE_ELEM;
 
24888
    return (-1);
 
24889
}
 
24890
 
 
24891
static int
 
24892
xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
 
24893
{
 
24894
    xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
 
24895
    xmlSchemaTypePtr actualType;
 
24896
 
 
24897
    /*
 
24898
    * cvc-elt (3.3.4) : 1
 
24899
    */
 
24900
    if (elemDecl == NULL) {
 
24901
        VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
 
24902
            "No matching declaration available");
 
24903
        return (vctxt->err);
 
24904
    }
 
24905
    actualType = WXS_ELEM_TYPEDEF(elemDecl);
 
24906
    /*
 
24907
    * cvc-elt (3.3.4) : 2
 
24908
    */
 
24909
    if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
 
24910
        VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
 
24911
            "The element declaration is abstract");
 
24912
        return (vctxt->err);
 
24913
    }
 
24914
    if (actualType == NULL) {
 
24915
        VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
 
24916
            "The type definition is absent");
 
24917
        return (XML_SCHEMAV_CVC_TYPE_1);
 
24918
    }
 
24919
    if (vctxt->nbAttrInfos != 0) {
 
24920
        int ret;
 
24921
        xmlSchemaAttrInfoPtr iattr;
 
24922
        /*
 
24923
        * cvc-elt (3.3.4) : 3
 
24924
        * Handle 'xsi:nil'.
 
24925
        */
 
24926
        iattr = xmlSchemaGetMetaAttrInfo(vctxt,
 
24927
            XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
 
24928
        if (iattr) {
 
24929
            ACTIVATE_ATTRIBUTE(iattr);
 
24930
            /*
 
24931
            * Validate the value.
 
24932
            */
 
24933
            ret = xmlSchemaVCheckCVCSimpleType(
 
24934
                ACTXT_CAST vctxt, NULL,
 
24935
                xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
 
24936
                iattr->value, &(iattr->val), 1, 0, 0);
 
24937
            ACTIVATE_ELEM;
 
24938
            if (ret < 0) {
 
24939
                VERROR_INT("xmlSchemaValidateElemDecl",
 
24940
                    "calling xmlSchemaVCheckCVCSimpleType() to "
 
24941
                    "validate the attribute 'xsi:nil'");
 
24942
                return (-1);
 
24943
            }
 
24944
            if (ret == 0) {
 
24945
                if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
 
24946
                    /*
 
24947
                    * cvc-elt (3.3.4) : 3.1
 
24948
                    */
 
24949
                    VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
 
24950
                        "The element is not 'nillable'");
 
24951
                    /* Does not return an error on purpose. */
 
24952
                } else {
 
24953
                    if (xmlSchemaValueGetAsBoolean(iattr->val)) {
 
24954
                        /*
 
24955
                        * cvc-elt (3.3.4) : 3.2.2
 
24956
                        */
 
24957
                        if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
 
24958
                            (elemDecl->value != NULL)) {
 
24959
                            VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
 
24960
                                "The element cannot be 'nilled' because "
 
24961
                                "there is a fixed value constraint defined "
 
24962
                                "for it");
 
24963
                             /* Does not return an error on purpose. */
 
24964
                        } else
 
24965
                            vctxt->inode->flags |=
 
24966
                                XML_SCHEMA_ELEM_INFO_NILLED;
 
24967
                    }
 
24968
                }
 
24969
            }
 
24970
        }
 
24971
        /*
 
24972
        * cvc-elt (3.3.4) : 4
 
24973
        * Handle 'xsi:type'.
 
24974
        */
 
24975
        iattr = xmlSchemaGetMetaAttrInfo(vctxt,
 
24976
            XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
 
24977
        if (iattr) {
 
24978
            xmlSchemaTypePtr localType = NULL;
 
24979
 
 
24980
            ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
 
24981
                elemDecl);
 
24982
            if (ret != 0) {
 
24983
                if (ret == -1) {
 
24984
                    VERROR_INT("xmlSchemaValidateElemDecl",
 
24985
                        "calling xmlSchemaProcessXSIType() to "
 
24986
                        "process the attribute 'xsi:type'");
 
24987
                    return (-1);
 
24988
                }
 
24989
                /* Does not return an error on purpose. */
 
24990
            }
 
24991
            if (localType != NULL) {
 
24992
                vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
 
24993
                actualType = localType;
 
24994
            }
 
24995
        }
 
24996
    }
 
24997
    /*
 
24998
    * IDC: Register identity-constraint XPath matchers.
 
24999
    */
 
25000
    if ((elemDecl->idcs != NULL) &&
 
25001
        (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
 
25002
            return (-1);
 
25003
    /*
 
25004
    * No actual type definition.
 
25005
    */
 
25006
    if (actualType == NULL) {
 
25007
        VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
 
25008
            "The type definition is absent");
 
25009
        return (XML_SCHEMAV_CVC_TYPE_1);
 
25010
    }
 
25011
    /*
 
25012
    * Remember the actual type definition.
 
25013
    */
 
25014
    vctxt->inode->typeDef = actualType;
 
25015
 
 
25016
    return (0);
 
25017
}
 
25018
 
 
25019
static int
 
25020
xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
 
25021
{
 
25022
    xmlSchemaAttrInfoPtr iattr;
 
25023
    int ret = 0, i;
 
25024
 
 
25025
    /*
 
25026
    * SPEC cvc-type (3.1.1)
 
25027
    * "The attributes of must be empty, excepting those whose namespace
 
25028
    * name is identical to http://www.w3.org/2001/XMLSchema-instance and
 
25029
    * whose local name is one of type, nil, schemaLocation or
 
25030
    * noNamespaceSchemaLocation."
 
25031
    */
 
25032
    if (vctxt->nbAttrInfos == 0)
 
25033
        return (0);
 
25034
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
 
25035
        iattr = vctxt->attrInfos[i];
 
25036
        if (! iattr->metaType) {
 
25037
            ACTIVATE_ATTRIBUTE(iattr)
 
25038
            xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
 
25039
                XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
 
25040
            ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
 
25041
        }
 
25042
    }
 
25043
    ACTIVATE_ELEM
 
25044
    return (ret);
 
25045
}
 
25046
 
 
25047
/*
 
25048
* Cleanup currently used attribute infos.
 
25049
*/
 
25050
static void
 
25051
xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
 
25052
{
 
25053
    int i;
 
25054
    xmlSchemaAttrInfoPtr attr;
 
25055
 
 
25056
    if (vctxt->nbAttrInfos == 0)
 
25057
        return;
 
25058
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
 
25059
        attr = vctxt->attrInfos[i];
 
25060
        if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
 
25061
            if (attr->localName != NULL)
 
25062
                xmlFree((xmlChar *) attr->localName);
 
25063
            if (attr->nsName != NULL)
 
25064
                xmlFree((xmlChar *) attr->nsName);
 
25065
        }
 
25066
        if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
 
25067
            if (attr->value != NULL)
 
25068
                xmlFree((xmlChar *) attr->value);
 
25069
        }
 
25070
        if (attr->val != NULL) {
 
25071
            xmlSchemaFreeValue(attr->val);
 
25072
            attr->val = NULL;
 
25073
        }
 
25074
        memset(attr, 0, sizeof(xmlSchemaAttrInfo));
 
25075
    }
 
25076
    vctxt->nbAttrInfos = 0;
 
25077
}
 
25078
 
 
25079
/*
 
25080
* 3.4.4 Complex Type Definition Validation Rules
 
25081
*   Element Locally Valid (Complex Type) (cvc-complex-type)
 
25082
* 3.2.4 Attribute Declaration Validation Rules
 
25083
*   Validation Rule: Attribute Locally Valid (cvc-attribute)
 
25084
*   Attribute Locally Valid (Use) (cvc-au)
 
25085
*
 
25086
* Only "assessed" attribute information items will be visible to
 
25087
* IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
 
25088
*/
 
25089
static int
 
25090
xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
 
25091
{
 
25092
    xmlSchemaTypePtr type = vctxt->inode->typeDef;    
 
25093
    xmlSchemaItemListPtr attrUseList;
 
25094
    xmlSchemaAttributeUsePtr attrUse = NULL;
 
25095
    xmlSchemaAttributePtr attrDecl = NULL;
 
25096
    xmlSchemaAttrInfoPtr iattr, tmpiattr;    
 
25097
    int i, j, found, nbAttrs, nbUses;
 
25098
    int xpathRes = 0, res, wildIDs = 0, fixed;
 
25099
    xmlNodePtr defAttrOwnerElem = NULL;
 
25100
 
 
25101
    /*
 
25102
    * SPEC (cvc-attribute)
 
25103
    * (1) "The declaration must not be ļæ½absentļæ½ (see Missing
 
25104
    * Sub-components (ļæ½5.3) for how this can fail to be
 
25105
    * the case)."
 
25106
    * (2) "Its {type definition} must not be absent."
 
25107
    *
 
25108
    * NOTE (1) + (2): This is not handled here, since we currently do not
 
25109
    * allow validation against schemas which have missing sub-components.
 
25110
    *
 
25111
    * SPEC (cvc-complex-type)
 
25112
    * (3) "For each attribute information item in the element information
 
25113
    * item's [attributes] excepting those whose [namespace name] is
 
25114
    * identical to http://www.w3.org/2001/XMLSchema-instance and whose
 
25115
    * [local name] is one of type, nil, schemaLocation or
 
25116
    * noNamespaceSchemaLocation, the appropriate case among the following
 
25117
    * must be true:
 
25118
    *
 
25119
    */
 
25120
    attrUseList = (xmlSchemaItemListPtr) type->attrUses;
 
25121
    /*
 
25122
    * @nbAttrs is the number of attributes present in the instance.
 
25123
    */
 
25124
    nbAttrs = vctxt->nbAttrInfos;
 
25125
    if (attrUseList != NULL)
 
25126
        nbUses = attrUseList->nbItems;
 
25127
    else
 
25128
        nbUses = 0;
 
25129
    for (i = 0; i < nbUses; i++) {
 
25130
        found = 0;
 
25131
        attrUse = attrUseList->items[i];
 
25132
        attrDecl = WXS_ATTRUSE_DECL(attrUse);
 
25133
        for (j = 0; j < nbAttrs; j++) {
 
25134
            iattr = vctxt->attrInfos[j];
 
25135
            /*
 
25136
            * SPEC (cvc-complex-type) (3)
 
25137
            * Skip meta attributes.
 
25138
            */
 
25139
            if (iattr->metaType)
 
25140
                continue;
 
25141
            if (iattr->localName[0] != attrDecl->name[0])
 
25142
                continue;
 
25143
            if (!xmlStrEqual(iattr->localName, attrDecl->name))
 
25144
                continue;
 
25145
            if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
 
25146
                continue;
 
25147
            found = 1;
 
25148
            /*
 
25149
            * SPEC (cvc-complex-type)
 
25150
            * (3.1) "If there is among the {attribute uses} an attribute
 
25151
            * use with an {attribute declaration} whose {name} matches
 
25152
            * the attribute information item's [local name] and whose
 
25153
            * {target namespace} is identical to the attribute information
 
25154
            * item's [namespace name] (where an ļæ½absentļæ½ {target namespace}
 
25155
            * is taken to be identical to a [namespace name] with no value),
 
25156
            * then the attribute information must be ļæ½validļæ½ with respect
 
25157
            * to that attribute use as per Attribute Locally Valid (Use)
 
25158
            * (ļæ½3.5.4). In this case the {attribute declaration} of that
 
25159
            * attribute use is the ļæ½context-determined declarationļæ½ for the
 
25160
            * attribute information item with respect to Schema-Validity
 
25161
            * Assessment (Attribute) (ļæ½3.2.4) and
 
25162
            * Assessment Outcome (Attribute) (ļæ½3.2.5).
 
25163
            */
 
25164
            iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
 
25165
            iattr->use = attrUse;
 
25166
            /*
 
25167
            * Context-determined declaration.
 
25168
            */
 
25169
            iattr->decl = attrDecl;
 
25170
            iattr->typeDef = attrDecl->subtypes;
 
25171
            break;
 
25172
        }
 
25173
 
 
25174
        if (found)
 
25175
            continue;
 
25176
 
 
25177
        if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
 
25178
            /*
 
25179
            * Handle non-existent, required attributes.
 
25180
            *
 
25181
            * SPEC (cvc-complex-type)
 
25182
            * (4) "The {attribute declaration} of each attribute use in
 
25183
            * the {attribute uses} whose {required} is true matches one
 
25184
            * of the attribute information items in the element information
 
25185
            * item's [attributes] as per clause 3.1 above."
 
25186
            */
 
25187
            tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
 
25188
            if (tmpiattr == NULL) {
 
25189
                VERROR_INT(
 
25190
                    "xmlSchemaVAttributesComplex",
 
25191
                    "calling xmlSchemaGetFreshAttrInfo()");
 
25192
                return (-1);
 
25193
            }
 
25194
            tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
 
25195
            tmpiattr->use = attrUse;
 
25196
            tmpiattr->decl = attrDecl;      
 
25197
        } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
 
25198
            ((attrUse->defValue != NULL) ||
 
25199
             (attrDecl->defValue != NULL))) {
 
25200
            /*
 
25201
            * Handle non-existent, optional, default/fixed attributes.
 
25202
            */
 
25203
            tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
 
25204
            if (tmpiattr == NULL) {
 
25205
                VERROR_INT(
 
25206
                    "xmlSchemaVAttributesComplex",
 
25207
                    "calling xmlSchemaGetFreshAttrInfo()");
 
25208
                return (-1);
 
25209
            }
 
25210
            tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
 
25211
            tmpiattr->use = attrUse;
 
25212
            tmpiattr->decl = attrDecl;
 
25213
            tmpiattr->typeDef = attrDecl->subtypes;
 
25214
            tmpiattr->localName = attrDecl->name;
 
25215
            tmpiattr->nsName = attrDecl->targetNamespace;
 
25216
        }
 
25217
    }
 
25218
 
 
25219
    if (vctxt->nbAttrInfos == 0)
 
25220
        return (0);
 
25221
    nbUses = vctxt->nbAttrInfos;
 
25222
    /*
 
25223
    * Validate against the wildcard.
 
25224
    */
 
25225
    if (type->attributeWildcard != NULL) {
 
25226
        /*
 
25227
        * SPEC (cvc-complex-type)
 
25228
        * (3.2.1) "There must be an {attribute wildcard}."
 
25229
        */
 
25230
        for (i = 0; i < nbAttrs; i++) {
 
25231
            iattr = vctxt->attrInfos[i];
 
25232
            /*
 
25233
            * SPEC (cvc-complex-type) (3)
 
25234
            * Skip meta attributes.
 
25235
            */
 
25236
            if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
 
25237
                continue;
 
25238
            /*
 
25239
            * SPEC (cvc-complex-type)
 
25240
            * (3.2.2) "The attribute information item must be ļæ½validļæ½ with
 
25241
            * respect to it as defined in Item Valid (Wildcard) (ļæ½3.10.4)."
 
25242
            *
 
25243
            * SPEC Item Valid (Wildcard) (cvc-wildcard)
 
25244
            * "... its [namespace name] must be ļæ½validļæ½ with respect to
 
25245
            * the wildcard constraint, as defined in Wildcard allows
 
25246
            * Namespace Name (ļæ½3.10.4)."
 
25247
            */
 
25248
            if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
 
25249
                    iattr->nsName) == 0) {
 
25250
                /*
 
25251
                * Handle processContents.
 
25252
                *
 
25253
                * SPEC (cvc-wildcard):
 
25254
                * processContents | context-determined declaration:
 
25255
                * "strict"          "mustFind"
 
25256
                * "lax"             "none"
 
25257
                * "skip"            "skip"
 
25258
                */
 
25259
                if (type->attributeWildcard->processContents ==
 
25260
                    XML_SCHEMAS_ANY_SKIP) {
 
25261
                     /*
 
25262
                    * context-determined declaration = "skip"
 
25263
                    *
 
25264
                    * SPEC PSVI Assessment Outcome (Attribute)
 
25265
                    * [validity] = "notKnown"
 
25266
                    * [validation attempted] = "none"
 
25267
                    */
 
25268
                    iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
 
25269
                    continue;
 
25270
                }
 
25271
                /*
 
25272
                * Find an attribute declaration.
 
25273
                */
 
25274
                iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
 
25275
                    iattr->localName, iattr->nsName);
 
25276
                if (iattr->decl != NULL) {
 
25277
                    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
 
25278
                    /*
 
25279
                    * SPEC (cvc-complex-type)
 
25280
                    * (5) "Let [Definition:]  the wild IDs be the set of
 
25281
                    * all attribute information item to which clause 3.2
 
25282
                    * applied and whose ļæ½validationļæ½ resulted in a
 
25283
                    * ļæ½context-determined declarationļæ½ of mustFind or no
 
25284
                    * ļæ½context-determined declarationļæ½ at all, and whose
 
25285
                    * [local name] and [namespace name] resolve (as
 
25286
                    * defined by QName resolution (Instance) (ļæ½3.15.4)) to
 
25287
                    * an attribute declaration whose {type definition} is
 
25288
                    * or is derived from ID. Then all of the following
 
25289
                    * must be true:"
 
25290
                    */
 
25291
                    iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
 
25292
                    if (xmlSchemaIsDerivedFromBuiltInType(
 
25293
                        iattr->typeDef, XML_SCHEMAS_ID)) {
 
25294
                        /*
 
25295
                        * SPEC (5.1) "There must be no more than one
 
25296
                        * item in ļæ½wild IDsļæ½."
 
25297
                        */
 
25298
                        if (wildIDs != 0) {
 
25299
                            /* VAL TODO */
 
25300
                            iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
 
25301
                            TODO
 
25302
                            continue;
 
25303
                        }
 
25304
                        wildIDs++;
 
25305
                        /*
 
25306
                        * SPEC (cvc-complex-type)
 
25307
                        * (5.2) "If ļæ½wild IDsļæ½ is non-empty, there must not
 
25308
                        * be any attribute uses among the {attribute uses}
 
25309
                        * whose {attribute declaration}'s {type definition}
 
25310
                        * is or is derived from ID."
 
25311
                        */
 
25312
                        for (j = 0; j < attrUseList->nbItems; j++) {
 
25313
                            if (xmlSchemaIsDerivedFromBuiltInType(
 
25314
                                WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
 
25315
                                XML_SCHEMAS_ID)) {
 
25316
                                /* URGENT VAL TODO: implement */
 
25317
                                iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
 
25318
                                TODO
 
25319
                                break;
 
25320
                            }
 
25321
                        }
 
25322
                    }
 
25323
                } else if (type->attributeWildcard->processContents ==
 
25324
                    XML_SCHEMAS_ANY_LAX) {
 
25325
                    iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
 
25326
                    /*
 
25327
                    * SPEC PSVI Assessment Outcome (Attribute)
 
25328
                    * [validity] = "notKnown"
 
25329
                    * [validation attempted] = "none"
 
25330
                    */
 
25331
                } else {
 
25332
                    iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
 
25333
                }
 
25334
            }
 
25335
        }
 
25336
    }
 
25337
 
 
25338
    if (vctxt->nbAttrInfos == 0)
 
25339
        return (0);
 
25340
 
 
25341
    /*
 
25342
    * Get the owner element; needed for creation of default attributes.
 
25343
    * This fixes bug #341337, reported by David Grohmann.
 
25344
    */
 
25345
    if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
 
25346
        xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
 
25347
        if (ielem && ielem->node && ielem->node->doc)
 
25348
            defAttrOwnerElem = ielem->node;
 
25349
    }
 
25350
    /*
 
25351
    * Validate values, create default attributes, evaluate IDCs.
 
25352
    */
 
25353
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
 
25354
        iattr = vctxt->attrInfos[i];
 
25355
        /*
 
25356
        * VAL TODO: Note that we won't try to resolve IDCs to
 
25357
        * "lax" and "skip" validated attributes. Check what to
 
25358
        * do in this case.
 
25359
        */
 
25360
        if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
 
25361
            (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
 
25362
            continue;
 
25363
        /*
 
25364
        * VAL TODO: What to do if the type definition is missing?
 
25365
        */
 
25366
        if (iattr->typeDef == NULL) {
 
25367
            iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
 
25368
            continue;
 
25369
        }
 
25370
 
 
25371
        ACTIVATE_ATTRIBUTE(iattr);
 
25372
        fixed = 0;
 
25373
        xpathRes = 0;
 
25374
 
 
25375
        if (vctxt->xpathStates != NULL) {
 
25376
            /*
 
25377
            * Evaluate IDCs.
 
25378
            */
 
25379
            xpathRes = xmlSchemaXPathEvaluate(vctxt,
 
25380
                XML_ATTRIBUTE_NODE);
 
25381
            if (xpathRes == -1) {
 
25382
                VERROR_INT("xmlSchemaVAttributesComplex",
 
25383
                    "calling xmlSchemaXPathEvaluate()");
 
25384
                goto internal_error;
 
25385
            }
 
25386
        }
 
25387
 
 
25388
        if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
 
25389
            /*
 
25390
            * Default/fixed attributes.
 
25391
            * We need the value only if we need to resolve IDCs or
 
25392
            * will create default attributes.
 
25393
            */
 
25394
            if ((xpathRes) || (defAttrOwnerElem)) {
 
25395
                if (iattr->use->defValue != NULL) {
 
25396
                    iattr->value = (xmlChar *) iattr->use->defValue;
 
25397
                    iattr->val = iattr->use->defVal;
 
25398
                } else {
 
25399
                    iattr->value = (xmlChar *) iattr->decl->defValue;
 
25400
                    iattr->val = iattr->decl->defVal;
 
25401
                }
 
25402
                /*
 
25403
                * IDCs will consume the precomputed default value,
 
25404
                * so we need to clone it.
 
25405
                */
 
25406
                if (iattr->val == NULL) {
 
25407
                    VERROR_INT("xmlSchemaVAttributesComplex",
 
25408
                        "default/fixed value on an attribute use was "
 
25409
                        "not precomputed");
 
25410
                    goto internal_error;
 
25411
                }
 
25412
                iattr->val = xmlSchemaCopyValue(iattr->val);
 
25413
                if (iattr->val == NULL) {
 
25414
                    VERROR_INT("xmlSchemaVAttributesComplex",
 
25415
                        "calling xmlSchemaCopyValue()");
 
25416
                    goto internal_error;
 
25417
                }
 
25418
            }
 
25419
            /*
 
25420
            * PSVI: Add the default attribute to the current element.
 
25421
            * VAL TODO: Should we use the *normalized* value? This currently
 
25422
            *   uses the *initial* value.
 
25423
            */
 
25424
            
 
25425
            if (defAttrOwnerElem) {
 
25426
                xmlChar *normValue;
 
25427
                const xmlChar *value;
 
25428
 
 
25429
                value = iattr->value;
 
25430
                /*
 
25431
                * Normalize the value.
 
25432
                */
 
25433
                normValue = xmlSchemaNormalizeValue(iattr->typeDef,
 
25434
                    iattr->value);
 
25435
                if (normValue != NULL)
 
25436
                    value = BAD_CAST normValue;
 
25437
 
 
25438
                if (iattr->nsName == NULL) {
 
25439
                    if (xmlNewProp(defAttrOwnerElem,
 
25440
                        iattr->localName, value) == NULL) {
 
25441
                        VERROR_INT("xmlSchemaVAttributesComplex",
 
25442
                            "callling xmlNewProp()");
 
25443
                        if (normValue != NULL)
 
25444
                            xmlFree(normValue);
 
25445
                        goto internal_error;
 
25446
                    }
 
25447
                } else {
 
25448
                    xmlNsPtr ns;
 
25449
 
 
25450
                    ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
 
25451
                        defAttrOwnerElem, iattr->nsName);
 
25452
                    if (ns == NULL) {
 
25453
                        xmlChar prefix[12];
 
25454
                        int counter = 0;
 
25455
 
 
25456
                        /*
 
25457
                        * Create a namespace declaration on the validation
 
25458
                        * root node if no namespace declaration is in scope.
 
25459
                        */
 
25460
                        do {
 
25461
                            snprintf((char *) prefix, 12, "p%d", counter++);
 
25462
                            ns = xmlSearchNs(defAttrOwnerElem->doc,
 
25463
                                defAttrOwnerElem, BAD_CAST prefix);
 
25464
                            if (counter > 1000) {
 
25465
                                VERROR_INT(
 
25466
                                    "xmlSchemaVAttributesComplex",
 
25467
                                    "could not compute a ns prefix for a "
 
25468
                                    "default/fixed attribute");
 
25469
                                if (normValue != NULL)
 
25470
                                    xmlFree(normValue);
 
25471
                                goto internal_error;
 
25472
                            }
 
25473
                        } while (ns != NULL);
 
25474
                        ns = xmlNewNs(vctxt->validationRoot,
 
25475
                            iattr->nsName, BAD_CAST prefix);
 
25476
                    }
 
25477
                    /*
 
25478
                    * TODO:
 
25479
                    * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
 
25480
                    * If we have QNames: do we need to ensure there's a
 
25481
                    * prefix defined for the QName?
 
25482
                    */
 
25483
                    xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
 
25484
                }
 
25485
                if (normValue != NULL)
 
25486
                    xmlFree(normValue);
 
25487
            }
 
25488
            /*
 
25489
            * Go directly to IDC evaluation.
 
25490
            */
 
25491
            goto eval_idcs;
 
25492
        }
 
25493
        /*
 
25494
        * Validate the value.
 
25495
        */
 
25496
        if (vctxt->value != NULL) {
 
25497
            /*
 
25498
            * Free last computed value; just for safety reasons.
 
25499
            */
 
25500
            xmlSchemaFreeValue(vctxt->value);
 
25501
            vctxt->value = NULL;
 
25502
        }
 
25503
        /*
 
25504
        * Note that the attribute *use* can be unavailable, if
 
25505
        * the attribute was a wild attribute.
 
25506
        */
 
25507
        if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
 
25508
            ((iattr->use != NULL) &&
 
25509
             (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
 
25510
            fixed = 1;
 
25511
        else
 
25512
            fixed = 0;
 
25513
        /*
 
25514
        * SPEC (cvc-attribute)
 
25515
        * (3) "The item's ļæ½normalized valueļæ½ must be locally ļæ½validļæ½
 
25516
        * with respect to that {type definition} as per 
 
25517
        * String Valid (ļæ½3.14.4)."
 
25518
        *
 
25519
        * VAL TODO: Do we already have the
 
25520
        * "normalized attribute value" here?
 
25521
        */
 
25522
        if (xpathRes || fixed) {
 
25523
            iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
 
25524
            /*
 
25525
            * Request a computed value.
 
25526
            */
 
25527
            res = xmlSchemaVCheckCVCSimpleType(
 
25528
                ACTXT_CAST vctxt,
 
25529
                iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
 
25530
                1, 1, 0);
 
25531
        } else {
 
25532
            res = xmlSchemaVCheckCVCSimpleType(
 
25533
                ACTXT_CAST vctxt,
 
25534
                iattr->node, iattr->typeDef, iattr->value, NULL,
 
25535
                1, 0, 0);
 
25536
        }
 
25537
            
 
25538
        if (res != 0) {
 
25539
            if (res == -1) {
 
25540
                VERROR_INT("xmlSchemaVAttributesComplex",
 
25541
                    "calling xmlSchemaStreamValidateSimpleTypeValue()");
 
25542
                goto internal_error;
 
25543
            }
 
25544
            iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
 
25545
            /*
 
25546
            * SPEC PSVI Assessment Outcome (Attribute)
 
25547
            * [validity] = "invalid"
 
25548
            */
 
25549
            goto eval_idcs;
 
25550
        }
 
25551
 
 
25552
        if (fixed) {        
 
25553
            /*
 
25554
            * SPEC Attribute Locally Valid (Use) (cvc-au)
 
25555
            * "For an attribute information item to beļæ½validļæ½
 
25556
            * with respect to an attribute use its *normalized*
 
25557
            * valueļæ½ must match the *canonical* lexical
 
25558
            * representation of the attribute use's {value
 
25559
            * constraint}value, if it is present and fixed."
 
25560
            *
 
25561
            * VAL TODO: The requirement for the *canonical* value
 
25562
            * will be removed in XML Schema 1.1.
 
25563
            */
 
25564
            /*
 
25565
            * SPEC Attribute Locally Valid (cvc-attribute)
 
25566
            * (4) "The item's *actual* valueļæ½ must match the *value* of
 
25567
            * the {value constraint}, if it is present and fixed."
 
25568
            */
 
25569
            if (iattr->val == NULL) {
 
25570
                /* VAL TODO: A value was not precomputed. */
 
25571
                TODO
 
25572
                goto eval_idcs;
 
25573
            }
 
25574
            if ((iattr->use != NULL) &&
 
25575
                (iattr->use->defValue != NULL)) {
 
25576
                if (iattr->use->defVal == NULL) {
 
25577
                    /* VAL TODO: A default value was not precomputed. */
 
25578
                    TODO
 
25579
                    goto eval_idcs;
 
25580
                }
 
25581
                iattr->vcValue = iattr->use->defValue;
 
25582
                /*
 
25583
                if (xmlSchemaCompareValuesWhtsp(attr->val,
 
25584
                    (xmlSchemaWhitespaceValueType) ws,
 
25585
                    attr->use->defVal,
 
25586
                    (xmlSchemaWhitespaceValueType) ws) != 0) {
 
25587
                */
 
25588
                if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
 
25589
                    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
 
25590
            } else {
 
25591
                if (iattr->decl->defVal == NULL) {
 
25592
                    /* VAL TODO: A default value was not precomputed. */
 
25593
                    TODO
 
25594
                    goto eval_idcs;
 
25595
                }
 
25596
                iattr->vcValue = iattr->decl->defValue;
 
25597
                /*
 
25598
                if (xmlSchemaCompareValuesWhtsp(attr->val,
 
25599
                    (xmlSchemaWhitespaceValueType) ws,
 
25600
                    attrDecl->defVal,
 
25601
                    (xmlSchemaWhitespaceValueType) ws) != 0) {
 
25602
                */
 
25603
                if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
 
25604
                    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
 
25605
            }
 
25606
            /*
 
25607
            * [validity] = "valid"
 
25608
            */
 
25609
        }
 
25610
eval_idcs:
 
25611
        /*
 
25612
        * Evaluate IDCs.
 
25613
        */
 
25614
        if (xpathRes) {
 
25615
            if (xmlSchemaXPathProcessHistory(vctxt,
 
25616
                vctxt->depth +1) == -1) {
 
25617
                VERROR_INT("xmlSchemaVAttributesComplex",
 
25618
                    "calling xmlSchemaXPathEvaluate()");
 
25619
                goto internal_error;
 
25620
            }
 
25621
        } else if (vctxt->xpathStates != NULL)
 
25622
            xmlSchemaXPathPop(vctxt);
 
25623
    }
 
25624
 
 
25625
    /*
 
25626
    * Report errors.
 
25627
    */
 
25628
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
 
25629
        iattr = vctxt->attrInfos[i];
 
25630
        if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
 
25631
            (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
 
25632
            (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
 
25633
            (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
 
25634
            continue;
 
25635
        ACTIVATE_ATTRIBUTE(iattr);
 
25636
        switch (iattr->state) {
 
25637
            case XML_SCHEMAS_ATTR_ERR_MISSING: {
 
25638
                    xmlChar *str = NULL;
 
25639
                    ACTIVATE_ELEM;
 
25640
                    xmlSchemaCustomErr(ACTXT_CAST vctxt,
 
25641
                        XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
 
25642
                        "The attribute '%s' is required but missing",
 
25643
                        xmlSchemaFormatQName(&str,
 
25644
                            iattr->decl->targetNamespace,
 
25645
                            iattr->decl->name),
 
25646
                        NULL);
 
25647
                    FREE_AND_NULL(str)
 
25648
                    break;
 
25649
                }
 
25650
            case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
 
25651
                VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
 
25652
                    "The type definition is absent");
 
25653
                break;
 
25654
            case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
 
25655
                xmlSchemaCustomErr(ACTXT_CAST vctxt,
 
25656
                    XML_SCHEMAV_CVC_AU, NULL, NULL,
 
25657
                    "The value '%s' does not match the fixed "
 
25658
                    "value constraint '%s'", 
 
25659
                    iattr->value, iattr->vcValue);              
 
25660
                break;
 
25661
            case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
 
25662
                VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
 
25663
                    "No matching global attribute declaration available, but "
 
25664
                    "demanded by the strict wildcard");
 
25665
                break;
 
25666
            case XML_SCHEMAS_ATTR_UNKNOWN:
 
25667
                if (iattr->metaType)
 
25668
                    break;
 
25669
                /*
 
25670
                * MAYBE VAL TODO: One might report different error messages
 
25671
                * for the following errors.
 
25672
                */
 
25673
                if (type->attributeWildcard == NULL) {
 
25674
                    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
 
25675
                        XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
 
25676
                } else {
 
25677
                    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
 
25678
                        XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
 
25679
                }
 
25680
                break;
 
25681
            default:
 
25682
                break;
 
25683
        }
 
25684
    }
 
25685
 
 
25686
    ACTIVATE_ELEM;
 
25687
    return (0);
 
25688
internal_error:
 
25689
    ACTIVATE_ELEM;
 
25690
    return (-1);
 
25691
}
 
25692
 
 
25693
static int
 
25694
xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
 
25695
                              int *skip)
 
25696
{
 
25697
    xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
 
25698
    /*
 
25699
    * The namespace of the element was already identified to be
 
25700
    * matching the wildcard.
 
25701
    */
 
25702
    if ((skip == NULL) || (wild == NULL) ||
 
25703
        (wild->type != XML_SCHEMA_TYPE_ANY)) {
 
25704
        VERROR_INT("xmlSchemaValidateElemWildcard",
 
25705
            "bad arguments");
 
25706
        return (-1);
 
25707
    }
 
25708
    *skip = 0;
 
25709
    if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
 
25710
        /*
 
25711
        * URGENT VAL TODO: Either we need to position the stream to the
 
25712
        * next sibling, or walk the whole subtree.
 
25713
        */
 
25714
        *skip = 1;
 
25715
        return (0);
 
25716
    }
 
25717
    {
 
25718
        xmlSchemaElementPtr decl = NULL;
 
25719
 
 
25720
        decl = xmlSchemaGetElem(vctxt->schema,
 
25721
            vctxt->inode->localName, vctxt->inode->nsName);         
 
25722
        if (decl != NULL) {
 
25723
            vctxt->inode->decl = decl;
 
25724
            return (0);
 
25725
        }
 
25726
    }
 
25727
    if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
 
25728
        /* VAL TODO: Change to proper error code. */
 
25729
        VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
 
25730
            "No matching global element declaration available, but "
 
25731
            "demanded by the strict wildcard");
 
25732
        return (vctxt->err);
 
25733
    }
 
25734
    if (vctxt->nbAttrInfos != 0) {
 
25735
        xmlSchemaAttrInfoPtr iattr;
 
25736
        /*
 
25737
        * SPEC Validation Rule: Schema-Validity Assessment (Element)
 
25738
        * (1.2.1.2.1) - (1.2.1.2.3 )
 
25739
        *
 
25740
        * Use the xsi:type attribute for the type definition.
 
25741
        */
 
25742
        iattr = xmlSchemaGetMetaAttrInfo(vctxt,
 
25743
            XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
 
25744
        if (iattr != NULL) {
 
25745
            if (xmlSchemaProcessXSIType(vctxt, iattr,
 
25746
                &(vctxt->inode->typeDef), NULL) == -1) {
 
25747
                VERROR_INT("xmlSchemaValidateElemWildcard",
 
25748
                    "calling xmlSchemaProcessXSIType() to "
 
25749
                    "process the attribute 'xsi:nil'");
 
25750
                return (-1);
 
25751
            }
 
25752
            /*
 
25753
            * Don't return an error on purpose.
 
25754
            */
 
25755
            return (0);
 
25756
        }
 
25757
    }
 
25758
    /*
 
25759
    * SPEC Validation Rule: Schema-Validity Assessment (Element)
 
25760
    *
 
25761
    * Fallback to "anyType".
 
25762
    */
 
25763
    vctxt->inode->typeDef =
 
25764
        xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
 
25765
    return (0);
 
25766
}
 
25767
 
 
25768
/*
 
25769
* xmlSchemaCheckCOSValidDefault:
 
25770
*
 
25771
* This will be called if: not nilled, no content and a default/fixed
 
25772
* value is provided.
 
25773
*/
 
25774
 
 
25775
static int
 
25776
xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
 
25777
                              const xmlChar *value,
 
25778
                              xmlSchemaValPtr *val)
 
25779
{   
 
25780
    int ret = 0;
 
25781
    xmlSchemaNodeInfoPtr inode = vctxt->inode;
 
25782
 
 
25783
    /*
 
25784
    * cos-valid-default:
 
25785
    * Schema Component Constraint: Element Default Valid (Immediate)
 
25786
    * For a string to be a valid default with respect to a type 
 
25787
    * definition the appropriate case among the following must be true:
 
25788
    */    
 
25789
    if WXS_IS_COMPLEX(inode->typeDef) {
 
25790
        /*
 
25791
        * Complex type.
 
25792
        *
 
25793
        * SPEC (2.1) "its {content type} must be a simple type definition
 
25794
        * or mixed."
 
25795
        * SPEC (2.2.2) "If the {content type} is mixed, then the {content
 
25796
        * type}'s particle must be ļæ½emptiableļæ½ as defined by 
 
25797
        * Particle Emptiable (ļæ½3.9.6)."
 
25798
        */
 
25799
        if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
 
25800
            ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
 
25801
             (! WXS_EMPTIABLE(inode->typeDef)))) {
 
25802
            ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
 
25803
            /* NOTE that this covers (2.2.2) as well. */
 
25804
            VERROR(ret, NULL,
 
25805
                "For a string to be a valid default, the type definition "
 
25806
                "must be a simple type or a complex type with simple content "
 
25807
                "or mixed content and a particle emptiable");
 
25808
            return(ret);
 
25809
        }
 
25810
    }   
 
25811
    /*
 
25812
    * 1 If the type definition is a simple type definition, then the string 
 
25813
    * must be ļæ½validļæ½ with respect to that definition as defined by String 
 
25814
    * Valid (ļæ½3.14.4).
 
25815
    *
 
25816
    * AND
 
25817
    *
 
25818
    * 2.2.1 If the {content type} is a simple type definition, then the 
 
25819
    * string must be ļæ½validļæ½ with respect to that simple type definition 
 
25820
    * as defined by String Valid (ļæ½3.14.4).
 
25821
    */  
 
25822
    if (WXS_IS_SIMPLE(inode->typeDef)) {
 
25823
 
 
25824
        ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
 
25825
            NULL, inode->typeDef, value, val, 1, 1, 0);
 
25826
 
 
25827
    } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
 
25828
 
 
25829
        ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
 
25830
            NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
 
25831
    }
 
25832
    if (ret < 0) {
 
25833
        VERROR_INT("xmlSchemaCheckCOSValidDefault",
 
25834
            "calling xmlSchemaVCheckCVCSimpleType()");
 
25835
    }    
 
25836
    return (ret);
 
25837
}
 
25838
 
 
25839
static void
 
25840
xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
 
25841
                               const xmlChar * name ATTRIBUTE_UNUSED,
 
25842
                               xmlSchemaElementPtr item,
 
25843
                               xmlSchemaNodeInfoPtr inode)
 
25844
{
 
25845
    inode->decl = item;
 
25846
#ifdef DEBUG_CONTENT
 
25847
    {
 
25848
        xmlChar *str = NULL;
 
25849
 
 
25850
        if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
 
25851
            xmlGenericError(xmlGenericErrorContext,
 
25852
                "AUTOMATON callback for '%s' [declaration]\n",
 
25853
                xmlSchemaFormatQName(&str,
 
25854
                inode->localName, inode->nsName));
 
25855
        } else {
 
25856
            xmlGenericError(xmlGenericErrorContext,
 
25857
                    "AUTOMATON callback for '%s' [wildcard]\n",
 
25858
                    xmlSchemaFormatQName(&str,
 
25859
                    inode->localName, inode->nsName));
 
25860
 
 
25861
        }
 
25862
        FREE_AND_NULL(str)
 
25863
    }
 
25864
#endif
 
25865
}
 
25866
 
 
25867
static int
 
25868
xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
 
25869
{    
 
25870
    vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
 
25871
    if (vctxt->inode == NULL) {
 
25872
        VERROR_INT("xmlSchemaValidatorPushElem",
 
25873
            "calling xmlSchemaGetFreshElemInfo()");
 
25874
        return (-1);
 
25875
    }   
 
25876
    vctxt->nbAttrInfos = 0;
 
25877
    return (0);
 
25878
}
 
25879
 
 
25880
static int
 
25881
xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
 
25882
                             xmlSchemaNodeInfoPtr inode,
 
25883
                             xmlSchemaTypePtr type,
 
25884
                             const xmlChar *value)
 
25885
{
 
25886
    if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
 
25887
        return (xmlSchemaVCheckCVCSimpleType(
 
25888
            ACTXT_CAST vctxt, NULL,
 
25889
            type, value, &(inode->val), 1, 1, 0));
 
25890
    else
 
25891
        return (xmlSchemaVCheckCVCSimpleType(
 
25892
            ACTXT_CAST vctxt, NULL,
 
25893
            type, value, NULL, 1, 0, 0));
 
25894
}
 
25895
 
 
25896
 
 
25897
 
 
25898
/* 
 
25899
* Process END of element.
 
25900
*/
 
25901
static int
 
25902
xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
 
25903
{
 
25904
    int ret = 0;
 
25905
    xmlSchemaNodeInfoPtr inode = vctxt->inode;
 
25906
 
 
25907
    if (vctxt->nbAttrInfos != 0)
 
25908
        xmlSchemaClearAttrInfos(vctxt);
 
25909
    if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
 
25910
        /*
 
25911
        * This element was not expected;
 
25912
        * we will not validate child elements of broken parents.
 
25913
        * Skip validation of all content of the parent.
 
25914
        */
 
25915
        vctxt->skipDepth = vctxt->depth -1;
 
25916
        goto end_elem;
 
25917
    }    
 
25918
    if ((inode->typeDef == NULL) ||
 
25919
        (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
 
25920
        /*
 
25921
        * 1. the type definition might be missing if the element was
 
25922
        *    error prone
 
25923
        * 2. it might be abstract.
 
25924
        */
 
25925
        goto end_elem;
 
25926
    }
 
25927
    /*
 
25928
    * Check the content model.
 
25929
    */
 
25930
    if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
 
25931
        (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
 
25932
 
 
25933
        /*
 
25934
        * Workaround for "anyType".
 
25935
        */
 
25936
        if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
 
25937
            goto character_content;                     
 
25938
        
 
25939
        if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
 
25940
            xmlChar *values[10];
 
25941
            int terminal, nbval = 10, nbneg;
 
25942
 
 
25943
            if (inode->regexCtxt == NULL) {
 
25944
                /*
 
25945
                * Create the regex context.
 
25946
                */
 
25947
                inode->regexCtxt =
 
25948
                    xmlRegNewExecCtxt(inode->typeDef->contModel,
 
25949
                    (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
 
25950
                    vctxt);
 
25951
                if (inode->regexCtxt == NULL) {
 
25952
                    VERROR_INT("xmlSchemaValidatorPopElem",
 
25953
                        "failed to create a regex context");
 
25954
                    goto internal_error;
 
25955
                }
 
25956
#ifdef DEBUG_AUTOMATA
 
25957
                xmlGenericError(xmlGenericErrorContext,
 
25958
                    "AUTOMATON create on '%s'\n", inode->localName);
 
25959
#endif      
 
25960
            }
 
25961
            /*
 
25962
            * Get hold of the still expected content, since a further
 
25963
            * call to xmlRegExecPushString() will loose this information.
 
25964
            */ 
 
25965
            xmlRegExecNextValues(inode->regexCtxt,
 
25966
                &nbval, &nbneg, &values[0], &terminal);
 
25967
            ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
 
25968
            if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
 
25969
                /*
 
25970
                * Still missing something.
 
25971
                */
 
25972
                ret = 1;
 
25973
                inode->flags |=
 
25974
                    XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
 
25975
                xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
 
25976
                    XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
 
25977
                    "Missing child element(s)",
 
25978
                    nbval, nbneg, values);
 
25979
#ifdef DEBUG_AUTOMATA
 
25980
                xmlGenericError(xmlGenericErrorContext,
 
25981
                    "AUTOMATON missing ERROR on '%s'\n",
 
25982
                    inode->localName);
 
25983
#endif
 
25984
            } else {
 
25985
                /*
 
25986
                * Content model is satisfied.
 
25987
                */
 
25988
                ret = 0;
 
25989
#ifdef DEBUG_AUTOMATA
 
25990
                xmlGenericError(xmlGenericErrorContext,
 
25991
                    "AUTOMATON succeeded on '%s'\n",
 
25992
                    inode->localName);
 
25993
#endif
 
25994
            }
 
25995
 
 
25996
        }
 
25997
    }
 
25998
    if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
 
25999
        goto end_elem;
 
26000
 
 
26001
character_content:
 
26002
 
 
26003
    if (vctxt->value != NULL) {
 
26004
        xmlSchemaFreeValue(vctxt->value);
 
26005
        vctxt->value = NULL;
 
26006
    }
 
26007
    /*
 
26008
    * Check character content.
 
26009
    */
 
26010
    if (inode->decl == NULL) {
 
26011
        /*
 
26012
        * Speedup if no declaration exists.
 
26013
        */
 
26014
        if (WXS_IS_SIMPLE(inode->typeDef)) {        
 
26015
            ret = xmlSchemaVCheckINodeDataType(vctxt,
 
26016
                inode, inode->typeDef, inode->value);
 
26017
        } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
 
26018
            ret = xmlSchemaVCheckINodeDataType(vctxt,
 
26019
                inode, inode->typeDef->contentTypeDef,
 
26020
                inode->value);
 
26021
        }               
 
26022
        if (ret < 0) {
 
26023
            VERROR_INT("xmlSchemaValidatorPopElem",
 
26024
                "calling xmlSchemaVCheckCVCSimpleType()");
 
26025
            goto internal_error;
 
26026
        }
 
26027
        goto end_elem;
 
26028
    }
 
26029
    /*
 
26030
    * cvc-elt (3.3.4) : 5 
 
26031
    * The appropriate case among the following must be true:
 
26032
    */
 
26033
    /*
 
26034
    * cvc-elt (3.3.4) : 5.1 
 
26035
    * If the declaration has a {value constraint}, 
 
26036
    * the item has neither element nor character [children] and 
 
26037
    * clause 3.2 has not applied, then all of the following must be true:
 
26038
    */
 
26039
    if ((inode->decl->value != NULL) &&
 
26040
        (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) && 
 
26041
        (! INODE_NILLED(inode))) {
 
26042
        /*
 
26043
        * cvc-elt (3.3.4) : 5.1.1 
 
26044
        * If the ļæ½actual type definitionļæ½ is a ļæ½local type definitionļæ½
 
26045
        * then the canonical lexical representation of the {value constraint}
 
26046
        * value must be a valid default for the ļæ½actual type definitionļæ½ as 
 
26047
        * defined in Element Default Valid (Immediate) (ļæ½3.3.6). 
 
26048
        */
 
26049
        /* 
 
26050
        * NOTE: 'local' above means types acquired by xsi:type.
 
26051
        * NOTE: Although the *canonical* value is stated, it is not
 
26052
        * relevant if canonical or not. Additionally XML Schema 1.1
 
26053
        * will removed this requirement as well.
 
26054
        */
 
26055
        if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
 
26056
 
 
26057
            ret = xmlSchemaCheckCOSValidDefault(vctxt,
 
26058
                inode->decl->value, &(inode->val));
 
26059
            if (ret != 0) {
 
26060
                if (ret < 0) {
 
26061
                    VERROR_INT("xmlSchemaValidatorPopElem",
 
26062
                        "calling xmlSchemaCheckCOSValidDefault()");
 
26063
                    goto internal_error;
 
26064
                }
 
26065
                goto end_elem;
 
26066
            }
 
26067
            /*
 
26068
            * Stop here, to avoid redundant validation of the value
 
26069
            * (see following).
 
26070
            */
 
26071
            goto default_psvi;
 
26072
        }       
 
26073
        /*
 
26074
        * cvc-elt (3.3.4) : 5.1.2 
 
26075
        * The element information item with the canonical lexical 
 
26076
        * representation of the {value constraint} value used as its 
 
26077
        * ļæ½normalized valueļæ½ must be ļæ½validļæ½ with respect to the 
 
26078
        * ļæ½actual type definitionļæ½ as defined by Element Locally Valid (Type)
 
26079
        * (ļæ½3.3.4).
 
26080
        */          
 
26081
        if (WXS_IS_SIMPLE(inode->typeDef)) {
 
26082
            ret = xmlSchemaVCheckINodeDataType(vctxt,
 
26083
                inode, inode->typeDef, inode->decl->value);
 
26084
        } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
 
26085
            ret = xmlSchemaVCheckINodeDataType(vctxt,
 
26086
                inode, inode->typeDef->contentTypeDef,
 
26087
                inode->decl->value);        
 
26088
        }
 
26089
        if (ret != 0) {
 
26090
            if (ret < 0) {
 
26091
                VERROR_INT("xmlSchemaValidatorPopElem",
 
26092
                    "calling xmlSchemaVCheckCVCSimpleType()");
 
26093
                goto internal_error;
 
26094
            }
 
26095
            goto end_elem;
 
26096
        }
 
26097
 
 
26098
default_psvi:
 
26099
        /*
 
26100
        * PSVI: Create a text node on the instance element.
 
26101
        */
 
26102
        if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
 
26103
            (inode->node != NULL)) {
 
26104
            xmlNodePtr textChild;
 
26105
            xmlChar *normValue;
 
26106
            /*
 
26107
            * VAL TODO: Normalize the value.
 
26108
            */      
 
26109
            normValue = xmlSchemaNormalizeValue(inode->typeDef,
 
26110
                inode->decl->value);
 
26111
            if (normValue != NULL) {
 
26112
                textChild = xmlNewText(BAD_CAST normValue);
 
26113
                xmlFree(normValue);
 
26114
            } else
 
26115
                textChild = xmlNewText(inode->decl->value);
 
26116
            if (textChild == NULL) {
 
26117
                VERROR_INT("xmlSchemaValidatorPopElem",
 
26118
                    "calling xmlNewText()");
 
26119
                goto internal_error;
 
26120
            } else
 
26121
                xmlAddChild(inode->node, textChild);        
 
26122
        }
 
26123
        
 
26124
    } else if (! INODE_NILLED(inode)) { 
 
26125
        /*
 
26126
        * 5.2.1 The element information item must be ļæ½validļæ½ with respect 
 
26127
        * to the ļæ½actual type definitionļæ½ as defined by Element Locally 
 
26128
        * Valid (Type) (ļæ½3.3.4).
 
26129
        */      
 
26130
        if (WXS_IS_SIMPLE(inode->typeDef)) {
 
26131
             /*
 
26132
            * SPEC (cvc-type) (3.1)
 
26133
            * "If the type definition is a simple type definition, ..."
 
26134
            * (3.1.3) "If clause 3.2 of Element Locally Valid
 
26135
            * (Element) (ļæ½3.3.4) did not apply, then the ļæ½normalized valueļæ½
 
26136
            * must be ļæ½validļæ½ with respect to the type definition as defined
 
26137
            * by String Valid (ļæ½3.14.4).
 
26138
            */      
 
26139
            ret = xmlSchemaVCheckINodeDataType(vctxt,
 
26140
                    inode, inode->typeDef, inode->value);
 
26141
        } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
 
26142
            /*
 
26143
            * SPEC (cvc-type) (3.2) "If the type definition is a complex type
 
26144
            * definition, then the element information item must be
 
26145
            * ļæ½validļæ½ with respect to the type definition as per
 
26146
            * Element Locally Valid (Complex Type) (ļæ½3.4.4);"
 
26147
            *
 
26148
            * SPEC (cvc-complex-type) (2.2)
 
26149
            * "If the {content type} is a simple type definition, ... 
 
26150
            * the ļæ½normalized valueļæ½ of the element information item is
 
26151
            * ļæ½validļæ½ with respect to that simple type definition as
 
26152
            * defined by String Valid (ļæ½3.14.4)."
 
26153
            */
 
26154
            ret = xmlSchemaVCheckINodeDataType(vctxt,
 
26155
                inode, inode->typeDef->contentTypeDef, inode->value);
 
26156
        }       
 
26157
        if (ret != 0) {
 
26158
            if (ret < 0) {
 
26159
                VERROR_INT("xmlSchemaValidatorPopElem",
 
26160
                    "calling xmlSchemaVCheckCVCSimpleType()");
 
26161
                goto internal_error;
 
26162
            }
 
26163
            goto end_elem;
 
26164
        }
 
26165
        /*
 
26166
        * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has 
 
26167
        * not applied, all of the following must be true:
 
26168
        */
 
26169
        if ((inode->decl->value != NULL) &&
 
26170
            (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
 
26171
 
 
26172
            /*
 
26173
            * TODO: We will need a computed value, when comparison is
 
26174
            * done on computed values.
 
26175
            */
 
26176
            /*
 
26177
            * 5.2.2.1 The element information item must have no element 
 
26178
            * information item [children].
 
26179
            */
 
26180
            if (inode->flags &
 
26181
                    XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
 
26182
                ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
 
26183
                VERROR(ret, NULL,
 
26184
                    "The content must not containt element nodes since "
 
26185
                    "there is a fixed value constraint");
 
26186
                goto end_elem;
 
26187
            } else {
 
26188
                /*
 
26189
                * 5.2.2.2 The appropriate case among the following must 
 
26190
                * be true:
 
26191
                */              
 
26192
                if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
 
26193
                    /*
 
26194
                    * 5.2.2.2.1 If the {content type} of the ļæ½actual type 
 
26195
                    * definitionļæ½ is mixed, then the *initial value* of the 
 
26196
                    * item must match the canonical lexical representation 
 
26197
                    * of the {value constraint} value.
 
26198
                    *
 
26199
                    * ... the *initial value* of an element information 
 
26200
                    * item is the string composed of, in order, the 
 
26201
                    * [character code] of each character information item in 
 
26202
                    * the [children] of that element information item.
 
26203
                    */             
 
26204
                    if (! xmlStrEqual(inode->value, inode->decl->value)){
 
26205
                        /* 
 
26206
                        * VAL TODO: Report invalid & expected values as well.
 
26207
                        * VAL TODO: Implement the canonical stuff.
 
26208
                        */
 
26209
                        ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
 
26210
                        xmlSchemaCustomErr(ACTXT_CAST vctxt, 
 
26211
                            ret, NULL, NULL,
 
26212
                            "The initial value '%s' does not match the fixed "
 
26213
                            "value constraint '%s'",
 
26214
                            inode->value, inode->decl->value);
 
26215
                        goto end_elem;
 
26216
                    }
 
26217
                } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
 
26218
                    /*
 
26219
                    * 5.2.2.2.2 If the {content type} of the ļæ½actual type 
 
26220
                    * definitionļæ½ is a simple type definition, then the 
 
26221
                    * *actual value* of the item must match the canonical 
 
26222
                    * lexical representation of the {value constraint} value.
 
26223
                    */
 
26224
                    /*
 
26225
                    * VAL TODO: *actual value* is the normalized value, impl.
 
26226
                    *           this.
 
26227
                    * VAL TODO: Report invalid & expected values as well.
 
26228
                    * VAL TODO: Implement a comparison with the computed values.
 
26229
                    */
 
26230
                    if (! xmlStrEqual(inode->value,
 
26231
                            inode->decl->value)) {
 
26232
                        ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
 
26233
                        xmlSchemaCustomErr(ACTXT_CAST vctxt,
 
26234
                            ret, NULL, NULL,
 
26235
                            "The actual value '%s' does not match the fixed "
 
26236
                            "value constraint '%s'", 
 
26237
                            inode->value,
 
26238
                            inode->decl->value);
 
26239
                        goto end_elem;
 
26240
                    }               
 
26241
                }
 
26242
            }       
 
26243
        }
 
26244
    }
 
26245
    
 
26246
end_elem:
 
26247
    if (vctxt->depth < 0) {
 
26248
        /* TODO: raise error? */
 
26249
        return (0);
 
26250
    }
 
26251
    if (vctxt->depth == vctxt->skipDepth)
 
26252
        vctxt->skipDepth = -1;
 
26253
    /*
 
26254
    * Evaluate the history of XPath state objects.
 
26255
    */    
 
26256
    if (inode->appliedXPath &&
 
26257
        (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
 
26258
        goto internal_error;
 
26259
    /*
 
26260
    * MAYBE TODO:
 
26261
    * SPEC (6) "The element information item must be ļæ½validļæ½ with
 
26262
    * respect to each of the {identity-constraint definitions} as per
 
26263
    * Identity-constraint Satisfied (ļæ½3.11.4)."
 
26264
    */
 
26265
    /*
 
26266
    * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
 
26267
    *   need to be built in any case.
 
26268
    *   We will currently build IDC node-tables and bubble them only if
 
26269
    *   keyrefs do exist.
 
26270
    */
 
26271
    
 
26272
    /*
 
26273
    * Add the current IDC target-nodes to the IDC node-tables.
 
26274
    */
 
26275
    if ((inode->idcMatchers != NULL) &&
 
26276
        (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
 
26277
    {
 
26278
        if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
 
26279
            goto internal_error;
 
26280
    }
 
26281
    /*
 
26282
    * Validate IDC keyrefs.
 
26283
    */
 
26284
    if (vctxt->inode->hasKeyrefs)
 
26285
        if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
 
26286
            goto internal_error;
 
26287
    /*
 
26288
    * Merge/free the IDC table.
 
26289
    */
 
26290
    if (inode->idcTable != NULL) {
 
26291
#ifdef DEBUG_IDC_NODE_TABLE
 
26292
        xmlSchemaDebugDumpIDCTable(stdout,
 
26293
            inode->nsName,
 
26294
            inode->localName,
 
26295
            inode->idcTable);
 
26296
#endif
 
26297
        if ((vctxt->depth > 0) &&
 
26298
            (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
 
26299
        {
 
26300
            /*
 
26301
            * Merge the IDC node table with the table of the parent node.
 
26302
            */
 
26303
            if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
 
26304
                goto internal_error;
 
26305
        }       
 
26306
    }
 
26307
    /*
 
26308
    * Clear the current ielem.
 
26309
    * VAL TODO: Don't free the PSVI IDC tables if they are
 
26310
    * requested for the PSVI.
 
26311
    */
 
26312
    xmlSchemaClearElemInfo(vctxt, inode);
 
26313
    /*
 
26314
    * Skip further processing if we are on the validation root.
 
26315
    */
 
26316
    if (vctxt->depth == 0) {
 
26317
        vctxt->depth--;
 
26318
        vctxt->inode = NULL;
 
26319
        return (0);
 
26320
    }
 
26321
    /*
 
26322
    * Reset the keyrefDepth if needed.
 
26323
    */
 
26324
    if (vctxt->aidcs != NULL) {
 
26325
        xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
 
26326
        do {
 
26327
            if (aidc->keyrefDepth == vctxt->depth) {
 
26328
                /*
 
26329
                * A 'keyrefDepth' of a key/unique IDC matches the current
 
26330
                * depth, this means that we are leaving the scope of the
 
26331
                * top-most keyref IDC which refers to this IDC.
 
26332
                */
 
26333
                aidc->keyrefDepth = -1;
 
26334
            }
 
26335
            aidc = aidc->next;
 
26336
        } while (aidc != NULL);
 
26337
    }
 
26338
    vctxt->depth--;        
 
26339
    vctxt->inode = vctxt->elemInfos[vctxt->depth];
 
26340
    /*
 
26341
    * VAL TODO: 7 If the element information item is the ļæ½validation rootļæ½, it must be 
 
26342
    * ļæ½validļæ½ per Validation Root Valid (ID/IDREF) (ļæ½3.3.4).
 
26343
    */
 
26344
    return (ret);
 
26345
 
 
26346
internal_error:
 
26347
    vctxt->err = -1;
 
26348
    return (-1);
 
26349
}
 
26350
 
 
26351
/*
 
26352
* 3.4.4 Complex Type Definition Validation Rules
 
26353
* Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
 
26354
*/
 
26355
static int
 
26356
xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
 
26357
{
 
26358
    xmlSchemaNodeInfoPtr pielem;
 
26359
    xmlSchemaTypePtr ptype;
 
26360
    int ret = 0;
 
26361
 
 
26362
    if (vctxt->depth <= 0) {
 
26363
        VERROR_INT("xmlSchemaValidateChildElem",
 
26364
            "not intended for the validation root");
 
26365
        return (-1);
 
26366
    }
 
26367
    pielem = vctxt->elemInfos[vctxt->depth -1];
 
26368
    if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
 
26369
        pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
 
26370
    /*
 
26371
    * Handle 'nilled' elements.
 
26372
    */
 
26373
    if (INODE_NILLED(pielem)) {
 
26374
        /*
 
26375
        * SPEC (cvc-elt) (3.3.4) : (3.2.1)
 
26376
        */
 
26377
        ACTIVATE_PARENT_ELEM;
 
26378
        ret = XML_SCHEMAV_CVC_ELT_3_2_1;
 
26379
        VERROR(ret, NULL,
 
26380
            "Neither character nor element content is allowed, "
 
26381
            "because the element was 'nilled'");
 
26382
        ACTIVATE_ELEM;
 
26383
        goto unexpected_elem;
 
26384
    }
 
26385
 
 
26386
    ptype = pielem->typeDef;
 
26387
 
 
26388
    if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
 
26389
        /*
 
26390
        * Workaround for "anyType": we have currently no content model
 
26391
        * assigned for "anyType", so handle it explicitely.
 
26392
        * "anyType" has an unbounded, lax "any" wildcard.
 
26393
        */
 
26394
        vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
 
26395
            vctxt->inode->localName,
 
26396
            vctxt->inode->nsName);
 
26397
 
 
26398
        if (vctxt->inode->decl == NULL) {
 
26399
            xmlSchemaAttrInfoPtr iattr;
 
26400
            /*
 
26401
            * Process "xsi:type".
 
26402
            * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
 
26403
            */
 
26404
            iattr = xmlSchemaGetMetaAttrInfo(vctxt,
 
26405
                XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
 
26406
            if (iattr != NULL) {
 
26407
                ret = xmlSchemaProcessXSIType(vctxt, iattr,
 
26408
                    &(vctxt->inode->typeDef), NULL);
 
26409
                if (ret != 0) {
 
26410
                    if (ret == -1) {
 
26411
                        VERROR_INT("xmlSchemaValidateChildElem",
 
26412
                            "calling xmlSchemaProcessXSIType() to "
 
26413
                            "process the attribute 'xsi:nil'");
 
26414
                        return (-1);
 
26415
                    }
 
26416
                    return (ret);
 
26417
                }
 
26418
            } else {
 
26419
                 /*
 
26420
                 * Fallback to "anyType".
 
26421
                 *
 
26422
                 * SPEC (cvc-assess-elt)
 
26423
                 * "If the item cannot be ļæ½strictly assessedļæ½, [...]
 
26424
                 * an element information item's schema validity may be laxly
 
26425
                 * assessed if its ļæ½context-determined declarationļæ½ is not
 
26426
                 * skip by ļæ½validatingļæ½ with respect to the ļæ½ur-type
 
26427
                 * definitionļæ½ as per Element Locally Valid (Type) (ļæ½3.3.4)."
 
26428
                */
 
26429
                vctxt->inode->typeDef =
 
26430
                    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
 
26431
            }
 
26432
        }
 
26433
        return (0);
 
26434
    }
 
26435
 
 
26436
    switch (ptype->contentType) {
 
26437
        case XML_SCHEMA_CONTENT_EMPTY:
 
26438
            /*
 
26439
            * SPEC (2.1) "If the {content type} is empty, then the
 
26440
            * element information item has no character or element
 
26441
            * information item [children]."
 
26442
            */
 
26443
            ACTIVATE_PARENT_ELEM
 
26444
            ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
 
26445
            VERROR(ret, NULL,
 
26446
                "Element content is not allowed, "
 
26447
                "because the content type is empty");
 
26448
            ACTIVATE_ELEM
 
26449
            goto unexpected_elem;
 
26450
            break;
 
26451
 
 
26452
        case XML_SCHEMA_CONTENT_MIXED:
 
26453
        case XML_SCHEMA_CONTENT_ELEMENTS: {
 
26454
            xmlRegExecCtxtPtr regexCtxt;
 
26455
            xmlChar *values[10];
 
26456
            int terminal, nbval = 10, nbneg;
 
26457
 
 
26458
            /* VAL TODO: Optimized "anyType" validation.*/
 
26459
 
 
26460
            if (ptype->contModel == NULL) {
 
26461
                VERROR_INT("xmlSchemaValidateChildElem",
 
26462
                    "type has elem content but no content model");
 
26463
                return (-1);
 
26464
            }
 
26465
            /*
 
26466
            * Safety belf for evaluation if the cont. model was already
 
26467
            * examined to be invalid.
 
26468
            */
 
26469
            if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
 
26470
                VERROR_INT("xmlSchemaValidateChildElem",
 
26471
                    "validating elem, but elem content is already invalid");
 
26472
                return (-1);
 
26473
            }
 
26474
 
 
26475
            regexCtxt = pielem->regexCtxt;
 
26476
            if (regexCtxt == NULL) {
 
26477
                /*
 
26478
                * Create the regex context.
 
26479
                */
 
26480
                regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
 
26481
                    (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
 
26482
                    vctxt);
 
26483
                if (regexCtxt == NULL) {
 
26484
                    VERROR_INT("xmlSchemaValidateChildElem",
 
26485
                        "failed to create a regex context");
 
26486
                    return (-1);
 
26487
                }
 
26488
                pielem->regexCtxt = regexCtxt;
 
26489
#ifdef DEBUG_AUTOMATA
 
26490
                xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
 
26491
                    pielem->localName);
 
26492
#endif
 
26493
            }
 
26494
 
 
26495
            /*
 
26496
            * SPEC (2.4) "If the {content type} is element-only or mixed,
 
26497
            * then the sequence of the element information item's
 
26498
            * element information item [children], if any, taken in
 
26499
            * order, is ļæ½validļæ½ with respect to the {content type}'s
 
26500
            * particle, as defined in Element Sequence Locally Valid
 
26501
            * (Particle) (ļæ½3.9.4)."
 
26502
            */
 
26503
            ret = xmlRegExecPushString2(regexCtxt,
 
26504
                vctxt->inode->localName,
 
26505
                vctxt->inode->nsName,
 
26506
                vctxt->inode);
 
26507
#ifdef DEBUG_AUTOMATA
 
26508
            if (ret < 0)
 
26509
                xmlGenericError(xmlGenericErrorContext,
 
26510
                "AUTOMATON push ERROR for '%s' on '%s'\n",
 
26511
                vctxt->inode->localName, pielem->localName);
 
26512
            else
 
26513
                xmlGenericError(xmlGenericErrorContext,
 
26514
                "AUTOMATON push OK for '%s' on '%s'\n",
 
26515
                vctxt->inode->localName, pielem->localName);
 
26516
#endif
 
26517
            if (vctxt->err == XML_SCHEMAV_INTERNAL) {
 
26518
                VERROR_INT("xmlSchemaValidateChildElem",
 
26519
                    "calling xmlRegExecPushString2()");
 
26520
                return (-1);
 
26521
            }
 
26522
            if (ret < 0) {
 
26523
                xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
 
26524
                    &values[0], &terminal);
 
26525
                xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
 
26526
                    XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
 
26527
                    "This element is not expected",
 
26528
                    nbval, nbneg, values);
 
26529
                ret = vctxt->err;
 
26530
                goto unexpected_elem;
 
26531
            } else
 
26532
                ret = 0;
 
26533
        }
 
26534
            break;
 
26535
        case XML_SCHEMA_CONTENT_SIMPLE:
 
26536
        case XML_SCHEMA_CONTENT_BASIC:
 
26537
            ACTIVATE_PARENT_ELEM
 
26538
            if (WXS_IS_COMPLEX(ptype)) {
 
26539
                /*
 
26540
                * SPEC (cvc-complex-type) (2.2)
 
26541
                * "If the {content type} is a simple type definition, then
 
26542
                * the element information item has no element information
 
26543
                * item [children], ..."
 
26544
                */
 
26545
                ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
 
26546
                VERROR(ret, NULL, "Element content is not allowed, "
 
26547
                    "because the content type is a simple type definition");
 
26548
            } else {
 
26549
                /*
 
26550
                * SPEC (cvc-type) (3.1.2) "The element information item must
 
26551
                * have no element information item [children]."
 
26552
                */
 
26553
                ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
 
26554
                VERROR(ret, NULL, "Element content is not allowed, "
 
26555
                    "because the type definition is simple");
 
26556
            }
 
26557
            ACTIVATE_ELEM
 
26558
            ret = vctxt->err;
 
26559
            goto unexpected_elem;
 
26560
            break;
 
26561
 
 
26562
        default:
 
26563
            break;
 
26564
    }
 
26565
    return (ret);
 
26566
unexpected_elem:
 
26567
    /*
 
26568
    * Pop this element and set the skipDepth to skip
 
26569
    * all further content of the parent element.
 
26570
    */
 
26571
    vctxt->skipDepth = vctxt->depth;
 
26572
    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
 
26573
    pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
 
26574
    return (ret);
 
26575
}
 
26576
 
 
26577
#define XML_SCHEMA_PUSH_TEXT_PERSIST 1
 
26578
#define XML_SCHEMA_PUSH_TEXT_CREATED 2
 
26579
#define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
 
26580
 
 
26581
static int
 
26582
xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
 
26583
                  int nodeType, const xmlChar *value, int len,
 
26584
                  int mode, int *consumed)
 
26585
{
 
26586
    /*
 
26587
    * Unfortunately we have to duplicate the text sometimes.
 
26588
    * OPTIMIZE: Maybe we could skip it, if:
 
26589
    *   1. content type is simple
 
26590
    *   2. whitespace is "collapse"
 
26591
    *   3. it consists of whitespace only
 
26592
    *
 
26593
    * Process character content.
 
26594
    */
 
26595
    if (consumed != NULL)
 
26596
        *consumed = 0;
 
26597
    if (INODE_NILLED(vctxt->inode)) {
 
26598
        /* 
 
26599
        * SPEC cvc-elt (3.3.4 - 3.2.1)
 
26600
        * "The element information item must have no character or
 
26601
        * element information item [children]."
 
26602
        */
 
26603
        VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
 
26604
            "Neither character nor element content is allowed "
 
26605
            "because the element is 'nilled'");
 
26606
        return (vctxt->err);
 
26607
    }
 
26608
    /*
 
26609
    * SPEC (2.1) "If the {content type} is empty, then the
 
26610
    * element information item has no character or element
 
26611
    * information item [children]."
 
26612
    */
 
26613
    if (vctxt->inode->typeDef->contentType ==
 
26614
            XML_SCHEMA_CONTENT_EMPTY) {    
 
26615
        VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
 
26616
            "Character content is not allowed, "
 
26617
            "because the content type is empty");
 
26618
        return (vctxt->err);
 
26619
    }
 
26620
 
 
26621
    if (vctxt->inode->typeDef->contentType ==
 
26622
            XML_SCHEMA_CONTENT_ELEMENTS) {
 
26623
        if ((nodeType != XML_TEXT_NODE) ||
 
26624
            (! xmlSchemaIsBlank((xmlChar *) value, len))) {
 
26625
            /* 
 
26626
            * SPEC cvc-complex-type (2.3) 
 
26627
            * "If the {content type} is element-only, then the 
 
26628
            * element information item has no character information 
 
26629
            * item [children] other than those whose [character 
 
26630
            * code] is defined as a white space in [XML 1.0 (Second 
 
26631
            * Edition)]."
 
26632
            */
 
26633
            VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
 
26634
                "Character content other than whitespace is not allowed "
 
26635
                "because the content type is 'element-only'");
 
26636
            return (vctxt->err);
 
26637
        }
 
26638
        return (0);
 
26639
    }
 
26640
    
 
26641
    if ((value == NULL) || (value[0] == 0))
 
26642
        return (0);
 
26643
    /*
 
26644
    * Save the value.
 
26645
    * NOTE that even if the content type is *mixed*, we need the
 
26646
    * *initial value* for default/fixed value constraints.
 
26647
    */
 
26648
    if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
 
26649
        ((vctxt->inode->decl == NULL) ||
 
26650
        (vctxt->inode->decl->value == NULL)))
 
26651
        return (0);
 
26652
    
 
26653
    if (vctxt->inode->value == NULL) {
 
26654
        /*
 
26655
        * Set the value.
 
26656
        */
 
26657
        switch (mode) {
 
26658
            case XML_SCHEMA_PUSH_TEXT_PERSIST:
 
26659
                /*
 
26660
                * When working on a tree.
 
26661
                */
 
26662
                vctxt->inode->value = value;
 
26663
                break;
 
26664
            case XML_SCHEMA_PUSH_TEXT_CREATED:
 
26665
                /*
 
26666
                * When working with the reader.
 
26667
                * The value will be freed by the element info.
 
26668
                */
 
26669
                vctxt->inode->value = value;
 
26670
                if (consumed != NULL)
 
26671
                    *consumed = 1;
 
26672
                vctxt->inode->flags |=
 
26673
                    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
 
26674
                break;
 
26675
            case XML_SCHEMA_PUSH_TEXT_VOLATILE:
 
26676
                /*
 
26677
                * When working with SAX.
 
26678
                * The value will be freed by the element info.
 
26679
                */
 
26680
                if (len != -1)
 
26681
                    vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
 
26682
                else
 
26683
                    vctxt->inode->value = BAD_CAST xmlStrdup(value);
 
26684
                vctxt->inode->flags |=
 
26685
                    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
 
26686
                break;
 
26687
            default:
 
26688
                break;
 
26689
        }
 
26690
    } else {
 
26691
        if (len < 0)
 
26692
            len = xmlStrlen(value);
 
26693
        /*
 
26694
        * Concat the value.
 
26695
        */      
 
26696
        if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
 
26697
            vctxt->inode->value = BAD_CAST xmlStrncat(
 
26698
                (xmlChar *) vctxt->inode->value, value, len);
 
26699
        } else {
 
26700
            vctxt->inode->value =
 
26701
                BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
 
26702
            vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
 
26703
        }
 
26704
    }   
 
26705
 
 
26706
    return (0);
 
26707
}
 
26708
 
 
26709
static int
 
26710
xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
 
26711
{
 
26712
    int ret = 0;
 
26713
 
 
26714
    if ((vctxt->skipDepth != -1) &&
 
26715
        (vctxt->depth >= vctxt->skipDepth)) {
 
26716
        VERROR_INT("xmlSchemaValidateElem",
 
26717
            "in skip-state");
 
26718
        goto internal_error;
 
26719
    }
 
26720
    if (vctxt->xsiAssemble) {
 
26721
        /* 
 
26722
        * We will stop validation if there was an error during
 
26723
        * dynamic schema construction.
 
26724
        * Note that we simply set @skipDepth to 0, this could
 
26725
        * mean that a streaming document via SAX would be
 
26726
        * still read to the end but it won't be validated any more.
 
26727
        * TODO: If we are sure how to stop the validation at once
 
26728
        *   for all input scenarios, then this should be changed to
 
26729
        *   instantly stop the validation.
 
26730
        */
 
26731
        ret = xmlSchemaAssembleByXSI(vctxt);
 
26732
        if (ret != 0) {
 
26733
            if (ret == -1)
 
26734
                goto internal_error;
 
26735
            vctxt->skipDepth = 0;
 
26736
            return(ret);
 
26737
        }
 
26738
    }
 
26739
    if (vctxt->depth > 0) {
 
26740
        /*
 
26741
        * Validate this element against the content model
 
26742
        * of the parent.
 
26743
        */
 
26744
        ret = xmlSchemaValidateChildElem(vctxt);
 
26745
        if (ret != 0) {
 
26746
            if (ret < 0) {
 
26747
                VERROR_INT("xmlSchemaValidateElem",
 
26748
                    "calling xmlSchemaStreamValidateChildElement()");
 
26749
                goto internal_error;
 
26750
            }
 
26751
            goto exit;
 
26752
        }
 
26753
        if (vctxt->depth == vctxt->skipDepth)
 
26754
            goto exit;
 
26755
        if ((vctxt->inode->decl == NULL) &&
 
26756
            (vctxt->inode->typeDef == NULL)) {
 
26757
            VERROR_INT("xmlSchemaValidateElem",
 
26758
                "the child element was valid but neither the "
 
26759
                "declaration nor the type was set");
 
26760
            goto internal_error;
 
26761
        }
 
26762
    } else {
 
26763
        /*
 
26764
        * Get the declaration of the validation root.
 
26765
        */
 
26766
        vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
 
26767
            vctxt->inode->localName,
 
26768
            vctxt->inode->nsName);
 
26769
        if (vctxt->inode->decl == NULL) {
 
26770
            ret = XML_SCHEMAV_CVC_ELT_1;
 
26771
            VERROR(ret, NULL,
 
26772
                "No matching global declaration available "
 
26773
                "for the validation root");
 
26774
            goto exit;
 
26775
        }
 
26776
    }
 
26777
 
 
26778
    if (vctxt->inode->decl == NULL)
 
26779
        goto type_validation;
 
26780
 
 
26781
    if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
 
26782
        int skip;
 
26783
        /*
 
26784
        * Wildcards.
 
26785
        */
 
26786
        ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
 
26787
        if (ret != 0) {
 
26788
            if (ret < 0) {
 
26789
                VERROR_INT("xmlSchemaValidateElem",
 
26790
                    "calling xmlSchemaValidateElemWildcard()");
 
26791
                goto internal_error;
 
26792
            }
 
26793
            goto exit;
 
26794
        }
 
26795
        if (skip) {
 
26796
            vctxt->skipDepth = vctxt->depth;
 
26797
            goto exit;
 
26798
        }
 
26799
        /*
 
26800
        * The declaration might be set by the wildcard validation,
 
26801
        * when the processContents is "lax" or "strict".
 
26802
        */
 
26803
        if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
 
26804
            /*
 
26805
            * Clear the "decl" field to not confuse further processing.
 
26806
            */
 
26807
            vctxt->inode->decl = NULL;
 
26808
            goto type_validation;
 
26809
        }
 
26810
    }
 
26811
    /*
 
26812
    * Validate against the declaration.
 
26813
    */
 
26814
    ret = xmlSchemaValidateElemDecl(vctxt);
 
26815
    if (ret != 0) {
 
26816
        if (ret < 0) {
 
26817
            VERROR_INT("xmlSchemaValidateElem",
 
26818
                "calling xmlSchemaValidateElemDecl()");
 
26819
            goto internal_error;
 
26820
        }
 
26821
        goto exit;
 
26822
    }
 
26823
    /*
 
26824
    * Validate against the type definition.
 
26825
    */
 
26826
type_validation:
 
26827
 
 
26828
    if (vctxt->inode->typeDef == NULL) {
 
26829
        vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
 
26830
        ret = XML_SCHEMAV_CVC_TYPE_1;
 
26831
        VERROR(ret, NULL,
 
26832
            "The type definition is absent");
 
26833
        goto exit;
 
26834
    }    
 
26835
    if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
 
26836
        vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
 
26837
        ret = XML_SCHEMAV_CVC_TYPE_2;
 
26838
            VERROR(ret, NULL,
 
26839
            "The type definition is abstract"); 
 
26840
        goto exit;
 
26841
    }
 
26842
    /*
 
26843
    * Evaluate IDCs. Do it here, since new IDC matchers are registered
 
26844
    * during validation against the declaration. This must be done
 
26845
    * _before_ attribute validation.
 
26846
    */
 
26847
    if (vctxt->xpathStates != NULL) {
 
26848
        ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
 
26849
        vctxt->inode->appliedXPath = 1;
 
26850
        if (ret == -1) {
 
26851
            VERROR_INT("xmlSchemaValidateElem",
 
26852
                "calling xmlSchemaXPathEvaluate()");
 
26853
            goto internal_error;
 
26854
        }
 
26855
    }
 
26856
    /*
 
26857
    * Validate attributes.
 
26858
    */
 
26859
    if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
 
26860
        if ((vctxt->nbAttrInfos != 0) ||
 
26861
            (vctxt->inode->typeDef->attrUses != NULL)) {
 
26862
 
 
26863
            ret = xmlSchemaVAttributesComplex(vctxt);
 
26864
        }
 
26865
    } else if (vctxt->nbAttrInfos != 0) {
 
26866
 
 
26867
        ret = xmlSchemaVAttributesSimple(vctxt);
 
26868
    }
 
26869
    /*
 
26870
    * Clear registered attributes.
 
26871
    */
 
26872
    if (vctxt->nbAttrInfos != 0)
 
26873
        xmlSchemaClearAttrInfos(vctxt);
 
26874
    if (ret == -1) {
 
26875
        VERROR_INT("xmlSchemaValidateElem",
 
26876
            "calling attributes validation");
 
26877
        goto internal_error;
 
26878
    }
 
26879
    /*
 
26880
    * Don't return an error if attributes are invalid on purpose.
 
26881
    */
 
26882
    ret = 0;
 
26883
 
 
26884
exit:
 
26885
    if (ret != 0)
 
26886
        vctxt->skipDepth = vctxt->depth;
 
26887
    return (ret);
 
26888
internal_error:
 
26889
    return (-1);
 
26890
}
 
26891
 
 
26892
#ifdef XML_SCHEMA_READER_ENABLED
 
26893
static int
 
26894
xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
 
26895
{
 
26896
    const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
 
26897
    int depth, nodeType, ret = 0, consumed;
 
26898
    xmlSchemaNodeInfoPtr ielem;
 
26899
 
 
26900
    vctxt->depth = -1;
 
26901
    ret = xmlTextReaderRead(vctxt->reader);
 
26902
    /*
 
26903
    * Move to the document element.
 
26904
    */
 
26905
    while (ret == 1) {
 
26906
        nodeType = xmlTextReaderNodeType(vctxt->reader);
 
26907
        if (nodeType == XML_ELEMENT_NODE)
 
26908
            goto root_found;
 
26909
        ret = xmlTextReaderRead(vctxt->reader);
 
26910
    }
 
26911
    goto exit;
 
26912
 
 
26913
root_found:
 
26914
 
 
26915
    do {
 
26916
        depth = xmlTextReaderDepth(vctxt->reader);
 
26917
        nodeType = xmlTextReaderNodeType(vctxt->reader);
 
26918
 
 
26919
        if (nodeType == XML_ELEMENT_NODE) {
 
26920
            
 
26921
            vctxt->depth++;
 
26922
            if (xmlSchemaValidatorPushElem(vctxt) == -1) {
 
26923
                VERROR_INT("xmlSchemaVReaderWalk",
 
26924
                    "calling xmlSchemaValidatorPushElem()");
 
26925
                goto internal_error;
 
26926
            }
 
26927
            ielem = vctxt->inode;
 
26928
            ielem->localName = xmlTextReaderLocalName(vctxt->reader);
 
26929
            ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
 
26930
            ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
 
26931
            /*
 
26932
            * Is the element empty?
 
26933
            */
 
26934
            ret = xmlTextReaderIsEmptyElement(vctxt->reader);
 
26935
            if (ret == -1) {
 
26936
                VERROR_INT("xmlSchemaVReaderWalk",
 
26937
                    "calling xmlTextReaderIsEmptyElement()");
 
26938
                goto internal_error;
 
26939
            }
 
26940
            if (ret) {
 
26941
                ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
 
26942
            }
 
26943
            /*
 
26944
            * Register attributes.
 
26945
            */
 
26946
            vctxt->nbAttrInfos = 0;
 
26947
            ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
 
26948
            if (ret == -1) {
 
26949
                VERROR_INT("xmlSchemaVReaderWalk",
 
26950
                    "calling xmlTextReaderMoveToFirstAttribute()");
 
26951
                goto internal_error;
 
26952
            }
 
26953
            if (ret == 1) {
 
26954
                do {
 
26955
                    /*
 
26956
                    * VAL TODO: How do we know that the reader works on a
 
26957
                    * node tree, to be able to pass a node here?
 
26958
                    */
 
26959
                    if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
 
26960
                        (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
 
26961
                        xmlTextReaderNamespaceUri(vctxt->reader), 1,
 
26962
                        xmlTextReaderValue(vctxt->reader), 1) == -1) {
 
26963
 
 
26964
                        VERROR_INT("xmlSchemaVReaderWalk",
 
26965
                            "calling xmlSchemaValidatorPushAttribute()");
 
26966
                        goto internal_error;
 
26967
                    }
 
26968
                    ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
 
26969
                    if (ret == -1) {
 
26970
                        VERROR_INT("xmlSchemaVReaderWalk",
 
26971
                            "calling xmlTextReaderMoveToFirstAttribute()");
 
26972
                        goto internal_error;
 
26973
                    }
 
26974
                } while (ret == 1);
 
26975
                /*
 
26976
                * Back to element position.
 
26977
                */
 
26978
                ret = xmlTextReaderMoveToElement(vctxt->reader);
 
26979
                if (ret == -1) {
 
26980
                    VERROR_INT("xmlSchemaVReaderWalk",
 
26981
                        "calling xmlTextReaderMoveToElement()");
 
26982
                    goto internal_error;
 
26983
                }
 
26984
            }
 
26985
            /*
 
26986
            * Validate the element.
 
26987
            */
 
26988
            ret= xmlSchemaValidateElem(vctxt);
 
26989
            if (ret != 0) {
 
26990
                if (ret == -1) {
 
26991
                    VERROR_INT("xmlSchemaVReaderWalk",
 
26992
                        "calling xmlSchemaValidateElem()");
 
26993
                    goto internal_error;
 
26994
                }
 
26995
                goto exit;
 
26996
            }
 
26997
            if (vctxt->depth == vctxt->skipDepth) {
 
26998
                int curDepth;
 
26999
                /*
 
27000
                * Skip all content.
 
27001
                */
 
27002
                if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
 
27003
                    ret = xmlTextReaderRead(vctxt->reader);
 
27004
                    curDepth = xmlTextReaderDepth(vctxt->reader);
 
27005
                    while ((ret == 1) && (curDepth != depth)) {
 
27006
                        ret = xmlTextReaderRead(vctxt->reader);
 
27007
                        curDepth = xmlTextReaderDepth(vctxt->reader);
 
27008
                    }
 
27009
                    if (ret < 0) {
 
27010
                        /*
 
27011
                        * VAL TODO: A reader error occured; what to do here?
 
27012
                        */
 
27013
                        ret = 1;
 
27014
                        goto exit;
 
27015
                    }
 
27016
                }
 
27017
                goto leave_elem;
 
27018
            }
 
27019
            /*
 
27020
            * READER VAL TODO: Is an END_ELEM really never called
 
27021
            * if the elem is empty?
 
27022
            */
 
27023
            if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
 
27024
                goto leave_elem;
 
27025
        } else if (nodeType == END_ELEM) {
 
27026
            /*
 
27027
            * Process END of element.
 
27028
            */
 
27029
leave_elem:
 
27030
            ret = xmlSchemaValidatorPopElem(vctxt);
 
27031
            if (ret != 0) {
 
27032
                if (ret < 0) {
 
27033
                    VERROR_INT("xmlSchemaVReaderWalk",
 
27034
                        "calling xmlSchemaValidatorPopElem()");
 
27035
                    goto internal_error;
 
27036
                }
 
27037
                goto exit;
 
27038
            }
 
27039
            if (vctxt->depth >= 0)
 
27040
                ielem = vctxt->inode;
 
27041
            else
 
27042
                ielem = NULL;
 
27043
        } else if ((nodeType == XML_TEXT_NODE) ||
 
27044
            (nodeType == XML_CDATA_SECTION_NODE) ||
 
27045
            (nodeType == WHTSP) ||
 
27046
            (nodeType == SIGN_WHTSP)) {
 
27047
            /*
 
27048
            * Process character content.
 
27049
            */
 
27050
            xmlChar *value;
 
27051
 
 
27052
            if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
 
27053
                nodeType = XML_TEXT_NODE;
 
27054
 
 
27055
            value = xmlTextReaderValue(vctxt->reader);
 
27056
            ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
 
27057
                -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
 
27058
            if (! consumed)
 
27059
                xmlFree(value);
 
27060
            if (ret == -1) {
 
27061
                VERROR_INT("xmlSchemaVReaderWalk",
 
27062
                    "calling xmlSchemaVPushText()");
 
27063
                goto internal_error;
 
27064
            }
 
27065
        } else if ((nodeType == XML_ENTITY_NODE) ||
 
27066
            (nodeType == XML_ENTITY_REF_NODE)) {
 
27067
            /*
 
27068
            * VAL TODO: What to do with entities?
 
27069
            */
 
27070
            TODO
 
27071
        }
 
27072
        /*
 
27073
        * Read next node.
 
27074
        */
 
27075
        ret = xmlTextReaderRead(vctxt->reader);
 
27076
    } while (ret == 1);
 
27077
 
 
27078
exit:
 
27079
    return (ret);
 
27080
internal_error:
 
27081
    return (-1);
 
27082
}
 
27083
#endif
 
27084
 
 
27085
/************************************************************************
 
27086
 *                                                                      *
 
27087
 *                      SAX validation handlers                         *
 
27088
 *                                                                      *
 
27089
 ************************************************************************/
 
27090
 
 
27091
/*
 
27092
* Process text content.
 
27093
*/
 
27094
static void
 
27095
xmlSchemaSAXHandleText(void *ctx, 
 
27096
                       const xmlChar * ch, 
 
27097
                       int len)
 
27098
{
 
27099
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
 
27100
 
 
27101
    if (vctxt->depth < 0)
 
27102
        return;
 
27103
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
 
27104
        return;
 
27105
    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
 
27106
        vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
 
27107
    if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
 
27108
        XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
 
27109
        VERROR_INT("xmlSchemaSAXHandleCDataSection",
 
27110
            "calling xmlSchemaVPushText()");
 
27111
        vctxt->err = -1;
 
27112
        xmlStopParser(vctxt->parserCtxt);
 
27113
    }
 
27114
}
 
27115
 
 
27116
/*
 
27117
* Process CDATA content.
 
27118
*/
 
27119
static void
 
27120
xmlSchemaSAXHandleCDataSection(void *ctx, 
 
27121
                             const xmlChar * ch, 
 
27122
                             int len)
 
27123
{   
 
27124
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
 
27125
 
 
27126
    if (vctxt->depth < 0)
 
27127
        return;
 
27128
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
 
27129
        return;
 
27130
    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
 
27131
        vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
 
27132
    if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
 
27133
        XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
 
27134
        VERROR_INT("xmlSchemaSAXHandleCDataSection",
 
27135
            "calling xmlSchemaVPushText()");
 
27136
        vctxt->err = -1;
 
27137
        xmlStopParser(vctxt->parserCtxt);
 
27138
    }
 
27139
}
 
27140
 
 
27141
static void
 
27142
xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
 
27143
                            const xmlChar * name ATTRIBUTE_UNUSED)
 
27144
{
 
27145
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
 
27146
 
 
27147
    if (vctxt->depth < 0)
 
27148
        return;
 
27149
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
 
27150
        return;
 
27151
    /* SAX VAL TODO: What to do here? */
 
27152
    TODO
 
27153
}
 
27154
 
 
27155
static void
 
27156
xmlSchemaSAXHandleStartElementNs(void *ctx,
 
27157
                                 const xmlChar * localname, 
 
27158
                                 const xmlChar * prefix ATTRIBUTE_UNUSED, 
 
27159
                                 const xmlChar * URI, 
 
27160
                                 int nb_namespaces, 
 
27161
                                 const xmlChar ** namespaces, 
 
27162
                                 int nb_attributes, 
 
27163
                                 int nb_defaulted ATTRIBUTE_UNUSED, 
 
27164
                                 const xmlChar ** attributes)
 
27165
{  
 
27166
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
 
27167
    int ret;
 
27168
    xmlSchemaNodeInfoPtr ielem;
 
27169
    int i, j;
 
27170
    
 
27171
    /*
 
27172
    * SAX VAL TODO: What to do with nb_defaulted?
 
27173
    */
 
27174
    /*
 
27175
    * Skip elements if inside a "skip" wildcard or invalid.
 
27176
    */
 
27177
    vctxt->depth++;
 
27178
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
 
27179
        return;
 
27180
    /*
 
27181
    * Push the element.
 
27182
    */
 
27183
    if (xmlSchemaValidatorPushElem(vctxt) == -1) {
 
27184
        VERROR_INT("xmlSchemaSAXHandleStartElementNs",
 
27185
            "calling xmlSchemaValidatorPushElem()");
 
27186
        goto internal_error;
 
27187
    }
 
27188
    ielem = vctxt->inode;
 
27189
    /*
 
27190
    * TODO: Is this OK?
 
27191
    */
 
27192
    ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
 
27193
    ielem->localName = localname;
 
27194
    ielem->nsName = URI;
 
27195
    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
 
27196
    /*
 
27197
    * Register namespaces on the elem info.
 
27198
    */    
 
27199
    if (nb_namespaces != 0) {
 
27200
        /*
 
27201
        * Although the parser builds its own namespace list,
 
27202
        * we have no access to it, so we'll use an own one.
 
27203
        */
 
27204
        for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {        
 
27205
            /*
 
27206
            * Store prefix and namespace name.
 
27207
            */     
 
27208
            if (ielem->nsBindings == NULL) {
 
27209
                ielem->nsBindings =
 
27210
                    (const xmlChar **) xmlMalloc(10 *
 
27211
                        sizeof(const xmlChar *));
 
27212
                if (ielem->nsBindings == NULL) {
 
27213
                    xmlSchemaVErrMemory(vctxt,
 
27214
                        "allocating namespace bindings for SAX validation",
 
27215
                        NULL);
 
27216
                    goto internal_error;
 
27217
                }
 
27218
                ielem->nbNsBindings = 0;
 
27219
                ielem->sizeNsBindings = 5;
 
27220
            } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
 
27221
                ielem->sizeNsBindings *= 2;
 
27222
                ielem->nsBindings =
 
27223
                    (const xmlChar **) xmlRealloc(
 
27224
                        (void *) ielem->nsBindings,
 
27225
                        ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
 
27226
                if (ielem->nsBindings == NULL) {
 
27227
                    xmlSchemaVErrMemory(vctxt,
 
27228
                        "re-allocating namespace bindings for SAX validation",
 
27229
                        NULL);
 
27230
                    goto internal_error;
 
27231
                }
 
27232
            }
 
27233
 
 
27234
            ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
 
27235
            if (namespaces[j+1][0] == 0) {
 
27236
                /*
 
27237
                * Handle xmlns="".
 
27238
                */
 
27239
                ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
 
27240
            } else
 
27241
                ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
 
27242
                    namespaces[j+1];
 
27243
            ielem->nbNsBindings++;                  
 
27244
        }
 
27245
    }
 
27246
    /*
 
27247
    * Register attributes.
 
27248
    * SAX VAL TODO: We are not adding namespace declaration
 
27249
    * attributes yet.
 
27250
    */
 
27251
    if (nb_attributes != 0) {
 
27252
        xmlChar *value;
 
27253
 
 
27254
        for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
 
27255
            /*
 
27256
            * Duplicate the value.
 
27257
            */   
 
27258
            value = xmlStrndup(attributes[j+3],
 
27259
                attributes[j+4] - attributes[j+3]);
 
27260
            /*
 
27261
            * TODO: Set the node line.
 
27262
            */
 
27263
            ret = xmlSchemaValidatorPushAttribute(vctxt,
 
27264
                NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
 
27265
                value, 1);
 
27266
            if (ret == -1) {
 
27267
                VERROR_INT("xmlSchemaSAXHandleStartElementNs",
 
27268
                    "calling xmlSchemaValidatorPushAttribute()");
 
27269
                goto internal_error;
 
27270
            }
 
27271
        }
 
27272
    }
 
27273
    /*
 
27274
    * Validate the element.
 
27275
    */
 
27276
    ret = xmlSchemaValidateElem(vctxt);
 
27277
    if (ret != 0) {
 
27278
        if (ret == -1) {
 
27279
            VERROR_INT("xmlSchemaSAXHandleStartElementNs",
 
27280
                "calling xmlSchemaValidateElem()");
 
27281
            goto internal_error;
 
27282
        }
 
27283
        goto exit;
 
27284
    }    
 
27285
 
 
27286
exit:
 
27287
    return;
 
27288
internal_error:
 
27289
    vctxt->err = -1;
 
27290
    xmlStopParser(vctxt->parserCtxt);
 
27291
    return;
 
27292
}
 
27293
 
 
27294
static void
 
27295
xmlSchemaSAXHandleEndElementNs(void *ctx,
 
27296
                               const xmlChar * localname ATTRIBUTE_UNUSED,
 
27297
                               const xmlChar * prefix ATTRIBUTE_UNUSED,
 
27298
                               const xmlChar * URI ATTRIBUTE_UNUSED)
 
27299
{
 
27300
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
 
27301
    int res;
 
27302
 
 
27303
    /*
 
27304
    * Skip elements if inside a "skip" wildcard or if invalid.
 
27305
    */
 
27306
    if (vctxt->skipDepth != -1) {
 
27307
        if (vctxt->depth > vctxt->skipDepth) {
 
27308
            vctxt->depth--;
 
27309
            return;
 
27310
        } else
 
27311
            vctxt->skipDepth = -1;
 
27312
    }
 
27313
    /*
 
27314
    * SAX VAL TODO: Just a temporary check.
 
27315
    */
 
27316
    if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
 
27317
        (!xmlStrEqual(vctxt->inode->nsName, URI))) {
 
27318
        VERROR_INT("xmlSchemaSAXHandleEndElementNs",
 
27319
            "elem pop mismatch");
 
27320
    }
 
27321
    res = xmlSchemaValidatorPopElem(vctxt);
 
27322
    if (res != 0) {
 
27323
        if (res < 0) {
 
27324
            VERROR_INT("xmlSchemaSAXHandleEndElementNs",
 
27325
                "calling xmlSchemaValidatorPopElem()");
 
27326
            goto internal_error;
 
27327
        }
 
27328
        goto exit;
 
27329
    }
 
27330
exit:
 
27331
    return;
 
27332
internal_error:
 
27333
    vctxt->err = -1;
 
27334
    xmlStopParser(vctxt->parserCtxt);
 
27335
    return;
 
27336
}
 
27337
 
 
27338
/************************************************************************
 
27339
 *                                                                      *
 
27340
 *                      Validation interfaces                           *
 
27341
 *                                                                      *
 
27342
 ************************************************************************/
 
27343
 
 
27344
/**
 
27345
 * xmlSchemaNewValidCtxt:
 
27346
 * @schema:  a precompiled XML Schemas
 
27347
 *
 
27348
 * Create an XML Schemas validation context based on the given schema.
 
27349
 *
 
27350
 * Returns the validation context or NULL in case of error
 
27351
 */
 
27352
xmlSchemaValidCtxtPtr
 
27353
xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
 
27354
{
 
27355
    xmlSchemaValidCtxtPtr ret;
 
27356
 
 
27357
    ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
 
27358
    if (ret == NULL) {
 
27359
        xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
 
27360
        return (NULL);
 
27361
    }
 
27362
    memset(ret, 0, sizeof(xmlSchemaValidCtxt));
 
27363
    ret->type = XML_SCHEMA_CTXT_VALIDATOR;
 
27364
    ret->dict = xmlDictCreate();
 
27365
    ret->nodeQNames = xmlSchemaItemListCreate();
 
27366
    ret->schema = schema;
 
27367
    return (ret);
 
27368
}
 
27369
 
 
27370
/**
 
27371
 * xmlSchemaClearValidCtxt:
 
27372
 * @ctxt: the schema validation context
 
27373
 *
 
27374
 * Free the resources associated to the schema validation context;
 
27375
 * leaves some fields alive intended for reuse of the context.
 
27376
 */
 
27377
static void
 
27378
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
 
27379
{
 
27380
    if (vctxt == NULL)
 
27381
        return;
 
27382
 
 
27383
    /*
 
27384
    * TODO: Should we clear the flags?
 
27385
    *   Might be problematic if one reuses the context
 
27386
    *   and assumes that the options remain the same.
 
27387
    */
 
27388
    vctxt->flags = 0;
 
27389
    vctxt->validationRoot = NULL;
 
27390
    vctxt->doc = NULL;
 
27391
#ifdef LIBXML_READER_ENABLED
 
27392
    vctxt->reader = NULL;
 
27393
#endif
 
27394
    vctxt->hasKeyrefs = 0;    
 
27395
 
 
27396
    if (vctxt->value != NULL) {
 
27397
        xmlSchemaFreeValue(vctxt->value);
 
27398
        vctxt->value = NULL;
 
27399
    }
 
27400
    /*
 
27401
    * Augmented IDC information.
 
27402
    */
 
27403
    if (vctxt->aidcs != NULL) {
 
27404
        xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
 
27405
        do {
 
27406
            next = cur->next;
 
27407
            xmlFree(cur);
 
27408
            cur = next;
 
27409
        } while (cur != NULL);
 
27410
        vctxt->aidcs = NULL;
 
27411
    }
 
27412
    if (vctxt->idcMatcherCache != NULL) {
 
27413
        xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
 
27414
 
 
27415
        while (matcher) {
 
27416
            tmp = matcher;
 
27417
            matcher = matcher->nextCached;
 
27418
            xmlSchemaIDCFreeMatcherList(tmp);
 
27419
        }
 
27420
        vctxt->idcMatcherCache = NULL;
 
27421
    }
 
27422
 
 
27423
 
 
27424
    if (vctxt->idcNodes != NULL) {
 
27425
        int i;
 
27426
        xmlSchemaPSVIIDCNodePtr item;
 
27427
 
 
27428
        for (i = 0; i < vctxt->nbIdcNodes; i++) {
 
27429
            item = vctxt->idcNodes[i];
 
27430
            xmlFree(item->keys);
 
27431
            xmlFree(item);
 
27432
        }
 
27433
        xmlFree(vctxt->idcNodes);
 
27434
        vctxt->idcNodes = NULL;
 
27435
        vctxt->nbIdcNodes = 0;
 
27436
        vctxt->sizeIdcNodes = 0;
 
27437
    }
 
27438
    /*
 
27439
    * Note that we won't delete the XPath state pool here.
 
27440
    */
 
27441
    if (vctxt->xpathStates != NULL) {
 
27442
        xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
 
27443
        vctxt->xpathStates = NULL;
 
27444
    }
 
27445
    /*
 
27446
    * Attribute info.
 
27447
    */
 
27448
    if (vctxt->nbAttrInfos != 0) {
 
27449
        xmlSchemaClearAttrInfos(vctxt);
 
27450
    }
 
27451
    /*
 
27452
    * Element info.
 
27453
    */
 
27454
    if (vctxt->elemInfos != NULL) {
 
27455
        int i;
 
27456
        xmlSchemaNodeInfoPtr ei;
 
27457
 
 
27458
        for (i = 0; i < vctxt->sizeElemInfos; i++) {
 
27459
            ei = vctxt->elemInfos[i];
 
27460
            if (ei == NULL)
 
27461
                break;
 
27462
            xmlSchemaClearElemInfo(vctxt, ei);
 
27463
        }
 
27464
    }    
 
27465
    xmlSchemaItemListClear(vctxt->nodeQNames);
 
27466
    /* Recreate the dict. */
 
27467
    xmlDictFree(vctxt->dict);
 
27468
    /*
 
27469
    * TODO: Is is save to recreate it? Do we have a scenario
 
27470
    * where the user provides the dict?
 
27471
    */
 
27472
    vctxt->dict = xmlDictCreate();
 
27473
}
 
27474
 
 
27475
/**
 
27476
 * xmlSchemaFreeValidCtxt:
 
27477
 * @ctxt:  the schema validation context
 
27478
 *
 
27479
 * Free the resources associated to the schema validation context
 
27480
 */
 
27481
void
 
27482
xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
 
27483
{
 
27484
    if (ctxt == NULL)
 
27485
        return;
 
27486
    if (ctxt->value != NULL)
 
27487
        xmlSchemaFreeValue(ctxt->value);
 
27488
    if (ctxt->pctxt != NULL)
 
27489
        xmlSchemaFreeParserCtxt(ctxt->pctxt);
 
27490
    if (ctxt->idcNodes != NULL) {
 
27491
        int i;
 
27492
        xmlSchemaPSVIIDCNodePtr item;
 
27493
 
 
27494
        for (i = 0; i < ctxt->nbIdcNodes; i++) {
 
27495
            item = ctxt->idcNodes[i];
 
27496
            xmlFree(item->keys);
 
27497
            xmlFree(item);
 
27498
        }
 
27499
        xmlFree(ctxt->idcNodes);
 
27500
    }
 
27501
    if (ctxt->idcKeys != NULL) {
 
27502
        int i;
 
27503
        for (i = 0; i < ctxt->nbIdcKeys; i++)
 
27504
            xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
 
27505
        xmlFree(ctxt->idcKeys);
 
27506
    }
 
27507
 
 
27508
    if (ctxt->xpathStates != NULL) {
 
27509
        xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
 
27510
        ctxt->xpathStates = NULL;
 
27511
    }
 
27512
    if (ctxt->xpathStatePool != NULL) {
 
27513
        xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
 
27514
        ctxt->xpathStatePool = NULL;
 
27515
    }
 
27516
 
 
27517
    /*
 
27518
    * Augmented IDC information.
 
27519
    */
 
27520
    if (ctxt->aidcs != NULL) {
 
27521
        xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
 
27522
        do {
 
27523
            next = cur->next;
 
27524
            xmlFree(cur);
 
27525
            cur = next;
 
27526
        } while (cur != NULL);
 
27527
    }
 
27528
    if (ctxt->attrInfos != NULL) {
 
27529
        int i;
 
27530
        xmlSchemaAttrInfoPtr attr;
 
27531
 
 
27532
        /* Just a paranoid call to the cleanup. */
 
27533
        if (ctxt->nbAttrInfos != 0)
 
27534
            xmlSchemaClearAttrInfos(ctxt);
 
27535
        for (i = 0; i < ctxt->sizeAttrInfos; i++) {
 
27536
            attr = ctxt->attrInfos[i];
 
27537
            xmlFree(attr);
 
27538
        }
 
27539
        xmlFree(ctxt->attrInfos);
 
27540
    }
 
27541
    if (ctxt->elemInfos != NULL) {
 
27542
        int i;
 
27543
        xmlSchemaNodeInfoPtr ei;
 
27544
 
 
27545
        for (i = 0; i < ctxt->sizeElemInfos; i++) {
 
27546
            ei = ctxt->elemInfos[i];
 
27547
            if (ei == NULL)
 
27548
                break;
 
27549
            xmlSchemaClearElemInfo(ctxt, ei);
 
27550
            xmlFree(ei);
 
27551
        }
 
27552
        xmlFree(ctxt->elemInfos);
 
27553
    }
 
27554
    if (ctxt->nodeQNames != NULL)
 
27555
        xmlSchemaItemListFree(ctxt->nodeQNames);
 
27556
    if (ctxt->dict != NULL)
 
27557
        xmlDictFree(ctxt->dict);
 
27558
    xmlFree(ctxt);
 
27559
}
 
27560
 
 
27561
/**
 
27562
 * xmlSchemaIsValid:
 
27563
 * @ctxt: the schema validation context
 
27564
 *
 
27565
 * Check if any error was detected during validation.
 
27566
 * 
 
27567
 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
 
27568
 *         of internal error.
 
27569
 */
 
27570
int
 
27571
xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
 
27572
{
 
27573
    if (ctxt == NULL)
 
27574
        return(-1);
 
27575
    return(ctxt->err == 0);
 
27576
}
 
27577
 
 
27578
/**
 
27579
 * xmlSchemaSetValidErrors:
 
27580
 * @ctxt:  a schema validation context
 
27581
 * @err:  the error function
 
27582
 * @warn: the warning function
 
27583
 * @ctx: the functions context
 
27584
 *
 
27585
 * Set the error and warning callback informations
 
27586
 */
 
27587
void
 
27588
xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
 
27589
                        xmlSchemaValidityErrorFunc err,
 
27590
                        xmlSchemaValidityWarningFunc warn, void *ctx)
 
27591
{
 
27592
    if (ctxt == NULL)
 
27593
        return;
 
27594
    ctxt->error = err;
 
27595
    ctxt->warning = warn;
 
27596
    ctxt->errCtxt = ctx;
 
27597
    if (ctxt->pctxt != NULL)
 
27598
        xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
 
27599
}
 
27600
 
 
27601
/**
 
27602
 * xmlSchemaSetValidStructuredErrors:
 
27603
 * @ctxt:  a schema validation context
 
27604
 * @serror:  the structured error function
 
27605
 * @ctx: the functions context
 
27606
 *
 
27607
 * Set the structured error callback
 
27608
 */
 
27609
void
 
27610
xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
 
27611
                                  xmlStructuredErrorFunc serror, void *ctx)
 
27612
{
 
27613
    if (ctxt == NULL)
 
27614
        return;
 
27615
        ctxt->serror = serror;
 
27616
    ctxt->error = NULL;
 
27617
    ctxt->warning = NULL;
 
27618
    ctxt->errCtxt = ctx;
 
27619
    if (ctxt->pctxt != NULL)
 
27620
        xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
 
27621
}
 
27622
 
 
27623
/**
 
27624
 * xmlSchemaGetValidErrors:
 
27625
 * @ctxt:       a XML-Schema validation context
 
27626
 * @err: the error function result
 
27627
 * @warn: the warning function result
 
27628
 * @ctx: the functions context result
 
27629
 *
 
27630
 * Get the error and warning callback informations
 
27631
 *
 
27632
 * Returns -1 in case of error and 0 otherwise
 
27633
 */
 
27634
int
 
27635
xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
 
27636
                        xmlSchemaValidityErrorFunc * err,
 
27637
                        xmlSchemaValidityWarningFunc * warn, void **ctx)
 
27638
{
 
27639
        if (ctxt == NULL)
 
27640
                return (-1);
 
27641
        if (err != NULL)
 
27642
                *err = ctxt->error;
 
27643
        if (warn != NULL)
 
27644
                *warn = ctxt->warning;
 
27645
        if (ctx != NULL)
 
27646
                *ctx = ctxt->errCtxt;
 
27647
        return (0);
 
27648
}
 
27649
 
 
27650
 
 
27651
/**
 
27652
 * xmlSchemaSetValidOptions:
 
27653
 * @ctxt:       a schema validation context
 
27654
 * @options: a combination of xmlSchemaValidOption
 
27655
 *
 
27656
 * Sets the options to be used during the validation.
 
27657
 *
 
27658
 * Returns 0 in case of success, -1 in case of an
 
27659
 * API error.
 
27660
 */
 
27661
int
 
27662
xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
 
27663
                         int options)
 
27664
 
 
27665
{
 
27666
    int i;
 
27667
 
 
27668
    if (ctxt == NULL)
 
27669
        return (-1);
 
27670
    /*
 
27671
    * WARNING: Change the start value if adding to the
 
27672
    * xmlSchemaValidOption.
 
27673
    * TODO: Is there an other, more easy to maintain,
 
27674
    * way?
 
27675
    */
 
27676
    for (i = 1; i < (int) sizeof(int) * 8; i++) {
 
27677
        if (options & 1<<i)
 
27678
            return (-1);
 
27679
    }
 
27680
    ctxt->options = options;
 
27681
    return (0);
 
27682
}
 
27683
 
 
27684
/**
 
27685
 * xmlSchemaValidCtxtGetOptions:
 
27686
 * @ctxt:       a schema validation context
 
27687
 *
 
27688
 * Get the validation context options.
 
27689
 *
 
27690
 * Returns the option combination or -1 on error.
 
27691
 */
 
27692
int
 
27693
xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
 
27694
 
 
27695
{
 
27696
    if (ctxt == NULL)
 
27697
        return (-1);
 
27698
    else
 
27699
        return (ctxt->options);
 
27700
}
 
27701
 
 
27702
static int
 
27703
xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
 
27704
{
 
27705
    xmlAttrPtr attr;
 
27706
    int ret = 0;
 
27707
    xmlSchemaNodeInfoPtr ielem = NULL;
 
27708
    xmlNodePtr node, valRoot;
 
27709
    const xmlChar *nsName;
 
27710
 
 
27711
    /* DOC VAL TODO: Move this to the start function. */
 
27712
    valRoot = xmlDocGetRootElement(vctxt->doc);
 
27713
    if (valRoot == NULL) {
 
27714
        /* VAL TODO: Error code? */
 
27715
        VERROR(1, NULL, "The document has no document element");
 
27716
        return (1);
 
27717
    }
 
27718
    vctxt->depth = -1;
 
27719
    vctxt->validationRoot = valRoot;
 
27720
    node = valRoot;
 
27721
    while (node != NULL) {
 
27722
        if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
 
27723
            goto next_sibling;
 
27724
        if (node->type == XML_ELEMENT_NODE) {
 
27725
 
 
27726
            /*
 
27727
            * Init the node-info.
 
27728
            */
 
27729
            vctxt->depth++;
 
27730
            if (xmlSchemaValidatorPushElem(vctxt) == -1)
 
27731
                goto internal_error;
 
27732
            ielem = vctxt->inode;
 
27733
            ielem->node = node;
 
27734
            ielem->nodeLine = node->line;
 
27735
            ielem->localName = node->name;
 
27736
            if (node->ns != NULL)
 
27737
                ielem->nsName = node->ns->href;
 
27738
            ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
 
27739
            /*
 
27740
            * Register attributes.
 
27741
            * DOC VAL TODO: We do not register namespace declaration
 
27742
            * attributes yet.
 
27743
            */
 
27744
            vctxt->nbAttrInfos = 0;
 
27745
            if (node->properties != NULL) {
 
27746
                attr = node->properties;
 
27747
                do {
 
27748
                    if (attr->ns != NULL)
 
27749
                        nsName = attr->ns->href;
 
27750
                    else
 
27751
                        nsName = NULL;
 
27752
                    ret = xmlSchemaValidatorPushAttribute(vctxt,
 
27753
                        (xmlNodePtr) attr,
 
27754
                        /* 
 
27755
                        * Note that we give it the line number of the
 
27756
                        * parent element.
 
27757
                        */
 
27758
                        ielem->nodeLine,
 
27759
                        attr->name, nsName, 0,
 
27760
                        xmlNodeListGetString(attr->doc, attr->children, 1), 1);
 
27761
                    if (ret == -1) {
 
27762
                        VERROR_INT("xmlSchemaDocWalk",
 
27763
                            "calling xmlSchemaValidatorPushAttribute()");
 
27764
                        goto internal_error;
 
27765
                    }
 
27766
                    attr = attr->next;
 
27767
                } while (attr);
 
27768
            }
 
27769
            /*
 
27770
            * Validate the element.
 
27771
            */
 
27772
            ret = xmlSchemaValidateElem(vctxt);
 
27773
            if (ret != 0) {
 
27774
                if (ret == -1) {
 
27775
                    VERROR_INT("xmlSchemaDocWalk",
 
27776
                        "calling xmlSchemaValidateElem()");
 
27777
                    goto internal_error;
 
27778
                }
 
27779
                /*
 
27780
                * Don't stop validation; just skip the content
 
27781
                * of this element.
 
27782
                */
 
27783
                goto leave_node;
 
27784
            }
 
27785
            if ((vctxt->skipDepth != -1) &&
 
27786
                (vctxt->depth >= vctxt->skipDepth))
 
27787
                goto leave_node;
 
27788
        } else if ((node->type == XML_TEXT_NODE) ||
 
27789
            (node->type == XML_CDATA_SECTION_NODE)) {
 
27790
            /*
 
27791
            * Process character content.
 
27792
            */
 
27793
            if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
 
27794
                ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
 
27795
            ret = xmlSchemaVPushText(vctxt, node->type, node->content,
 
27796
                -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
 
27797
            if (ret < 0) {
 
27798
                VERROR_INT("xmlSchemaVDocWalk",
 
27799
                    "calling xmlSchemaVPushText()");
 
27800
                goto internal_error;
 
27801
            }
 
27802
            /*
 
27803
            * DOC VAL TODO: Should we skip further validation of the
 
27804
            * element content here?
 
27805
            */
 
27806
        } else if ((node->type == XML_ENTITY_NODE) ||
 
27807
            (node->type == XML_ENTITY_REF_NODE)) {
 
27808
            /*
 
27809
            * DOC VAL TODO: What to do with entities?
 
27810
            */      
 
27811
            VERROR_INT("xmlSchemaVDocWalk",
 
27812
                "there is at least one entity reference in the node-tree "
 
27813
                "currently being validated. Processing of entities with "
 
27814
                "this XML Schema processor is not supported (yet). Please "
 
27815
                "substitute entities before validation.");
 
27816
            goto internal_error;
 
27817
        } else {
 
27818
            goto leave_node;
 
27819
            /*
 
27820
            * DOC VAL TODO: XInclude nodes, etc.
 
27821
            */
 
27822
        }
 
27823
        /*
 
27824
        * Walk the doc.
 
27825
        */
 
27826
        if (node->children != NULL) {
 
27827
            node = node->children;
 
27828
            continue;
 
27829
        }
 
27830
leave_node:
 
27831
        if (node->type == XML_ELEMENT_NODE) {
 
27832
            /*
 
27833
            * Leaving the scope of an element.
 
27834
            */
 
27835
            if (node != vctxt->inode->node) {
 
27836
                VERROR_INT("xmlSchemaVDocWalk",
 
27837
                    "element position mismatch");
 
27838
                goto internal_error;
 
27839
            }
 
27840
            ret = xmlSchemaValidatorPopElem(vctxt);
 
27841
            if (ret != 0) {
 
27842
                if (ret < 0) {
 
27843
                    VERROR_INT("xmlSchemaVDocWalk",
 
27844
                        "calling xmlSchemaValidatorPopElem()");
 
27845
                    goto internal_error;
 
27846
                }
 
27847
            }
 
27848
            if (node == valRoot)
 
27849
                goto exit;
 
27850
        }
 
27851
next_sibling:
 
27852
        if (node->next != NULL)
 
27853
            node = node->next;
 
27854
        else {
 
27855
            node = node->parent;
 
27856
            goto leave_node;
 
27857
        }
 
27858
    }
 
27859
 
 
27860
exit:
 
27861
    return (ret);
 
27862
internal_error:
 
27863
    return (-1);
 
27864
}
 
27865
 
 
27866
static int
 
27867
xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
 
27868
    /*
 
27869
    * Some initialization.
 
27870
    */    
 
27871
    vctxt->err = 0;
 
27872
    vctxt->nberrors = 0;
 
27873
    vctxt->depth = -1;
 
27874
    vctxt->skipDepth = -1;
 
27875
    vctxt->xsiAssemble = 0;
 
27876
    vctxt->hasKeyrefs = 0;
 
27877
#ifdef ENABLE_IDC_NODE_TABLES_TEST
 
27878
    vctxt->createIDCNodeTables = 1;
 
27879
#else
 
27880
    vctxt->createIDCNodeTables = 0;
 
27881
#endif
 
27882
    /*
 
27883
    * Create a schema + parser if necessary.
 
27884
    */
 
27885
    if (vctxt->schema == NULL) {
 
27886
        xmlSchemaParserCtxtPtr pctxt;
 
27887
        
 
27888
        vctxt->xsiAssemble = 1;
 
27889
        /* 
 
27890
        * If not schema was given then we will create a schema
 
27891
        * dynamically using XSI schema locations.
 
27892
        *
 
27893
        * Create the schema parser context.
 
27894
        */
 
27895
        if ((vctxt->pctxt == NULL) &&
 
27896
           (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
 
27897
           return (-1);
 
27898
        pctxt = vctxt->pctxt;
 
27899
        pctxt->xsiAssemble = 1;
 
27900
        /*
 
27901
        * Create the schema.
 
27902
        */
 
27903
        vctxt->schema = xmlSchemaNewSchema(pctxt);
 
27904
        if (vctxt->schema == NULL)
 
27905
            return (-1);                
 
27906
        /* 
 
27907
        * Create the schema construction context.
 
27908
        */
 
27909
        pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
 
27910
        if (pctxt->constructor == NULL)
 
27911
            return(-1);
 
27912
        pctxt->constructor->mainSchema = vctxt->schema;
 
27913
        /*
 
27914
        * Take ownership of the constructor to be able to free it.
 
27915
        */
 
27916
        pctxt->ownsConstructor = 1;
 
27917
    }   
 
27918
    /* 
 
27919
    * Augment the IDC definitions for the main schema and all imported ones 
 
27920
    * NOTE: main schema if the first in the imported list
 
27921
    */
 
27922
    xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
 
27923
    
 
27924
    return(0);
 
27925
}
 
27926
 
 
27927
static void
 
27928
xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
 
27929
    if (vctxt->xsiAssemble) {
 
27930
        if (vctxt->schema != NULL) {
 
27931
            xmlSchemaFree(vctxt->schema);
 
27932
            vctxt->schema = NULL;
 
27933
        }
 
27934
    }
 
27935
    xmlSchemaClearValidCtxt(vctxt);
 
27936
}
 
27937
 
 
27938
static int
 
27939
xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
 
27940
{
 
27941
    int ret = 0;
 
27942
 
 
27943
    if (xmlSchemaPreRun(vctxt) < 0)
 
27944
        return(-1);
 
27945
 
 
27946
    if (vctxt->doc != NULL) {
 
27947
        /*
 
27948
         * Tree validation.
 
27949
         */
 
27950
        ret = xmlSchemaVDocWalk(vctxt);
 
27951
#ifdef LIBXML_READER_ENABLED
 
27952
    } else if (vctxt->reader != NULL) {
 
27953
        /*
 
27954
         * XML Reader validation.
 
27955
         */
 
27956
#ifdef XML_SCHEMA_READER_ENABLED
 
27957
        ret = xmlSchemaVReaderWalk(vctxt);
 
27958
#endif
 
27959
#endif
 
27960
    } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
 
27961
        /*
 
27962
         * SAX validation.
 
27963
         */
 
27964
        ret = xmlParseDocument(vctxt->parserCtxt);
 
27965
    } else {
 
27966
        VERROR_INT("xmlSchemaVStart",
 
27967
            "no instance to validate");
 
27968
        ret = -1;
 
27969
    }
 
27970
 
 
27971
    xmlSchemaPostRun(vctxt);
 
27972
    if (ret == 0)
 
27973
        ret = vctxt->err;
 
27974
    return (ret);
 
27975
}
 
27976
 
 
27977
/**
 
27978
 * xmlSchemaValidateOneElement:
 
27979
 * @ctxt:  a schema validation context
 
27980
 * @elem:  an element node
 
27981
 *
 
27982
 * Validate a branch of a tree, starting with the given @elem.
 
27983
 *
 
27984
 * Returns 0 if the element and its subtree is valid, a positive error
 
27985
 * code number otherwise and -1 in case of an internal or API error.
 
27986
 */
 
27987
int
 
27988
xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
 
27989
{
 
27990
    if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
 
27991
        return (-1);
 
27992
 
 
27993
    if (ctxt->schema == NULL)
 
27994
        return (-1);
 
27995
 
 
27996
    ctxt->doc = elem->doc;
 
27997
    ctxt->node = elem;
 
27998
    ctxt->validationRoot = elem;
 
27999
    return(xmlSchemaVStart(ctxt));
 
28000
}
 
28001
 
 
28002
/**
 
28003
 * xmlSchemaValidateDoc:
 
28004
 * @ctxt:  a schema validation context
 
28005
 * @doc:  a parsed document tree
 
28006
 *
 
28007
 * Validate a document tree in memory.
 
28008
 *
 
28009
 * Returns 0 if the document is schemas valid, a positive error code
 
28010
 *     number otherwise and -1 in case of internal or API error.
 
28011
 */
 
28012
int
 
28013
xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
 
28014
{
 
28015
    if ((ctxt == NULL) || (doc == NULL))
 
28016
        return (-1);
 
28017
 
 
28018
    ctxt->doc = doc;
 
28019
    ctxt->node = xmlDocGetRootElement(doc);
 
28020
    if (ctxt->node == NULL) {
 
28021
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
 
28022
            XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
 
28023
            (xmlNodePtr) doc, NULL,
 
28024
            "The document has no document element", NULL, NULL);
 
28025
        return (ctxt->err);
 
28026
    }
 
28027
    ctxt->validationRoot = ctxt->node;
 
28028
    return (xmlSchemaVStart(ctxt));
 
28029
}
 
28030
 
 
28031
 
 
28032
/************************************************************************
 
28033
 *                                                                      *
 
28034
 *              Function and data for SAX streaming API                 *
 
28035
 *                                                                      *
 
28036
 ************************************************************************/
 
28037
typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
 
28038
typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
 
28039
 
 
28040
struct _xmlSchemaSplitSAXData {
 
28041
    xmlSAXHandlerPtr      user_sax;
 
28042
    void                 *user_data;
 
28043
    xmlSchemaValidCtxtPtr ctxt;
 
28044
    xmlSAXHandlerPtr      schemas_sax;
 
28045
};
 
28046
 
 
28047
#define XML_SAX_PLUG_MAGIC 0xdc43ba21
 
28048
 
 
28049
struct _xmlSchemaSAXPlug {
 
28050
    unsigned int magic;
 
28051
 
 
28052
    /* the original callbacks informations */
 
28053
    xmlSAXHandlerPtr     *user_sax_ptr;
 
28054
    xmlSAXHandlerPtr      user_sax;
 
28055
    void                **user_data_ptr;
 
28056
    void                 *user_data;
 
28057
 
 
28058
    /* the block plugged back and validation informations */
 
28059
    xmlSAXHandler         schemas_sax;
 
28060
    xmlSchemaValidCtxtPtr ctxt;
 
28061
};
 
28062
 
 
28063
/* All those functions just bounces to the user provided SAX handlers */
 
28064
static void
 
28065
internalSubsetSplit(void *ctx, const xmlChar *name,
 
28066
               const xmlChar *ExternalID, const xmlChar *SystemID)
 
28067
{
 
28068
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28069
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28070
        (ctxt->user_sax->internalSubset != NULL))
 
28071
        ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
 
28072
                                       SystemID);
 
28073
}
 
28074
 
 
28075
static int
 
28076
isStandaloneSplit(void *ctx)
 
28077
{
 
28078
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28079
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28080
        (ctxt->user_sax->isStandalone != NULL))
 
28081
        return(ctxt->user_sax->isStandalone(ctxt->user_data));
 
28082
    return(0);
 
28083
}
 
28084
 
 
28085
static int
 
28086
hasInternalSubsetSplit(void *ctx)
 
28087
{
 
28088
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28089
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28090
        (ctxt->user_sax->hasInternalSubset != NULL))
 
28091
        return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
 
28092
    return(0);
 
28093
}
 
28094
 
 
28095
static int
 
28096
hasExternalSubsetSplit(void *ctx)
 
28097
{
 
28098
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28099
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28100
        (ctxt->user_sax->hasExternalSubset != NULL))
 
28101
        return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
 
28102
    return(0);
 
28103
}
 
28104
 
 
28105
static void
 
28106
externalSubsetSplit(void *ctx, const xmlChar *name,
 
28107
               const xmlChar *ExternalID, const xmlChar *SystemID)
 
28108
{
 
28109
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28110
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28111
        (ctxt->user_sax->externalSubset != NULL))
 
28112
        ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
 
28113
                                       SystemID);
 
28114
}
 
28115
 
 
28116
static xmlParserInputPtr
 
28117
resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
 
28118
{
 
28119
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28120
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28121
        (ctxt->user_sax->resolveEntity != NULL))
 
28122
        return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
 
28123
                                             systemId));
 
28124
    return(NULL);
 
28125
}
 
28126
 
 
28127
static xmlEntityPtr
 
28128
getEntitySplit(void *ctx, const xmlChar *name)
 
28129
{
 
28130
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28131
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28132
        (ctxt->user_sax->getEntity != NULL))
 
28133
        return(ctxt->user_sax->getEntity(ctxt->user_data, name));
 
28134
    return(NULL);
 
28135
}
 
28136
 
 
28137
static xmlEntityPtr
 
28138
getParameterEntitySplit(void *ctx, const xmlChar *name)
 
28139
{
 
28140
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28141
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28142
        (ctxt->user_sax->getParameterEntity != NULL))
 
28143
        return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
 
28144
    return(NULL);
 
28145
}
 
28146
 
 
28147
 
 
28148
static void
 
28149
entityDeclSplit(void *ctx, const xmlChar *name, int type,
 
28150
          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
 
28151
{
 
28152
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28153
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28154
        (ctxt->user_sax->entityDecl != NULL))
 
28155
        ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
 
28156
                                   systemId, content);
 
28157
}
 
28158
 
 
28159
static void
 
28160
attributeDeclSplit(void *ctx, const xmlChar * elem,
 
28161
                   const xmlChar * name, int type, int def,
 
28162
                   const xmlChar * defaultValue, xmlEnumerationPtr tree)
 
28163
{
 
28164
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28165
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28166
        (ctxt->user_sax->attributeDecl != NULL)) {
 
28167
        ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
 
28168
                                      def, defaultValue, tree);
 
28169
    } else {
 
28170
        xmlFreeEnumeration(tree);
 
28171
    }
 
28172
}
 
28173
 
 
28174
static void
 
28175
elementDeclSplit(void *ctx, const xmlChar *name, int type,
 
28176
            xmlElementContentPtr content)
 
28177
{
 
28178
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28179
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28180
        (ctxt->user_sax->elementDecl != NULL))
 
28181
        ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
 
28182
}
 
28183
 
 
28184
static void
 
28185
notationDeclSplit(void *ctx, const xmlChar *name,
 
28186
             const xmlChar *publicId, const xmlChar *systemId)
 
28187
{
 
28188
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28189
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28190
        (ctxt->user_sax->notationDecl != NULL))
 
28191
        ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
 
28192
                                     systemId);
 
28193
}
 
28194
 
 
28195
static void
 
28196
unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
 
28197
                   const xmlChar *publicId, const xmlChar *systemId,
 
28198
                   const xmlChar *notationName)
 
28199
{
 
28200
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28201
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28202
        (ctxt->user_sax->unparsedEntityDecl != NULL))
 
28203
        ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
 
28204
                                           systemId, notationName);
 
28205
}
 
28206
 
 
28207
static void
 
28208
setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
 
28209
{
 
28210
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28211
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28212
        (ctxt->user_sax->setDocumentLocator != NULL))
 
28213
        ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
 
28214
}
 
28215
 
 
28216
static void
 
28217
startDocumentSplit(void *ctx)
 
28218
{
 
28219
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28220
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28221
        (ctxt->user_sax->startDocument != NULL))
 
28222
        ctxt->user_sax->startDocument(ctxt->user_data);
 
28223
}
 
28224
 
 
28225
static void
 
28226
endDocumentSplit(void *ctx)
 
28227
{
 
28228
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28229
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28230
        (ctxt->user_sax->endDocument != NULL))
 
28231
        ctxt->user_sax->endDocument(ctxt->user_data);
 
28232
}
 
28233
 
 
28234
static void
 
28235
processingInstructionSplit(void *ctx, const xmlChar *target,
 
28236
                      const xmlChar *data)
 
28237
{
 
28238
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28239
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28240
        (ctxt->user_sax->processingInstruction != NULL))
 
28241
        ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
 
28242
}
 
28243
 
 
28244
static void
 
28245
commentSplit(void *ctx, const xmlChar *value)
 
28246
{
 
28247
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28248
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28249
        (ctxt->user_sax->comment != NULL))
 
28250
        ctxt->user_sax->comment(ctxt->user_data, value);
 
28251
}
 
28252
 
 
28253
/*
 
28254
 * Varargs error callbacks to the user application, harder ...
 
28255
 */
 
28256
 
 
28257
static void XMLCDECL
 
28258
warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
 
28259
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28260
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28261
        (ctxt->user_sax->warning != NULL)) {
 
28262
        TODO
 
28263
    }
 
28264
}
 
28265
static void XMLCDECL
 
28266
errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
 
28267
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28268
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28269
        (ctxt->user_sax->error != NULL)) {
 
28270
        TODO
 
28271
    }
 
28272
}
 
28273
static void XMLCDECL
 
28274
fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
 
28275
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28276
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28277
        (ctxt->user_sax->fatalError != NULL)) {
 
28278
        TODO
 
28279
    }
 
28280
}
 
28281
 
 
28282
/*
 
28283
 * Those are function where both the user handler and the schemas handler
 
28284
 * need to be called.
 
28285
 */
 
28286
static void
 
28287
charactersSplit(void *ctx, const xmlChar *ch, int len)
 
28288
{
 
28289
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28290
    if (ctxt == NULL)
 
28291
        return;
 
28292
    if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
 
28293
        ctxt->user_sax->characters(ctxt->user_data, ch, len);
 
28294
    if (ctxt->ctxt != NULL)
 
28295
        xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
 
28296
}
 
28297
 
 
28298
static void
 
28299
ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
 
28300
{
 
28301
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28302
    if (ctxt == NULL)
 
28303
        return;
 
28304
    if ((ctxt->user_sax != NULL) &&
 
28305
        (ctxt->user_sax->ignorableWhitespace != NULL))
 
28306
        ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
 
28307
    if (ctxt->ctxt != NULL)
 
28308
        xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
 
28309
}
 
28310
 
 
28311
static void
 
28312
cdataBlockSplit(void *ctx, const xmlChar *value, int len)
 
28313
{
 
28314
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28315
    if (ctxt == NULL)
 
28316
        return;
 
28317
    if ((ctxt->user_sax != NULL) &&
 
28318
        (ctxt->user_sax->cdataBlock != NULL))
 
28319
        ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
 
28320
    if (ctxt->ctxt != NULL)
 
28321
        xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
 
28322
}
 
28323
 
 
28324
static void
 
28325
referenceSplit(void *ctx, const xmlChar *name)
 
28326
{
 
28327
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28328
    if (ctxt == NULL)
 
28329
        return;
 
28330
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
 
28331
        (ctxt->user_sax->reference != NULL))
 
28332
        ctxt->user_sax->reference(ctxt->user_data, name);
 
28333
    if (ctxt->ctxt != NULL)
 
28334
        xmlSchemaSAXHandleReference(ctxt->user_data, name);
 
28335
}
 
28336
 
 
28337
static void
 
28338
startElementNsSplit(void *ctx, const xmlChar * localname, 
 
28339
                    const xmlChar * prefix, const xmlChar * URI, 
 
28340
                    int nb_namespaces, const xmlChar ** namespaces, 
 
28341
                    int nb_attributes, int nb_defaulted, 
 
28342
                    const xmlChar ** attributes) {
 
28343
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28344
    if (ctxt == NULL)
 
28345
        return;
 
28346
    if ((ctxt->user_sax != NULL) &&
 
28347
        (ctxt->user_sax->startElementNs != NULL))
 
28348
        ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
 
28349
                                       URI, nb_namespaces, namespaces,
 
28350
                                       nb_attributes, nb_defaulted,
 
28351
                                       attributes);
 
28352
    if (ctxt->ctxt != NULL)
 
28353
        xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
 
28354
                                         URI, nb_namespaces, namespaces,
 
28355
                                         nb_attributes, nb_defaulted,
 
28356
                                         attributes);
 
28357
}
 
28358
 
 
28359
static void
 
28360
endElementNsSplit(void *ctx, const xmlChar * localname, 
 
28361
                    const xmlChar * prefix, const xmlChar * URI) {
 
28362
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
 
28363
    if (ctxt == NULL)
 
28364
        return;
 
28365
    if ((ctxt->user_sax != NULL) &&
 
28366
        (ctxt->user_sax->endElementNs != NULL))
 
28367
        ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
 
28368
    if (ctxt->ctxt != NULL)
 
28369
        xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
 
28370
}
 
28371
 
 
28372
/**
 
28373
 * xmlSchemaSAXPlug:
 
28374
 * @ctxt:  a schema validation context
 
28375
 * @sax:  a pointer to the original xmlSAXHandlerPtr
 
28376
 * @user_data:  a pointer to the original SAX user data pointer
 
28377
 *
 
28378
 * Plug a SAX based validation layer in a SAX parsing event flow.
 
28379
 * The original @saxptr and @dataptr data are replaced by new pointers
 
28380
 * but the calls to the original will be maintained.
 
28381
 *
 
28382
 * Returns a pointer to a data structure needed to unplug the validation layer
 
28383
 *         or NULL in case of errors.
 
28384
 */
 
28385
xmlSchemaSAXPlugPtr
 
28386
xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
 
28387
                 xmlSAXHandlerPtr *sax, void **user_data)
 
28388
{
 
28389
    xmlSchemaSAXPlugPtr ret;
 
28390
    xmlSAXHandlerPtr old_sax;
 
28391
 
 
28392
    if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
 
28393
        return(NULL);
 
28394
 
 
28395
    /*
 
28396
     * We only allow to plug into SAX2 event streams
 
28397
     */
 
28398
    old_sax = *sax;
 
28399
    if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
 
28400
        return(NULL);
 
28401
    if ((old_sax != NULL) && 
 
28402
        (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
 
28403
        ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
 
28404
        return(NULL);
 
28405
 
 
28406
    /*
 
28407
     * everything seems right allocate the local data needed for that layer
 
28408
     */
 
28409
    ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
 
28410
    if (ret == NULL) {
 
28411
        return(NULL);
 
28412
    }
 
28413
    memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
 
28414
    ret->magic = XML_SAX_PLUG_MAGIC;
 
28415
    ret->schemas_sax.initialized = XML_SAX2_MAGIC;
 
28416
    ret->ctxt = ctxt;
 
28417
    ret->user_sax_ptr = sax;
 
28418
    ret->user_sax = old_sax;
 
28419
    if (old_sax == NULL) {      
 
28420
        /*
 
28421
         * go direct, no need for the split block and functions.
 
28422
         */
 
28423
        ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
 
28424
        ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
 
28425
        /*
 
28426
         * Note that we use the same text-function for both, to prevent
 
28427
         * the parser from testing for ignorable whitespace.
 
28428
         */
 
28429
        ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
 
28430
        ret->schemas_sax.characters = xmlSchemaSAXHandleText;
 
28431
 
 
28432
        ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
 
28433
        ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
 
28434
 
 
28435
        ret->user_data = ctxt;
 
28436
        *user_data = ctxt;
 
28437
    } else {
 
28438
       /*
 
28439
        * for each callback unused by Schemas initialize it to the Split
 
28440
        * routine only if non NULL in the user block, this can speed up 
 
28441
        * things at the SAX level.
 
28442
        */
 
28443
        if (old_sax->internalSubset != NULL)
 
28444
            ret->schemas_sax.internalSubset = internalSubsetSplit;
 
28445
        if (old_sax->isStandalone != NULL)
 
28446
            ret->schemas_sax.isStandalone = isStandaloneSplit;
 
28447
        if (old_sax->hasInternalSubset != NULL)
 
28448
            ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
 
28449
        if (old_sax->hasExternalSubset != NULL)
 
28450
            ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
 
28451
        if (old_sax->resolveEntity != NULL)
 
28452
            ret->schemas_sax.resolveEntity = resolveEntitySplit;
 
28453
        if (old_sax->getEntity != NULL)
 
28454
            ret->schemas_sax.getEntity = getEntitySplit;
 
28455
        if (old_sax->entityDecl != NULL)
 
28456
            ret->schemas_sax.entityDecl = entityDeclSplit;
 
28457
        if (old_sax->notationDecl != NULL)
 
28458
            ret->schemas_sax.notationDecl = notationDeclSplit;
 
28459
        if (old_sax->attributeDecl != NULL)
 
28460
            ret->schemas_sax.attributeDecl = attributeDeclSplit;
 
28461
        if (old_sax->elementDecl != NULL)
 
28462
            ret->schemas_sax.elementDecl = elementDeclSplit;
 
28463
        if (old_sax->unparsedEntityDecl != NULL)
 
28464
            ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
 
28465
        if (old_sax->setDocumentLocator != NULL)
 
28466
            ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
 
28467
        if (old_sax->startDocument != NULL)
 
28468
            ret->schemas_sax.startDocument = startDocumentSplit;
 
28469
        if (old_sax->endDocument != NULL)
 
28470
            ret->schemas_sax.endDocument = endDocumentSplit;
 
28471
        if (old_sax->processingInstruction != NULL)
 
28472
            ret->schemas_sax.processingInstruction = processingInstructionSplit;
 
28473
        if (old_sax->comment != NULL)
 
28474
            ret->schemas_sax.comment = commentSplit;
 
28475
        if (old_sax->warning != NULL)
 
28476
            ret->schemas_sax.warning = warningSplit;
 
28477
        if (old_sax->error != NULL)
 
28478
            ret->schemas_sax.error = errorSplit;
 
28479
        if (old_sax->fatalError != NULL)
 
28480
            ret->schemas_sax.fatalError = fatalErrorSplit;
 
28481
        if (old_sax->getParameterEntity != NULL)
 
28482
            ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
 
28483
        if (old_sax->externalSubset != NULL)
 
28484
            ret->schemas_sax.externalSubset = externalSubsetSplit;
 
28485
 
 
28486
        /*
 
28487
         * the 6 schemas callback have to go to the splitter functions
 
28488
         * Note that we use the same text-function for ignorableWhitespace
 
28489
         * if possible, to prevent the parser from testing for ignorable
 
28490
         * whitespace.
 
28491
         */
 
28492
        ret->schemas_sax.characters = charactersSplit;
 
28493
        if ((old_sax->ignorableWhitespace != NULL) &&
 
28494
            (old_sax->ignorableWhitespace != old_sax->characters))
 
28495
            ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
 
28496
        else
 
28497
            ret->schemas_sax.ignorableWhitespace = charactersSplit;
 
28498
        ret->schemas_sax.cdataBlock = cdataBlockSplit;
 
28499
        ret->schemas_sax.reference = referenceSplit;
 
28500
        ret->schemas_sax.startElementNs = startElementNsSplit;
 
28501
        ret->schemas_sax.endElementNs = endElementNsSplit;
 
28502
 
 
28503
        ret->user_data_ptr = user_data;
 
28504
        ret->user_data = *user_data;
 
28505
        *user_data = ret;
 
28506
    }
 
28507
 
 
28508
    /*
 
28509
     * plug the pointers back.
 
28510
     */
 
28511
    *sax = &(ret->schemas_sax);
 
28512
    ctxt->sax = *sax;
 
28513
    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
 
28514
    xmlSchemaPreRun(ctxt);
 
28515
    return(ret);
 
28516
}
 
28517
 
 
28518
/**
 
28519
 * xmlSchemaSAXUnplug:
 
28520
 * @plug:  a data structure returned by xmlSchemaSAXPlug
 
28521
 *
 
28522
 * Unplug a SAX based validation layer in a SAX parsing event flow.
 
28523
 * The original pointers used in the call are restored.
 
28524
 *
 
28525
 * Returns 0 in case of success and -1 in case of failure.
 
28526
 */
 
28527
int
 
28528
xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
 
28529
{
 
28530
    xmlSAXHandlerPtr *sax;
 
28531
    void **user_data;
 
28532
 
 
28533
    if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
 
28534
        return(-1);
 
28535
    plug->magic = 0;
 
28536
 
 
28537
    xmlSchemaPostRun(plug->ctxt);
 
28538
    /* restore the data */
 
28539
    sax = plug->user_sax_ptr;
 
28540
    *sax = plug->user_sax;
 
28541
    if (plug->user_sax != NULL) {
 
28542
        user_data = plug->user_data_ptr;
 
28543
        *user_data = plug->user_data;
 
28544
    }
 
28545
 
 
28546
    /* free and return */
 
28547
    xmlFree(plug);
 
28548
    return(0);
 
28549
}
 
28550
 
 
28551
/**
 
28552
 * xmlSchemaValidateStream:
 
28553
 * @ctxt:  a schema validation context
 
28554
 * @input:  the input to use for reading the data
 
28555
 * @enc:  an optional encoding information
 
28556
 * @sax:  a SAX handler for the resulting events
 
28557
 * @user_data:  the context to provide to the SAX handler.
 
28558
 *
 
28559
 * Validate an input based on a flow of SAX event from the parser
 
28560
 * and forward the events to the @sax handler with the provided @user_data
 
28561
 * the user provided @sax handler must be a SAX2 one.
 
28562
 *
 
28563
 * Returns 0 if the document is schemas valid, a positive error code
 
28564
 *     number otherwise and -1 in case of internal or API error.
 
28565
 */
 
28566
int
 
28567
xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
 
28568
                        xmlParserInputBufferPtr input, xmlCharEncoding enc,
 
28569
                        xmlSAXHandlerPtr sax, void *user_data)
 
28570
{
 
28571
    xmlSchemaSAXPlugPtr plug = NULL;
 
28572
    xmlSAXHandlerPtr old_sax = NULL;
 
28573
    xmlParserCtxtPtr pctxt = NULL;
 
28574
    xmlParserInputPtr inputStream = NULL;
 
28575
    int ret;
 
28576
 
 
28577
    if ((ctxt == NULL) || (input == NULL))
 
28578
        return (-1);
 
28579
 
 
28580
    /*
 
28581
     * prepare the parser
 
28582
     */
 
28583
    pctxt = xmlNewParserCtxt();
 
28584
    if (pctxt == NULL)
 
28585
        return (-1);
 
28586
    old_sax = pctxt->sax;
 
28587
    pctxt->sax = sax;
 
28588
    pctxt->userData = user_data;
 
28589
#if 0
 
28590
    if (options)
 
28591
        xmlCtxtUseOptions(pctxt, options);
 
28592
#endif
 
28593
    pctxt->linenumbers = 1;    
 
28594
 
 
28595
    inputStream = xmlNewIOInputStream(pctxt, input, enc);;
 
28596
    if (inputStream == NULL) {
 
28597
        ret = -1;
 
28598
        goto done;
 
28599
    }
 
28600
    inputPush(pctxt, inputStream);
 
28601
    ctxt->parserCtxt = pctxt;
 
28602
    ctxt->input = input;
 
28603
 
 
28604
    /*
 
28605
     * Plug the validation and launch the parsing
 
28606
     */
 
28607
    plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
 
28608
    if (plug == NULL) {
 
28609
        ret = -1;
 
28610
        goto done;
 
28611
    }
 
28612
    ctxt->input = input;
 
28613
    ctxt->enc = enc;
 
28614
    ctxt->sax = pctxt->sax;
 
28615
    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
 
28616
    ret = xmlSchemaVStart(ctxt);
 
28617
 
 
28618
    if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
 
28619
        ret = ctxt->parserCtxt->errNo;
 
28620
        if (ret == 0)
 
28621
            ret = 1;
 
28622
    }    
 
28623
 
 
28624
done:
 
28625
    ctxt->parserCtxt = NULL;
 
28626
    ctxt->sax = NULL;
 
28627
    ctxt->input = NULL;
 
28628
    if (plug != NULL) {
 
28629
        xmlSchemaSAXUnplug(plug);
 
28630
    }
 
28631
    /* cleanup */
 
28632
    if (pctxt != NULL) {
 
28633
        pctxt->sax = old_sax;
 
28634
        xmlFreeParserCtxt(pctxt);
 
28635
    }
 
28636
    return (ret);
 
28637
}
 
28638
 
 
28639
/**
 
28640
 * xmlSchemaValidateFile:
 
28641
 * @ctxt: a schema validation context
 
28642
 * @filename: the URI of the instance
 
28643
 * @options: a future set of options, currently unused
 
28644
 *
 
28645
 * Do a schemas validation of the given resource, it will use the
 
28646
 * SAX streamable validation internally.
 
28647
 *
 
28648
 * Returns 0 if the document is valid, a positive error code
 
28649
 *     number otherwise and -1 in case of an internal or API error.
 
28650
 */
 
28651
int
 
28652
xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
 
28653
                      const char * filename,
 
28654
                      int options ATTRIBUTE_UNUSED)
 
28655
{
 
28656
    int ret;
 
28657
    xmlParserInputBufferPtr input;
 
28658
 
 
28659
    if ((ctxt == NULL) || (filename == NULL))
 
28660
        return (-1);
 
28661
    
 
28662
    input = xmlParserInputBufferCreateFilename(filename,
 
28663
        XML_CHAR_ENCODING_NONE);
 
28664
    if (input == NULL)
 
28665
        return (-1);
 
28666
    ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
 
28667
        NULL, NULL);    
 
28668
    return (ret);
 
28669
}
 
28670
 
 
28671
#define bottom_xmlschemas
 
28672
#include "elfgcchack.h"
 
28673
#endif /* LIBXML_SCHEMAS_ENABLED */