Home | History | Annotate | Download | only in libxml2
      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 xmlSchemaIsBlank(xmlChar * str, int len)
   4988 {
   4989     if (str == NULL)
   4990         return (1);
   4991     if (len < 0) {
   4992 	while (*str != 0) {
   4993 	    if (!(IS_BLANK_CH(*str)))
   4994 		return (0);
   4995 	    str++;
   4996 	}
   4997     } else while ((*str != 0) && (len != 0)) {
   4998 	if (!(IS_BLANK_CH(*str)))
   4999 	    return (0);
   5000 	str++;
   5001 	len--;
   5002     }
   5003 
   5004     return (1);
   5005 }
   5006 
   5007 #define WXS_COMP_NAME(c, t) ((t) (c))->name
   5008 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
   5009 /*
   5010 * xmlSchemaFindRedefCompInGraph:
   5011 * ATTENTION TODO: This uses pointer comp. for strings.
   5012 */
   5013 static xmlSchemaBasicItemPtr
   5014 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
   5015 			      xmlSchemaTypeType type,
   5016 			      const xmlChar *name,
   5017 			      const xmlChar *nsName)
   5018 {
   5019     xmlSchemaBasicItemPtr ret;
   5020     int i;
   5021 
   5022     if ((bucket == NULL) || (name == NULL))
   5023 	return(NULL);
   5024     if ((bucket->globals == NULL) ||
   5025 	(bucket->globals->nbItems == 0))
   5026 	goto subschemas;
   5027     /*
   5028     * Search in global components.
   5029     */
   5030     for (i = 0; i < bucket->globals->nbItems; i++) {
   5031 	ret = bucket->globals->items[i];
   5032 	if (ret->type == type) {
   5033 	    switch (type) {
   5034 		case XML_SCHEMA_TYPE_COMPLEX:
   5035 		case XML_SCHEMA_TYPE_SIMPLE:
   5036 		    if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
   5037 			(WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
   5038 			nsName))
   5039 		    {
   5040 			return(ret);
   5041 		    }
   5042 		    break;
   5043 		case XML_SCHEMA_TYPE_GROUP:
   5044 		    if ((WXS_COMP_NAME(ret,
   5045 			    xmlSchemaModelGroupDefPtr) == name) &&
   5046 			(WXS_COMP_TNS(ret,
   5047 			    xmlSchemaModelGroupDefPtr) == nsName))
   5048 		    {
   5049 			return(ret);
   5050 		    }
   5051 		    break;
   5052 		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   5053 		    if ((WXS_COMP_NAME(ret,
   5054 			    xmlSchemaAttributeGroupPtr) == name) &&
   5055 			(WXS_COMP_TNS(ret,
   5056 			    xmlSchemaAttributeGroupPtr) == nsName))
   5057 		    {
   5058 			return(ret);
   5059 		    }
   5060 		    break;
   5061 		default:
   5062 		    /* Should not be hit. */
   5063 		    return(NULL);
   5064 	    }
   5065 	}
   5066     }
   5067 subschemas:
   5068     /*
   5069     * Process imported/included schemas.
   5070     */
   5071     if (bucket->relations != NULL) {
   5072 	xmlSchemaSchemaRelationPtr rel = bucket->relations;
   5073 
   5074 	/*
   5075 	* TODO: Marking the bucket will not avoid multiple searches
   5076 	* in the same schema, but avoids at least circularity.
   5077 	*/
   5078 	bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
   5079 	do {
   5080 	    if ((rel->bucket != NULL) &&
   5081 		((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
   5082 		ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
   5083 		    type, name, nsName);
   5084 		if (ret != NULL)
   5085 		    return(ret);
   5086 	    }
   5087 	    rel = rel->next;
   5088 	} while (rel != NULL);
   5089 	 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
   5090     }
   5091     return(NULL);
   5092 }
   5093 
   5094 /**
   5095  * xmlSchemaAddNotation:
   5096  * @ctxt:  a schema parser context
   5097  * @schema:  the schema being built
   5098  * @name:  the item name
   5099  *
   5100  * Add an XML schema annotation declaration
   5101  * *WARNING* this interface is highly subject to change
   5102  *
   5103  * Returns the new struture or NULL in case of error
   5104  */
   5105 static xmlSchemaNotationPtr
   5106 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5107                      const xmlChar *name, const xmlChar *nsName,
   5108 		     xmlNodePtr node ATTRIBUTE_UNUSED)
   5109 {
   5110     xmlSchemaNotationPtr ret = NULL;
   5111 
   5112     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
   5113         return (NULL);
   5114 
   5115     ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
   5116     if (ret == NULL) {
   5117         xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
   5118         return (NULL);
   5119     }
   5120     memset(ret, 0, sizeof(xmlSchemaNotation));
   5121     ret->type = XML_SCHEMA_TYPE_NOTATION;
   5122     ret->name = name;
   5123     ret->targetNamespace = nsName;
   5124     /* TODO: do we need the node to be set?
   5125     * ret->node = node;*/
   5126     WXS_ADD_GLOBAL(ctxt, ret);
   5127     return (ret);
   5128 }
   5129 
   5130 /**
   5131  * xmlSchemaAddAttribute:
   5132  * @ctxt:  a schema parser context
   5133  * @schema:  the schema being built
   5134  * @name:  the item name
   5135  * @namespace:  the namespace
   5136  *
   5137  * Add an XML schema Attrribute declaration
   5138  * *WARNING* this interface is highly subject to change
   5139  *
   5140  * Returns the new struture or NULL in case of error
   5141  */
   5142 static xmlSchemaAttributePtr
   5143 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5144                       const xmlChar * name, const xmlChar * nsName,
   5145 		      xmlNodePtr node, int topLevel)
   5146 {
   5147     xmlSchemaAttributePtr ret = NULL;
   5148 
   5149     if ((ctxt == NULL) || (schema == NULL))
   5150         return (NULL);
   5151 
   5152     ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
   5153     if (ret == NULL) {
   5154         xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
   5155         return (NULL);
   5156     }
   5157     memset(ret, 0, sizeof(xmlSchemaAttribute));
   5158     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
   5159     ret->node = node;
   5160     ret->name = name;
   5161     ret->targetNamespace = nsName;
   5162 
   5163     if (topLevel)
   5164 	WXS_ADD_GLOBAL(ctxt, ret);
   5165     else
   5166 	WXS_ADD_LOCAL(ctxt, ret);
   5167     WXS_ADD_PENDING(ctxt, ret);
   5168     return (ret);
   5169 }
   5170 
   5171 /**
   5172  * xmlSchemaAddAttributeUse:
   5173  * @ctxt:  a schema parser context
   5174  * @schema:  the schema being built
   5175  * @name:  the item name
   5176  * @namespace:  the namespace
   5177  *
   5178  * Add an XML schema Attrribute declaration
   5179  * *WARNING* this interface is highly subject to change
   5180  *
   5181  * Returns the new struture or NULL in case of error
   5182  */
   5183 static xmlSchemaAttributeUsePtr
   5184 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
   5185 			 xmlNodePtr node)
   5186 {
   5187     xmlSchemaAttributeUsePtr ret = NULL;
   5188 
   5189     if (pctxt == NULL)
   5190         return (NULL);
   5191 
   5192     ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
   5193     if (ret == NULL) {
   5194         xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
   5195         return (NULL);
   5196     }
   5197     memset(ret, 0, sizeof(xmlSchemaAttributeUse));
   5198     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
   5199     ret->node = node;
   5200 
   5201     WXS_ADD_LOCAL(pctxt, ret);
   5202     return (ret);
   5203 }
   5204 
   5205 /*
   5206 * xmlSchemaAddRedef:
   5207 *
   5208 * Adds a redefinition information. This is used at a later stage to:
   5209 * resolve references to the redefined components and to check constraints.
   5210 */
   5211 static xmlSchemaRedefPtr
   5212 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
   5213 		  xmlSchemaBucketPtr targetBucket,
   5214 		  void *item,
   5215 		  const xmlChar *refName,
   5216 		  const xmlChar *refTargetNs)
   5217 {
   5218     xmlSchemaRedefPtr ret;
   5219 
   5220     ret = (xmlSchemaRedefPtr)
   5221 	xmlMalloc(sizeof(xmlSchemaRedef));
   5222     if (ret == NULL) {
   5223 	xmlSchemaPErrMemory(pctxt,
   5224 	    "allocating redefinition info", NULL);
   5225 	return (NULL);
   5226     }
   5227     memset(ret, 0, sizeof(xmlSchemaRedef));
   5228     ret->item = item;
   5229     ret->targetBucket = targetBucket;
   5230     ret->refName = refName;
   5231     ret->refTargetNs = refTargetNs;
   5232     if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
   5233 	WXS_CONSTRUCTOR(pctxt)->redefs = ret;
   5234     else
   5235 	WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
   5236     WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
   5237 
   5238     return (ret);
   5239 }
   5240 
   5241 /**
   5242  * xmlSchemaAddAttributeGroupDefinition:
   5243  * @ctxt:  a schema parser context
   5244  * @schema:  the schema being built
   5245  * @name:  the item name
   5246  * @nsName:  the target namespace
   5247  * @node: the corresponding node
   5248  *
   5249  * Add an XML schema Attrribute Group definition.
   5250  *
   5251  * Returns the new struture or NULL in case of error
   5252  */
   5253 static xmlSchemaAttributeGroupPtr
   5254 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
   5255                            xmlSchemaPtr schema ATTRIBUTE_UNUSED,
   5256 			   const xmlChar *name,
   5257 			   const xmlChar *nsName,
   5258 			   xmlNodePtr node)
   5259 {
   5260     xmlSchemaAttributeGroupPtr ret = NULL;
   5261 
   5262     if ((pctxt == NULL) || (name == NULL))
   5263         return (NULL);
   5264 
   5265     ret = (xmlSchemaAttributeGroupPtr)
   5266         xmlMalloc(sizeof(xmlSchemaAttributeGroup));
   5267     if (ret == NULL) {
   5268 	xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
   5269 	return (NULL);
   5270     }
   5271     memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
   5272     ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
   5273     ret->name = name;
   5274     ret->targetNamespace = nsName;
   5275     ret->node = node;
   5276 
   5277     /* TODO: Remove the flag. */
   5278     ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
   5279     if (pctxt->isRedefine) {
   5280 	pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
   5281 	    ret, name, nsName);
   5282 	if (pctxt->redef == NULL) {
   5283 	    xmlFree(ret);
   5284 	    return(NULL);
   5285 	}
   5286 	pctxt->redefCounter = 0;
   5287     }
   5288     WXS_ADD_GLOBAL(pctxt, ret);
   5289     WXS_ADD_PENDING(pctxt, ret);
   5290     return (ret);
   5291 }
   5292 
   5293 /**
   5294  * xmlSchemaAddElement:
   5295  * @ctxt:  a schema parser context
   5296  * @schema:  the schema being built
   5297  * @name:  the type name
   5298  * @namespace:  the type namespace
   5299  *
   5300  * Add an XML schema Element declaration
   5301  * *WARNING* this interface is highly subject to change
   5302  *
   5303  * Returns the new struture or NULL in case of error
   5304  */
   5305 static xmlSchemaElementPtr
   5306 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
   5307                     const xmlChar * name, const xmlChar * nsName,
   5308 		    xmlNodePtr node, int topLevel)
   5309 {
   5310     xmlSchemaElementPtr ret = NULL;
   5311 
   5312     if ((ctxt == NULL) || (name == NULL))
   5313         return (NULL);
   5314 
   5315     ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
   5316     if (ret == NULL) {
   5317         xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
   5318         return (NULL);
   5319     }
   5320     memset(ret, 0, sizeof(xmlSchemaElement));
   5321     ret->type = XML_SCHEMA_TYPE_ELEMENT;
   5322     ret->name = name;
   5323     ret->targetNamespace = nsName;
   5324     ret->node = node;
   5325 
   5326     if (topLevel)
   5327 	WXS_ADD_GLOBAL(ctxt, ret);
   5328     else
   5329 	WXS_ADD_LOCAL(ctxt, ret);
   5330     WXS_ADD_PENDING(ctxt, ret);
   5331     return (ret);
   5332 }
   5333 
   5334 /**
   5335  * xmlSchemaAddType:
   5336  * @ctxt:  a schema parser context
   5337  * @schema:  the schema being built
   5338  * @name:  the item name
   5339  * @namespace:  the namespace
   5340  *
   5341  * Add an XML schema item
   5342  * *WARNING* this interface is highly subject to change
   5343  *
   5344  * Returns the new struture or NULL in case of error
   5345  */
   5346 static xmlSchemaTypePtr
   5347 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5348 		 xmlSchemaTypeType type,
   5349                  const xmlChar * name, const xmlChar * nsName,
   5350 		 xmlNodePtr node, int topLevel)
   5351 {
   5352     xmlSchemaTypePtr ret = NULL;
   5353 
   5354     if ((ctxt == NULL) || (schema == NULL))
   5355         return (NULL);
   5356 
   5357     ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
   5358     if (ret == NULL) {
   5359         xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
   5360         return (NULL);
   5361     }
   5362     memset(ret, 0, sizeof(xmlSchemaType));
   5363     ret->type = type;
   5364     ret->name = name;
   5365     ret->targetNamespace = nsName;
   5366     ret->node = node;
   5367     if (topLevel) {
   5368 	if (ctxt->isRedefine) {
   5369 	    ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
   5370 		ret, name, nsName);
   5371 	    if (ctxt->redef == NULL) {
   5372 		xmlFree(ret);
   5373 		return(NULL);
   5374 	    }
   5375 	    ctxt->redefCounter = 0;
   5376 	}
   5377 	WXS_ADD_GLOBAL(ctxt, ret);
   5378     } else
   5379 	WXS_ADD_LOCAL(ctxt, ret);
   5380     WXS_ADD_PENDING(ctxt, ret);
   5381     return (ret);
   5382 }
   5383 
   5384 static xmlSchemaQNameRefPtr
   5385 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
   5386 		     xmlSchemaTypeType refType,
   5387 		     const xmlChar *refName,
   5388 		     const xmlChar *refNs)
   5389 {
   5390     xmlSchemaQNameRefPtr ret;
   5391 
   5392     ret = (xmlSchemaQNameRefPtr)
   5393 	xmlMalloc(sizeof(xmlSchemaQNameRef));
   5394     if (ret == NULL) {
   5395 	xmlSchemaPErrMemory(pctxt,
   5396 	    "allocating QName reference item", NULL);
   5397 	return (NULL);
   5398     }
   5399     ret->node = NULL;
   5400     ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
   5401     ret->name = refName;
   5402     ret->targetNamespace = refNs;
   5403     ret->item = NULL;
   5404     ret->itemType = refType;
   5405     /*
   5406     * Store the reference item in the schema.
   5407     */
   5408     WXS_ADD_LOCAL(pctxt, ret);
   5409     return (ret);
   5410 }
   5411 
   5412 static xmlSchemaAttributeUseProhibPtr
   5413 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
   5414 {
   5415     xmlSchemaAttributeUseProhibPtr ret;
   5416 
   5417     ret = (xmlSchemaAttributeUseProhibPtr)
   5418 	xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
   5419     if (ret == NULL) {
   5420 	xmlSchemaPErrMemory(pctxt,
   5421 	    "allocating attribute use prohibition", NULL);
   5422 	return (NULL);
   5423     }
   5424     memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
   5425     ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
   5426     WXS_ADD_LOCAL(pctxt, ret);
   5427     return (ret);
   5428 }
   5429 
   5430 
   5431 /**
   5432  * xmlSchemaAddModelGroup:
   5433  * @ctxt:  a schema parser context
   5434  * @schema:  the schema being built
   5435  * @type: the "compositor" type of the model group
   5436  * @node: the node in the schema doc
   5437  *
   5438  * Adds a schema model group
   5439  * *WARNING* this interface is highly subject to change
   5440  *
   5441  * Returns the new struture or NULL in case of error
   5442  */
   5443 static xmlSchemaModelGroupPtr
   5444 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
   5445 		       xmlSchemaPtr schema,
   5446 		       xmlSchemaTypeType type,
   5447 		       xmlNodePtr node)
   5448 {
   5449     xmlSchemaModelGroupPtr ret = NULL;
   5450 
   5451     if ((ctxt == NULL) || (schema == NULL))
   5452         return (NULL);
   5453 
   5454     ret = (xmlSchemaModelGroupPtr)
   5455 	xmlMalloc(sizeof(xmlSchemaModelGroup));
   5456     if (ret == NULL) {
   5457 	xmlSchemaPErrMemory(ctxt, "allocating model group component",
   5458 	    NULL);
   5459 	return (NULL);
   5460     }
   5461     memset(ret, 0, sizeof(xmlSchemaModelGroup));
   5462     ret->type = type;
   5463     ret->node = node;
   5464     WXS_ADD_LOCAL(ctxt, ret);
   5465     if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
   5466 	(type == XML_SCHEMA_TYPE_CHOICE))
   5467 	WXS_ADD_PENDING(ctxt, ret);
   5468     return (ret);
   5469 }
   5470 
   5471 
   5472 /**
   5473  * xmlSchemaAddParticle:
   5474  * @ctxt:  a schema parser context
   5475  * @schema:  the schema being built
   5476  * @node: the corresponding node in the schema doc
   5477  * @min: the minOccurs
   5478  * @max: the maxOccurs
   5479  *
   5480  * Adds an XML schema particle component.
   5481  * *WARNING* this interface is highly subject to change
   5482  *
   5483  * Returns the new struture or NULL in case of error
   5484  */
   5485 static xmlSchemaParticlePtr
   5486 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
   5487 		     xmlNodePtr node, int min, int max)
   5488 {
   5489     xmlSchemaParticlePtr ret = NULL;
   5490     if (ctxt == NULL)
   5491         return (NULL);
   5492 
   5493 #ifdef DEBUG
   5494     fprintf(stderr, "Adding particle component\n");
   5495 #endif
   5496     ret = (xmlSchemaParticlePtr)
   5497 	xmlMalloc(sizeof(xmlSchemaParticle));
   5498     if (ret == NULL) {
   5499 	xmlSchemaPErrMemory(ctxt, "allocating particle component",
   5500 	    NULL);
   5501 	return (NULL);
   5502     }
   5503     ret->type = XML_SCHEMA_TYPE_PARTICLE;
   5504     ret->annot = NULL;
   5505     ret->node = node;
   5506     ret->minOccurs = min;
   5507     ret->maxOccurs = max;
   5508     ret->next = NULL;
   5509     ret->children = NULL;
   5510 
   5511     WXS_ADD_LOCAL(ctxt, ret);
   5512     /*
   5513     * Note that addition to pending components will be done locally
   5514     * to the specific parsing function, since the most particles
   5515     * need not to be fixed up (i.e. the reference to be resolved).
   5516     * REMOVED: WXS_ADD_PENDING(ctxt, ret);
   5517     */
   5518     return (ret);
   5519 }
   5520 
   5521 /**
   5522  * xmlSchemaAddModelGroupDefinition:
   5523  * @ctxt:  a schema validation context
   5524  * @schema:  the schema being built
   5525  * @name:  the group name
   5526  *
   5527  * Add an XML schema Group definition
   5528  *
   5529  * Returns the new struture or NULL in case of error
   5530  */
   5531 static xmlSchemaModelGroupDefPtr
   5532 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
   5533 				 xmlSchemaPtr schema,
   5534 				 const xmlChar *name,
   5535 				 const xmlChar *nsName,
   5536 				 xmlNodePtr node)
   5537 {
   5538     xmlSchemaModelGroupDefPtr ret = NULL;
   5539 
   5540     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
   5541         return (NULL);
   5542 
   5543     ret = (xmlSchemaModelGroupDefPtr)
   5544 	xmlMalloc(sizeof(xmlSchemaModelGroupDef));
   5545     if (ret == NULL) {
   5546         xmlSchemaPErrMemory(ctxt, "adding group", NULL);
   5547         return (NULL);
   5548     }
   5549     memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
   5550     ret->name = name;
   5551     ret->type = XML_SCHEMA_TYPE_GROUP;
   5552     ret->node = node;
   5553     ret->targetNamespace = nsName;
   5554 
   5555     if (ctxt->isRedefine) {
   5556 	ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
   5557 	    ret, name, nsName);
   5558 	if (ctxt->redef == NULL) {
   5559 	    xmlFree(ret);
   5560 	    return(NULL);
   5561 	}
   5562 	ctxt->redefCounter = 0;
   5563     }
   5564     WXS_ADD_GLOBAL(ctxt, ret);
   5565     WXS_ADD_PENDING(ctxt, ret);
   5566     return (ret);
   5567 }
   5568 
   5569 /**
   5570  * xmlSchemaNewWildcardNs:
   5571  * @ctxt:  a schema validation context
   5572  *
   5573  * Creates a new wildcard namespace constraint.
   5574  *
   5575  * Returns the new struture or NULL in case of error
   5576  */
   5577 static xmlSchemaWildcardNsPtr
   5578 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
   5579 {
   5580     xmlSchemaWildcardNsPtr ret;
   5581 
   5582     ret = (xmlSchemaWildcardNsPtr)
   5583 	xmlMalloc(sizeof(xmlSchemaWildcardNs));
   5584     if (ret == NULL) {
   5585 	xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
   5586 	return (NULL);
   5587     }
   5588     ret->value = NULL;
   5589     ret->next = NULL;
   5590     return (ret);
   5591 }
   5592 
   5593 static xmlSchemaIDCPtr
   5594 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5595                   const xmlChar *name, const xmlChar *nsName,
   5596 		  int category, xmlNodePtr node)
   5597 {
   5598     xmlSchemaIDCPtr ret = NULL;
   5599 
   5600     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
   5601         return (NULL);
   5602 
   5603     ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
   5604     if (ret == NULL) {
   5605         xmlSchemaPErrMemory(ctxt,
   5606 	    "allocating an identity-constraint definition", NULL);
   5607         return (NULL);
   5608     }
   5609     memset(ret, 0, sizeof(xmlSchemaIDC));
   5610     /* The target namespace of the parent element declaration. */
   5611     ret->targetNamespace = nsName;
   5612     ret->name = name;
   5613     ret->type = category;
   5614     ret->node = node;
   5615 
   5616     WXS_ADD_GLOBAL(ctxt, ret);
   5617     /*
   5618     * Only keyrefs need to be fixup up.
   5619     */
   5620     if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
   5621 	WXS_ADD_PENDING(ctxt, ret);
   5622     return (ret);
   5623 }
   5624 
   5625 /**
   5626  * xmlSchemaAddWildcard:
   5627  * @ctxt:  a schema validation context
   5628  * @schema: a schema
   5629  *
   5630  * Adds a wildcard.
   5631  * It corresponds to a xsd:anyAttribute and xsd:any.
   5632  *
   5633  * Returns the new struture or NULL in case of error
   5634  */
   5635 static xmlSchemaWildcardPtr
   5636 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5637 		     xmlSchemaTypeType type, xmlNodePtr node)
   5638 {
   5639     xmlSchemaWildcardPtr ret = NULL;
   5640 
   5641     if ((ctxt == NULL) || (schema == NULL))
   5642         return (NULL);
   5643 
   5644     ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
   5645     if (ret == NULL) {
   5646         xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
   5647         return (NULL);
   5648     }
   5649     memset(ret, 0, sizeof(xmlSchemaWildcard));
   5650     ret->type = type;
   5651     ret->node = node;
   5652     WXS_ADD_LOCAL(ctxt, ret);
   5653     return (ret);
   5654 }
   5655 
   5656 static void
   5657 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
   5658 {
   5659     if (group == NULL)
   5660 	return;
   5661     if (group->members != NULL)
   5662 	xmlSchemaItemListFree(group->members);
   5663     xmlFree(group);
   5664 }
   5665 
   5666 static xmlSchemaSubstGroupPtr
   5667 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
   5668 		       xmlSchemaElementPtr head)
   5669 {
   5670     xmlSchemaSubstGroupPtr ret;
   5671 
   5672     /* Init subst group hash. */
   5673     if (WXS_SUBST_GROUPS(pctxt) == NULL) {
   5674 	WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
   5675 	if (WXS_SUBST_GROUPS(pctxt) == NULL)
   5676 	    return(NULL);
   5677     }
   5678     /* Create a new substitution group. */
   5679     ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
   5680     if (ret == NULL) {
   5681 	xmlSchemaPErrMemory(NULL,
   5682 	    "allocating a substitution group container", NULL);
   5683 	return(NULL);
   5684     }
   5685     memset(ret, 0, sizeof(xmlSchemaSubstGroup));
   5686     ret->head = head;
   5687     /* Create list of members. */
   5688     ret->members = xmlSchemaItemListCreate();
   5689     if (ret->members == NULL) {
   5690 	xmlSchemaSubstGroupFree(ret);
   5691 	return(NULL);
   5692     }
   5693     /* Add subst group to hash. */
   5694     if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
   5695 	head->name, head->targetNamespace, ret) != 0) {
   5696 	PERROR_INT("xmlSchemaSubstGroupAdd",
   5697 	    "failed to add a new substitution container");
   5698 	xmlSchemaSubstGroupFree(ret);
   5699 	return(NULL);
   5700     }
   5701     return(ret);
   5702 }
   5703 
   5704 static xmlSchemaSubstGroupPtr
   5705 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
   5706 		       xmlSchemaElementPtr head)
   5707 {
   5708     if (WXS_SUBST_GROUPS(pctxt) == NULL)
   5709 	return(NULL);
   5710     return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
   5711 	head->name, head->targetNamespace));
   5712 
   5713 }
   5714 
   5715 /**
   5716  * xmlSchemaAddElementSubstitutionMember:
   5717  * @pctxt:  a schema parser context
   5718  * @head:  the head of the substitution group
   5719  * @member: the new member of the substitution group
   5720  *
   5721  * Allocate a new annotation structure.
   5722  *
   5723  * Returns the newly allocated structure or NULL in case or error
   5724  */
   5725 static int
   5726 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
   5727 				      xmlSchemaElementPtr head,
   5728 				      xmlSchemaElementPtr member)
   5729 {
   5730     xmlSchemaSubstGroupPtr substGroup = NULL;
   5731 
   5732     if ((pctxt == NULL) || (head == NULL) || (member == NULL))
   5733 	return (-1);
   5734 
   5735     substGroup = xmlSchemaSubstGroupGet(pctxt, head);
   5736     if (substGroup == NULL)
   5737 	substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
   5738     if (substGroup == NULL)
   5739 	return(-1);
   5740     if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
   5741 	return(-1);
   5742     return(0);
   5743 }
   5744 
   5745 /************************************************************************
   5746  * 									*
   5747  *		Utilities for parsing					*
   5748  * 									*
   5749  ************************************************************************/
   5750 
   5751 /**
   5752  * xmlSchemaPValAttrNodeQNameValue:
   5753  * @ctxt:  a schema parser context
   5754  * @schema: the schema context
   5755  * @ownerDes: the designation of the parent element
   5756  * @ownerItem: the parent as a schema object
   5757  * @value:  the QName value
   5758  * @local: the resulting local part if found, the attribute value otherwise
   5759  * @uri:  the resulting namespace URI if found
   5760  *
   5761  * Extracts the local name and the URI of a QName value and validates it.
   5762  * This one is intended to be used on attribute values that
   5763  * should resolve to schema components.
   5764  *
   5765  * Returns 0, in case the QName is valid, a positive error code
   5766  * if not valid and -1 if an internal error occurs.
   5767  */
   5768 static int
   5769 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
   5770 				       xmlSchemaPtr schema,
   5771 				       xmlSchemaBasicItemPtr ownerItem,
   5772 				       xmlAttrPtr attr,
   5773 				       const xmlChar *value,
   5774 				       const xmlChar **uri,
   5775 				       const xmlChar **local)
   5776 {
   5777     const xmlChar *pref;
   5778     xmlNsPtr ns;
   5779     int len, ret;
   5780 
   5781     *uri = NULL;
   5782     *local = NULL;
   5783     ret = xmlValidateQName(value, 1);
   5784     if (ret > 0) {
   5785 	xmlSchemaPSimpleTypeErr(ctxt,
   5786 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5787 	    ownerItem, (xmlNodePtr) attr,
   5788 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
   5789 	    NULL, value, NULL, NULL, NULL);
   5790 	*local = value;
   5791 	return (ctxt->err);
   5792     } else if (ret < 0)
   5793 	return (-1);
   5794 
   5795     if (!strchr((char *) value, ':')) {
   5796 	ns = xmlSearchNs(attr->doc, attr->parent, NULL);
   5797 	if (ns)
   5798 	    *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
   5799 	else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
   5800 	    /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
   5801 	    * parser context. */
   5802 	    /*
   5803 	    * This one takes care of included schemas with no
   5804 	    * target namespace.
   5805 	    */
   5806 	    *uri = ctxt->targetNamespace;
   5807 	}
   5808 	*local = xmlDictLookup(ctxt->dict, value, -1);
   5809 	return (0);
   5810     }
   5811     /*
   5812     * At this point xmlSplitQName3 has to return a local name.
   5813     */
   5814     *local = xmlSplitQName3(value, &len);
   5815     *local = xmlDictLookup(ctxt->dict, *local, -1);
   5816     pref = xmlDictLookup(ctxt->dict, value, len);
   5817     ns = xmlSearchNs(attr->doc, attr->parent, pref);
   5818     if (ns == NULL) {
   5819 	xmlSchemaPSimpleTypeErr(ctxt,
   5820 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5821 	    ownerItem, (xmlNodePtr) attr,
   5822 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
   5823 	    "The value '%s' of simple type 'xs:QName' has no "
   5824 	    "corresponding namespace declaration in scope", value, NULL);
   5825 	return (ctxt->err);
   5826     } else {
   5827         *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
   5828     }
   5829     return (0);
   5830 }
   5831 
   5832 /**
   5833  * xmlSchemaPValAttrNodeQName:
   5834  * @ctxt:  a schema parser context
   5835  * @schema: the schema context
   5836  * @ownerDes: the designation of the owner element
   5837  * @ownerItem: the owner as a schema object
   5838  * @attr:  the attribute node
   5839  * @local: the resulting local part if found, the attribute value otherwise
   5840  * @uri:  the resulting namespace URI if found
   5841  *
   5842  * Extracts and validates the QName of an attribute value.
   5843  * This one is intended to be used on attribute values that
   5844  * should resolve to schema components.
   5845  *
   5846  * Returns 0, in case the QName is valid, a positive error code
   5847  * if not valid and -1 if an internal error occurs.
   5848  */
   5849 static int
   5850 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
   5851 				       xmlSchemaPtr schema,
   5852 				       xmlSchemaBasicItemPtr ownerItem,
   5853 				       xmlAttrPtr attr,
   5854 				       const xmlChar **uri,
   5855 				       const xmlChar **local)
   5856 {
   5857     const xmlChar *value;
   5858 
   5859     value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   5860     return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
   5861 	ownerItem, attr, value, uri, local));
   5862 }
   5863 
   5864 /**
   5865  * xmlSchemaPValAttrQName:
   5866  * @ctxt:  a schema parser context
   5867  * @schema: the schema context
   5868  * @ownerDes: the designation of the parent element
   5869  * @ownerItem: the owner as a schema object
   5870  * @ownerElem:  the parent node of the attribute
   5871  * @name:  the name of the attribute
   5872  * @local: the resulting local part if found, the attribute value otherwise
   5873  * @uri:  the resulting namespace URI if found
   5874  *
   5875  * Extracts and validates the QName of an attribute value.
   5876  *
   5877  * Returns 0, in case the QName is valid, a positive error code
   5878  * if not valid and -1 if an internal error occurs.
   5879  */
   5880 static int
   5881 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
   5882 				   xmlSchemaPtr schema,
   5883 				   xmlSchemaBasicItemPtr ownerItem,
   5884 				   xmlNodePtr ownerElem,
   5885 				   const char *name,
   5886 				   const xmlChar **uri,
   5887 				   const xmlChar **local)
   5888 {
   5889     xmlAttrPtr attr;
   5890 
   5891     attr = xmlSchemaGetPropNode(ownerElem, name);
   5892     if (attr == NULL) {
   5893 	*local = NULL;
   5894 	*uri = NULL;
   5895 	return (0);
   5896     }
   5897     return (xmlSchemaPValAttrNodeQName(ctxt, schema,
   5898 	ownerItem, attr, uri, local));
   5899 }
   5900 
   5901 /**
   5902  * xmlSchemaPValAttrID:
   5903  * @ctxt:  a schema parser context
   5904  * @schema: the schema context
   5905  * @ownerDes: the designation of the parent element
   5906  * @ownerItem: the owner as a schema object
   5907  * @ownerElem:  the parent node of the attribute
   5908  * @name:  the name of the attribute
   5909  *
   5910  * Extracts and validates the ID of an attribute value.
   5911  *
   5912  * Returns 0, in case the ID is valid, a positive error code
   5913  * if not valid and -1 if an internal error occurs.
   5914  */
   5915 static int
   5916 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
   5917 {
   5918     int ret;
   5919     const xmlChar *value;
   5920 
   5921     if (attr == NULL)
   5922 	return(0);
   5923     value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
   5924     ret = xmlValidateNCName(value, 1);
   5925     if (ret == 0) {
   5926 	/*
   5927 	* NOTE: the IDness might have already be declared in the DTD
   5928 	*/
   5929 	if (attr->atype != XML_ATTRIBUTE_ID) {
   5930 	    xmlIDPtr res;
   5931 	    xmlChar *strip;
   5932 
   5933 	    /*
   5934 	    * TODO: Use xmlSchemaStrip here; it's not exported at this
   5935 	    * moment.
   5936 	    */
   5937 	    strip = xmlSchemaCollapseString(value);
   5938 	    if (strip != NULL) {
   5939 		xmlFree((xmlChar *) value);
   5940 		value = strip;
   5941 	    }
   5942     	    res = xmlAddID(NULL, attr->doc, value, attr);
   5943 	    if (res == NULL) {
   5944 		ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   5945 		xmlSchemaPSimpleTypeErr(ctxt,
   5946 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5947 		    NULL, (xmlNodePtr) attr,
   5948 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
   5949 		    NULL, NULL, "Duplicate value '%s' of simple "
   5950 		    "type 'xs:ID'", value, NULL);
   5951 	    } else
   5952 		attr->atype = XML_ATTRIBUTE_ID;
   5953 	}
   5954     } else if (ret > 0) {
   5955 	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   5956 	xmlSchemaPSimpleTypeErr(ctxt,
   5957 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5958 	    NULL, (xmlNodePtr) attr,
   5959 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
   5960 	    NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
   5961 	    "not a valid 'xs:NCName'",
   5962 	    value, NULL);
   5963     }
   5964     if (value != NULL)
   5965 	xmlFree((xmlChar *)value);
   5966 
   5967     return (ret);
   5968 }
   5969 
   5970 static int
   5971 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
   5972 		    xmlNodePtr ownerElem,
   5973 		    const xmlChar *name)
   5974 {
   5975     xmlAttrPtr attr;
   5976 
   5977     attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
   5978     if (attr == NULL)
   5979 	return(0);
   5980     return(xmlSchemaPValAttrNodeID(ctxt, attr));
   5981 
   5982 }
   5983 
   5984 /**
   5985  * xmlGetMaxOccurs:
   5986  * @ctxt:  a schema validation context
   5987  * @node:  a subtree containing XML Schema informations
   5988  *
   5989  * Get the maxOccurs property
   5990  *
   5991  * Returns the default if not found, or the value
   5992  */
   5993 static int
   5994 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
   5995 		int min, int max, int def, const char *expected)
   5996 {
   5997     const xmlChar *val, *cur;
   5998     int ret = 0;
   5999     xmlAttrPtr attr;
   6000 
   6001     attr = xmlSchemaGetPropNode(node, "maxOccurs");
   6002     if (attr == NULL)
   6003 	return (def);
   6004     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6005 
   6006     if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
   6007 	if (max != UNBOUNDED) {
   6008 	    xmlSchemaPSimpleTypeErr(ctxt,
   6009 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6010 		/* XML_SCHEMAP_INVALID_MINOCCURS, */
   6011 		NULL, (xmlNodePtr) attr, NULL, expected,
   6012 		val, NULL, NULL, NULL);
   6013 	    return (def);
   6014 	} else
   6015 	    return (UNBOUNDED);  /* encoding it with -1 might be another option */
   6016     }
   6017 
   6018     cur = val;
   6019     while (IS_BLANK_CH(*cur))
   6020         cur++;
   6021     if (*cur == 0) {
   6022         xmlSchemaPSimpleTypeErr(ctxt,
   6023 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6024 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6025 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6026 	    val, NULL, NULL, NULL);
   6027 	return (def);
   6028     }
   6029     while ((*cur >= '0') && (*cur <= '9')) {
   6030         ret = ret * 10 + (*cur - '0');
   6031         cur++;
   6032     }
   6033     while (IS_BLANK_CH(*cur))
   6034         cur++;
   6035     /*
   6036     * TODO: Restrict the maximal value to Integer.
   6037     */
   6038     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
   6039 	xmlSchemaPSimpleTypeErr(ctxt,
   6040 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6041 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6042 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6043 	    val, NULL, NULL, NULL);
   6044         return (def);
   6045     }
   6046     return (ret);
   6047 }
   6048 
   6049 /**
   6050  * xmlGetMinOccurs:
   6051  * @ctxt:  a schema validation context
   6052  * @node:  a subtree containing XML Schema informations
   6053  *
   6054  * Get the minOccurs property
   6055  *
   6056  * Returns the default if not found, or the value
   6057  */
   6058 static int
   6059 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
   6060 		int min, int max, int def, const char *expected)
   6061 {
   6062     const xmlChar *val, *cur;
   6063     int ret = 0;
   6064     xmlAttrPtr attr;
   6065 
   6066     attr = xmlSchemaGetPropNode(node, "minOccurs");
   6067     if (attr == NULL)
   6068 	return (def);
   6069     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6070     cur = val;
   6071     while (IS_BLANK_CH(*cur))
   6072         cur++;
   6073     if (*cur == 0) {
   6074         xmlSchemaPSimpleTypeErr(ctxt,
   6075 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6076 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6077 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6078 	    val, NULL, NULL, NULL);
   6079         return (def);
   6080     }
   6081     while ((*cur >= '0') && (*cur <= '9')) {
   6082         ret = ret * 10 + (*cur - '0');
   6083         cur++;
   6084     }
   6085     while (IS_BLANK_CH(*cur))
   6086         cur++;
   6087     /*
   6088     * TODO: Restrict the maximal value to Integer.
   6089     */
   6090     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
   6091 	xmlSchemaPSimpleTypeErr(ctxt,
   6092 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6093 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6094 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6095 	    val, NULL, NULL, NULL);
   6096         return (def);
   6097     }
   6098     return (ret);
   6099 }
   6100 
   6101 /**
   6102  * xmlSchemaPGetBoolNodeValue:
   6103  * @ctxt:  a schema validation context
   6104  * @ownerDes:  owner designation
   6105  * @ownerItem:  the owner as a schema item
   6106  * @node: the node holding the value
   6107  *
   6108  * Converts a boolean string value into 1 or 0.
   6109  *
   6110  * Returns 0 or 1.
   6111  */
   6112 static int
   6113 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
   6114 			   xmlSchemaBasicItemPtr ownerItem,
   6115 			   xmlNodePtr node)
   6116 {
   6117     xmlChar *value = NULL;
   6118     int res = 0;
   6119 
   6120     value = xmlNodeGetContent(node);
   6121     /*
   6122     * 3.2.2.1 Lexical representation
   6123     * An instance of a datatype that is defined as boolean
   6124     * can have the following legal literals {true, false, 1, 0}.
   6125     */
   6126     if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
   6127         res = 1;
   6128     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
   6129         res = 0;
   6130     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
   6131 	res = 1;
   6132     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
   6133         res = 0;
   6134     else {
   6135         xmlSchemaPSimpleTypeErr(ctxt,
   6136 	    XML_SCHEMAP_INVALID_BOOLEAN,
   6137 	    ownerItem, node,
   6138 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
   6139 	    NULL, BAD_CAST value,
   6140 	    NULL, NULL, NULL);
   6141     }
   6142     if (value != NULL)
   6143 	xmlFree(value);
   6144     return (res);
   6145 }
   6146 
   6147 /**
   6148  * xmlGetBooleanProp:
   6149  * @ctxt:  a schema validation context
   6150  * @node:  a subtree containing XML Schema informations
   6151  * @name:  the attribute name
   6152  * @def:  the default value
   6153  *
   6154  * Evaluate if a boolean property is set
   6155  *
   6156  * Returns the default if not found, 0 if found to be false,
   6157  * 1 if found to be true
   6158  */
   6159 static int
   6160 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
   6161 		  xmlNodePtr node,
   6162                   const char *name, int def)
   6163 {
   6164     const xmlChar *val;
   6165 
   6166     val = xmlSchemaGetProp(ctxt, node, name);
   6167     if (val == NULL)
   6168         return (def);
   6169     /*
   6170     * 3.2.2.1 Lexical representation
   6171     * An instance of a datatype that is defined as boolean
   6172     * can have the following legal literals {true, false, 1, 0}.
   6173     */
   6174     if (xmlStrEqual(val, BAD_CAST "true"))
   6175         def = 1;
   6176     else if (xmlStrEqual(val, BAD_CAST "false"))
   6177         def = 0;
   6178     else if (xmlStrEqual(val, BAD_CAST "1"))
   6179 	def = 1;
   6180     else if (xmlStrEqual(val, BAD_CAST "0"))
   6181         def = 0;
   6182     else {
   6183         xmlSchemaPSimpleTypeErr(ctxt,
   6184 	    XML_SCHEMAP_INVALID_BOOLEAN,
   6185 	    NULL,
   6186 	    (xmlNodePtr) xmlSchemaGetPropNode(node, name),
   6187 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
   6188 	    NULL, val, NULL, NULL, NULL);
   6189     }
   6190     return (def);
   6191 }
   6192 
   6193 /************************************************************************
   6194  * 									*
   6195  *		Shema extraction from an Infoset			*
   6196  * 									*
   6197  ************************************************************************/
   6198 static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
   6199                                                  ctxt, xmlSchemaPtr schema,
   6200                                                  xmlNodePtr node,
   6201 						 int topLevel);
   6202 static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
   6203                                                   ctxt,
   6204                                                   xmlSchemaPtr schema,
   6205                                                   xmlNodePtr node,
   6206 						  int topLevel);
   6207 static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
   6208                                                   ctxt,
   6209                                                   xmlSchemaPtr schema,
   6210                                                   xmlNodePtr node,
   6211 						  xmlSchemaTypeType parentType);
   6212 static xmlSchemaBasicItemPtr
   6213 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
   6214 			     xmlSchemaPtr schema,
   6215 			     xmlNodePtr node,
   6216 			     xmlSchemaItemListPtr uses,
   6217 			     int parentType);
   6218 static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
   6219                                            xmlSchemaPtr schema,
   6220                                            xmlNodePtr node);
   6221 static xmlSchemaWildcardPtr
   6222 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
   6223                            xmlSchemaPtr schema, xmlNodePtr node);
   6224 
   6225 /**
   6226  * xmlSchemaPValAttrNodeValue:
   6227  *
   6228  * @ctxt:  a schema parser context
   6229  * @ownerDes: the designation of the parent element
   6230  * @ownerItem: the schema object owner if existent
   6231  * @attr:  the schema attribute node being validated
   6232  * @value: the value
   6233  * @type: the built-in type to be validated against
   6234  *
   6235  * Validates a value against the given built-in type.
   6236  * This one is intended to be used internally for validation
   6237  * of schema attribute values during parsing of the schema.
   6238  *
   6239  * Returns 0 if the value is valid, a positive error code
   6240  * number otherwise and -1 in case of an internal or API error.
   6241  */
   6242 static int
   6243 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
   6244 			   xmlSchemaBasicItemPtr ownerItem,
   6245 			   xmlAttrPtr attr,
   6246 			   const xmlChar *value,
   6247 			   xmlSchemaTypePtr type)
   6248 {
   6249 
   6250     int ret = 0;
   6251 
   6252     /*
   6253     * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
   6254     * one is really meant to be used internally, so better not.
   6255     */
   6256     if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
   6257 	return (-1);
   6258     if (type->type != XML_SCHEMA_TYPE_BASIC) {
   6259 	PERROR_INT("xmlSchemaPValAttrNodeValue",
   6260 	    "the given type is not a built-in type");
   6261 	return (-1);
   6262     }
   6263     switch (type->builtInType) {
   6264 	case XML_SCHEMAS_NCNAME:
   6265 	case XML_SCHEMAS_QNAME:
   6266 	case XML_SCHEMAS_ANYURI:
   6267 	case XML_SCHEMAS_TOKEN:
   6268 	case XML_SCHEMAS_LANGUAGE:
   6269 	    ret = xmlSchemaValPredefTypeNode(type, value, NULL,
   6270 		(xmlNodePtr) attr);
   6271 	    break;
   6272 	default: {
   6273 	    PERROR_INT("xmlSchemaPValAttrNodeValue",
   6274 		"validation using the given type is not supported while "
   6275 		"parsing a schema");
   6276 	    return (-1);
   6277 	}
   6278     }
   6279     /*
   6280     * TODO: Should we use the S4S error codes instead?
   6281     */
   6282     if (ret < 0) {
   6283 	PERROR_INT("xmlSchemaPValAttrNodeValue",
   6284 	    "failed to validate a schema attribute value");
   6285 	return (-1);
   6286     } else if (ret > 0) {
   6287 	if (WXS_IS_LIST(type))
   6288 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   6289 	else
   6290 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
   6291 	xmlSchemaPSimpleTypeErr(pctxt,
   6292 	    ret, ownerItem, (xmlNodePtr) attr,
   6293 	    type, NULL, value, NULL, NULL, NULL);
   6294     }
   6295     return (ret);
   6296 }
   6297 
   6298 /**
   6299  * xmlSchemaPValAttrNode:
   6300  *
   6301  * @ctxt:  a schema parser context
   6302  * @ownerDes: the designation of the parent element
   6303  * @ownerItem: the schema object owner if existent
   6304  * @attr:  the schema attribute node being validated
   6305  * @type: the built-in type to be validated against
   6306  * @value: the resulting value if any
   6307  *
   6308  * Extracts and validates a value against the given built-in type.
   6309  * This one is intended to be used internally for validation
   6310  * of schema attribute values during parsing of the schema.
   6311  *
   6312  * Returns 0 if the value is valid, a positive error code
   6313  * number otherwise and -1 in case of an internal or API error.
   6314  */
   6315 static int
   6316 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
   6317 			   xmlSchemaBasicItemPtr ownerItem,
   6318 			   xmlAttrPtr attr,
   6319 			   xmlSchemaTypePtr type,
   6320 			   const xmlChar **value)
   6321 {
   6322     const xmlChar *val;
   6323 
   6324     if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
   6325 	return (-1);
   6326 
   6327     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6328     if (value != NULL)
   6329 	*value = val;
   6330 
   6331     return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
   6332 	val, type));
   6333 }
   6334 
   6335 /**
   6336  * xmlSchemaPValAttr:
   6337  *
   6338  * @ctxt:  a schema parser context
   6339  * @node: the element node of the attribute
   6340  * @ownerDes: the designation of the parent element
   6341  * @ownerItem: the schema object owner if existent
   6342  * @ownerElem: the owner element node
   6343  * @name:  the name of the schema attribute node
   6344  * @type: the built-in type to be validated against
   6345  * @value: the resulting value if any
   6346  *
   6347  * Extracts and validates a value against the given built-in type.
   6348  * This one is intended to be used internally for validation
   6349  * of schema attribute values during parsing of the schema.
   6350  *
   6351  * Returns 0 if the value is valid, a positive error code
   6352  * number otherwise and -1 in case of an internal or API error.
   6353  */
   6354 static int
   6355 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
   6356 		       xmlSchemaBasicItemPtr ownerItem,
   6357 		       xmlNodePtr ownerElem,
   6358 		       const char *name,
   6359 		       xmlSchemaTypePtr type,
   6360 		       const xmlChar **value)
   6361 {
   6362     xmlAttrPtr attr;
   6363 
   6364     if ((ctxt == NULL) || (type == NULL)) {
   6365 	if (value != NULL)
   6366 	    *value = NULL;
   6367 	return (-1);
   6368     }
   6369     if (type->type != XML_SCHEMA_TYPE_BASIC) {
   6370 	if (value != NULL)
   6371 	    *value = NULL;
   6372 	xmlSchemaPErr(ctxt, ownerElem,
   6373 	    XML_SCHEMAP_INTERNAL,
   6374 	    "Internal error: xmlSchemaPValAttr, the given "
   6375 	    "type '%s' is not a built-in type.\n",
   6376 	    type->name, NULL);
   6377 	return (-1);
   6378     }
   6379     attr = xmlSchemaGetPropNode(ownerElem, name);
   6380     if (attr == NULL) {
   6381 	if (value != NULL)
   6382 	    *value = NULL;
   6383 	return (0);
   6384     }
   6385     return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
   6386 	type, value));
   6387 }
   6388 
   6389 static int
   6390 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
   6391 		  xmlSchemaPtr schema ATTRIBUTE_UNUSED,
   6392 		  xmlNodePtr node,
   6393 		  xmlAttrPtr attr,
   6394 		  const xmlChar *namespaceName)
   6395 {
   6396     /* TODO: Pointer comparison instead? */
   6397     if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
   6398 	return (0);
   6399     if (xmlStrEqual(xmlSchemaNs, namespaceName))
   6400 	return (0);
   6401     /*
   6402     * Check if the referenced namespace was <import>ed.
   6403     */
   6404     if (WXS_BUCKET(pctxt)->relations != NULL) {
   6405 	xmlSchemaSchemaRelationPtr rel;
   6406 
   6407 	rel = WXS_BUCKET(pctxt)->relations;
   6408 	do {
   6409 	    if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
   6410 		xmlStrEqual(namespaceName, rel->importNamespace))
   6411 		return (0);
   6412 	    rel = rel->next;
   6413 	} while (rel != NULL);
   6414     }
   6415     /*
   6416     * No matching <import>ed namespace found.
   6417     */
   6418     {
   6419 	xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
   6420 
   6421 	if (namespaceName == NULL)
   6422 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   6423 		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
   6424 		"References from this schema to components in no "
   6425 		"namespace are not allowed, since not indicated by an "
   6426 		"import statement", NULL, NULL);
   6427 	else
   6428 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   6429 		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
   6430 		"References from this schema to components in the "
   6431 		"namespace '%s' are not allowed, since not indicated by an "
   6432 		"import statement", namespaceName, NULL);
   6433     }
   6434     return (XML_SCHEMAP_SRC_RESOLVE);
   6435 }
   6436 
   6437 /**
   6438  * xmlSchemaParseLocalAttributes:
   6439  * @ctxt:  a schema validation context
   6440  * @schema:  the schema being built
   6441  * @node:  a subtree containing XML Schema informations
   6442  * @type:  the hosting type where the attributes will be anchored
   6443  *
   6444  * Parses attribute uses and attribute declarations and
   6445  * attribute group references.
   6446  */
   6447 static int
   6448 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6449                         xmlNodePtr *child, xmlSchemaItemListPtr *list,
   6450 			int parentType, int *hasRefs)
   6451 {
   6452     void *item;
   6453 
   6454     while ((IS_SCHEMA((*child), "attribute")) ||
   6455            (IS_SCHEMA((*child), "attributeGroup"))) {
   6456         if (IS_SCHEMA((*child), "attribute")) {
   6457 	    item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
   6458 		*list, parentType);
   6459         } else {
   6460             item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
   6461 	    if ((item != NULL) && (hasRefs != NULL))
   6462 		*hasRefs = 1;
   6463         }
   6464 	if (item != NULL) {
   6465 	    if (*list == NULL) {
   6466 		/* TODO: Customize grow factor. */
   6467 		*list = xmlSchemaItemListCreate();
   6468 		if (*list == NULL)
   6469 		    return(-1);
   6470 	    }
   6471 	    if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
   6472 		return(-1);
   6473 	}
   6474         *child = (*child)->next;
   6475     }
   6476     return (0);
   6477 }
   6478 
   6479 /**
   6480  * xmlSchemaParseAnnotation:
   6481  * @ctxt:  a schema validation context
   6482  * @schema:  the schema being built
   6483  * @node:  a subtree containing XML Schema informations
   6484  *
   6485  * parse a XML schema Attrribute declaration
   6486  * *WARNING* this interface is highly subject to change
   6487  *
   6488  * Returns -1 in case of error, 0 if the declaration is improper and
   6489  *         1 in case of success.
   6490  */
   6491 static xmlSchemaAnnotPtr
   6492 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
   6493 {
   6494     xmlSchemaAnnotPtr ret;
   6495     xmlNodePtr child = NULL;
   6496     xmlAttrPtr attr;
   6497     int barked = 0;
   6498 
   6499     /*
   6500     * INFO: S4S completed.
   6501     */
   6502     /*
   6503     * id = ID
   6504     * {any attributes with non-schema namespace . . .}>
   6505     * Content: (appinfo | documentation)*
   6506     */
   6507     if ((ctxt == NULL) || (node == NULL))
   6508         return (NULL);
   6509     if (needed)
   6510 	ret = xmlSchemaNewAnnot(ctxt, node);
   6511     else
   6512 	ret = NULL;
   6513     attr = node->properties;
   6514     while (attr != NULL) {
   6515 	if (((attr->ns == NULL) &&
   6516 	    (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
   6517 	    ((attr->ns != NULL) &&
   6518 	    xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
   6519 
   6520 	    xmlSchemaPIllegalAttrErr(ctxt,
   6521 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6522 	}
   6523 	attr = attr->next;
   6524     }
   6525     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   6526     /*
   6527     * And now for the children...
   6528     */
   6529     child = node->children;
   6530     while (child != NULL) {
   6531 	if (IS_SCHEMA(child, "appinfo")) {
   6532 	    /* TODO: make available the content of "appinfo". */
   6533 	    /*
   6534 	    * source = anyURI
   6535 	    * {any attributes with non-schema namespace . . .}>
   6536 	    * Content: ({any})*
   6537 	    */
   6538 	    attr = child->properties;
   6539 	    while (attr != NULL) {
   6540 		if (((attr->ns == NULL) &&
   6541 		     (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
   6542 		     ((attr->ns != NULL) &&
   6543 		      xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
   6544 
   6545 		    xmlSchemaPIllegalAttrErr(ctxt,
   6546 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6547 		}
   6548 		attr = attr->next;
   6549 	    }
   6550 	    xmlSchemaPValAttr(ctxt, NULL, child, "source",
   6551 		xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
   6552 	    child = child->next;
   6553 	} else if (IS_SCHEMA(child, "documentation")) {
   6554 	    /* TODO: make available the content of "documentation". */
   6555 	    /*
   6556 	    * source = anyURI
   6557 	    * {any attributes with non-schema namespace . . .}>
   6558 	    * Content: ({any})*
   6559 	    */
   6560 	    attr = child->properties;
   6561 	    while (attr != NULL) {
   6562 		if (attr->ns == NULL) {
   6563 		    if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
   6564 			xmlSchemaPIllegalAttrErr(ctxt,
   6565 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6566 		    }
   6567 		} else {
   6568 		    if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
   6569 			(xmlStrEqual(attr->name, BAD_CAST "lang") &&
   6570 			(!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
   6571 
   6572 			xmlSchemaPIllegalAttrErr(ctxt,
   6573 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6574 		    }
   6575 		}
   6576 		attr = attr->next;
   6577 	    }
   6578 	    /*
   6579 	    * Attribute "xml:lang".
   6580 	    */
   6581 	    attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
   6582 	    if (attr != NULL)
   6583 		xmlSchemaPValAttrNode(ctxt, NULL, attr,
   6584 		xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
   6585 	    child = child->next;
   6586 	} else {
   6587 	    if (!barked)
   6588 		xmlSchemaPContentErr(ctxt,
   6589 		    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   6590 		    NULL, node, child, NULL, "(appinfo | documentation)*");
   6591 	    barked = 1;
   6592 	    child = child->next;
   6593 	}
   6594     }
   6595 
   6596     return (ret);
   6597 }
   6598 
   6599 /**
   6600  * xmlSchemaParseFacet:
   6601  * @ctxt:  a schema validation context
   6602  * @schema:  the schema being built
   6603  * @node:  a subtree containing XML Schema informations
   6604  *
   6605  * parse a XML schema Facet declaration
   6606  * *WARNING* this interface is highly subject to change
   6607  *
   6608  * Returns the new type structure or NULL in case of error
   6609  */
   6610 static xmlSchemaFacetPtr
   6611 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6612                     xmlNodePtr node)
   6613 {
   6614     xmlSchemaFacetPtr facet;
   6615     xmlNodePtr child = NULL;
   6616     const xmlChar *value;
   6617 
   6618     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   6619         return (NULL);
   6620 
   6621     facet = xmlSchemaNewFacet();
   6622     if (facet == NULL) {
   6623         xmlSchemaPErrMemory(ctxt, "allocating facet", node);
   6624         return (NULL);
   6625     }
   6626     facet->node = node;
   6627     value = xmlSchemaGetProp(ctxt, node, "value");
   6628     if (value == NULL) {
   6629         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
   6630                        "Facet %s has no value\n", node->name, NULL);
   6631         xmlSchemaFreeFacet(facet);
   6632         return (NULL);
   6633     }
   6634     if (IS_SCHEMA(node, "minInclusive")) {
   6635         facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
   6636     } else if (IS_SCHEMA(node, "minExclusive")) {
   6637         facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
   6638     } else if (IS_SCHEMA(node, "maxInclusive")) {
   6639         facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
   6640     } else if (IS_SCHEMA(node, "maxExclusive")) {
   6641         facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
   6642     } else if (IS_SCHEMA(node, "totalDigits")) {
   6643         facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
   6644     } else if (IS_SCHEMA(node, "fractionDigits")) {
   6645         facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
   6646     } else if (IS_SCHEMA(node, "pattern")) {
   6647         facet->type = XML_SCHEMA_FACET_PATTERN;
   6648     } else if (IS_SCHEMA(node, "enumeration")) {
   6649         facet->type = XML_SCHEMA_FACET_ENUMERATION;
   6650     } else if (IS_SCHEMA(node, "whiteSpace")) {
   6651         facet->type = XML_SCHEMA_FACET_WHITESPACE;
   6652     } else if (IS_SCHEMA(node, "length")) {
   6653         facet->type = XML_SCHEMA_FACET_LENGTH;
   6654     } else if (IS_SCHEMA(node, "maxLength")) {
   6655         facet->type = XML_SCHEMA_FACET_MAXLENGTH;
   6656     } else if (IS_SCHEMA(node, "minLength")) {
   6657         facet->type = XML_SCHEMA_FACET_MINLENGTH;
   6658     } else {
   6659         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
   6660                        "Unknown facet type %s\n", node->name, NULL);
   6661         xmlSchemaFreeFacet(facet);
   6662         return (NULL);
   6663     }
   6664     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   6665     facet->value = value;
   6666     if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
   6667 	(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
   6668 	const xmlChar *fixed;
   6669 
   6670 	fixed = xmlSchemaGetProp(ctxt, node, "fixed");
   6671 	if (fixed != NULL) {
   6672 	    if (xmlStrEqual(fixed, BAD_CAST "true"))
   6673 		facet->fixed = 1;
   6674 	}
   6675     }
   6676     child = node->children;
   6677 
   6678     if (IS_SCHEMA(child, "annotation")) {
   6679         facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   6680         child = child->next;
   6681     }
   6682     if (child != NULL) {
   6683         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
   6684                        "Facet %s has unexpected child content\n",
   6685                        node->name, NULL);
   6686     }
   6687     return (facet);
   6688 }
   6689 
   6690 /**
   6691  * xmlSchemaParseWildcardNs:
   6692  * @ctxt:  a schema parser context
   6693  * @wildc:  the wildcard, already created
   6694  * @node:  a subtree containing XML Schema informations
   6695  *
   6696  * Parses the attribute "processContents" and "namespace"
   6697  * of a xsd:anyAttribute and xsd:any.
   6698  * *WARNING* this interface is highly subject to change
   6699  *
   6700  * Returns 0 if everything goes fine, a positive error code
   6701  * if something is not valid and -1 if an internal error occurs.
   6702  */
   6703 static int
   6704 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
   6705 			 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
   6706 			 xmlSchemaWildcardPtr wildc,
   6707 			 xmlNodePtr node)
   6708 {
   6709     const xmlChar *pc, *ns, *dictnsItem;
   6710     int ret = 0;
   6711     xmlChar *nsItem;
   6712     xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
   6713     xmlAttrPtr attr;
   6714 
   6715     pc = xmlSchemaGetProp(ctxt, node, "processContents");
   6716     if ((pc == NULL)
   6717         || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
   6718         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
   6719     } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
   6720         wildc->processContents = XML_SCHEMAS_ANY_SKIP;
   6721     } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
   6722         wildc->processContents = XML_SCHEMAS_ANY_LAX;
   6723     } else {
   6724         xmlSchemaPSimpleTypeErr(ctxt,
   6725 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6726 	    NULL, node,
   6727 	    NULL, "(strict | skip | lax)", pc,
   6728 	    NULL, NULL, NULL);
   6729         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
   6730 	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   6731     }
   6732     /*
   6733      * Build the namespace constraints.
   6734      */
   6735     attr = xmlSchemaGetPropNode(node, "namespace");
   6736     ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6737     if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
   6738 	wildc->any = 1;
   6739     else if (xmlStrEqual(ns, BAD_CAST "##other")) {
   6740 	wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   6741 	if (wildc->negNsSet == NULL) {
   6742 	    return (-1);
   6743 	}
   6744 	wildc->negNsSet->value = ctxt->targetNamespace;
   6745     } else {
   6746 	const xmlChar *end, *cur;
   6747 
   6748 	cur = ns;
   6749 	do {
   6750 	    while (IS_BLANK_CH(*cur))
   6751 		cur++;
   6752 	    end = cur;
   6753 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   6754 		end++;
   6755 	    if (end == cur)
   6756 		break;
   6757 	    nsItem = xmlStrndup(cur, end - cur);
   6758 	    if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
   6759 		    (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
   6760 		xmlSchemaPSimpleTypeErr(ctxt,
   6761 		    XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
   6762 		    NULL, (xmlNodePtr) attr,
   6763 		    NULL,
   6764 		    "((##any | ##other) | List of (xs:anyURI | "
   6765 		    "(##targetNamespace | ##local)))",
   6766 		    nsItem, NULL, NULL, NULL);
   6767 		ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
   6768 	    } else {
   6769 		if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
   6770 		    dictnsItem = ctxt->targetNamespace;
   6771 		} else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
   6772 		    dictnsItem = NULL;
   6773 		} else {
   6774 		    /*
   6775 		    * Validate the item (anyURI).
   6776 		    */
   6777 		    xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
   6778 			nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
   6779 		    dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
   6780 		}
   6781 		/*
   6782 		* Avoid dublicate namespaces.
   6783 		*/
   6784 		tmp = wildc->nsSet;
   6785 		while (tmp != NULL) {
   6786 		    if (dictnsItem == tmp->value)
   6787 			break;
   6788 		    tmp = tmp->next;
   6789 		}
   6790 		if (tmp == NULL) {
   6791 		    tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
   6792 		    if (tmp == NULL) {
   6793 			xmlFree(nsItem);
   6794 			return (-1);
   6795 		    }
   6796 		    tmp->value = dictnsItem;
   6797 		    tmp->next = NULL;
   6798 		    if (wildc->nsSet == NULL)
   6799 			wildc->nsSet = tmp;
   6800 		    else
   6801 			lastNs->next = tmp;
   6802 		    lastNs = tmp;
   6803 		}
   6804 
   6805 	    }
   6806 	    xmlFree(nsItem);
   6807 	    cur = end;
   6808 	} while (*cur != 0);
   6809     }
   6810     return (ret);
   6811 }
   6812 
   6813 static int
   6814 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
   6815 				 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
   6816 				 xmlNodePtr node,
   6817 				 int minOccurs,
   6818 				 int maxOccurs) {
   6819 
   6820     if ((maxOccurs == 0) && ( minOccurs == 0))
   6821 	return (0);
   6822     if (maxOccurs != UNBOUNDED) {
   6823 	/*
   6824 	* TODO: Maybe we should better not create the particle,
   6825 	* if min/max is invalid, since it could confuse the build of the
   6826 	* content model.
   6827 	*/
   6828 	/*
   6829 	* 3.9.6 Schema Component Constraint: Particle Correct
   6830 	*
   6831 	*/
   6832 	if (maxOccurs < 1) {
   6833 	    /*
   6834 	    * 2.2 {max occurs} must be greater than or equal to 1.
   6835 	    */
   6836 	    xmlSchemaPCustomAttrErr(ctxt,
   6837 		XML_SCHEMAP_P_PROPS_CORRECT_2_2,
   6838 		NULL, NULL,
   6839 		xmlSchemaGetPropNode(node, "maxOccurs"),
   6840 		"The value must be greater than or equal to 1");
   6841 	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
   6842 	} else if (minOccurs > maxOccurs) {
   6843 	    /*
   6844 	    * 2.1 {min occurs} must not be greater than {max occurs}.
   6845 	    */
   6846 	    xmlSchemaPCustomAttrErr(ctxt,
   6847 		XML_SCHEMAP_P_PROPS_CORRECT_2_1,
   6848 		NULL, NULL,
   6849 		xmlSchemaGetPropNode(node, "minOccurs"),
   6850 		"The value must not be greater than the value of 'maxOccurs'");
   6851 	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
   6852 	}
   6853     }
   6854     return (0);
   6855 }
   6856 
   6857 /**
   6858  * xmlSchemaParseAny:
   6859  * @ctxt:  a schema validation context
   6860  * @schema:  the schema being built
   6861  * @node:  a subtree containing XML Schema informations
   6862  *
   6863  * Parsea a XML schema <any> element. A particle and wildcard
   6864  * will be created (except if minOccurs==maxOccurs==0, in this case
   6865  * nothing will be created).
   6866  * *WARNING* this interface is highly subject to change
   6867  *
   6868  * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
   6869  */
   6870 static xmlSchemaParticlePtr
   6871 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6872                   xmlNodePtr node)
   6873 {
   6874     xmlSchemaParticlePtr particle;
   6875     xmlNodePtr child = NULL;
   6876     xmlSchemaWildcardPtr wild;
   6877     int min, max;
   6878     xmlAttrPtr attr;
   6879     xmlSchemaAnnotPtr annot = NULL;
   6880 
   6881     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   6882         return (NULL);
   6883     /*
   6884     * Check for illegal attributes.
   6885     */
   6886     attr = node->properties;
   6887     while (attr != NULL) {
   6888 	if (attr->ns == NULL) {
   6889 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   6890 		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
   6891 		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
   6892 	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
   6893 		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
   6894 		xmlSchemaPIllegalAttrErr(ctxt,
   6895 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6896 	    }
   6897 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   6898 	    xmlSchemaPIllegalAttrErr(ctxt,
   6899 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6900 	}
   6901 	attr = attr->next;
   6902     }
   6903     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   6904     /*
   6905     * minOccurs/maxOccurs.
   6906     */
   6907     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
   6908 	"(xs:nonNegativeInteger | unbounded)");
   6909     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
   6910 	"xs:nonNegativeInteger");
   6911     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
   6912     /*
   6913     * Create & parse the wildcard.
   6914     */
   6915     wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
   6916     if (wild == NULL)
   6917 	return (NULL);
   6918     xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
   6919     /*
   6920     * And now for the children...
   6921     */
   6922     child = node->children;
   6923     if (IS_SCHEMA(child, "annotation")) {
   6924         annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   6925         child = child->next;
   6926     }
   6927     if (child != NULL) {
   6928 	xmlSchemaPContentErr(ctxt,
   6929 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   6930 	    NULL, node, child,
   6931 	    NULL, "(annotation?)");
   6932     }
   6933     /*
   6934     * No component if minOccurs==maxOccurs==0.
   6935     */
   6936     if ((min == 0) && (max == 0)) {
   6937 	/* Don't free the wildcard, since it's already on the list. */
   6938 	return (NULL);
   6939     }
   6940     /*
   6941     * Create the particle.
   6942     */
   6943     particle = xmlSchemaAddParticle(ctxt, node, min, max);
   6944     if (particle == NULL)
   6945         return (NULL);
   6946     particle->annot = annot;
   6947     particle->children = (xmlSchemaTreeItemPtr) wild;
   6948 
   6949     return (particle);
   6950 }
   6951 
   6952 /**
   6953  * xmlSchemaParseNotation:
   6954  * @ctxt:  a schema validation context
   6955  * @schema:  the schema being built
   6956  * @node:  a subtree containing XML Schema informations
   6957  *
   6958  * parse a XML schema Notation declaration
   6959  *
   6960  * Returns the new structure or NULL in case of error
   6961  */
   6962 static xmlSchemaNotationPtr
   6963 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6964                        xmlNodePtr node)
   6965 {
   6966     const xmlChar *name;
   6967     xmlSchemaNotationPtr ret;
   6968     xmlNodePtr child = NULL;
   6969 
   6970     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   6971         return (NULL);
   6972     name = xmlSchemaGetProp(ctxt, node, "name");
   6973     if (name == NULL) {
   6974         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
   6975                        "Notation has no name\n", NULL, NULL);
   6976         return (NULL);
   6977     }
   6978     ret = xmlSchemaAddNotation(ctxt, schema, name,
   6979 	ctxt->targetNamespace, node);
   6980     if (ret == NULL)
   6981         return (NULL);
   6982     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   6983 
   6984     child = node->children;
   6985     if (IS_SCHEMA(child, "annotation")) {
   6986         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   6987         child = child->next;
   6988     }
   6989     if (child != NULL) {
   6990 	xmlSchemaPContentErr(ctxt,
   6991 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   6992 	    NULL, node, child,
   6993 	    NULL, "(annotation?)");
   6994     }
   6995 
   6996     return (ret);
   6997 }
   6998 
   6999 /**
   7000  * xmlSchemaParseAnyAttribute:
   7001  * @ctxt:  a schema validation context
   7002  * @schema:  the schema being built
   7003  * @node:  a subtree containing XML Schema informations
   7004  *
   7005  * parse a XML schema AnyAttrribute declaration
   7006  * *WARNING* this interface is highly subject to change
   7007  *
   7008  * Returns a wildcard or NULL.
   7009  */
   7010 static xmlSchemaWildcardPtr
   7011 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
   7012                            xmlSchemaPtr schema, xmlNodePtr node)
   7013 {
   7014     xmlSchemaWildcardPtr ret;
   7015     xmlNodePtr child = NULL;
   7016     xmlAttrPtr attr;
   7017 
   7018     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   7019         return (NULL);
   7020 
   7021     ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
   7022 	node);
   7023     if (ret == NULL) {
   7024         return (NULL);
   7025     }
   7026     /*
   7027     * Check for illegal attributes.
   7028     */
   7029     attr = node->properties;
   7030     while (attr != NULL) {
   7031 	if (attr->ns == NULL) {
   7032 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   7033 	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
   7034 		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
   7035 		xmlSchemaPIllegalAttrErr(ctxt,
   7036 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7037 	    }
   7038 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7039 	    xmlSchemaPIllegalAttrErr(ctxt,
   7040 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7041 	}
   7042 	attr = attr->next;
   7043     }
   7044     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   7045     /*
   7046     * Parse the namespace list.
   7047     */
   7048     if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
   7049 	return (NULL);
   7050     /*
   7051     * And now for the children...
   7052     */
   7053     child = node->children;
   7054     if (IS_SCHEMA(child, "annotation")) {
   7055         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   7056         child = child->next;
   7057     }
   7058     if (child != NULL) {
   7059 	xmlSchemaPContentErr(ctxt,
   7060 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7061 	    NULL, node, child,
   7062 	    NULL, "(annotation?)");
   7063     }
   7064 
   7065     return (ret);
   7066 }
   7067 
   7068 
   7069 /**
   7070  * xmlSchemaParseAttribute:
   7071  * @ctxt:  a schema validation context
   7072  * @schema:  the schema being built
   7073  * @node:  a subtree containing XML Schema informations
   7074  *
   7075  * parse a XML schema Attrribute declaration
   7076  * *WARNING* this interface is highly subject to change
   7077  *
   7078  * Returns the attribute declaration.
   7079  */
   7080 static xmlSchemaBasicItemPtr
   7081 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
   7082 			     xmlSchemaPtr schema,
   7083 			     xmlNodePtr node,
   7084 			     xmlSchemaItemListPtr uses,
   7085 			     int parentType)
   7086 {
   7087     const xmlChar *attrValue, *name = NULL, *ns = NULL;
   7088     xmlSchemaAttributeUsePtr use = NULL;
   7089     xmlNodePtr child = NULL;
   7090     xmlAttrPtr attr;
   7091     const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
   7092     int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
   7093     int	nberrors, hasForm = 0, defValueType = 0;
   7094 
   7095 #define WXS_ATTR_DEF_VAL_DEFAULT 1
   7096 #define WXS_ATTR_DEF_VAL_FIXED 2
   7097 
   7098     /*
   7099      * 3.2.3 Constraints on XML Representations of Attribute Declarations
   7100      */
   7101 
   7102     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7103         return (NULL);
   7104     attr = xmlSchemaGetPropNode(node, "ref");
   7105     if (attr != NULL) {
   7106 	if (xmlSchemaPValAttrNodeQName(pctxt, schema,
   7107 	    NULL, attr, &tmpNs, &tmpName) != 0) {
   7108 	    return (NULL);
   7109 	}
   7110 	if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
   7111 	    return(NULL);
   7112 	isRef = 1;
   7113     }
   7114     nberrors = pctxt->nberrors;
   7115     /*
   7116     * Check for illegal attributes.
   7117     */
   7118     attr = node->properties;
   7119     while (attr != NULL) {
   7120 	if (attr->ns == NULL) {
   7121 	    if (isRef) {
   7122 		if (xmlStrEqual(attr->name, BAD_CAST "id")) {
   7123 		    xmlSchemaPValAttrNodeID(pctxt, attr);
   7124 		    goto attr_next;
   7125 		} else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
   7126 		    goto attr_next;
   7127 		}
   7128 	    } else {
   7129 		if (xmlStrEqual(attr->name, BAD_CAST "name")) {
   7130 		    goto attr_next;
   7131 		} else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
   7132 		    xmlSchemaPValAttrNodeID(pctxt, attr);
   7133 		    goto attr_next;
   7134 		} else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
   7135 		    xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
   7136 			attr, &tmpNs, &tmpName);
   7137 		    goto attr_next;
   7138 		} else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
   7139 		    /*
   7140 		    * Evaluate the target namespace
   7141 		    */
   7142 		    hasForm = 1;
   7143 		    attrValue = xmlSchemaGetNodeContent(pctxt,
   7144 			(xmlNodePtr) attr);
   7145 		    if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
   7146 			ns = pctxt->targetNamespace;
   7147 		    } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
   7148 		    {
   7149 			xmlSchemaPSimpleTypeErr(pctxt,
   7150 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   7151 			    NULL, (xmlNodePtr) attr,
   7152 			    NULL, "(qualified | unqualified)",
   7153 			    attrValue, NULL, NULL, NULL);
   7154 		    }
   7155 		    goto attr_next;
   7156 		}
   7157 	    }
   7158 	    if (xmlStrEqual(attr->name, BAD_CAST "use")) {
   7159 
   7160 		attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7161 		/* TODO: Maybe we need to normalize the value beforehand. */
   7162 		if (xmlStrEqual(attrValue, BAD_CAST "optional"))
   7163 		    occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
   7164 		else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
   7165 		    occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
   7166 		else if (xmlStrEqual(attrValue, BAD_CAST "required"))
   7167 		    occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
   7168 		else {
   7169 		    xmlSchemaPSimpleTypeErr(pctxt,
   7170 			XML_SCHEMAP_INVALID_ATTR_USE,
   7171 			NULL, (xmlNodePtr) attr,
   7172 			NULL, "(optional | prohibited | required)",
   7173 			attrValue, NULL, NULL, NULL);
   7174 		}
   7175 		goto attr_next;
   7176 	    } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
   7177 		/*
   7178 		* 3.2.3 : 1
   7179 		* default and fixed must not both be present.
   7180 		*/
   7181 		if (defValue) {
   7182 		    xmlSchemaPMutualExclAttrErr(pctxt,
   7183 			XML_SCHEMAP_SRC_ATTRIBUTE_1,
   7184 			NULL, attr, "default", "fixed");
   7185 		} else {
   7186 		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7187 		    defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
   7188 		}
   7189 		goto attr_next;
   7190 	    } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
   7191 		/*
   7192 		* 3.2.3 : 1
   7193 		* default and fixed must not both be present.
   7194 		*/
   7195 		if (defValue) {
   7196 		    xmlSchemaPMutualExclAttrErr(pctxt,
   7197 			XML_SCHEMAP_SRC_ATTRIBUTE_1,
   7198 			NULL, attr, "default", "fixed");
   7199 		} else {
   7200 		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7201 		    defValueType = WXS_ATTR_DEF_VAL_FIXED;
   7202 		}
   7203 		goto attr_next;
   7204 	    }
   7205 	} else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
   7206 	    goto attr_next;
   7207 
   7208 	xmlSchemaPIllegalAttrErr(pctxt,
   7209 	    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7210 
   7211 attr_next:
   7212 	attr = attr->next;
   7213     }
   7214     /*
   7215     * 3.2.3 : 2
   7216     * If default and use are both present, use must have
   7217     * the actual value optional.
   7218     */
   7219     if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
   7220 	(occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
   7221 	xmlSchemaPSimpleTypeErr(pctxt,
   7222 	    XML_SCHEMAP_SRC_ATTRIBUTE_2,
   7223 	    NULL, node, NULL,
   7224 	    "(optional | prohibited | required)", NULL,
   7225 	    "The value of the attribute 'use' must be 'optional' "
   7226 	    "if the attribute 'default' is present",
   7227 	    NULL, NULL);
   7228     }
   7229     /*
   7230     * We want correct attributes.
   7231     */
   7232     if (nberrors != pctxt->nberrors)
   7233 	return(NULL);
   7234     if (! isRef) {
   7235 	xmlSchemaAttributePtr attrDecl;
   7236 
   7237 	/* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
   7238 	if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
   7239 	    ns = pctxt->targetNamespace;
   7240 	/*
   7241 	* 3.2.6 Schema Component Constraint: xsi: Not Allowed
   7242 	* TODO: Move this to the component layer.
   7243 	*/
   7244 	if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
   7245 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   7246 		XML_SCHEMAP_NO_XSI,
   7247 		node, NULL,
   7248 		"The target namespace must not match '%s'",
   7249 		xmlSchemaInstanceNs, NULL);
   7250 	}
   7251 	attr = xmlSchemaGetPropNode(node, "name");
   7252 	if (attr == NULL) {
   7253 	    xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
   7254 		NULL, node, "name", NULL);
   7255 	    return (NULL);
   7256 	}
   7257 	if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
   7258 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   7259 	    return (NULL);
   7260 	}
   7261 	/*
   7262 	* 3.2.6 Schema Component Constraint: xmlns Not Allowed
   7263 	* TODO: Move this to the component layer.
   7264 	*/
   7265 	if (xmlStrEqual(name, BAD_CAST "xmlns")) {
   7266 	    xmlSchemaPSimpleTypeErr(pctxt,
   7267 		XML_SCHEMAP_NO_XMLNS,
   7268 		NULL, (xmlNodePtr) attr,
   7269 		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
   7270 		"The value of the attribute must not match 'xmlns'",
   7271 		NULL, NULL);
   7272 	    return (NULL);
   7273 	}
   7274 	if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
   7275 	    goto check_children;
   7276 	/*
   7277 	* Create the attribute use component.
   7278 	*/
   7279 	use = xmlSchemaAddAttributeUse(pctxt, node);
   7280 	if (use == NULL)
   7281 	    return(NULL);
   7282 	use->occurs = occurs;
   7283 	/*
   7284 	* Create the attribute declaration.
   7285 	*/
   7286 	attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
   7287 	if (attrDecl == NULL)
   7288 	    return (NULL);
   7289 	if (tmpName != NULL) {
   7290 	    attrDecl->typeName = tmpName;
   7291 	    attrDecl->typeNs = tmpNs;
   7292 	}
   7293 	use->attrDecl = attrDecl;
   7294 	/*
   7295 	* Value constraint.
   7296 	*/
   7297 	if (defValue != NULL) {
   7298 	    attrDecl->defValue = defValue;
   7299 	    if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
   7300 		attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
   7301 	}
   7302     } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
   7303 	xmlSchemaQNameRefPtr ref;
   7304 
   7305 	/*
   7306 	* Create the attribute use component.
   7307 	*/
   7308 	use = xmlSchemaAddAttributeUse(pctxt, node);
   7309 	if (use == NULL)
   7310 	    return(NULL);
   7311 	/*
   7312 	* We need to resolve the reference at later stage.
   7313 	*/
   7314 	WXS_ADD_PENDING(pctxt, use);
   7315 	use->occurs = occurs;
   7316 	/*
   7317 	* Create a QName reference to the attribute declaration.
   7318 	*/
   7319 	ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
   7320 	    tmpName, tmpNs);
   7321 	if (ref == NULL)
   7322 	    return(NULL);
   7323 	/*
   7324 	* Assign the reference. This will be substituted for the
   7325 	* referenced attribute declaration when the QName is resolved.
   7326 	*/
   7327 	use->attrDecl = WXS_ATTR_CAST ref;
   7328 	/*
   7329 	* Value constraint.
   7330 	*/
   7331 	if (defValue != NULL)
   7332 	    use->defValue = defValue;
   7333 	    if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
   7334 		use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
   7335     }
   7336 
   7337 check_children:
   7338     /*
   7339     * And now for the children...
   7340     */
   7341     child = node->children;
   7342     if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
   7343 	xmlSchemaAttributeUseProhibPtr prohib;
   7344 
   7345 	if (IS_SCHEMA(child, "annotation")) {
   7346 	    xmlSchemaParseAnnotation(pctxt, child, 0);
   7347 	    child = child->next;
   7348 	}
   7349 	if (child != NULL) {
   7350 	    xmlSchemaPContentErr(pctxt,
   7351 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7352 		NULL, node, child, NULL,
   7353 		"(annotation?)");
   7354 	}
   7355 	/*
   7356 	* Check for pointlessness of attribute prohibitions.
   7357 	*/
   7358 	if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
   7359 	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   7360 		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   7361 		node, NULL,
   7362 		"Skipping attribute use prohibition, since it is "
   7363 		"pointless inside an <attributeGroup>",
   7364 		NULL, NULL, NULL);
   7365 	    return(NULL);
   7366 	} else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
   7367 	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   7368 		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   7369 		node, NULL,
   7370 		"Skipping attribute use prohibition, since it is "
   7371 		"pointless when extending a type",
   7372 		NULL, NULL, NULL);
   7373 	    return(NULL);
   7374 	}
   7375 	if (! isRef) {
   7376 	    tmpName = name;
   7377 	    tmpNs = ns;
   7378 	}
   7379 	/*
   7380 	* Check for duplicate attribute prohibitions.
   7381 	*/
   7382 	if (uses) {
   7383 	    int i;
   7384 
   7385 	    for (i = 0; i < uses->nbItems; i++) {
   7386 		use = uses->items[i];
   7387 		if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
   7388 		    (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
   7389 		    (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
   7390 		{
   7391 		    xmlChar *str = NULL;
   7392 
   7393 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   7394 			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   7395 			node, NULL,
   7396 			"Skipping duplicate attribute use prohibition '%s'",
   7397 			xmlSchemaFormatQName(&str, tmpNs, tmpName),
   7398 			NULL, NULL);
   7399 		    FREE_AND_NULL(str)
   7400 		    return(NULL);
   7401 		}
   7402 	    }
   7403 	}
   7404 	/*
   7405 	* Create the attribute prohibition helper component.
   7406 	*/
   7407 	prohib = xmlSchemaAddAttributeUseProhib(pctxt);
   7408 	if (prohib == NULL)
   7409 	    return(NULL);
   7410 	prohib->node = node;
   7411 	prohib->name = tmpName;
   7412 	prohib->targetNamespace = tmpNs;
   7413 	if (isRef) {
   7414 	    /*
   7415 	    * We need at least to resolve to the attribute declaration.
   7416 	    */
   7417 	    WXS_ADD_PENDING(pctxt, prohib);
   7418 	}
   7419 	return(WXS_BASIC_CAST prohib);
   7420     } else {
   7421 	if (IS_SCHEMA(child, "annotation")) {
   7422 	    /*
   7423 	    * TODO: Should this go into the attr decl?
   7424 	    */
   7425 	    use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
   7426 	    child = child->next;
   7427 	}
   7428 	if (isRef) {
   7429 	    if (child != NULL) {
   7430 		if (IS_SCHEMA(child, "simpleType"))
   7431 		    /*
   7432 		    * 3.2.3 : 3.2
   7433 		    * If ref is present, then all of <simpleType>,
   7434 		    * form and type must be absent.
   7435 		    */
   7436 		    xmlSchemaPContentErr(pctxt,
   7437 			XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
   7438 			NULL, node, child, NULL,
   7439 			"(annotation?)");
   7440 		else
   7441 		    xmlSchemaPContentErr(pctxt,
   7442 			XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7443 			NULL, node, child, NULL,
   7444 			"(annotation?)");
   7445 	    }
   7446 	} else {
   7447 	    if (IS_SCHEMA(child, "simpleType")) {
   7448 		if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
   7449 		    /*
   7450 		    * 3.2.3 : 4
   7451 		    * type and <simpleType> must not both be present.
   7452 		    */
   7453 		    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
   7454 			NULL, node, child,
   7455 			"The attribute 'type' and the <simpleType> child "
   7456 			"are mutually exclusive", NULL);
   7457 		} else
   7458 		    WXS_ATTRUSE_TYPEDEF(use) =
   7459 			xmlSchemaParseSimpleType(pctxt, schema, child, 0);
   7460 		child = child->next;
   7461 	    }
   7462 	    if (child != NULL)
   7463 		xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7464 		NULL, node, child, NULL,
   7465 		"(annotation?, simpleType?)");
   7466 	}
   7467     }
   7468     return (WXS_BASIC_CAST use);
   7469 }
   7470 
   7471 
   7472 static xmlSchemaAttributePtr
   7473 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
   7474 			      xmlSchemaPtr schema,
   7475 			      xmlNodePtr node)
   7476 {
   7477     const xmlChar *attrValue;
   7478     xmlSchemaAttributePtr ret;
   7479     xmlNodePtr child = NULL;
   7480     xmlAttrPtr attr;
   7481 
   7482     /*
   7483      * Note that the w3c spec assumes the schema to be validated with schema
   7484      * for schemas beforehand.
   7485      *
   7486      * 3.2.3 Constraints on XML Representations of Attribute Declarations
   7487      */
   7488     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7489         return (NULL);
   7490     /*
   7491     * 3.2.3 : 3.1
   7492     * One of ref or name must be present, but not both
   7493     */
   7494     attr = xmlSchemaGetPropNode(node, "name");
   7495     if (attr == NULL) {
   7496 	xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
   7497 	    NULL, node, "name", NULL);
   7498 	return (NULL);
   7499     }
   7500     if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
   7501 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
   7502 	return (NULL);
   7503     }
   7504     /*
   7505     * 3.2.6 Schema Component Constraint: xmlns Not Allowed
   7506     * TODO: Move this to the component layer.
   7507     */
   7508     if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
   7509 	xmlSchemaPSimpleTypeErr(pctxt,
   7510 	    XML_SCHEMAP_NO_XMLNS,
   7511 	    NULL, (xmlNodePtr) attr,
   7512 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
   7513 	    "The value of the attribute must not match 'xmlns'",
   7514 	    NULL, NULL);
   7515 	return (NULL);
   7516     }
   7517     /*
   7518     * 3.2.6 Schema Component Constraint: xsi: Not Allowed
   7519     * TODO: Move this to the component layer.
   7520     *       Or better leave it here and add it to the component layer
   7521     *       if we have a schema construction API.
   7522     */
   7523     if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
   7524 	xmlSchemaCustomErr(ACTXT_CAST pctxt,
   7525 	    XML_SCHEMAP_NO_XSI, node, NULL,
   7526 	    "The target namespace must not match '%s'",
   7527 	    xmlSchemaInstanceNs, NULL);
   7528     }
   7529 
   7530     ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
   7531 	pctxt->targetNamespace, node, 1);
   7532     if (ret == NULL)
   7533 	return (NULL);
   7534     ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
   7535 
   7536     /*
   7537     * Check for illegal attributes.
   7538     */
   7539     attr = node->properties;
   7540     while (attr != NULL) {
   7541 	if (attr->ns == NULL) {
   7542 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   7543 		(!xmlStrEqual(attr->name, BAD_CAST "default")) &&
   7544 		(!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
   7545 		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   7546 		(!xmlStrEqual(attr->name, BAD_CAST "type")))
   7547 	    {
   7548 		xmlSchemaPIllegalAttrErr(pctxt,
   7549 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7550 	    }
   7551 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7552 	    xmlSchemaPIllegalAttrErr(pctxt,
   7553 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7554 	}
   7555 	attr = attr->next;
   7556     }
   7557     xmlSchemaPValAttrQName(pctxt, schema, NULL,
   7558 	node, "type", &ret->typeNs, &ret->typeName);
   7559 
   7560     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   7561     /*
   7562     * Attribute "fixed".
   7563     */
   7564     ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
   7565     if (ret->defValue != NULL)
   7566 	ret->flags |= XML_SCHEMAS_ATTR_FIXED;
   7567     /*
   7568     * Attribute "default".
   7569     */
   7570     attr = xmlSchemaGetPropNode(node, "default");
   7571     if (attr != NULL) {
   7572 	/*
   7573 	* 3.2.3 : 1
   7574 	* default and fixed must not both be present.
   7575 	*/
   7576 	if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
   7577 	    xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
   7578 		WXS_BASIC_CAST ret, attr, "default", "fixed");
   7579 	} else
   7580 	    ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7581     }
   7582     /*
   7583     * And now for the children...
   7584     */
   7585     child = node->children;
   7586     if (IS_SCHEMA(child, "annotation")) {
   7587         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
   7588         child = child->next;
   7589     }
   7590     if (IS_SCHEMA(child, "simpleType")) {
   7591 	if (ret->typeName != NULL) {
   7592 	    /*
   7593 	    * 3.2.3 : 4
   7594 	    * type and <simpleType> must not both be present.
   7595 	    */
   7596 	    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
   7597 		NULL, node, child,
   7598 		"The attribute 'type' and the <simpleType> child "
   7599 		"are mutually exclusive", NULL);
   7600 	} else
   7601 	    ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
   7602 	child = child->next;
   7603     }
   7604     if (child != NULL)
   7605 	xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7606 	    NULL, node, child, NULL,
   7607 	    "(annotation?, simpleType?)");
   7608 
   7609     return (ret);
   7610 }
   7611 
   7612 /**
   7613  * xmlSchemaParseAttributeGroupRef:
   7614  * @ctxt:  a schema validation context
   7615  * @schema:  the schema being built
   7616  * @node:  a subtree containing XML Schema informations
   7617  *
   7618  * Parse an attribute group definition reference.
   7619  * Note that a reference to an attribute group does not
   7620  * correspond to any component at all.
   7621  * *WARNING* this interface is highly subject to change
   7622  *
   7623  * Returns the attribute group or NULL in case of error.
   7624  */
   7625 static xmlSchemaQNameRefPtr
   7626 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
   7627 				xmlSchemaPtr schema,
   7628 				xmlNodePtr node)
   7629 {
   7630     xmlSchemaQNameRefPtr ret;
   7631     xmlNodePtr child = NULL;
   7632     xmlAttrPtr attr;
   7633     const xmlChar *refNs = NULL, *ref = NULL;
   7634 
   7635     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7636         return (NULL);
   7637 
   7638     attr = xmlSchemaGetPropNode(node, "ref");
   7639     if (attr == NULL) {
   7640 	xmlSchemaPMissingAttrErr(pctxt,
   7641 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   7642 	    NULL, node, "ref", NULL);
   7643 	return (NULL);
   7644     }
   7645     xmlSchemaPValAttrNodeQName(pctxt, schema,
   7646 	NULL, attr, &refNs, &ref);
   7647     if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
   7648 	return(NULL);
   7649 
   7650     /*
   7651     * Check for illegal attributes.
   7652     */
   7653     attr = node->properties;
   7654     while (attr != NULL) {
   7655 	if (attr->ns == NULL) {
   7656 	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
   7657 		(!xmlStrEqual(attr->name, BAD_CAST "id")))
   7658 	    {
   7659 		xmlSchemaPIllegalAttrErr(pctxt,
   7660 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7661 	    }
   7662 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7663 	    xmlSchemaPIllegalAttrErr(pctxt,
   7664 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7665 	}
   7666 	attr = attr->next;
   7667     }
   7668     /* Attribute ID */
   7669     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   7670 
   7671     /*
   7672     * And now for the children...
   7673     */
   7674     child = node->children;
   7675     if (IS_SCHEMA(child, "annotation")) {
   7676 	/*
   7677 	* TODO: We do not have a place to store the annotation, do we?
   7678 	*/
   7679         xmlSchemaParseAnnotation(pctxt, child, 0);
   7680         child = child->next;
   7681     }
   7682     if (child != NULL) {
   7683 	xmlSchemaPContentErr(pctxt,
   7684 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7685 	    NULL, node, child, NULL,
   7686 	    "(annotation?)");
   7687     }
   7688 
   7689     /*
   7690     * Handle attribute group redefinitions.
   7691     */
   7692     if (pctxt->isRedefine && pctxt->redef &&
   7693 	(pctxt->redef->item->type ==
   7694 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
   7695 	(ref == pctxt->redef->refName) &&
   7696 	(refNs == pctxt->redef->refTargetNs))
   7697     {
   7698 	/*
   7699 	* SPEC src-redefine:
   7700 	* (7.1) "If it has an <attributeGroup> among its contents
   7701 	* the actual value of whose ref [attribute] is the same
   7702 	* as the actual value of its own name attribute plus
   7703 	* target namespace, then it must have exactly one such group."
   7704 	*/
   7705 	if (pctxt->redefCounter != 0) {
   7706 	    xmlChar *str = NULL;
   7707 
   7708 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   7709 		XML_SCHEMAP_SRC_REDEFINE, node, NULL,
   7710 		"The redefining attribute group definition "
   7711 		"'%s' must not contain more than one "
   7712 		"reference to the redefined definition",
   7713 		xmlSchemaFormatQName(&str, refNs, ref), NULL);
   7714 	    FREE_AND_NULL(str);
   7715 	    return(NULL);
   7716 	}
   7717 	pctxt->redefCounter++;
   7718 	/*
   7719 	* URGENT TODO: How to ensure that the reference will not be
   7720 	* handled by the normal component resolution mechanism?
   7721 	*/
   7722 	ret = xmlSchemaNewQNameRef(pctxt,
   7723 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
   7724 	if (ret == NULL)
   7725 	    return(NULL);
   7726 	ret->node = node;
   7727 	pctxt->redef->reference = WXS_BASIC_CAST ret;
   7728     } else {
   7729 	/*
   7730 	* Create a QName-reference helper component. We will substitute this
   7731 	* component for the attribute uses of the referenced attribute group
   7732 	* definition.
   7733 	*/
   7734 	ret = xmlSchemaNewQNameRef(pctxt,
   7735 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
   7736 	if (ret == NULL)
   7737 	    return(NULL);
   7738 	ret->node = node;
   7739 	/* Add to pending items, to be able to resolve the reference. */
   7740 	WXS_ADD_PENDING(pctxt, ret);
   7741     }
   7742     return (ret);
   7743 }
   7744 
   7745 /**
   7746  * xmlSchemaParseAttributeGroupDefinition:
   7747  * @pctxt:  a schema validation context
   7748  * @schema:  the schema being built
   7749  * @node:  a subtree containing XML Schema informations
   7750  *
   7751  * parse a XML schema Attribute Group declaration
   7752  * *WARNING* this interface is highly subject to change
   7753  *
   7754  * Returns the attribute group definition or NULL in case of error.
   7755  */
   7756 static xmlSchemaAttributeGroupPtr
   7757 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
   7758 				       xmlSchemaPtr schema,
   7759 				       xmlNodePtr node)
   7760 {
   7761     const xmlChar *name;
   7762     xmlSchemaAttributeGroupPtr ret;
   7763     xmlNodePtr child = NULL;
   7764     xmlAttrPtr attr;
   7765     int hasRefs = 0;
   7766 
   7767     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7768         return (NULL);
   7769 
   7770     attr = xmlSchemaGetPropNode(node, "name");
   7771     if (attr == NULL) {
   7772 	xmlSchemaPMissingAttrErr(pctxt,
   7773 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   7774 	    NULL, node, "name", NULL);
   7775 	return (NULL);
   7776     }
   7777     /*
   7778     * The name is crucial, exit if invalid.
   7779     */
   7780     if (xmlSchemaPValAttrNode(pctxt,
   7781 	NULL, attr,
   7782 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   7783 	return (NULL);
   7784     }
   7785     ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
   7786 	name, pctxt->targetNamespace, node);
   7787     if (ret == NULL)
   7788 	return (NULL);
   7789     /*
   7790     * Check for illegal attributes.
   7791     */
   7792     attr = node->properties;
   7793     while (attr != NULL) {
   7794 	if (attr->ns == NULL) {
   7795 	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   7796 		(!xmlStrEqual(attr->name, BAD_CAST "id")))
   7797 	    {
   7798 		xmlSchemaPIllegalAttrErr(pctxt,
   7799 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7800 	    }
   7801 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7802 	    xmlSchemaPIllegalAttrErr(pctxt,
   7803 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7804 	}
   7805 	attr = attr->next;
   7806     }
   7807     /* Attribute ID */
   7808     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   7809     /*
   7810     * And now for the children...
   7811     */
   7812     child = node->children;
   7813     if (IS_SCHEMA(child, "annotation")) {
   7814         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
   7815         child = child->next;
   7816     }
   7817     /*
   7818     * Parse contained attribute decls/refs.
   7819     */
   7820     if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
   7821 	(xmlSchemaItemListPtr *) &(ret->attrUses),
   7822 	XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
   7823 	return(NULL);
   7824     if (hasRefs)
   7825 	ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
   7826     /*
   7827     * Parse the attribute wildcard.
   7828     */
   7829     if (IS_SCHEMA(child, "anyAttribute")) {
   7830 	ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
   7831 	    schema, child);
   7832 	child = child->next;
   7833     }
   7834     if (child != NULL) {
   7835 	xmlSchemaPContentErr(pctxt,
   7836 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7837 	    NULL, node, child, NULL,
   7838 	    "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
   7839     }
   7840     return (ret);
   7841 }
   7842 
   7843 /**
   7844  * xmlSchemaPValAttrFormDefault:
   7845  * @value:  the value
   7846  * @flags: the flags to be modified
   7847  * @flagQualified: the specific flag for "qualified"
   7848  *
   7849  * Returns 0 if the value is valid, 1 otherwise.
   7850  */
   7851 static int
   7852 xmlSchemaPValAttrFormDefault(const xmlChar *value,
   7853 			     int *flags,
   7854 			     int flagQualified)
   7855 {
   7856     if (xmlStrEqual(value, BAD_CAST "qualified")) {
   7857 	if  ((*flags & flagQualified) == 0)
   7858 	    *flags |= flagQualified;
   7859     } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
   7860 	return (1);
   7861 
   7862     return (0);
   7863 }
   7864 
   7865 /**
   7866  * xmlSchemaPValAttrBlockFinal:
   7867  * @value:  the value
   7868  * @flags: the flags to be modified
   7869  * @flagAll: the specific flag for "#all"
   7870  * @flagExtension: the specific flag for "extension"
   7871  * @flagRestriction: the specific flag for "restriction"
   7872  * @flagSubstitution: the specific flag for "substitution"
   7873  * @flagList: the specific flag for "list"
   7874  * @flagUnion: the specific flag for "union"
   7875  *
   7876  * Validates the value of the attribute "final" and "block". The value
   7877  * is converted into the specified flag values and returned in @flags.
   7878  *
   7879  * Returns 0 if the value is valid, 1 otherwise.
   7880  */
   7881 
   7882 static int
   7883 xmlSchemaPValAttrBlockFinal(const xmlChar *value,
   7884 			    int *flags,
   7885 			    int flagAll,
   7886 			    int flagExtension,
   7887 			    int flagRestriction,
   7888 			    int flagSubstitution,
   7889 			    int flagList,
   7890 			    int flagUnion)
   7891 {
   7892     int ret = 0;
   7893 
   7894     /*
   7895     * TODO: This does not check for dublicate entries.
   7896     */
   7897     if ((flags == NULL) || (value == NULL))
   7898 	return (-1);
   7899     if (value[0] == 0)
   7900 	return (0);
   7901     if (xmlStrEqual(value, BAD_CAST "#all")) {
   7902 	if (flagAll != -1)
   7903 	    *flags |= flagAll;
   7904 	else {
   7905 	    if (flagExtension != -1)
   7906 		*flags |= flagExtension;
   7907 	    if (flagRestriction != -1)
   7908 		*flags |= flagRestriction;
   7909 	    if (flagSubstitution != -1)
   7910 		*flags |= flagSubstitution;
   7911 	    if (flagList != -1)
   7912 		*flags |= flagList;
   7913 	    if (flagUnion != -1)
   7914 		*flags |= flagUnion;
   7915 	}
   7916     } else {
   7917 	const xmlChar *end, *cur = value;
   7918 	xmlChar *item;
   7919 
   7920 	do {
   7921 	    while (IS_BLANK_CH(*cur))
   7922 		cur++;
   7923 	    end = cur;
   7924 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   7925 		end++;
   7926 	    if (end == cur)
   7927 		break;
   7928 	    item = xmlStrndup(cur, end - cur);
   7929 	    if (xmlStrEqual(item, BAD_CAST "extension")) {
   7930 		if (flagExtension != -1) {
   7931 		    if ((*flags & flagExtension) == 0)
   7932 			*flags |= flagExtension;
   7933 		} else
   7934 		    ret = 1;
   7935 	    } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
   7936 		if (flagRestriction != -1) {
   7937 		    if ((*flags & flagRestriction) == 0)
   7938 			*flags |= flagRestriction;
   7939 		} else
   7940 		    ret = 1;
   7941 	    } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
   7942 		if (flagSubstitution != -1) {
   7943 		    if ((*flags & flagSubstitution) == 0)
   7944 			*flags |= flagSubstitution;
   7945 		} else
   7946 		    ret = 1;
   7947 	    } else if (xmlStrEqual(item, BAD_CAST "list")) {
   7948 		if (flagList != -1) {
   7949 		    if ((*flags & flagList) == 0)
   7950 			*flags |= flagList;
   7951 		} else
   7952 		    ret = 1;
   7953 	    } else if (xmlStrEqual(item, BAD_CAST "union")) {
   7954 		if (flagUnion != -1) {
   7955 		    if ((*flags & flagUnion) == 0)
   7956 			*flags |= flagUnion;
   7957 		} else
   7958 		    ret = 1;
   7959 	    } else
   7960 		ret = 1;
   7961 	    if (item != NULL)
   7962 		xmlFree(item);
   7963 	    cur = end;
   7964 	} while ((ret == 0) && (*cur != 0));
   7965     }
   7966 
   7967     return (ret);
   7968 }
   7969 
   7970 static int
   7971 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
   7972 			     xmlSchemaIDCPtr idc,
   7973 			     xmlSchemaIDCSelectPtr selector,
   7974 			     xmlAttrPtr attr,
   7975 			     int isField)
   7976 {
   7977     xmlNodePtr node;
   7978 
   7979     /*
   7980     * c-selector-xpath:
   7981     * Schema Component Constraint: Selector Value OK
   7982     *
   7983     * TODO: 1 The {selector} must be a valid XPath expression, as defined
   7984     * in [XPath].
   7985     */
   7986     if (selector == NULL) {
   7987 	xmlSchemaPErr(ctxt, idc->node,
   7988 	    XML_SCHEMAP_INTERNAL,
   7989 	    "Internal error: xmlSchemaCheckCSelectorXPath, "
   7990 	    "the selector is not specified.\n", NULL, NULL);
   7991 	return (-1);
   7992     }
   7993     if (attr == NULL)
   7994 	node = idc->node;
   7995     else
   7996 	node = (xmlNodePtr) attr;
   7997     if (selector->xpath == NULL) {
   7998 	xmlSchemaPCustomErr(ctxt,
   7999 	    /* TODO: Adjust error code. */
   8000 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8001 	    NULL, node,
   8002 	    "The XPath expression of the selector is not valid", NULL);
   8003 	return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
   8004     } else {
   8005 	const xmlChar **nsArray = NULL;
   8006 	xmlNsPtr *nsList = NULL;
   8007 	/*
   8008 	* Compile the XPath expression.
   8009 	*/
   8010 	/*
   8011 	* TODO: We need the array of in-scope namespaces for compilation.
   8012 	* TODO: Call xmlPatterncompile with different options for selector/
   8013 	* field.
   8014 	*/
   8015 	if (attr == NULL)
   8016 	    nsList = NULL;
   8017 	else
   8018 	    nsList = xmlGetNsList(attr->doc, attr->parent);
   8019 	/*
   8020 	* Build an array of prefixes and namespaces.
   8021 	*/
   8022 	if (nsList != NULL) {
   8023 	    int i, count = 0;
   8024 
   8025 	    for (i = 0; nsList[i] != NULL; i++)
   8026 		count++;
   8027 
   8028 	    nsArray = (const xmlChar **) xmlMalloc(
   8029 		(count * 2 + 1) * sizeof(const xmlChar *));
   8030 	    if (nsArray == NULL) {
   8031 		xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
   8032 		    NULL);
   8033 		xmlFree(nsList);
   8034 		return (-1);
   8035 	    }
   8036 	    for (i = 0; i < count; i++) {
   8037 		nsArray[2 * i] = nsList[i]->href;
   8038 		nsArray[2 * i + 1] = nsList[i]->prefix;
   8039 	    }
   8040 	    nsArray[count * 2] = NULL;
   8041 	    xmlFree(nsList);
   8042 	}
   8043 	/*
   8044 	* TODO: Differentiate between "selector" and "field".
   8045 	*/
   8046 	if (isField)
   8047 	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
   8048 		NULL, XML_PATTERN_XSFIELD, nsArray);
   8049 	else
   8050 	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
   8051 		NULL, XML_PATTERN_XSSEL, nsArray);
   8052 	if (nsArray != NULL)
   8053 	    xmlFree((xmlChar **) nsArray);
   8054 
   8055 	if (selector->xpathComp == NULL) {
   8056 	    xmlSchemaPCustomErr(ctxt,
   8057 		/* TODO: Adjust error code? */
   8058 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8059 		NULL, node,
   8060 		"The XPath expression '%s' could not be "
   8061 		"compiled", selector->xpath);
   8062 	    return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
   8063 	}
   8064     }
   8065     return (0);
   8066 }
   8067 
   8068 #define ADD_ANNOTATION(annot)   \
   8069     xmlSchemaAnnotPtr cur = item->annot; \
   8070     if (item->annot == NULL) {  \
   8071 	item->annot = annot;    \
   8072 	return (annot);         \
   8073     }                           \
   8074     cur = item->annot;          \
   8075     if (cur->next != NULL) {    \
   8076 	cur = cur->next;	\
   8077     }                           \
   8078     cur->next = annot;
   8079 
   8080 /**
   8081  * xmlSchemaAssignAnnotation:
   8082  * @item: the schema component
   8083  * @annot: the annotation
   8084  *
   8085  * Adds the annotation to the given schema component.
   8086  *
   8087  * Returns the given annotaion.
   8088  */
   8089 static xmlSchemaAnnotPtr
   8090 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
   8091 		       xmlSchemaAnnotPtr annot)
   8092 {
   8093     if ((annItem == NULL) || (annot == NULL))
   8094 	return (NULL);
   8095     switch (annItem->type) {
   8096 	case XML_SCHEMA_TYPE_ELEMENT: {
   8097 		xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
   8098 		ADD_ANNOTATION(annot)
   8099 	    }
   8100 	    break;
   8101 	case XML_SCHEMA_TYPE_ATTRIBUTE: {
   8102 		xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
   8103 		ADD_ANNOTATION(annot)
   8104 	    }
   8105 	    break;
   8106 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   8107 	case XML_SCHEMA_TYPE_ANY: {
   8108 		xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
   8109 		ADD_ANNOTATION(annot)
   8110 	    }
   8111 	    break;
   8112 	case XML_SCHEMA_TYPE_PARTICLE:
   8113 	case XML_SCHEMA_TYPE_IDC_KEY:
   8114 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   8115 	case XML_SCHEMA_TYPE_IDC_UNIQUE: {
   8116 		xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
   8117 		ADD_ANNOTATION(annot)
   8118 	    }
   8119 	    break;
   8120 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
   8121 		xmlSchemaAttributeGroupPtr item =
   8122 		    (xmlSchemaAttributeGroupPtr) annItem;
   8123 		ADD_ANNOTATION(annot)
   8124 	    }
   8125 	    break;
   8126 	case XML_SCHEMA_TYPE_NOTATION: {
   8127 		xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
   8128 		ADD_ANNOTATION(annot)
   8129 	    }
   8130 	    break;
   8131 	case XML_SCHEMA_FACET_MININCLUSIVE:
   8132 	case XML_SCHEMA_FACET_MINEXCLUSIVE:
   8133 	case XML_SCHEMA_FACET_MAXINCLUSIVE:
   8134 	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   8135 	case XML_SCHEMA_FACET_TOTALDIGITS:
   8136 	case XML_SCHEMA_FACET_FRACTIONDIGITS:
   8137 	case XML_SCHEMA_FACET_PATTERN:
   8138 	case XML_SCHEMA_FACET_ENUMERATION:
   8139 	case XML_SCHEMA_FACET_WHITESPACE:
   8140 	case XML_SCHEMA_FACET_LENGTH:
   8141 	case XML_SCHEMA_FACET_MAXLENGTH:
   8142 	case XML_SCHEMA_FACET_MINLENGTH: {
   8143 		xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
   8144 		ADD_ANNOTATION(annot)
   8145 	    }
   8146 	    break;
   8147 	case XML_SCHEMA_TYPE_SIMPLE:
   8148 	case XML_SCHEMA_TYPE_COMPLEX: {
   8149 		xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
   8150 		ADD_ANNOTATION(annot)
   8151 	    }
   8152 	    break;
   8153 	case XML_SCHEMA_TYPE_GROUP: {
   8154 		xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
   8155 		ADD_ANNOTATION(annot)
   8156 	    }
   8157 	    break;
   8158 	case XML_SCHEMA_TYPE_SEQUENCE:
   8159 	case XML_SCHEMA_TYPE_CHOICE:
   8160 	case XML_SCHEMA_TYPE_ALL: {
   8161 		xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
   8162 		ADD_ANNOTATION(annot)
   8163 	    }
   8164 	    break;
   8165 	default:
   8166 	     xmlSchemaPCustomErr(NULL,
   8167 		XML_SCHEMAP_INTERNAL,
   8168 		NULL, NULL,
   8169 		"Internal error: xmlSchemaAddAnnotation, "
   8170 		"The item is not a annotated schema component", NULL);
   8171 	     break;
   8172     }
   8173     return (annot);
   8174 }
   8175 
   8176 /**
   8177  * xmlSchemaParseIDCSelectorAndField:
   8178  * @ctxt:  a schema validation context
   8179  * @schema:  the schema being built
   8180  * @node:  a subtree containing XML Schema informations
   8181  *
   8182  * Parses a XML Schema identity-contraint definition's
   8183  * <selector> and <field> elements.
   8184  *
   8185  * Returns the parsed identity-constraint definition.
   8186  */
   8187 static xmlSchemaIDCSelectPtr
   8188 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
   8189 			  xmlSchemaIDCPtr idc,
   8190 			  xmlNodePtr node,
   8191 			  int isField)
   8192 {
   8193     xmlSchemaIDCSelectPtr item;
   8194     xmlNodePtr child = NULL;
   8195     xmlAttrPtr attr;
   8196 
   8197     /*
   8198     * Check for illegal attributes.
   8199     */
   8200     attr = node->properties;
   8201     while (attr != NULL) {
   8202 	if (attr->ns == NULL) {
   8203 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8204 		(!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
   8205 		xmlSchemaPIllegalAttrErr(ctxt,
   8206 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8207 	    }
   8208 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8209 	    xmlSchemaPIllegalAttrErr(ctxt,
   8210 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8211 	}
   8212 	attr = attr->next;
   8213     }
   8214     /*
   8215     * Create the item.
   8216     */
   8217     item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
   8218     if (item == NULL) {
   8219         xmlSchemaPErrMemory(ctxt,
   8220 	    "allocating a 'selector' of an identity-constraint definition",
   8221 	    NULL);
   8222         return (NULL);
   8223     }
   8224     memset(item, 0, sizeof(xmlSchemaIDCSelect));
   8225     /*
   8226     * Attribute "xpath" (mandatory).
   8227     */
   8228     attr = xmlSchemaGetPropNode(node, "xpath");
   8229     if (attr == NULL) {
   8230     	xmlSchemaPMissingAttrErr(ctxt,
   8231 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   8232 	    NULL, node,
   8233 	    "name", NULL);
   8234     } else {
   8235 	item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8236 	/*
   8237 	* URGENT TODO: "field"s have an other syntax than "selector"s.
   8238 	*/
   8239 
   8240 	if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
   8241 	    isField) == -1) {
   8242 	    xmlSchemaPErr(ctxt,
   8243 		(xmlNodePtr) attr,
   8244 		XML_SCHEMAP_INTERNAL,
   8245 		"Internal error: xmlSchemaParseIDCSelectorAndField, "
   8246 		"validating the XPath expression of a IDC selector.\n",
   8247 		NULL, NULL);
   8248 	}
   8249 
   8250     }
   8251     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8252     /*
   8253     * And now for the children...
   8254     */
   8255     child = node->children;
   8256     if (IS_SCHEMA(child, "annotation")) {
   8257 	/*
   8258 	* Add the annotation to the parent IDC.
   8259 	*/
   8260 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
   8261 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   8262 	child = child->next;
   8263     }
   8264     if (child != NULL) {
   8265 	xmlSchemaPContentErr(ctxt,
   8266 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8267 	    NULL, node, child,
   8268 	    NULL, "(annotation?)");
   8269     }
   8270 
   8271     return (item);
   8272 }
   8273 
   8274 /**
   8275  * xmlSchemaParseIDC:
   8276  * @ctxt:  a schema validation context
   8277  * @schema:  the schema being built
   8278  * @node:  a subtree containing XML Schema informations
   8279  *
   8280  * Parses a XML Schema identity-contraint definition.
   8281  *
   8282  * Returns the parsed identity-constraint definition.
   8283  */
   8284 static xmlSchemaIDCPtr
   8285 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
   8286 		  xmlSchemaPtr schema,
   8287 		  xmlNodePtr node,
   8288 		  xmlSchemaTypeType idcCategory,
   8289 		  const xmlChar *targetNamespace)
   8290 {
   8291     xmlSchemaIDCPtr item = NULL;
   8292     xmlNodePtr child = NULL;
   8293     xmlAttrPtr attr;
   8294     const xmlChar *name = NULL;
   8295     xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
   8296 
   8297     /*
   8298     * Check for illegal attributes.
   8299     */
   8300     attr = node->properties;
   8301     while (attr != NULL) {
   8302 	if (attr->ns == NULL) {
   8303 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8304 		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   8305 		((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
   8306 		 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
   8307 		xmlSchemaPIllegalAttrErr(ctxt,
   8308 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8309 	    }
   8310 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8311 	    xmlSchemaPIllegalAttrErr(ctxt,
   8312 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8313 	}
   8314 	attr = attr->next;
   8315     }
   8316     /*
   8317     * Attribute "name" (mandatory).
   8318     */
   8319     attr = xmlSchemaGetPropNode(node, "name");
   8320     if (attr == NULL) {
   8321 	xmlSchemaPMissingAttrErr(ctxt,
   8322 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   8323 	    NULL, node,
   8324 	    "name", NULL);
   8325 	return (NULL);
   8326     } else if (xmlSchemaPValAttrNode(ctxt,
   8327 	NULL, attr,
   8328 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   8329 	return (NULL);
   8330     }
   8331     /* Create the component. */
   8332     item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
   8333 	idcCategory, node);
   8334     if (item == NULL)
   8335 	return(NULL);
   8336 
   8337     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8338     if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
   8339 	/*
   8340 	* Attribute "refer" (mandatory).
   8341 	*/
   8342 	attr = xmlSchemaGetPropNode(node, "refer");
   8343 	if (attr == NULL) {
   8344 	    xmlSchemaPMissingAttrErr(ctxt,
   8345 		XML_SCHEMAP_S4S_ATTR_MISSING,
   8346 		NULL, node,
   8347 		"refer", NULL);
   8348 	} else {
   8349 	    /*
   8350 	    * Create a reference item.
   8351 	    */
   8352 	    item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
   8353 		NULL, NULL);
   8354 	    if (item->ref == NULL)
   8355 		return (NULL);
   8356 	    xmlSchemaPValAttrNodeQName(ctxt, schema,
   8357 		NULL, attr,
   8358 		&(item->ref->targetNamespace),
   8359 		&(item->ref->name));
   8360 	    xmlSchemaCheckReference(ctxt, schema, node, attr,
   8361 		item->ref->targetNamespace);
   8362 	}
   8363     }
   8364     /*
   8365     * And now for the children...
   8366     */
   8367     child = node->children;
   8368     if (IS_SCHEMA(child, "annotation")) {
   8369 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   8370 	child = child->next;
   8371     }
   8372     if (child == NULL) {
   8373 	xmlSchemaPContentErr(ctxt,
   8374 		XML_SCHEMAP_S4S_ELEM_MISSING,
   8375 		NULL, node, child,
   8376 		"A child element is missing",
   8377 		"(annotation?, (selector, field+))");
   8378     }
   8379     /*
   8380     * Child element <selector>.
   8381     */
   8382     if (IS_SCHEMA(child, "selector")) {
   8383 	item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
   8384 	    item, child, 0);
   8385 	child = child->next;
   8386 	/*
   8387 	* Child elements <field>.
   8388 	*/
   8389 	if (IS_SCHEMA(child, "field")) {
   8390 	    do {
   8391 		field = xmlSchemaParseIDCSelectorAndField(ctxt,
   8392 		    item, child, 1);
   8393 		if (field != NULL) {
   8394 		    field->index = item->nbFields;
   8395 		    item->nbFields++;
   8396 		    if (lastField != NULL)
   8397 			lastField->next = field;
   8398 		    else
   8399 			item->fields = field;
   8400 		    lastField = field;
   8401 		}
   8402 		child = child->next;
   8403 	    } while (IS_SCHEMA(child, "field"));
   8404 	} else {
   8405 	    xmlSchemaPContentErr(ctxt,
   8406 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8407 		NULL, node, child,
   8408 		NULL, "(annotation?, (selector, field+))");
   8409 	}
   8410     }
   8411     if (child != NULL) {
   8412 	xmlSchemaPContentErr(ctxt,
   8413 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8414 	    NULL, node, child,
   8415 	    NULL, "(annotation?, (selector, field+))");
   8416     }
   8417 
   8418     return (item);
   8419 }
   8420 
   8421 /**
   8422  * xmlSchemaParseElement:
   8423  * @ctxt:  a schema validation context
   8424  * @schema:  the schema being built
   8425  * @node:  a subtree containing XML Schema informations
   8426  * @topLevel: indicates if this is global declaration
   8427  *
   8428  * Parses a XML schema element declaration.
   8429  * *WARNING* this interface is highly subject to change
   8430  *
   8431  * Returns the element declaration or a particle; NULL in case
   8432  * of an error or if the particle has minOccurs==maxOccurs==0.
   8433  */
   8434 static xmlSchemaBasicItemPtr
   8435 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   8436                       xmlNodePtr node, int *isElemRef, int topLevel)
   8437 {
   8438     xmlSchemaElementPtr decl = NULL;
   8439     xmlSchemaParticlePtr particle = NULL;
   8440     xmlSchemaAnnotPtr annot = NULL;
   8441     xmlNodePtr child = NULL;
   8442     xmlAttrPtr attr, nameAttr;
   8443     int min, max, isRef = 0;
   8444     xmlChar *des = NULL;
   8445 
   8446     /* 3.3.3 Constraints on XML Representations of Element Declarations */
   8447     /* TODO: Complete implementation of 3.3.6 */
   8448 
   8449     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   8450         return (NULL);
   8451 
   8452     if (isElemRef != NULL)
   8453 	*isElemRef = 0;
   8454     /*
   8455     * If we get a "ref" attribute on a local <element> we will assume it's
   8456     * a reference - even if there's a "name" attribute; this seems to be more
   8457     * robust.
   8458     */
   8459     nameAttr = xmlSchemaGetPropNode(node, "name");
   8460     attr = xmlSchemaGetPropNode(node, "ref");
   8461     if ((topLevel) || (attr == NULL)) {
   8462 	if (nameAttr == NULL) {
   8463 	    xmlSchemaPMissingAttrErr(ctxt,
   8464 		XML_SCHEMAP_S4S_ATTR_MISSING,
   8465 		NULL, node, "name", NULL);
   8466 	    return (NULL);
   8467 	}
   8468     } else
   8469 	isRef = 1;
   8470 
   8471     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8472     child = node->children;
   8473     if (IS_SCHEMA(child, "annotation")) {
   8474 	annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   8475 	child = child->next;
   8476     }
   8477     /*
   8478     * Skip particle part if a global declaration.
   8479     */
   8480     if (topLevel)
   8481 	goto declaration_part;
   8482     /*
   8483     * The particle part ==================================================
   8484     */
   8485     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
   8486     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
   8487     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
   8488     particle = xmlSchemaAddParticle(ctxt, node, min, max);
   8489     if (particle == NULL)
   8490 	goto return_null;
   8491 
   8492     /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
   8493 
   8494     if (isRef) {
   8495 	const xmlChar *refNs = NULL, *ref = NULL;
   8496 	xmlSchemaQNameRefPtr refer = NULL;
   8497 	/*
   8498 	* The reference part =============================================
   8499 	*/
   8500 	if (isElemRef != NULL)
   8501 	    *isElemRef = 1;
   8502 
   8503 	xmlSchemaPValAttrNodeQName(ctxt, schema,
   8504 	    NULL, attr, &refNs, &ref);
   8505 	xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
   8506 	/*
   8507 	* SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
   8508 	*/
   8509 	if (nameAttr != NULL) {
   8510 	    xmlSchemaPMutualExclAttrErr(ctxt,
   8511 		XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
   8512 	}
   8513 	/*
   8514 	* Check for illegal attributes.
   8515 	*/
   8516 	attr = node->properties;
   8517 	while (attr != NULL) {
   8518 	    if (attr->ns == NULL) {
   8519 		if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
   8520 		    xmlStrEqual(attr->name, BAD_CAST "name") ||
   8521 		    xmlStrEqual(attr->name, BAD_CAST "id") ||
   8522 		    xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
   8523 		    xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
   8524 		{
   8525 		    attr = attr->next;
   8526 		    continue;
   8527 		} else {
   8528 		    /* SPEC (3.3.3 : 2.2) */
   8529 		    xmlSchemaPCustomAttrErr(ctxt,
   8530 			XML_SCHEMAP_SRC_ELEMENT_2_2,
   8531 			NULL, NULL, attr,
   8532 			"Only the attributes 'minOccurs', 'maxOccurs' and "
   8533 			"'id' are allowed in addition to 'ref'");
   8534 		    break;
   8535 		}
   8536 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8537 		xmlSchemaPIllegalAttrErr(ctxt,
   8538 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8539 	    }
   8540 	    attr = attr->next;
   8541 	}
   8542 	/*
   8543 	* No children except <annotation> expected.
   8544 	*/
   8545 	if (child != NULL) {
   8546 	    xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8547 		NULL, node, child, NULL, "(annotation?)");
   8548 	}
   8549 	if ((min == 0) && (max == 0))
   8550 	    goto return_null;
   8551 	/*
   8552 	* Create the reference item and attach it to the particle.
   8553 	*/
   8554 	refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
   8555 	    ref, refNs);
   8556 	if (refer == NULL)
   8557 	    goto return_null;
   8558 	particle->children = (xmlSchemaTreeItemPtr) refer;
   8559 	particle->annot = annot;
   8560 	/*
   8561 	* Add the particle to pending components, since the reference
   8562 	* need to be resolved.
   8563 	*/
   8564 	WXS_ADD_PENDING(ctxt, particle);
   8565 	return ((xmlSchemaBasicItemPtr) particle);
   8566     }
   8567     /*
   8568     * The declaration part ===============================================
   8569     */
   8570 declaration_part:
   8571     {
   8572 	const xmlChar *ns = NULL, *fixed, *name, *attrValue;
   8573 	xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
   8574 
   8575 	if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
   8576 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
   8577 	    goto return_null;
   8578 	/*
   8579 	* Evaluate the target namespace.
   8580 	*/
   8581 	if (topLevel) {
   8582 	    ns = ctxt->targetNamespace;
   8583 	} else {
   8584 	    attr = xmlSchemaGetPropNode(node, "form");
   8585 	    if (attr != NULL) {
   8586 		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8587 		if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
   8588 		    ns = ctxt->targetNamespace;
   8589 		} else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
   8590 		    xmlSchemaPSimpleTypeErr(ctxt,
   8591 			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8592 			NULL, (xmlNodePtr) attr,
   8593 			NULL, "(qualified | unqualified)",
   8594 			attrValue, NULL, NULL, NULL);
   8595 		}
   8596 	    } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
   8597 		ns = ctxt->targetNamespace;
   8598 	}
   8599 	decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
   8600 	if (decl == NULL) {
   8601 	    goto return_null;
   8602 	}
   8603 	/*
   8604 	* Check for illegal attributes.
   8605 	*/
   8606 	attr = node->properties;
   8607 	while (attr != NULL) {
   8608 	    if (attr->ns == NULL) {
   8609 		if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   8610 		    (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
   8611 		    (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8612 		    (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
   8613 		    (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
   8614 		    (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
   8615 		    (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
   8616 		{
   8617 		    if (topLevel == 0) {
   8618 			if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
   8619 			    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
   8620 			    (!xmlStrEqual(attr->name, BAD_CAST "form")))
   8621 			{
   8622 			    xmlSchemaPIllegalAttrErr(ctxt,
   8623 				XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8624 			}
   8625 		    } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
   8626 			(!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
   8627 			(!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
   8628 
   8629 			xmlSchemaPIllegalAttrErr(ctxt,
   8630 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8631 		    }
   8632 		}
   8633 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8634 
   8635 		xmlSchemaPIllegalAttrErr(ctxt,
   8636 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8637 	    }
   8638 	    attr = attr->next;
   8639 	}
   8640 	/*
   8641 	* Extract/validate attributes.
   8642 	*/
   8643 	if (topLevel) {
   8644 	    /*
   8645 	    * Process top attributes of global element declarations here.
   8646 	    */
   8647 	    decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
   8648 	    decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
   8649 	    xmlSchemaPValAttrQName(ctxt, schema,
   8650 		NULL, node, "substitutionGroup",
   8651 		&(decl->substGroupNs), &(decl->substGroup));
   8652 	    if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
   8653 		decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
   8654 	    /*
   8655 	    * Attribute "final".
   8656 	    */
   8657 	    attr = xmlSchemaGetPropNode(node, "final");
   8658 	    if (attr == NULL) {
   8659 		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
   8660 		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
   8661 		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   8662 		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
   8663 	    } else {
   8664 		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8665 		if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
   8666 		    -1,
   8667 		    XML_SCHEMAS_ELEM_FINAL_EXTENSION,
   8668 		    XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
   8669 		    xmlSchemaPSimpleTypeErr(ctxt,
   8670 			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8671 			NULL, (xmlNodePtr) attr,
   8672 			NULL, "(#all | List of (extension | restriction))",
   8673 			attrValue, NULL, NULL, NULL);
   8674 		}
   8675 	    }
   8676 	}
   8677 	/*
   8678 	* Attribute "block".
   8679 	*/
   8680 	attr = xmlSchemaGetPropNode(node, "block");
   8681 	if (attr == NULL) {
   8682 	    /*
   8683 	    * Apply default "block" values.
   8684 	    */
   8685 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
   8686 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
   8687 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
   8688 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
   8689 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
   8690 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
   8691 	} else {
   8692 	    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8693 	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
   8694 		-1,
   8695 		XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
   8696 		XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
   8697 		XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
   8698 		xmlSchemaPSimpleTypeErr(ctxt,
   8699 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8700 		    NULL, (xmlNodePtr) attr,
   8701 		    NULL, "(#all | List of (extension | "
   8702 		    "restriction | substitution))", attrValue,
   8703 		    NULL, NULL, NULL);
   8704 	    }
   8705 	}
   8706 	if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
   8707 	    decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
   8708 
   8709 	attr = xmlSchemaGetPropNode(node, "type");
   8710 	if (attr != NULL) {
   8711 	    xmlSchemaPValAttrNodeQName(ctxt, schema,
   8712 		NULL, attr,
   8713 		&(decl->namedTypeNs), &(decl->namedType));
   8714 	    xmlSchemaCheckReference(ctxt, schema, node,
   8715 		attr, decl->namedTypeNs);
   8716 	}
   8717 	decl->value = xmlSchemaGetProp(ctxt, node, "default");
   8718 	attr = xmlSchemaGetPropNode(node, "fixed");
   8719 	if (attr != NULL) {
   8720 	    fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8721 	    if (decl->value != NULL) {
   8722 		/*
   8723 		* 3.3.3 : 1
   8724 		* default and fixed must not both be present.
   8725 		*/
   8726 		xmlSchemaPMutualExclAttrErr(ctxt,
   8727 		    XML_SCHEMAP_SRC_ELEMENT_1,
   8728 		    NULL, attr, "default", "fixed");
   8729 	    } else {
   8730 		decl->flags |= XML_SCHEMAS_ELEM_FIXED;
   8731 		decl->value = fixed;
   8732 	    }
   8733 	}
   8734 	/*
   8735 	* And now for the children...
   8736 	*/
   8737 	if (IS_SCHEMA(child, "complexType")) {
   8738 	    /*
   8739 	    * 3.3.3 : 3
   8740 	    * "type" and either <simpleType> or <complexType> are mutually
   8741 	    * exclusive
   8742 	    */
   8743 	    if (decl->namedType != NULL) {
   8744 		xmlSchemaPContentErr(ctxt,
   8745 		    XML_SCHEMAP_SRC_ELEMENT_3,
   8746 		    NULL, node, child,
   8747 		    "The attribute 'type' and the <complexType> child are "
   8748 		    "mutually exclusive", NULL);
   8749 	    } else
   8750 		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
   8751 	    child = child->next;
   8752 	} else if (IS_SCHEMA(child, "simpleType")) {
   8753 	    /*
   8754 	    * 3.3.3 : 3
   8755 	    * "type" and either <simpleType> or <complexType> are
   8756 	    * mutually exclusive
   8757 	    */
   8758 	    if (decl->namedType != NULL) {
   8759 		xmlSchemaPContentErr(ctxt,
   8760 		    XML_SCHEMAP_SRC_ELEMENT_3,
   8761 		    NULL, node, child,
   8762 		    "The attribute 'type' and the <simpleType> child are "
   8763 		    "mutually exclusive", NULL);
   8764 	    } else
   8765 		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   8766 	    child = child->next;
   8767 	}
   8768 	while ((IS_SCHEMA(child, "unique")) ||
   8769 	    (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
   8770 	    if (IS_SCHEMA(child, "unique")) {
   8771 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
   8772 		    XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
   8773 	    } else if (IS_SCHEMA(child, "key")) {
   8774 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
   8775 		    XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
   8776 	    } else if (IS_SCHEMA(child, "keyref")) {
   8777 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
   8778 		    XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
   8779 	    }
   8780 	    if (lastIDC != NULL)
   8781 		lastIDC->next = curIDC;
   8782 	    else
   8783 		decl->idcs = (void *) curIDC;
   8784 	    lastIDC = curIDC;
   8785 	    child = child->next;
   8786 	}
   8787 	if (child != NULL) {
   8788 	    xmlSchemaPContentErr(ctxt,
   8789 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8790 		NULL, node, child,
   8791 		NULL, "(annotation?, ((simpleType | complexType)?, "
   8792 		"(unique | key | keyref)*))");
   8793 	}
   8794 	decl->annot = annot;
   8795     }
   8796     /*
   8797     * NOTE: Element Declaration Representation OK 4. will be checked at a
   8798     * different layer.
   8799     */
   8800     FREE_AND_NULL(des)
   8801     if (topLevel)
   8802 	return ((xmlSchemaBasicItemPtr) decl);
   8803     else {
   8804 	particle->children = (xmlSchemaTreeItemPtr) decl;
   8805 	return ((xmlSchemaBasicItemPtr) particle);
   8806     }
   8807 
   8808 return_null:
   8809     FREE_AND_NULL(des);
   8810     if (annot != NULL) {
   8811 	if (particle != NULL)
   8812 	    particle->annot = NULL;
   8813 	if (decl != NULL)
   8814 	    decl->annot = NULL;
   8815 	xmlSchemaFreeAnnot(annot);
   8816     }
   8817     return (NULL);
   8818 }
   8819 
   8820 /**
   8821  * xmlSchemaParseUnion:
   8822  * @ctxt:  a schema validation context
   8823  * @schema:  the schema being built
   8824  * @node:  a subtree containing XML Schema informations
   8825  *
   8826  * parse a XML schema Union definition
   8827  * *WARNING* this interface is highly subject to change
   8828  *
   8829  * Returns -1 in case of internal error, 0 in case of success and a positive
   8830  * error code otherwise.
   8831  */
   8832 static int
   8833 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   8834                     xmlNodePtr node)
   8835 {
   8836     xmlSchemaTypePtr type;
   8837     xmlNodePtr child = NULL;
   8838     xmlAttrPtr attr;
   8839     const xmlChar *cur = NULL;
   8840 
   8841     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   8842         return (-1);
   8843     /* Not a component, don't create it. */
   8844     type = ctxt->ctxtType;
   8845     /*
   8846     * Mark the simple type as being of variety "union".
   8847     */
   8848     type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
   8849     /*
   8850     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
   8851     * then the simple ur-type definition."
   8852     */
   8853     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
   8854     /*
   8855     * Check for illegal attributes.
   8856     */
   8857     attr = node->properties;
   8858     while (attr != NULL) {
   8859 	if (attr->ns == NULL) {
   8860 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8861 		(!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
   8862 		xmlSchemaPIllegalAttrErr(ctxt,
   8863 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8864 	    }
   8865 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8866 	    xmlSchemaPIllegalAttrErr(ctxt,
   8867 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8868 	}
   8869 	attr = attr->next;
   8870     }
   8871     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8872     /*
   8873     * Attribute "memberTypes". This is a list of QNames.
   8874     * TODO: Check the value to contain anything.
   8875     */
   8876     attr = xmlSchemaGetPropNode(node, "memberTypes");
   8877     if (attr != NULL) {
   8878 	const xmlChar *end;
   8879 	xmlChar *tmp;
   8880 	const xmlChar *localName, *nsName;
   8881 	xmlSchemaTypeLinkPtr link, lastLink = NULL;
   8882 	xmlSchemaQNameRefPtr ref;
   8883 
   8884 	cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8885 	type->base = cur;
   8886 	do {
   8887 	    while (IS_BLANK_CH(*cur))
   8888 		cur++;
   8889 	    end = cur;
   8890 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   8891 		end++;
   8892 	    if (end == cur)
   8893 		break;
   8894 	    tmp = xmlStrndup(cur, end - cur);
   8895 	    if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
   8896 		NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
   8897 		/*
   8898 		* Create the member type link.
   8899 		*/
   8900 		link = (xmlSchemaTypeLinkPtr)
   8901 		    xmlMalloc(sizeof(xmlSchemaTypeLink));
   8902 		if (link == NULL) {
   8903 		    xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
   8904 			"allocating a type link", NULL);
   8905 		    return (-1);
   8906 		}
   8907 		link->type = NULL;
   8908 		link->next = NULL;
   8909 		if (lastLink == NULL)
   8910 		    type->memberTypes = link;
   8911 		else
   8912 		    lastLink->next = link;
   8913 		lastLink = link;
   8914 		/*
   8915 		* Create a reference item.
   8916 		*/
   8917 		ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
   8918 		    localName, nsName);
   8919 		if (ref == NULL) {
   8920 		    FREE_AND_NULL(tmp)
   8921 		    return (-1);
   8922 		}
   8923 		/*
   8924 		* Assign the reference to the link, it will be resolved
   8925 		* later during fixup of the union simple type.
   8926 		*/
   8927 		link->type = (xmlSchemaTypePtr) ref;
   8928 	    }
   8929 	    FREE_AND_NULL(tmp)
   8930 	    cur = end;
   8931 	} while (*cur != 0);
   8932 
   8933     }
   8934     /*
   8935     * And now for the children...
   8936     */
   8937     child = node->children;
   8938     if (IS_SCHEMA(child, "annotation")) {
   8939 	/*
   8940 	* Add the annotation to the simple type ancestor.
   8941 	*/
   8942 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   8943 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   8944         child = child->next;
   8945     }
   8946     if (IS_SCHEMA(child, "simpleType")) {
   8947 	xmlSchemaTypePtr subtype, last = NULL;
   8948 
   8949 	/*
   8950 	* Anchor the member types in the "subtypes" field of the
   8951 	* simple type.
   8952 	*/
   8953 	while (IS_SCHEMA(child, "simpleType")) {
   8954 	    subtype = (xmlSchemaTypePtr)
   8955 		xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   8956 	    if (subtype != NULL) {
   8957 		if (last == NULL) {
   8958 		    type->subtypes = subtype;
   8959 		    last = subtype;
   8960 		} else {
   8961 		    last->next = subtype;
   8962 		    last = subtype;
   8963 		}
   8964 		last->next = NULL;
   8965 	    }
   8966 	    child = child->next;
   8967 	}
   8968     }
   8969     if (child != NULL) {
   8970 	xmlSchemaPContentErr(ctxt,
   8971 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8972 	    NULL, node, child, NULL, "(annotation?, simpleType*)");
   8973     }
   8974     if ((attr == NULL) && (type->subtypes == NULL)) {
   8975 	 /*
   8976 	* src-union-memberTypes-or-simpleTypes
   8977 	* Either the memberTypes [attribute] of the <union> element must
   8978 	* be non-empty or there must be at least one simpleType [child].
   8979 	*/
   8980 	xmlSchemaPCustomErr(ctxt,
   8981 	    XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
   8982 	    NULL, node,
   8983 	    "Either the attribute 'memberTypes' or "
   8984 	    "at least one <simpleType> child must be present", NULL);
   8985     }
   8986     return (0);
   8987 }
   8988 
   8989 /**
   8990  * xmlSchemaParseList:
   8991  * @ctxt:  a schema validation context
   8992  * @schema:  the schema being built
   8993  * @node:  a subtree containing XML Schema informations
   8994  *
   8995  * parse a XML schema List definition
   8996  * *WARNING* this interface is highly subject to change
   8997  *
   8998  * Returns -1 in case of error, 0 if the declaration is improper and
   8999  *         1 in case of success.
   9000  */
   9001 static xmlSchemaTypePtr
   9002 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   9003                    xmlNodePtr node)
   9004 {
   9005     xmlSchemaTypePtr type;
   9006     xmlNodePtr child = NULL;
   9007     xmlAttrPtr attr;
   9008 
   9009     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9010         return (NULL);
   9011     /* Not a component, don't create it. */
   9012     type = ctxt->ctxtType;
   9013     /*
   9014     * Mark the type as being of variety "list".
   9015     */
   9016     type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
   9017     /*
   9018     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
   9019     * then the simple ur-type definition."
   9020     */
   9021     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
   9022     /*
   9023     * Check for illegal attributes.
   9024     */
   9025     attr = node->properties;
   9026     while (attr != NULL) {
   9027 	if (attr->ns == NULL) {
   9028 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   9029 		(!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
   9030 		xmlSchemaPIllegalAttrErr(ctxt,
   9031 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9032 	    }
   9033 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9034 	    xmlSchemaPIllegalAttrErr(ctxt,
   9035 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9036 	}
   9037 	attr = attr->next;
   9038     }
   9039 
   9040     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9041 
   9042     /*
   9043     * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
   9044     * fields for holding the reference to the itemType.
   9045     *
   9046     * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
   9047     * the "ref" fields.
   9048     */
   9049     xmlSchemaPValAttrQName(ctxt, schema, NULL,
   9050 	node, "itemType", &(type->baseNs), &(type->base));
   9051     /*
   9052     * And now for the children...
   9053     */
   9054     child = node->children;
   9055     if (IS_SCHEMA(child, "annotation")) {
   9056 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   9057 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   9058         child = child->next;
   9059     }
   9060     if (IS_SCHEMA(child, "simpleType")) {
   9061 	/*
   9062 	* src-list-itemType-or-simpleType
   9063 	* Either the itemType [attribute] or the <simpleType> [child] of
   9064 	* the <list> element must be present, but not both.
   9065 	*/
   9066 	if (type->base != NULL) {
   9067 	    xmlSchemaPCustomErr(ctxt,
   9068 		XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   9069 		NULL, node,
   9070 		"The attribute 'itemType' and the <simpleType> child "
   9071 		"are mutually exclusive", NULL);
   9072 	} else {
   9073 	    type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   9074 	}
   9075         child = child->next;
   9076     } else if (type->base == NULL) {
   9077 	xmlSchemaPCustomErr(ctxt,
   9078 	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   9079 	    NULL, node,
   9080 	    "Either the attribute 'itemType' or the <simpleType> child "
   9081 	    "must be present", NULL);
   9082     }
   9083     if (child != NULL) {
   9084 	xmlSchemaPContentErr(ctxt,
   9085 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9086 	    NULL, node, child, NULL, "(annotation?, simpleType?)");
   9087     }
   9088     if ((type->base == NULL) &&
   9089 	(type->subtypes == NULL) &&
   9090 	(xmlSchemaGetPropNode(node, "itemType") == NULL)) {
   9091 	xmlSchemaPCustomErr(ctxt,
   9092 	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   9093 	    NULL, node,
   9094 	    "Either the attribute 'itemType' or the <simpleType> child "
   9095 	    "must be present", NULL);
   9096     }
   9097     return (NULL);
   9098 }
   9099 
   9100 /**
   9101  * xmlSchemaParseSimpleType:
   9102  * @ctxt:  a schema validation context
   9103  * @schema:  the schema being built
   9104  * @node:  a subtree containing XML Schema informations
   9105  *
   9106  * parse a XML schema Simple Type definition
   9107  * *WARNING* this interface is highly subject to change
   9108  *
   9109  * Returns -1 in case of error, 0 if the declaration is improper and
   9110  * 1 in case of success.
   9111  */
   9112 static xmlSchemaTypePtr
   9113 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   9114                          xmlNodePtr node, int topLevel)
   9115 {
   9116     xmlSchemaTypePtr type, oldCtxtType;
   9117     xmlNodePtr child = NULL;
   9118     const xmlChar *attrValue = NULL;
   9119     xmlAttrPtr attr;
   9120     int hasRestriction = 0;
   9121 
   9122     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9123         return (NULL);
   9124 
   9125     if (topLevel) {
   9126 	attr = xmlSchemaGetPropNode(node, "name");
   9127 	if (attr == NULL) {
   9128 	    xmlSchemaPMissingAttrErr(ctxt,
   9129 		XML_SCHEMAP_S4S_ATTR_MISSING,
   9130 		NULL, node,
   9131 		"name", NULL);
   9132 	    return (NULL);
   9133 	} else {
   9134 	    if (xmlSchemaPValAttrNode(ctxt,
   9135 		NULL, attr,
   9136 		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
   9137 		return (NULL);
   9138 	    /*
   9139 	    * Skip built-in types.
   9140 	    */
   9141 	    if (ctxt->isS4S) {
   9142 		xmlSchemaTypePtr biType;
   9143 
   9144 		if (ctxt->isRedefine) {
   9145 		    /*
   9146 		    * REDEFINE: Disallow redefinition of built-in-types.
   9147 		    * TODO: It seems that the spec does not say anything
   9148 		    * about this case.
   9149 		    */
   9150 		    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   9151 			NULL, node,
   9152 			"Redefinition of built-in simple types is not "
   9153 			"supported", NULL);
   9154 		    return(NULL);
   9155 		}
   9156 		biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
   9157 		if (biType != NULL)
   9158 		    return (biType);
   9159 	    }
   9160 	}
   9161     }
   9162     /*
   9163     * TargetNamespace:
   9164     * SPEC "The actual value of the targetNamespace [attribute]
   9165     * of the <schema> ancestor element information item if present,
   9166     * otherwise absent.
   9167     */
   9168     if (topLevel == 0) {
   9169 #ifdef ENABLE_NAMED_LOCALS
   9170         char buf[40];
   9171 #endif
   9172 	/*
   9173 	* Parse as local simple type definition.
   9174 	*/
   9175 #ifdef ENABLE_NAMED_LOCALS
   9176         snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
   9177 	type = xmlSchemaAddType(ctxt, schema,
   9178 	    XML_SCHEMA_TYPE_SIMPLE,
   9179 	    xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
   9180 	    ctxt->targetNamespace, node, 0);
   9181 #else
   9182 	type = xmlSchemaAddType(ctxt, schema,
   9183 	    XML_SCHEMA_TYPE_SIMPLE,
   9184 	    NULL, ctxt->targetNamespace, node, 0);
   9185 #endif
   9186 	if (type == NULL)
   9187 	    return (NULL);
   9188 	type->type = XML_SCHEMA_TYPE_SIMPLE;
   9189 	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   9190 	/*
   9191 	* Check for illegal attributes.
   9192 	*/
   9193 	attr = node->properties;
   9194 	while (attr != NULL) {
   9195 	    if (attr->ns == NULL) {
   9196 		if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
   9197 		    xmlSchemaPIllegalAttrErr(ctxt,
   9198 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9199 		}
   9200 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9201 		    xmlSchemaPIllegalAttrErr(ctxt,
   9202 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9203 	    }
   9204 	    attr = attr->next;
   9205 	}
   9206     } else {
   9207 	/*
   9208 	* Parse as global simple type definition.
   9209 	*
   9210 	* Note that attrValue is the value of the attribute "name" here.
   9211 	*/
   9212 	type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
   9213 	    attrValue, ctxt->targetNamespace, node, 1);
   9214 	if (type == NULL)
   9215 	    return (NULL);
   9216 	type->type = XML_SCHEMA_TYPE_SIMPLE;
   9217 	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   9218 	type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
   9219 	/*
   9220 	* Check for illegal attributes.
   9221 	*/
   9222 	attr = node->properties;
   9223 	while (attr != NULL) {
   9224 	    if (attr->ns == NULL) {
   9225 		if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   9226 		    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   9227 		    (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
   9228 		    xmlSchemaPIllegalAttrErr(ctxt,
   9229 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9230 		}
   9231 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9232 		xmlSchemaPIllegalAttrErr(ctxt,
   9233 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9234 	    }
   9235 	    attr = attr->next;
   9236 	}
   9237 	/*
   9238 	* Attribute "final".
   9239 	*/
   9240 	attr = xmlSchemaGetPropNode(node, "final");
   9241 	if (attr == NULL) {
   9242 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   9243 		type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
   9244 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
   9245 		type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
   9246 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
   9247 		type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
   9248 	} else {
   9249 	    attrValue = xmlSchemaGetProp(ctxt, node, "final");
   9250 	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
   9251 		-1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
   9252 		XML_SCHEMAS_TYPE_FINAL_LIST,
   9253 		XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
   9254 
   9255 		xmlSchemaPSimpleTypeErr(ctxt,
   9256 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   9257 		    WXS_BASIC_CAST type, (xmlNodePtr) attr,
   9258 		    NULL, "(#all | List of (list | union | restriction)",
   9259 		    attrValue, NULL, NULL, NULL);
   9260 	    }
   9261 	}
   9262     }
   9263     type->targetNamespace = ctxt->targetNamespace;
   9264     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9265     /*
   9266     * And now for the children...
   9267     */
   9268     oldCtxtType = ctxt->ctxtType;
   9269 
   9270     ctxt->ctxtType = type;
   9271 
   9272     child = node->children;
   9273     if (IS_SCHEMA(child, "annotation")) {
   9274         type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9275         child = child->next;
   9276     }
   9277     if (child == NULL) {
   9278 	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
   9279 	    NULL, node, child, NULL,
   9280 	    "(annotation?, (restriction | list | union))");
   9281     } else if (IS_SCHEMA(child, "restriction")) {
   9282         xmlSchemaParseRestriction(ctxt, schema, child,
   9283 	    XML_SCHEMA_TYPE_SIMPLE);
   9284 	hasRestriction = 1;
   9285         child = child->next;
   9286     } else if (IS_SCHEMA(child, "list")) {
   9287         xmlSchemaParseList(ctxt, schema, child);
   9288         child = child->next;
   9289     } else if (IS_SCHEMA(child, "union")) {
   9290         xmlSchemaParseUnion(ctxt, schema, child);
   9291         child = child->next;
   9292     }
   9293     if (child != NULL) {
   9294 	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9295 	    NULL, node, child, NULL,
   9296 	    "(annotation?, (restriction | list | union))");
   9297     }
   9298     /*
   9299     * REDEFINE: SPEC src-redefine (5)
   9300     * "Within the [children], each <simpleType> must have a
   9301     * <restriction> among its [children] ... the actual value of whose
   9302     * base [attribute] must be the same as the actual value of its own
   9303     * name attribute plus target namespace;"
   9304     */
   9305     if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
   9306 	xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   9307 	    NULL, node, "This is a redefinition, thus the "
   9308 	    "<simpleType> must have a <restriction> child", NULL);
   9309     }
   9310 
   9311     ctxt->ctxtType = oldCtxtType;
   9312     return (type);
   9313 }
   9314 
   9315 /**
   9316  * xmlSchemaParseModelGroupDefRef:
   9317  * @ctxt:  the parser context
   9318  * @schema: the schema being built
   9319  * @node:  the node
   9320  *
   9321  * Parses a reference to a model group definition.
   9322  *
   9323  * We will return a particle component with a qname-component or
   9324  * NULL in case of an error.
   9325  */
   9326 static xmlSchemaTreeItemPtr
   9327 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
   9328 			       xmlSchemaPtr schema,
   9329 			       xmlNodePtr node)
   9330 {
   9331     xmlSchemaParticlePtr item;
   9332     xmlNodePtr child = NULL;
   9333     xmlAttrPtr attr;
   9334     const xmlChar *ref = NULL, *refNs = NULL;
   9335     int min, max;
   9336 
   9337     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9338         return (NULL);
   9339 
   9340     attr = xmlSchemaGetPropNode(node, "ref");
   9341     if (attr == NULL) {
   9342 	xmlSchemaPMissingAttrErr(ctxt,
   9343 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   9344 	    NULL, node, "ref", NULL);
   9345 	return (NULL);
   9346     } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
   9347 	attr, &refNs, &ref) != 0) {
   9348 	return (NULL);
   9349     }
   9350     xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
   9351     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
   9352     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
   9353 	"(xs:nonNegativeInteger | unbounded)");
   9354     /*
   9355     * Check for illegal attributes.
   9356     */
   9357     attr = node->properties;
   9358     while (attr != NULL) {
   9359 	if (attr->ns == NULL) {
   9360 	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
   9361 		(!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   9362 		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
   9363 		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
   9364 		xmlSchemaPIllegalAttrErr(ctxt,
   9365 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9366 	    }
   9367 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9368 	    xmlSchemaPIllegalAttrErr(ctxt,
   9369 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9370 	}
   9371 	attr = attr->next;
   9372     }
   9373     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9374     item = xmlSchemaAddParticle(ctxt, node, min, max);
   9375     if (item == NULL)
   9376 	return (NULL);
   9377     /*
   9378     * Create a qname-reference and set as the term; it will be substituted
   9379     * for the model group after the reference has been resolved.
   9380     */
   9381     item->children = (xmlSchemaTreeItemPtr)
   9382 	xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
   9383     xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
   9384     /*
   9385     * And now for the children...
   9386     */
   9387     child = node->children;
   9388     /* TODO: Is annotation even allowed for a model group reference? */
   9389     if (IS_SCHEMA(child, "annotation")) {
   9390 	/*
   9391 	* TODO: What to do exactly with the annotation?
   9392 	*/
   9393 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9394 	child = child->next;
   9395     }
   9396     if (child != NULL) {
   9397 	xmlSchemaPContentErr(ctxt,
   9398 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9399 	    NULL, node, child, NULL,
   9400 	    "(annotation?)");
   9401     }
   9402     /*
   9403     * Corresponds to no component at all if minOccurs==maxOccurs==0.
   9404     */
   9405     if ((min == 0) && (max == 0))
   9406 	return (NULL);
   9407 
   9408     return ((xmlSchemaTreeItemPtr) item);
   9409 }
   9410 
   9411 /**
   9412  * xmlSchemaParseModelGroupDefinition:
   9413  * @ctxt:  a schema validation context
   9414  * @schema:  the schema being built
   9415  * @node:  a subtree containing XML Schema informations
   9416  *
   9417  * Parses a XML schema model group definition.
   9418  *
   9419  * Note that the contraint src-redefine (6.2) can't be applied until
   9420  * references have been resolved. So we will do this at the
   9421  * component fixup level.
   9422  *
   9423  * *WARNING* this interface is highly subject to change
   9424  *
   9425  * Returns -1 in case of error, 0 if the declaration is improper and
   9426  *         1 in case of success.
   9427  */
   9428 static xmlSchemaModelGroupDefPtr
   9429 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
   9430 				   xmlSchemaPtr schema,
   9431 				   xmlNodePtr node)
   9432 {
   9433     xmlSchemaModelGroupDefPtr item;
   9434     xmlNodePtr child = NULL;
   9435     xmlAttrPtr attr;
   9436     const xmlChar *name;
   9437 
   9438     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9439         return (NULL);
   9440 
   9441     attr = xmlSchemaGetPropNode(node, "name");
   9442     if (attr == NULL) {
   9443 	xmlSchemaPMissingAttrErr(ctxt,
   9444 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   9445 	    NULL, node,
   9446 	    "name", NULL);
   9447 	return (NULL);
   9448     } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
   9449 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   9450 	return (NULL);
   9451     }
   9452     item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
   9453 	ctxt->targetNamespace, node);
   9454     if (item == NULL)
   9455 	return (NULL);
   9456     /*
   9457     * Check for illegal attributes.
   9458     */
   9459     attr = node->properties;
   9460     while (attr != NULL) {
   9461 	if (attr->ns == NULL) {
   9462 	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   9463 		(!xmlStrEqual(attr->name, BAD_CAST "id"))) {
   9464 		xmlSchemaPIllegalAttrErr(ctxt,
   9465 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9466 	    }
   9467 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9468 	    xmlSchemaPIllegalAttrErr(ctxt,
   9469 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9470 	}
   9471 	attr = attr->next;
   9472     }
   9473     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9474     /*
   9475     * And now for the children...
   9476     */
   9477     child = node->children;
   9478     if (IS_SCHEMA(child, "annotation")) {
   9479 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9480 	child = child->next;
   9481     }
   9482     if (IS_SCHEMA(child, "all")) {
   9483 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
   9484 	    XML_SCHEMA_TYPE_ALL, 0);
   9485 	child = child->next;
   9486     } else if (IS_SCHEMA(child, "choice")) {
   9487 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
   9488 	    XML_SCHEMA_TYPE_CHOICE, 0);
   9489 	child = child->next;
   9490     } else if (IS_SCHEMA(child, "sequence")) {
   9491 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
   9492 	    XML_SCHEMA_TYPE_SEQUENCE, 0);
   9493 	child = child->next;
   9494     }
   9495 
   9496 
   9497 
   9498     if (child != NULL) {
   9499 	xmlSchemaPContentErr(ctxt,
   9500 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9501 	    NULL, node, child, NULL,
   9502 	    "(annotation?, (all | choice | sequence)?)");
   9503     }
   9504     return (item);
   9505 }
   9506 
   9507 /**
   9508  * xmlSchemaCleanupDoc:
   9509  * @ctxt:  a schema validation context
   9510  * @node:  the root of the document.
   9511  *
   9512  * removes unwanted nodes in a schemas document tree
   9513  */
   9514 static void
   9515 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
   9516 {
   9517     xmlNodePtr delete, cur;
   9518 
   9519     if ((ctxt == NULL) || (root == NULL)) return;
   9520 
   9521     /*
   9522      * Remove all the blank text nodes
   9523      */
   9524     delete = NULL;
   9525     cur = root;
   9526     while (cur != NULL) {
   9527         if (delete != NULL) {
   9528             xmlUnlinkNode(delete);
   9529             xmlFreeNode(delete);
   9530             delete = NULL;
   9531         }
   9532         if (cur->type == XML_TEXT_NODE) {
   9533             if (IS_BLANK_NODE(cur)) {
   9534                 if (xmlNodeGetSpacePreserve(cur) != 1) {
   9535                     delete = cur;
   9536                 }
   9537             }
   9538         } else if ((cur->type != XML_ELEMENT_NODE) &&
   9539                    (cur->type != XML_CDATA_SECTION_NODE)) {
   9540             delete = cur;
   9541             goto skip_children;
   9542         }
   9543 
   9544         /*
   9545          * Skip to next node
   9546          */
   9547         if (cur->children != NULL) {
   9548             if ((cur->children->type != XML_ENTITY_DECL) &&
   9549                 (cur->children->type != XML_ENTITY_REF_NODE) &&
   9550                 (cur->children->type != XML_ENTITY_NODE)) {
   9551                 cur = cur->children;
   9552                 continue;
   9553             }
   9554         }
   9555       skip_children:
   9556         if (cur->next != NULL) {
   9557             cur = cur->next;
   9558             continue;
   9559         }
   9560 
   9561         do {
   9562             cur = cur->parent;
   9563             if (cur == NULL)
   9564                 break;
   9565             if (cur == root) {
   9566                 cur = NULL;
   9567                 break;
   9568             }
   9569             if (cur->next != NULL) {
   9570                 cur = cur->next;
   9571                 break;
   9572             }
   9573         } while (cur != NULL);
   9574     }
   9575     if (delete != NULL) {
   9576         xmlUnlinkNode(delete);
   9577         xmlFreeNode(delete);
   9578         delete = NULL;
   9579     }
   9580 }
   9581 
   9582 
   9583 static void
   9584 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
   9585 {
   9586     if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
   9587 	schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
   9588 
   9589     if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
   9590 	schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
   9591 
   9592     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
   9593 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
   9594     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   9595 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
   9596     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
   9597 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
   9598     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
   9599 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
   9600 
   9601     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
   9602 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
   9603     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
   9604 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
   9605     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
   9606 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
   9607 }
   9608 
   9609 static int
   9610 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
   9611 			     xmlSchemaPtr schema,
   9612 			     xmlNodePtr node)
   9613 {
   9614     xmlAttrPtr attr;
   9615     const xmlChar *val;
   9616     int res = 0, oldErrs = ctxt->nberrors;
   9617 
   9618     /*
   9619     * Those flags should be moved to the parser context flags,
   9620     * since they are not visible at the component level. I.e.
   9621     * they are used if processing schema *documents* only.
   9622     */
   9623     res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9624     HFAILURE;
   9625 
   9626     /*
   9627     * Since the version is of type xs:token, we won't bother to
   9628     * check it.
   9629     */
   9630     /* REMOVED:
   9631     attr = xmlSchemaGetPropNode(node, "version");
   9632     if (attr != NULL) {
   9633 	res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
   9634 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
   9635 	HFAILURE;
   9636     }
   9637     */
   9638     attr = xmlSchemaGetPropNode(node, "targetNamespace");
   9639     if (attr != NULL) {
   9640 	res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
   9641 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
   9642 	HFAILURE;
   9643 	if (res != 0) {
   9644 	    ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   9645 	    goto exit;
   9646 	}
   9647     }
   9648     attr = xmlSchemaGetPropNode(node, "elementFormDefault");
   9649     if (attr != NULL) {
   9650 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9651 	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
   9652 	    XML_SCHEMAS_QUALIF_ELEM);
   9653 	HFAILURE;
   9654 	if (res != 0) {
   9655 	    xmlSchemaPSimpleTypeErr(ctxt,
   9656 		XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
   9657 		NULL, (xmlNodePtr) attr, NULL,
   9658 		"(qualified | unqualified)", val, NULL, NULL, NULL);
   9659 	}
   9660     }
   9661     attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
   9662     if (attr != NULL) {
   9663 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9664 	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
   9665 	    XML_SCHEMAS_QUALIF_ATTR);
   9666 	HFAILURE;
   9667 	if (res != 0) {
   9668 	    xmlSchemaPSimpleTypeErr(ctxt,
   9669 		XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
   9670 		NULL, (xmlNodePtr) attr, NULL,
   9671 		"(qualified | unqualified)", val, NULL, NULL, NULL);
   9672 	}
   9673     }
   9674     attr = xmlSchemaGetPropNode(node, "finalDefault");
   9675     if (attr != NULL) {
   9676 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9677 	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
   9678 	    XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
   9679 	    XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
   9680 	    -1,
   9681 	    XML_SCHEMAS_FINAL_DEFAULT_LIST,
   9682 	    XML_SCHEMAS_FINAL_DEFAULT_UNION);
   9683 	HFAILURE;
   9684 	if (res != 0) {
   9685 	    xmlSchemaPSimpleTypeErr(ctxt,
   9686 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   9687 		NULL, (xmlNodePtr) attr, NULL,
   9688 		"(#all | List of (extension | restriction | list | union))",
   9689 		val, NULL, NULL, NULL);
   9690 	}
   9691     }
   9692     attr = xmlSchemaGetPropNode(node, "blockDefault");
   9693     if (attr != NULL) {
   9694 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9695 	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
   9696 	    XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
   9697 	    XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
   9698 	    XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
   9699 	HFAILURE;
   9700 	if (res != 0) {
   9701 	    xmlSchemaPSimpleTypeErr(ctxt,
   9702 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   9703 		NULL, (xmlNodePtr) attr, NULL,
   9704 		"(#all | List of (extension | restriction | substitution))",
   9705 		val, NULL, NULL, NULL);
   9706 	}
   9707     }
   9708 
   9709 exit:
   9710     if (oldErrs != ctxt->nberrors)
   9711 	res = ctxt->err;
   9712     return(res);
   9713 exit_failure:
   9714     return(-1);
   9715 }
   9716 
   9717 /**
   9718  * xmlSchemaParseSchemaTopLevel:
   9719  * @ctxt:  a schema validation context
   9720  * @schema:  the schemas
   9721  * @nodes:  the list of top level nodes
   9722  *
   9723  * Returns the internal XML Schema structure built from the resource or
   9724  *         NULL in case of error
   9725  */
   9726 static int
   9727 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
   9728                              xmlSchemaPtr schema, xmlNodePtr nodes)
   9729 {
   9730     xmlNodePtr child;
   9731     xmlSchemaAnnotPtr annot;
   9732     int res = 0, oldErrs, tmpOldErrs;
   9733 
   9734     if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
   9735         return(-1);
   9736 
   9737     oldErrs = ctxt->nberrors;
   9738     child = nodes;
   9739     while ((IS_SCHEMA(child, "include")) ||
   9740 	   (IS_SCHEMA(child, "import")) ||
   9741 	   (IS_SCHEMA(child, "redefine")) ||
   9742 	   (IS_SCHEMA(child, "annotation"))) {
   9743 	if (IS_SCHEMA(child, "annotation")) {
   9744 	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9745 	    if (schema->annot == NULL)
   9746 		schema->annot = annot;
   9747 	    else
   9748 		xmlSchemaFreeAnnot(annot);
   9749 	} else if (IS_SCHEMA(child, "import")) {
   9750 	    tmpOldErrs = ctxt->nberrors;
   9751 	    res = xmlSchemaParseImport(ctxt, schema, child);
   9752 	    HFAILURE;
   9753 	    HSTOP(ctxt);
   9754 	    if (tmpOldErrs != ctxt->nberrors)
   9755 		goto exit;
   9756 	} else if (IS_SCHEMA(child, "include")) {
   9757 	    tmpOldErrs = ctxt->nberrors;
   9758 	    res = xmlSchemaParseInclude(ctxt, schema, child);
   9759 	    HFAILURE;
   9760 	    HSTOP(ctxt);
   9761 	    if (tmpOldErrs != ctxt->nberrors)
   9762 		goto exit;
   9763 	} else if (IS_SCHEMA(child, "redefine")) {
   9764 	    tmpOldErrs = ctxt->nberrors;
   9765 	    res = xmlSchemaParseRedefine(ctxt, schema, child);
   9766 	    HFAILURE;
   9767 	    HSTOP(ctxt);
   9768 	    if (tmpOldErrs != ctxt->nberrors)
   9769 		goto exit;
   9770 	}
   9771 	child = child->next;
   9772     }
   9773     /*
   9774     * URGENT TODO: Change the functions to return int results.
   9775     * We need especially to catch internal errors.
   9776     */
   9777     while (child != NULL) {
   9778 	if (IS_SCHEMA(child, "complexType")) {
   9779 	    xmlSchemaParseComplexType(ctxt, schema, child, 1);
   9780 	    child = child->next;
   9781 	} else if (IS_SCHEMA(child, "simpleType")) {
   9782 	    xmlSchemaParseSimpleType(ctxt, schema, child, 1);
   9783 	    child = child->next;
   9784 	} else if (IS_SCHEMA(child, "element")) {
   9785 	    xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
   9786 	    child = child->next;
   9787 	} else if (IS_SCHEMA(child, "attribute")) {
   9788 	    xmlSchemaParseGlobalAttribute(ctxt, schema, child);
   9789 	    child = child->next;
   9790 	} else if (IS_SCHEMA(child, "attributeGroup")) {
   9791 	    xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
   9792 	    child = child->next;
   9793 	} else if (IS_SCHEMA(child, "group")) {
   9794 	    xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
   9795 	    child = child->next;
   9796 	} else if (IS_SCHEMA(child, "notation")) {
   9797 	    xmlSchemaParseNotation(ctxt, schema, child);
   9798 	    child = child->next;
   9799 	} else {
   9800 	    xmlSchemaPContentErr(ctxt,
   9801 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9802 		NULL, child->parent, child,
   9803 		NULL, "((include | import | redefine | annotation)*, "
   9804 		"(((simpleType | complexType | group | attributeGroup) "
   9805 		"| element | attribute | notation), annotation*)*)");
   9806 	    child = child->next;
   9807 	}
   9808 	while (IS_SCHEMA(child, "annotation")) {
   9809 	    /*
   9810 	    * TODO: We should add all annotations.
   9811 	    */
   9812 	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9813 	    if (schema->annot == NULL)
   9814 		schema->annot = annot;
   9815 	    else
   9816 		xmlSchemaFreeAnnot(annot);
   9817 	    child = child->next;
   9818 	}
   9819     }
   9820 exit:
   9821     ctxt->ctxtType = NULL;
   9822     if (oldErrs != ctxt->nberrors)
   9823 	res = ctxt->err;
   9824     return(res);
   9825 exit_failure:
   9826     return(-1);
   9827 }
   9828 
   9829 static xmlSchemaSchemaRelationPtr
   9830 xmlSchemaSchemaRelationCreate(void)
   9831 {
   9832     xmlSchemaSchemaRelationPtr ret;
   9833 
   9834     ret = (xmlSchemaSchemaRelationPtr)
   9835 	xmlMalloc(sizeof(xmlSchemaSchemaRelation));
   9836     if (ret == NULL) {
   9837 	xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
   9838 	return(NULL);
   9839     }
   9840     memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
   9841     return(ret);
   9842 }
   9843 
   9844 #if 0
   9845 static void
   9846 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
   9847 {
   9848     xmlFree(rel);
   9849 }
   9850 #endif
   9851 
   9852 static void
   9853 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
   9854 {
   9855     xmlSchemaRedefPtr prev;
   9856 
   9857     while (redef != NULL) {
   9858 	prev = redef;
   9859 	redef = redef->next;
   9860 	xmlFree(prev);
   9861     }
   9862 }
   9863 
   9864 static void
   9865 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
   9866 {
   9867     /*
   9868     * After the construction context has been freed, there will be
   9869     * no schema graph available any more. Only the schema buckets
   9870     * will stay alive, which are put into the "schemasImports" and
   9871     * "includes" slots of the xmlSchema.
   9872     */
   9873     if (con->buckets != NULL)
   9874 	xmlSchemaItemListFree(con->buckets);
   9875     if (con->pending != NULL)
   9876 	xmlSchemaItemListFree(con->pending);
   9877     if (con->substGroups != NULL)
   9878 	xmlHashFree(con->substGroups,
   9879 	    (xmlHashDeallocator) xmlSchemaSubstGroupFree);
   9880     if (con->redefs != NULL)
   9881 	xmlSchemaRedefListFree(con->redefs);
   9882     if (con->dict != NULL)
   9883 	xmlDictFree(con->dict);
   9884     xmlFree(con);
   9885 }
   9886 
   9887 static xmlSchemaConstructionCtxtPtr
   9888 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
   9889 {
   9890     xmlSchemaConstructionCtxtPtr ret;
   9891 
   9892     ret = (xmlSchemaConstructionCtxtPtr)
   9893 	xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
   9894     if (ret == NULL) {
   9895         xmlSchemaPErrMemory(NULL,
   9896 	    "allocating schema construction context", NULL);
   9897         return (NULL);
   9898     }
   9899     memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
   9900 
   9901     ret->buckets = xmlSchemaItemListCreate();
   9902     if (ret->buckets == NULL) {
   9903 	xmlSchemaPErrMemory(NULL,
   9904 	    "allocating list of schema buckets", NULL);
   9905 	xmlFree(ret);
   9906         return (NULL);
   9907     }
   9908     ret->pending = xmlSchemaItemListCreate();
   9909     if (ret->pending == NULL) {
   9910 	xmlSchemaPErrMemory(NULL,
   9911 	    "allocating list of pending global components", NULL);
   9912 	xmlSchemaConstructionCtxtFree(ret);
   9913         return (NULL);
   9914     }
   9915     ret->dict = dict;
   9916     xmlDictReference(dict);
   9917     return(ret);
   9918 }
   9919 
   9920 static xmlSchemaParserCtxtPtr
   9921 xmlSchemaParserCtxtCreate(void)
   9922 {
   9923     xmlSchemaParserCtxtPtr ret;
   9924 
   9925     ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
   9926     if (ret == NULL) {
   9927         xmlSchemaPErrMemory(NULL, "allocating schema parser context",
   9928                             NULL);
   9929         return (NULL);
   9930     }
   9931     memset(ret, 0, sizeof(xmlSchemaParserCtxt));
   9932     ret->type = XML_SCHEMA_CTXT_PARSER;
   9933     ret->attrProhibs = xmlSchemaItemListCreate();
   9934     if (ret->attrProhibs == NULL) {
   9935 	xmlFree(ret);
   9936 	return(NULL);
   9937     }
   9938     return(ret);
   9939 }
   9940 
   9941 /**
   9942  * xmlSchemaNewParserCtxtUseDict:
   9943  * @URL:  the location of the schema
   9944  * @dict: the dictionary to be used
   9945  *
   9946  * Create an XML Schemas parse context for that file/resource expected
   9947  * to contain an XML Schemas file.
   9948  *
   9949  * Returns the parser context or NULL in case of error
   9950  */
   9951 static xmlSchemaParserCtxtPtr
   9952 xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
   9953 {
   9954     xmlSchemaParserCtxtPtr ret;
   9955 
   9956     ret = xmlSchemaParserCtxtCreate();
   9957     if (ret == NULL)
   9958         return (NULL);
   9959     ret->dict = dict;
   9960     xmlDictReference(dict);
   9961     if (URL != NULL)
   9962 	ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
   9963     return (ret);
   9964 }
   9965 
   9966 static int
   9967 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
   9968 {
   9969     if (vctxt->pctxt == NULL) {
   9970         if (vctxt->schema != NULL)
   9971 	    vctxt->pctxt =
   9972 		xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
   9973 	else
   9974 	    vctxt->pctxt = xmlSchemaNewParserCtxt("*");
   9975 	if (vctxt->pctxt == NULL) {
   9976 	    VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
   9977 		"failed to create a temp. parser context");
   9978 	    return (-1);
   9979 	}
   9980 	/* TODO: Pass user data. */
   9981 	xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
   9982 	    vctxt->warning, vctxt->errCtxt);
   9983 	xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
   9984 	    vctxt->errCtxt);
   9985     }
   9986     return (0);
   9987 }
   9988 
   9989 /**
   9990  * xmlSchemaGetSchemaBucket:
   9991  * @pctxt: the schema parser context
   9992  * @schemaLocation: the URI of the schema document
   9993  *
   9994  * Returns a schema bucket if it was already parsed.
   9995  *
   9996  * Returns a schema bucket if it was already parsed from
   9997  *         @schemaLocation, NULL otherwise.
   9998  */
   9999 static xmlSchemaBucketPtr
   10000 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
   10001 			    const xmlChar *schemaLocation)
   10002 {
   10003     xmlSchemaBucketPtr cur;
   10004     xmlSchemaItemListPtr list;
   10005 
   10006     list = pctxt->constructor->buckets;
   10007     if (list->nbItems == 0)
   10008 	return(NULL);
   10009     else {
   10010 	int i;
   10011 	for (i = 0; i < list->nbItems; i++) {
   10012 	    cur = (xmlSchemaBucketPtr) list->items[i];
   10013 	    /* Pointer comparison! */
   10014 	    if (cur->schemaLocation == schemaLocation)
   10015 		return(cur);
   10016 	}
   10017     }
   10018     return(NULL);
   10019 }
   10020 
   10021 static xmlSchemaBucketPtr
   10022 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
   10023 				     const xmlChar *schemaLocation,
   10024 				     const xmlChar *targetNamespace)
   10025 {
   10026     xmlSchemaBucketPtr cur;
   10027     xmlSchemaItemListPtr list;
   10028 
   10029     list = pctxt->constructor->buckets;
   10030     if (list->nbItems == 0)
   10031 	return(NULL);
   10032     else {
   10033 	int i;
   10034 	for (i = 0; i < list->nbItems; i++) {
   10035 	    cur = (xmlSchemaBucketPtr) list->items[i];
   10036 	    /* Pointer comparison! */
   10037 	    if ((cur->origTargetNamespace == NULL) &&
   10038 		(cur->schemaLocation == schemaLocation) &&
   10039 		(cur->targetNamespace == targetNamespace))
   10040 		return(cur);
   10041 	}
   10042     }
   10043     return(NULL);
   10044 }
   10045 
   10046 
   10047 #define IS_BAD_SCHEMA_DOC(b) \
   10048     (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
   10049 
   10050 static xmlSchemaBucketPtr
   10051 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
   10052 				 const xmlChar *targetNamespace,
   10053 				 int imported)
   10054 {
   10055     xmlSchemaBucketPtr cur;
   10056     xmlSchemaItemListPtr list;
   10057 
   10058     list = pctxt->constructor->buckets;
   10059     if (list->nbItems == 0)
   10060 	return(NULL);
   10061     else {
   10062 	int i;
   10063 	for (i = 0; i < list->nbItems; i++) {
   10064 	    cur = (xmlSchemaBucketPtr) list->items[i];
   10065 	    if ((! IS_BAD_SCHEMA_DOC(cur)) &&
   10066 		(cur->origTargetNamespace == targetNamespace) &&
   10067 		((imported && cur->imported) ||
   10068 		 ((!imported) && (!cur->imported))))
   10069 		return(cur);
   10070 	}
   10071     }
   10072     return(NULL);
   10073 }
   10074 
   10075 static int
   10076 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
   10077 		     xmlSchemaPtr schema,
   10078 		     xmlSchemaBucketPtr bucket)
   10079 {
   10080     int oldFlags;
   10081     xmlDocPtr oldDoc;
   10082     xmlNodePtr node;
   10083     int ret, oldErrs;
   10084     xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
   10085 
   10086     /*
   10087     * Save old values; reset the *main* schema.
   10088     * URGENT TODO: This is not good; move the per-document information
   10089     * to the parser. Get rid of passing the main schema to the
   10090     * parsing functions.
   10091     */
   10092     oldFlags = schema->flags;
   10093     oldDoc = schema->doc;
   10094     if (schema->flags != 0)
   10095 	xmlSchemaClearSchemaDefaults(schema);
   10096     schema->doc = bucket->doc;
   10097     pctxt->schema = schema;
   10098     /*
   10099     * Keep the current target namespace on the parser *not* on the
   10100     * main schema.
   10101     */
   10102     pctxt->targetNamespace = bucket->targetNamespace;
   10103     WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
   10104 
   10105     if ((bucket->targetNamespace != NULL) &&
   10106 	xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
   10107 	/*
   10108 	* We are parsing the schema for schemas!
   10109 	*/
   10110 	pctxt->isS4S = 1;
   10111     }
   10112     /* Mark it as parsed, even if parsing fails. */
   10113     bucket->parsed++;
   10114     /* Compile the schema doc. */
   10115     node = xmlDocGetRootElement(bucket->doc);
   10116     ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
   10117     if (ret != 0)
   10118 	goto exit;
   10119     /* An empty schema; just get out. */
   10120     if (node->children == NULL)
   10121 	goto exit;
   10122     oldErrs = pctxt->nberrors;
   10123     ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
   10124     if (ret != 0)
   10125 	goto exit;
   10126     /*
   10127     * TODO: Not nice, but I'm not 100% sure we will get always an error
   10128     * as a result of the obove functions; so better rely on pctxt->err
   10129     * as well.
   10130     */
   10131     if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
   10132 	ret = pctxt->err;
   10133 	goto exit;
   10134     }
   10135 
   10136 exit:
   10137     WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
   10138     /* Restore schema values. */
   10139     schema->doc = oldDoc;
   10140     schema->flags = oldFlags;
   10141     return(ret);
   10142 }
   10143 
   10144 static int
   10145 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
   10146 		     xmlSchemaPtr schema,
   10147 		     xmlSchemaBucketPtr bucket)
   10148 {
   10149     xmlSchemaParserCtxtPtr newpctxt;
   10150     int res = 0;
   10151 
   10152     if (bucket == NULL)
   10153 	return(0);
   10154     if (bucket->parsed) {
   10155 	PERROR_INT("xmlSchemaParseNewDoc",
   10156 	    "reparsing a schema doc");
   10157 	return(-1);
   10158     }
   10159     if (bucket->doc == NULL) {
   10160 	PERROR_INT("xmlSchemaParseNewDoc",
   10161 	    "parsing a schema doc, but there's no doc");
   10162 	return(-1);
   10163     }
   10164     if (pctxt->constructor == NULL) {
   10165 	PERROR_INT("xmlSchemaParseNewDoc",
   10166 	    "no constructor");
   10167 	return(-1);
   10168     }
   10169     /* Create and init the temporary parser context. */
   10170     newpctxt = xmlSchemaNewParserCtxtUseDict(
   10171 	(const char *) bucket->schemaLocation, pctxt->dict);
   10172     if (newpctxt == NULL)
   10173 	return(-1);
   10174     newpctxt->constructor = pctxt->constructor;
   10175     /*
   10176     * TODO: Can we avoid that the parser knows about the main schema?
   10177     * It would be better if he knows about the current schema bucket
   10178     * only.
   10179     */
   10180     newpctxt->schema = schema;
   10181     xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
   10182 	pctxt->errCtxt);
   10183     xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
   10184 	pctxt->errCtxt);
   10185     newpctxt->counter = pctxt->counter;
   10186 
   10187 
   10188     res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
   10189 
   10190     /* Channel back errors and cleanup the temporary parser context. */
   10191     if (res != 0)
   10192 	pctxt->err = res;
   10193     pctxt->nberrors += newpctxt->nberrors;
   10194     pctxt->counter = newpctxt->counter;
   10195     newpctxt->constructor = NULL;
   10196     /* Free the parser context. */
   10197     xmlSchemaFreeParserCtxt(newpctxt);
   10198     return(res);
   10199 }
   10200 
   10201 static void
   10202 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
   10203 				xmlSchemaSchemaRelationPtr rel)
   10204 {
   10205     xmlSchemaSchemaRelationPtr cur = bucket->relations;
   10206 
   10207     if (cur == NULL) {
   10208 	bucket->relations = rel;
   10209 	return;
   10210     }
   10211     while (cur->next != NULL)
   10212 	cur = cur->next;
   10213     cur->next = rel;
   10214 }
   10215 
   10216 
   10217 static const xmlChar *
   10218 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
   10219 			  xmlNodePtr ctxtNode)
   10220 {
   10221     /*
   10222     * Build an absolue location URI.
   10223     */
   10224     if (location != NULL) {
   10225 	if (ctxtNode == NULL)
   10226 	    return(location);
   10227 	else {
   10228 	    xmlChar *base, *URI;
   10229 	    const xmlChar *ret = NULL;
   10230 
   10231 	    base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
   10232 	    if (base == NULL) {
   10233 		URI = xmlBuildURI(location, ctxtNode->doc->URL);
   10234 	    } else {
   10235 		URI = xmlBuildURI(location, base);
   10236 		xmlFree(base);
   10237 	    }
   10238 	    if (URI != NULL) {
   10239 		ret = xmlDictLookup(dict, URI, -1);
   10240 		xmlFree(URI);
   10241 		return(ret);
   10242 	    }
   10243 	}
   10244     }
   10245     return(NULL);
   10246 }
   10247 
   10248 
   10249 
   10250 /**
   10251  * xmlSchemaAddSchemaDoc:
   10252  * @pctxt:  a schema validation context
   10253  * @schema:  the schema being built
   10254  * @node:  a subtree containing XML Schema informations
   10255  *
   10256  * Parse an included (and to-be-redefined) XML schema document.
   10257  *
   10258  * Returns 0 on success, a positive error code on errors and
   10259  *         -1 in case of an internal or API error.
   10260  */
   10261 
   10262 static int
   10263 xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
   10264 		int type, /* import or include or redefine */
   10265 		const xmlChar *schemaLocation,
   10266 		xmlDocPtr schemaDoc,
   10267 		const char *schemaBuffer,
   10268 		int schemaBufferLen,
   10269 		xmlNodePtr invokingNode,
   10270 		const xmlChar *sourceTargetNamespace,
   10271 		const xmlChar *importNamespace,
   10272 		xmlSchemaBucketPtr *bucket)
   10273 {
   10274     const xmlChar *targetNamespace = NULL;
   10275     xmlSchemaSchemaRelationPtr relation = NULL;
   10276     xmlDocPtr doc = NULL;
   10277     int res = 0, err = 0, located = 0, preserveDoc = 0;
   10278     xmlSchemaBucketPtr bkt = NULL;
   10279 
   10280     if (bucket != NULL)
   10281 	*bucket = NULL;
   10282 
   10283     switch (type) {
   10284 	case XML_SCHEMA_SCHEMA_IMPORT:
   10285 	case XML_SCHEMA_SCHEMA_MAIN:
   10286 	    err = XML_SCHEMAP_SRC_IMPORT;
   10287 	    break;
   10288 	case XML_SCHEMA_SCHEMA_INCLUDE:
   10289 	    err = XML_SCHEMAP_SRC_INCLUDE;
   10290 	    break;
   10291 	case XML_SCHEMA_SCHEMA_REDEFINE:
   10292 	    err = XML_SCHEMAP_SRC_REDEFINE;
   10293 	    break;
   10294     }
   10295 
   10296 
   10297     /* Special handling for the main schema:
   10298     * skip the location and relation logic and just parse the doc.
   10299     * We need just a bucket to be returned in this case.
   10300     */
   10301     if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
   10302 	goto doc_load;
   10303 
   10304     /* Note that we expect the location to be an absulute URI. */
   10305     if (schemaLocation != NULL) {
   10306 	bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
   10307 	if ((bkt != NULL) &&
   10308 	    (pctxt->constructor->bucket == bkt)) {
   10309 	    /* Report self-imports/inclusions/redefinitions. */
   10310 
   10311 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
   10312 		invokingNode, NULL,
   10313 		"The schema must not import/include/redefine itself",
   10314 		NULL, NULL);
   10315 	    goto exit;
   10316 	}
   10317     }
   10318     /*
   10319     * Create a relation for the graph of schemas.
   10320     */
   10321     relation = xmlSchemaSchemaRelationCreate();
   10322     if (relation == NULL)
   10323 	return(-1);
   10324     xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
   10325 	relation);
   10326     relation->type = type;
   10327 
   10328     /*
   10329     * Save the namespace import information.
   10330     */
   10331     if (WXS_IS_BUCKET_IMPMAIN(type)) {
   10332 	relation->importNamespace = importNamespace;
   10333 	if (schemaLocation == NULL) {
   10334 	    /*
   10335 	    * No location; this is just an import of the namespace.
   10336 	    * Note that we don't assign a bucket to the relation
   10337 	    * in this case.
   10338 	    */
   10339 	    goto exit;
   10340 	}
   10341 	targetNamespace = importNamespace;
   10342     }
   10343 
   10344     /* Did we already fetch the doc? */
   10345     if (bkt != NULL) {
   10346 	/* TODO: The following nasty cases will produce an error. */
   10347 	if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
   10348 	    /* We included/redefined and then try to import a schema. */
   10349 	    if (schemaLocation == NULL)
   10350 		schemaLocation = BAD_CAST "in_memory_buffer";
   10351 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
   10352 		invokingNode, NULL,
   10353 		"The schema document '%s' cannot be imported, since "
   10354 		"it was already included or redefined",
   10355 		schemaLocation, NULL);
   10356 	    goto exit;
   10357 	} else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
   10358 	    /* We imported and then try to include/redefine a schema. */
   10359 	    if (schemaLocation == NULL)
   10360 		schemaLocation = BAD_CAST "in_memory_buffer";
   10361 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
   10362 		invokingNode, NULL,
   10363 		"The schema document '%s' cannot be included or "
   10364 		"redefined, since it was already imported",
   10365 		schemaLocation, NULL);
   10366 	    goto exit;
   10367 	}
   10368     }
   10369 
   10370     if (WXS_IS_BUCKET_IMPMAIN(type)) {
   10371 	/*
   10372 	* Given that the schemaLocation [attribute] is only a hint, it is open
   10373 	* to applications to ignore all but the first <import> for a given
   10374 	* namespace, regardless of the actual value of schemaLocation, but
   10375 	* such a strategy risks missing useful information when new
   10376 	* schemaLocations are offered.
   10377 	*
   10378 	* We will use the first <import> that comes with a location.
   10379 	* Further <import>s *with* a location, will result in an error.
   10380 	* TODO: Better would be to just report a warning here, but
   10381 	* we'll try it this way until someone complains.
   10382 	*
   10383 	* Schema Document Location Strategy:
   10384 	* 3 Based on the namespace name, identify an existing schema document,
   10385 	* either as a resource which is an XML document or a <schema> element
   10386 	* information item, in some local schema repository;
   10387 	* 5 Attempt to resolve the namespace name to locate such a resource.
   10388 	*
   10389 	* NOTE: (3) and (5) are not supported.
   10390 	*/
   10391 	if (bkt != NULL) {
   10392 	    relation->bucket = bkt;
   10393 	    goto exit;
   10394 	}
   10395 	bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
   10396 	    importNamespace, 1);
   10397 
   10398 	if (bkt != NULL) {
   10399 	    relation->bucket = bkt;
   10400 	    if (bkt->schemaLocation == NULL) {
   10401 		/* First given location of the schema; load the doc. */
   10402 		bkt->schemaLocation = schemaLocation;
   10403 	    } else {
   10404 		if (!xmlStrEqual(schemaLocation,
   10405 		    bkt->schemaLocation)) {
   10406 		    /*
   10407 		    * Additional location given; just skip it.
   10408 		    * URGENT TODO: We should report a warning here.
   10409 		    * res = XML_SCHEMAP_SRC_IMPORT;
   10410 		    */
   10411 		    if (schemaLocation == NULL)
   10412 			schemaLocation = BAD_CAST "in_memory_buffer";
   10413 
   10414 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   10415 			XML_SCHEMAP_WARN_SKIP_SCHEMA,
   10416 			invokingNode, NULL,
   10417 			"Skipping import of schema located at '%s' for the "
   10418 			"namespace '%s', since this namespace was already "
   10419 			"imported with the schema located at '%s'",
   10420 			schemaLocation, importNamespace, bkt->schemaLocation);
   10421 		}
   10422 		goto exit;
   10423 	    }
   10424 	}
   10425 	/*
   10426 	* No bucket + first location: load the doc and create a
   10427 	* bucket.
   10428 	*/
   10429     } else {
   10430 	/* <include> and <redefine> */
   10431 	if (bkt != NULL) {
   10432 
   10433 	    if ((bkt->origTargetNamespace == NULL) &&
   10434 		(bkt->targetNamespace != sourceTargetNamespace)) {
   10435 		xmlSchemaBucketPtr chamel;
   10436 
   10437 		/*
   10438 		* Chameleon include/redefine: skip loading only if it was
   10439 		* aleady build for the targetNamespace of the including
   10440 		* schema.
   10441 		*/
   10442 		/*
   10443 		* URGENT TODO: If the schema is a chameleon-include then copy
   10444 		* the components into the including schema and modify the
   10445 		* targetNamespace of those components, do nothing otherwise.
   10446 		* NOTE: This is currently worked-around by compiling the
   10447 		* chameleon for every destinct including targetNamespace; thus
   10448 		* not performant at the moment.
   10449 		* TODO: Check when the namespace in wildcards for chameleons
   10450 		* needs to be converted: before we built wildcard intersections
   10451 		* or after.
   10452 		*   Answer: after!
   10453 		*/
   10454 		chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
   10455 		    schemaLocation, sourceTargetNamespace);
   10456 		if (chamel != NULL) {
   10457 		    /* A fitting chameleon was already parsed; NOP. */
   10458 		    relation->bucket = chamel;
   10459 		    goto exit;
   10460 		}
   10461 		/*
   10462 		* We need to parse the chameleon again for a different
   10463 		* targetNamespace.
   10464 		* CHAMELEON TODO: Optimize this by only parsing the
   10465 		* chameleon once, and then copying the components to
   10466 		* the new targetNamespace.
   10467 		*/
   10468 		bkt = NULL;
   10469 	    } else {
   10470 		relation->bucket = bkt;
   10471 		goto exit;
   10472 	    }
   10473 	}
   10474     }
   10475     if ((bkt != NULL) && (bkt->doc != NULL)) {
   10476 	PERROR_INT("xmlSchemaAddSchemaDoc",
   10477 	    "trying to load a schema doc, but a doc is already "
   10478 	    "assigned to the schema bucket");
   10479 	goto exit_failure;
   10480     }
   10481 
   10482 doc_load:
   10483     /*
   10484     * Load the document.
   10485     */
   10486     if (schemaDoc != NULL) {
   10487 	doc = schemaDoc;
   10488 	/* Don' free this one, since it was provided by the caller. */
   10489 	preserveDoc = 1;
   10490 	/* TODO: Does the context or the doc hold the location? */
   10491 	if (schemaDoc->URL != NULL)
   10492 	    schemaLocation = xmlDictLookup(pctxt->dict,
   10493 		schemaDoc->URL, -1);
   10494         else
   10495 	    schemaLocation = BAD_CAST "in_memory_buffer";
   10496     } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
   10497 	xmlParserCtxtPtr parserCtxt;
   10498 
   10499 	parserCtxt = xmlNewParserCtxt();
   10500 	if (parserCtxt == NULL) {
   10501 	    xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
   10502 		"allocating a parser context", NULL);
   10503 	    goto exit_failure;
   10504 	}
   10505 	if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
   10506 	    /*
   10507 	    * TODO: Do we have to burden the schema parser dict with all
   10508 	    * the content of the schema doc?
   10509 	    */
   10510 	    xmlDictFree(parserCtxt->dict);
   10511 	    parserCtxt->dict = pctxt->dict;
   10512 	    xmlDictReference(parserCtxt->dict);
   10513 	}
   10514 	if (schemaLocation != NULL) {
   10515 	    /* Parse from file. */
   10516 	    doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
   10517 		NULL, SCHEMAS_PARSE_OPTIONS);
   10518 	} else if (schemaBuffer != NULL) {
   10519 	    /* Parse from memory buffer. */
   10520 	    doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
   10521 		NULL, NULL, SCHEMAS_PARSE_OPTIONS);
   10522 	    schemaLocation = xmlStrdup(BAD_CAST "in_memory_buffer");
   10523 	    if (doc != NULL)
   10524 		doc->URL = schemaLocation;
   10525 	}
   10526 	/*
   10527 	* For <import>:
   10528 	* 2.1 The referent is (a fragment of) a resource which is an
   10529 	* XML document (see clause 1.1), which in turn corresponds to
   10530 	* a <schema> element information item in a well-formed information
   10531 	* set, which in turn corresponds to a valid schema.
   10532 	* TODO: (2.1) fragments of XML documents are not supported.
   10533 	*
   10534 	* 2.2 The referent is a <schema> element information item in
   10535 	* a well-formed information set, which in turn corresponds
   10536 	* to a valid schema.
   10537 	* TODO: (2.2) is not supported.
   10538 	*/
   10539 	if (doc == NULL) {
   10540 	    xmlErrorPtr lerr;
   10541 	    lerr = xmlGetLastError();
   10542 	    /*
   10543 	    * Check if this a parser error, or if the document could
   10544 	    * just not be located.
   10545 	    * TODO: Try to find specific error codes to react only on
   10546 	    * localisation failures.
   10547 	    */
   10548 	    if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
   10549 		/*
   10550 		* We assume a parser error here.
   10551 		*/
   10552 		located = 1;
   10553 		/* TODO: Error code ?? */
   10554 		res = XML_SCHEMAP_SRC_IMPORT_2_1;
   10555 		xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
   10556 		    invokingNode, NULL,
   10557 		    "Failed to parse the XML resource '%s'",
   10558 		    schemaLocation, NULL);
   10559 	    }
   10560 	}
   10561 	xmlFreeParserCtxt(parserCtxt);
   10562 	if ((doc == NULL) && located)
   10563 	    goto exit_error;
   10564     } else {
   10565 	xmlSchemaPErr(pctxt, NULL,
   10566 	    XML_SCHEMAP_NOTHING_TO_PARSE,
   10567 	    "No information for parsing was provided with the "
   10568 	    "given schema parser context.\n",
   10569 	    NULL, NULL);
   10570 	goto exit_failure;
   10571     }
   10572     /*
   10573     * Preprocess the document.
   10574     */
   10575     if (doc != NULL) {
   10576 	xmlNodePtr docElem = NULL;
   10577 
   10578 	located = 1;
   10579 	docElem = xmlDocGetRootElement(doc);
   10580 	if (docElem == NULL) {
   10581 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
   10582 		invokingNode, NULL,
   10583 		"The document '%s' has no document element",
   10584 		schemaLocation, NULL);
   10585 	    goto exit_error;
   10586 	}
   10587 	/*
   10588 	* Remove all the blank text nodes.
   10589 	*/
   10590 	xmlSchemaCleanupDoc(pctxt, docElem);
   10591 	/*
   10592 	* Check the schema's top level element.
   10593 	*/
   10594 	if (!IS_SCHEMA(docElem, "schema")) {
   10595 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
   10596 		invokingNode, NULL,
   10597 		"The XML document '%s' is not a schema document",
   10598 		schemaLocation, NULL);
   10599 	    goto exit_error;
   10600 	}
   10601 	/*
   10602 	* Note that we don't apply a type check for the
   10603 	* targetNamespace value here.
   10604 	*/
   10605 	targetNamespace = xmlSchemaGetProp(pctxt, docElem,
   10606 	    "targetNamespace");
   10607     }
   10608 
   10609 /* after_doc_loading: */
   10610     if ((bkt == NULL) && located) {
   10611 	/* Only create a bucket if the schema was located. */
   10612         bkt = xmlSchemaBucketCreate(pctxt, type,
   10613 	    targetNamespace);
   10614 	if (bkt == NULL)
   10615 	    goto exit_failure;
   10616     }
   10617     if (bkt != NULL) {
   10618 	bkt->schemaLocation = schemaLocation;
   10619 	bkt->located = located;
   10620 	if (doc != NULL) {
   10621 	    bkt->doc = doc;
   10622 	    bkt->targetNamespace = targetNamespace;
   10623 	    bkt->origTargetNamespace = targetNamespace;
   10624 	    if (preserveDoc)
   10625 		bkt->preserveDoc = 1;
   10626 	}
   10627 	if (WXS_IS_BUCKET_IMPMAIN(type))
   10628 	    bkt->imported++;
   10629 	    /*
   10630 	    * Add it to the graph of schemas.
   10631 	    */
   10632 	if (relation != NULL)
   10633 	    relation->bucket = bkt;
   10634     }
   10635 
   10636 exit:
   10637     /*
   10638     * Return the bucket explicitely; this is needed for the
   10639     * main schema.
   10640     */
   10641     if (bucket != NULL)
   10642 	*bucket = bkt;
   10643     return (0);
   10644 
   10645 exit_error:
   10646     if ((doc != NULL) && (! preserveDoc)) {
   10647 	xmlFreeDoc(doc);
   10648 	if (bkt != NULL)
   10649 	    bkt->doc = NULL;
   10650     }
   10651     return(pctxt->err);
   10652 
   10653 exit_failure:
   10654     if ((doc != NULL) && (! preserveDoc)) {
   10655 	xmlFreeDoc(doc);
   10656 	if (bkt != NULL)
   10657 	    bkt->doc = NULL;
   10658     }
   10659     return (-1);
   10660 }
   10661 
   10662 /**
   10663  * xmlSchemaParseImport:
   10664  * @ctxt:  a schema validation context
   10665  * @schema:  the schema being built
   10666  * @node:  a subtree containing XML Schema informations
   10667  *
   10668  * parse a XML schema Import definition
   10669  * *WARNING* this interface is highly subject to change
   10670  *
   10671  * Returns 0 in case of success, a positive error code if
   10672  * not valid and -1 in case of an internal error.
   10673  */
   10674 static int
   10675 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
   10676                      xmlNodePtr node)
   10677 {
   10678     xmlNodePtr child;
   10679     const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
   10680     const xmlChar *thisTargetNamespace;
   10681     xmlAttrPtr attr;
   10682     int ret = 0;
   10683     xmlSchemaBucketPtr bucket = NULL;
   10684 
   10685     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   10686         return (-1);
   10687 
   10688     /*
   10689     * Check for illegal attributes.
   10690     */
   10691     attr = node->properties;
   10692     while (attr != NULL) {
   10693 	if (attr->ns == NULL) {
   10694 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   10695 		(!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
   10696 		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
   10697 		xmlSchemaPIllegalAttrErr(pctxt,
   10698 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10699 	    }
   10700 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   10701 	    xmlSchemaPIllegalAttrErr(pctxt,
   10702 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10703 	}
   10704 	attr = attr->next;
   10705     }
   10706     /*
   10707     * Extract and validate attributes.
   10708     */
   10709     if (xmlSchemaPValAttr(pctxt, NULL, node,
   10710 	"namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10711 	&namespaceName) != 0) {
   10712 	xmlSchemaPSimpleTypeErr(pctxt,
   10713 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   10714 	    NULL, node,
   10715 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10716 	    NULL, namespaceName, NULL, NULL, NULL);
   10717 	return (pctxt->err);
   10718     }
   10719 
   10720     if (xmlSchemaPValAttr(pctxt, NULL, node,
   10721 	"schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10722 	&schemaLocation) != 0) {
   10723 	xmlSchemaPSimpleTypeErr(pctxt,
   10724 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   10725 	    NULL, node,
   10726 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10727 	    NULL, namespaceName, NULL, NULL, NULL);
   10728 	return (pctxt->err);
   10729     }
   10730     /*
   10731     * And now for the children...
   10732     */
   10733     child = node->children;
   10734     if (IS_SCHEMA(child, "annotation")) {
   10735         /*
   10736          * the annotation here is simply discarded ...
   10737 	 * TODO: really?
   10738          */
   10739         child = child->next;
   10740     }
   10741     if (child != NULL) {
   10742 	xmlSchemaPContentErr(pctxt,
   10743 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   10744 	    NULL, node, child, NULL,
   10745 	    "(annotation?)");
   10746     }
   10747     /*
   10748     * Apply additional constraints.
   10749     *
   10750     * Note that it is important to use the original @targetNamespace
   10751     * (or none at all), to rule out imports of schemas _with_ a
   10752     * @targetNamespace if the importing schema is a chameleon schema
   10753     * (with no @targetNamespace).
   10754     */
   10755     thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
   10756     if (namespaceName != NULL) {
   10757 	/*
   10758 	* 1.1 If the namespace [attribute] is present, then its actual value
   10759 	* must not match the actual value of the enclosing <schema>'s
   10760 	* targetNamespace [attribute].
   10761 	*/
   10762 	if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
   10763 	    xmlSchemaPCustomErr(pctxt,
   10764 		XML_SCHEMAP_SRC_IMPORT_1_1,
   10765 		NULL, node,
   10766 		"The value of the attribute 'namespace' must not match "
   10767 		"the target namespace '%s' of the importing schema",
   10768 		thisTargetNamespace);
   10769 	    return (pctxt->err);
   10770 	}
   10771     } else {
   10772 	/*
   10773 	* 1.2 If the namespace [attribute] is not present, then the enclosing
   10774 	* <schema> must have a targetNamespace [attribute].
   10775 	*/
   10776 	if (thisTargetNamespace == NULL) {
   10777 	    xmlSchemaPCustomErr(pctxt,
   10778 		XML_SCHEMAP_SRC_IMPORT_1_2,
   10779 		NULL, node,
   10780 		"The attribute 'namespace' must be existent if "
   10781 		"the importing schema has no target namespace",
   10782 		NULL);
   10783 	    return (pctxt->err);
   10784 	}