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