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