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     char *filename;
    979 
    980     int err;
    981     int nberrors;
    982 
    983     xmlNodePtr node;
    984     xmlNodePtr cur;
    985     /* xmlSchemaTypePtr type; */
    986 
    987     xmlRegExecCtxtPtr regexp;
    988     xmlSchemaValPtr value;
    989 
    990     int valueWS;
    991     int options;
    992     xmlNodePtr validationRoot;
    993     xmlSchemaParserCtxtPtr pctxt;
    994     int xsiAssemble;
    995 
    996     int depth;
    997     xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */
    998     int sizeElemInfos;
    999     xmlSchemaNodeInfoPtr inode; /* the current element information */
   1000 
   1001     xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */
   1002 
   1003     xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
   1004     xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
   1005     xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
   1006 
   1007     xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
   1008     int nbIdcNodes;
   1009     int sizeIdcNodes;
   1010 
   1011     xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
   1012     int nbIdcKeys;
   1013     int sizeIdcKeys;
   1014 
   1015     int flags;
   1016 
   1017     xmlDictPtr dict;
   1018 
   1019 #ifdef LIBXML_READER_ENABLED
   1020     xmlTextReaderPtr reader;
   1021 #endif
   1022 
   1023     xmlSchemaAttrInfoPtr *attrInfos;
   1024     int nbAttrInfos;
   1025     int sizeAttrInfos;
   1026 
   1027     int skipDepth;
   1028     xmlSchemaItemListPtr nodeQNames;
   1029     int hasKeyrefs;
   1030     int createIDCNodeTables;
   1031     int psviExposeIDCNodeTables;
   1032 
   1033     /* Locator for error reporting in streaming mode */
   1034     xmlSchemaValidityLocatorFunc locFunc;
   1035     void *locCtxt;
   1036 };
   1037 
   1038 /**
   1039  * xmlSchemaSubstGroup:
   1040  *
   1041  *
   1042  */
   1043 typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
   1044 typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
   1045 struct _xmlSchemaSubstGroup {
   1046     xmlSchemaElementPtr head;
   1047     xmlSchemaItemListPtr members;
   1048 };
   1049 
   1050 /************************************************************************
   1051  *									*
   1052  *			Some predeclarations				*
   1053  *									*
   1054  ************************************************************************/
   1055 
   1056 static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
   1057                                  xmlSchemaPtr schema,
   1058                                  xmlNodePtr node);
   1059 static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
   1060                                  xmlSchemaPtr schema,
   1061                                  xmlNodePtr node);
   1062 static int
   1063 xmlSchemaTypeFixup(xmlSchemaTypePtr type,
   1064                    xmlSchemaAbstractCtxtPtr ctxt);
   1065 static const xmlChar *
   1066 xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
   1067 static int
   1068 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   1069                      xmlNodePtr node);
   1070 static int
   1071 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
   1072                        xmlSchemaParserCtxtPtr ctxt);
   1073 static void
   1074 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
   1075 static xmlSchemaWhitespaceValueType
   1076 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
   1077 static xmlSchemaTreeItemPtr
   1078 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   1079 			 xmlNodePtr node, xmlSchemaTypeType type,
   1080 			 int withParticle);
   1081 static const xmlChar *
   1082 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
   1083 static xmlSchemaTypeLinkPtr
   1084 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
   1085 static void
   1086 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
   1087 		     const char *funcName,
   1088 		     const char *message);
   1089 static int
   1090 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
   1091 			     xmlSchemaTypePtr type,
   1092 			     xmlSchemaTypePtr baseType,
   1093 			     int subset);
   1094 static void
   1095 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
   1096 				   xmlSchemaParserCtxtPtr ctxt);
   1097 static void
   1098 xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
   1099 static xmlSchemaQNameRefPtr
   1100 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
   1101 				xmlSchemaPtr schema,
   1102 				xmlNodePtr node);
   1103 
   1104 /************************************************************************
   1105  *									*
   1106  *			Helper functions			        *
   1107  *									*
   1108  ************************************************************************/
   1109 
   1110 /**
   1111  * xmlSchemaItemTypeToStr:
   1112  * @type: the type of the schema item
   1113  *
   1114  * Returns the component name of a schema item.
   1115  */
   1116 static const xmlChar *
   1117 xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
   1118 {
   1119     switch (type) {
   1120 	case XML_SCHEMA_TYPE_BASIC:
   1121 	    return(BAD_CAST "simple type definition");
   1122 	case XML_SCHEMA_TYPE_SIMPLE:
   1123 	    return(BAD_CAST "simple type definition");
   1124 	case XML_SCHEMA_TYPE_COMPLEX:
   1125 	    return(BAD_CAST "complex type definition");
   1126 	case XML_SCHEMA_TYPE_ELEMENT:
   1127 	    return(BAD_CAST "element declaration");
   1128 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   1129 	    return(BAD_CAST "attribute use");
   1130 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   1131 	    return(BAD_CAST "attribute declaration");
   1132 	case XML_SCHEMA_TYPE_GROUP:
   1133 	    return(BAD_CAST "model group definition");
   1134 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1135 	    return(BAD_CAST "attribute group definition");
   1136 	case XML_SCHEMA_TYPE_NOTATION:
   1137 	    return(BAD_CAST "notation declaration");
   1138 	case XML_SCHEMA_TYPE_SEQUENCE:
   1139 	    return(BAD_CAST "model group (sequence)");
   1140 	case XML_SCHEMA_TYPE_CHOICE:
   1141 	    return(BAD_CAST "model group (choice)");
   1142 	case XML_SCHEMA_TYPE_ALL:
   1143 	    return(BAD_CAST "model group (all)");
   1144 	case XML_SCHEMA_TYPE_PARTICLE:
   1145 	    return(BAD_CAST "particle");
   1146 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1147 	    return(BAD_CAST "unique identity-constraint");
   1148 	    /* return(BAD_CAST "IDC (unique)"); */
   1149 	case XML_SCHEMA_TYPE_IDC_KEY:
   1150 	    return(BAD_CAST "key identity-constraint");
   1151 	    /* return(BAD_CAST "IDC (key)"); */
   1152 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1153 	    return(BAD_CAST "keyref identity-constraint");
   1154 	    /* return(BAD_CAST "IDC (keyref)"); */
   1155 	case XML_SCHEMA_TYPE_ANY:
   1156 	    return(BAD_CAST "wildcard (any)");
   1157 	case XML_SCHEMA_EXTRA_QNAMEREF:
   1158 	    return(BAD_CAST "[helper component] QName reference");
   1159 	case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
   1160 	    return(BAD_CAST "[helper component] attribute use prohibition");
   1161 	default:
   1162 	    return(BAD_CAST "Not a schema component");
   1163     }
   1164 }
   1165 
   1166 /**
   1167  * xmlSchemaGetComponentTypeStr:
   1168  * @type: the type of the schema item
   1169  *
   1170  * Returns the component name of a schema item.
   1171  */
   1172 static const xmlChar *
   1173 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
   1174 {
   1175     switch (item->type) {
   1176 	case XML_SCHEMA_TYPE_BASIC:
   1177 	    if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
   1178 		return(BAD_CAST "complex type definition");
   1179 	    else
   1180 		return(BAD_CAST "simple type definition");
   1181 	default:
   1182 	    return(xmlSchemaItemTypeToStr(item->type));
   1183     }
   1184 }
   1185 
   1186 /**
   1187  * xmlSchemaGetComponentNode:
   1188  * @item: a schema component
   1189  *
   1190  * Returns node associated with the schema component.
   1191  * NOTE that such a node need not be available; plus, a component's
   1192  * node need not to reflect the component directly, since there is no
   1193  * one-to-one relationship between the XML Schema representation and
   1194  * the component representation.
   1195  */
   1196 static xmlNodePtr
   1197 xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
   1198 {
   1199     switch (item->type) {
   1200 	case XML_SCHEMA_TYPE_ELEMENT:
   1201 	    return (((xmlSchemaElementPtr) item)->node);
   1202 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   1203 	    return (((xmlSchemaAttributePtr) item)->node);
   1204 	case XML_SCHEMA_TYPE_COMPLEX:
   1205 	case XML_SCHEMA_TYPE_SIMPLE:
   1206 	    return (((xmlSchemaTypePtr) item)->node);
   1207 	case XML_SCHEMA_TYPE_ANY:
   1208 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   1209 	    return (((xmlSchemaWildcardPtr) item)->node);
   1210 	case XML_SCHEMA_TYPE_PARTICLE:
   1211 	    return (((xmlSchemaParticlePtr) item)->node);
   1212 	case XML_SCHEMA_TYPE_SEQUENCE:
   1213 	case XML_SCHEMA_TYPE_CHOICE:
   1214 	case XML_SCHEMA_TYPE_ALL:
   1215 	    return (((xmlSchemaModelGroupPtr) item)->node);
   1216 	case XML_SCHEMA_TYPE_GROUP:
   1217 	    return (((xmlSchemaModelGroupDefPtr) item)->node);
   1218 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1219 	    return (((xmlSchemaAttributeGroupPtr) item)->node);
   1220 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1221 	case XML_SCHEMA_TYPE_IDC_KEY:
   1222 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1223 	    return (((xmlSchemaIDCPtr) item)->node);
   1224 	case XML_SCHEMA_EXTRA_QNAMEREF:
   1225 	    return(((xmlSchemaQNameRefPtr) item)->node);
   1226 	/* TODO: What to do with NOTATIONs?
   1227 	case XML_SCHEMA_TYPE_NOTATION:
   1228 	    return (((xmlSchemaNotationPtr) item)->node);
   1229 	*/
   1230 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   1231 	    return (((xmlSchemaAttributeUsePtr) item)->node);
   1232 	default:
   1233 	    return (NULL);
   1234     }
   1235 }
   1236 
   1237 #if 0
   1238 /**
   1239  * xmlSchemaGetNextComponent:
   1240  * @item: a schema component
   1241  *
   1242  * Returns the next sibling of the schema component.
   1243  */
   1244 static xmlSchemaBasicItemPtr
   1245 xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
   1246 {
   1247     switch (item->type) {
   1248 	case XML_SCHEMA_TYPE_ELEMENT:
   1249 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
   1250 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   1251 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
   1252 	case XML_SCHEMA_TYPE_COMPLEX:
   1253 	case XML_SCHEMA_TYPE_SIMPLE:
   1254 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
   1255 	case XML_SCHEMA_TYPE_ANY:
   1256 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   1257 	    return (NULL);
   1258 	case XML_SCHEMA_TYPE_PARTICLE:
   1259 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
   1260 	case XML_SCHEMA_TYPE_SEQUENCE:
   1261 	case XML_SCHEMA_TYPE_CHOICE:
   1262 	case XML_SCHEMA_TYPE_ALL:
   1263 	    return (NULL);
   1264 	case XML_SCHEMA_TYPE_GROUP:
   1265 	    return (NULL);
   1266 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1267 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
   1268 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1269 	case XML_SCHEMA_TYPE_IDC_KEY:
   1270 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1271 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
   1272 	default:
   1273 	    return (NULL);
   1274     }
   1275 }
   1276 #endif
   1277 
   1278 
   1279 /**
   1280  * xmlSchemaFormatQName:
   1281  * @buf: the string buffer
   1282  * @namespaceName:  the namespace name
   1283  * @localName: the local name
   1284  *
   1285  * Returns the given QName in the format "{namespaceName}localName" or
   1286  * just "localName" if @namespaceName is NULL.
   1287  *
   1288  * Returns the localName if @namespaceName is NULL, a formatted
   1289  * string otherwise.
   1290  */
   1291 static const xmlChar*
   1292 xmlSchemaFormatQName(xmlChar **buf,
   1293 		     const xmlChar *namespaceName,
   1294 		     const xmlChar *localName)
   1295 {
   1296     FREE_AND_NULL(*buf)
   1297     if (namespaceName != NULL) {
   1298 	*buf = xmlStrdup(BAD_CAST "{");
   1299 	*buf = xmlStrcat(*buf, namespaceName);
   1300 	*buf = xmlStrcat(*buf, BAD_CAST "}");
   1301     }
   1302     if (localName != NULL) {
   1303 	if (namespaceName == NULL)
   1304 	    return(localName);
   1305 	*buf = xmlStrcat(*buf, localName);
   1306     } else {
   1307 	*buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
   1308     }
   1309     return ((const xmlChar *) *buf);
   1310 }
   1311 
   1312 static const xmlChar*
   1313 xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
   1314 {
   1315     if (ns != NULL)
   1316 	return (xmlSchemaFormatQName(buf, ns->href, localName));
   1317     else
   1318 	return (xmlSchemaFormatQName(buf, NULL, localName));
   1319 }
   1320 
   1321 static const xmlChar *
   1322 xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
   1323 {
   1324     switch (item->type) {
   1325 	case XML_SCHEMA_TYPE_ELEMENT:
   1326 	    return (((xmlSchemaElementPtr) item)->name);
   1327 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   1328 	    return (((xmlSchemaAttributePtr) item)->name);
   1329 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1330 	    return (((xmlSchemaAttributeGroupPtr) item)->name);
   1331 	case XML_SCHEMA_TYPE_BASIC:
   1332 	case XML_SCHEMA_TYPE_SIMPLE:
   1333 	case XML_SCHEMA_TYPE_COMPLEX:
   1334 	    return (((xmlSchemaTypePtr) item)->name);
   1335 	case XML_SCHEMA_TYPE_GROUP:
   1336 	    return (((xmlSchemaModelGroupDefPtr) item)->name);
   1337 	case XML_SCHEMA_TYPE_IDC_KEY:
   1338 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1339 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1340 	    return (((xmlSchemaIDCPtr) item)->name);
   1341 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   1342 	    if (WXS_ATTRUSE_DECL(item) != NULL) {
   1343 		return(xmlSchemaGetComponentName(
   1344 		    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
   1345 	    } else
   1346 		return(NULL);
   1347 	case XML_SCHEMA_EXTRA_QNAMEREF:
   1348 	    return (((xmlSchemaQNameRefPtr) item)->name);
   1349 	case XML_SCHEMA_TYPE_NOTATION:
   1350 	    return (((xmlSchemaNotationPtr) item)->name);
   1351 	default:
   1352 	    /*
   1353 	    * Other components cannot have names.
   1354 	    */
   1355 	    break;
   1356     }
   1357     return (NULL);
   1358 }
   1359 
   1360 #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
   1361 #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
   1362 /*
   1363 static const xmlChar *
   1364 xmlSchemaGetQNameRefName(void *ref)
   1365 {
   1366     return(((xmlSchemaQNameRefPtr) ref)->name);
   1367 }
   1368 
   1369 static const xmlChar *
   1370 xmlSchemaGetQNameRefTargetNs(void *ref)
   1371 {
   1372     return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
   1373 }
   1374 */
   1375 
   1376 static const xmlChar *
   1377 xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
   1378 {
   1379     switch (item->type) {
   1380 	case XML_SCHEMA_TYPE_ELEMENT:
   1381 	    return (((xmlSchemaElementPtr) item)->targetNamespace);
   1382 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   1383 	    return (((xmlSchemaAttributePtr) item)->targetNamespace);
   1384 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1385 	    return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
   1386 	case XML_SCHEMA_TYPE_BASIC:
   1387 	    return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
   1388 	case XML_SCHEMA_TYPE_SIMPLE:
   1389 	case XML_SCHEMA_TYPE_COMPLEX:
   1390 	    return (((xmlSchemaTypePtr) item)->targetNamespace);
   1391 	case XML_SCHEMA_TYPE_GROUP:
   1392 	    return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
   1393 	case XML_SCHEMA_TYPE_IDC_KEY:
   1394 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1395 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1396 	    return (((xmlSchemaIDCPtr) item)->targetNamespace);
   1397 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   1398 	    if (WXS_ATTRUSE_DECL(item) != NULL) {
   1399 		return(xmlSchemaGetComponentTargetNs(
   1400 		    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
   1401 	    }
   1402 	    /* TODO: Will returning NULL break something? */
   1403 	    break;
   1404 	case XML_SCHEMA_EXTRA_QNAMEREF:
   1405 	    return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
   1406 	case XML_SCHEMA_TYPE_NOTATION:
   1407 	    return (((xmlSchemaNotationPtr) item)->targetNamespace);
   1408 	default:
   1409 	    /*
   1410 	    * Other components cannot have names.
   1411 	    */
   1412 	    break;
   1413     }
   1414     return (NULL);
   1415 }
   1416 
   1417 static const xmlChar*
   1418 xmlSchemaGetComponentQName(xmlChar **buf,
   1419 			   void *item)
   1420 {
   1421     return (xmlSchemaFormatQName(buf,
   1422 	xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
   1423 	xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
   1424 }
   1425 
   1426 static const xmlChar*
   1427 xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
   1428 {
   1429     xmlChar *str = NULL;
   1430 
   1431     *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
   1432     *buf = xmlStrcat(*buf, BAD_CAST " '");
   1433     *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
   1434 	(xmlSchemaBasicItemPtr) item));
   1435     *buf = xmlStrcat(*buf, BAD_CAST "'");
   1436     FREE_AND_NULL(str);
   1437     return(*buf);
   1438 }
   1439 
   1440 static const xmlChar*
   1441 xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
   1442 {
   1443     return(xmlSchemaGetComponentDesignation(buf, idc));
   1444 }
   1445 
   1446 /**
   1447  * xmlSchemaWildcardPCToString:
   1448  * @pc: the type of processContents
   1449  *
   1450  * Returns a string representation of the type of
   1451  * processContents.
   1452  */
   1453 static const xmlChar *
   1454 xmlSchemaWildcardPCToString(int pc)
   1455 {
   1456     switch (pc) {
   1457 	case XML_SCHEMAS_ANY_SKIP:
   1458 	    return (BAD_CAST "skip");
   1459 	case XML_SCHEMAS_ANY_LAX:
   1460 	    return (BAD_CAST "lax");
   1461 	case XML_SCHEMAS_ANY_STRICT:
   1462 	    return (BAD_CAST "strict");
   1463 	default:
   1464 	    return (BAD_CAST "invalid process contents");
   1465     }
   1466 }
   1467 
   1468 /**
   1469  * xmlSchemaGetCanonValueWhtspExt:
   1470  * @val: the precomputed value
   1471  * @retValue: the returned value
   1472  * @ws: the whitespace type of the value
   1473  *
   1474  * Get a the canonical representation of the value.
   1475  * The caller has to free the returned retValue.
   1476  *
   1477  * Returns 0 if the value could be built and -1 in case of
   1478  *         API errors or if the value type is not supported yet.
   1479  */
   1480 static int
   1481 xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
   1482 			       xmlSchemaWhitespaceValueType ws,
   1483 			       xmlChar **retValue)
   1484 {
   1485     int list;
   1486     xmlSchemaValType valType;
   1487     const xmlChar *value, *value2 = NULL;
   1488 
   1489 
   1490     if ((retValue == NULL) || (val == NULL))
   1491 	return (-1);
   1492     list = xmlSchemaValueGetNext(val) ? 1 : 0;
   1493     *retValue = NULL;
   1494     do {
   1495 	value = NULL;
   1496 	valType = xmlSchemaGetValType(val);
   1497 	switch (valType) {
   1498 	    case XML_SCHEMAS_STRING:
   1499 	    case XML_SCHEMAS_NORMSTRING:
   1500 	    case XML_SCHEMAS_ANYSIMPLETYPE:
   1501 		value = xmlSchemaValueGetAsString(val);
   1502 		if (value != NULL) {
   1503 		    if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
   1504 			value2 = xmlSchemaCollapseString(value);
   1505 		    else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
   1506 			value2 = xmlSchemaWhiteSpaceReplace(value);
   1507 		    if (value2 != NULL)
   1508 			value = value2;
   1509 		}
   1510 		break;
   1511 	    default:
   1512 		if (xmlSchemaGetCanonValue(val, &value2) == -1) {
   1513 		    if (value2 != NULL)
   1514 			xmlFree((xmlChar *) value2);
   1515 		    goto internal_error;
   1516 		}
   1517 		value = value2;
   1518 	}
   1519 	if (*retValue == NULL)
   1520 	    if (value == NULL) {
   1521 		if (! list)
   1522 		    *retValue = xmlStrdup(BAD_CAST "");
   1523 	    } else
   1524 		*retValue = xmlStrdup(value);
   1525 	else if (value != NULL) {
   1526 	    /* List. */
   1527 	    *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
   1528 	    *retValue = xmlStrcat((xmlChar *) *retValue, value);
   1529 	}
   1530 	FREE_AND_NULL(value2)
   1531 	val = xmlSchemaValueGetNext(val);
   1532     } while (val != NULL);
   1533 
   1534     return (0);
   1535 internal_error:
   1536     if (*retValue != NULL)
   1537 	xmlFree((xmlChar *) (*retValue));
   1538     if (value2 != NULL)
   1539 	xmlFree((xmlChar *) value2);
   1540     return (-1);
   1541 }
   1542 
   1543 /**
   1544  * xmlSchemaFormatItemForReport:
   1545  * @buf: the string buffer
   1546  * @itemDes: the designation of the item
   1547  * @itemName: the name of the item
   1548  * @item: the item as an object
   1549  * @itemNode: the node of the item
   1550  * @local: the local name
   1551  * @parsing: if the function is used during the parse
   1552  *
   1553  * Returns a representation of the given item used
   1554  * for error reports.
   1555  *
   1556  * The following order is used to build the resulting
   1557  * designation if the arguments are not NULL:
   1558  * 1a. If itemDes not NULL -> itemDes
   1559  * 1b. If (itemDes not NULL) and (itemName not NULL)
   1560  *     -> itemDes + itemName
   1561  * 2. If the preceding was NULL and (item not NULL) -> item
   1562  * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
   1563  *
   1564  * If the itemNode is an attribute node, the name of the attribute
   1565  * will be appended to the result.
   1566  *
   1567  * Returns the formatted string and sets @buf to the resulting value.
   1568  */
   1569 static xmlChar*
   1570 xmlSchemaFormatItemForReport(xmlChar **buf,
   1571 		     const xmlChar *itemDes,
   1572 		     xmlSchemaBasicItemPtr item,
   1573 		     xmlNodePtr itemNode)
   1574 {
   1575     xmlChar *str = NULL;
   1576     int named = 1;
   1577 
   1578     if (*buf != NULL) {
   1579 	xmlFree(*buf);
   1580 	*buf = NULL;
   1581     }
   1582 
   1583     if (itemDes != NULL) {
   1584 	*buf = xmlStrdup(itemDes);
   1585     } else if (item != NULL) {
   1586 	switch (item->type) {
   1587 	case XML_SCHEMA_TYPE_BASIC: {
   1588 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
   1589 
   1590 	    if (WXS_IS_ATOMIC(type))
   1591 		*buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
   1592 	    else if (WXS_IS_LIST(type))
   1593 		*buf = xmlStrdup(BAD_CAST "list type 'xs:");
   1594 	    else if (WXS_IS_UNION(type))
   1595 		*buf = xmlStrdup(BAD_CAST "union type 'xs:");
   1596 	    else
   1597 		*buf = xmlStrdup(BAD_CAST "simple type 'xs:");
   1598 	    *buf = xmlStrcat(*buf, type->name);
   1599 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1600 	    }
   1601 	    break;
   1602 	case XML_SCHEMA_TYPE_SIMPLE: {
   1603 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
   1604 
   1605 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
   1606 		*buf = xmlStrdup(BAD_CAST"");
   1607 	    } else {
   1608 		*buf = xmlStrdup(BAD_CAST "local ");
   1609 	    }
   1610 	    if (WXS_IS_ATOMIC(type))
   1611 		*buf = xmlStrcat(*buf, BAD_CAST "atomic type");
   1612 	    else if (WXS_IS_LIST(type))
   1613 		*buf = xmlStrcat(*buf, BAD_CAST "list type");
   1614 	    else if (WXS_IS_UNION(type))
   1615 		*buf = xmlStrcat(*buf, BAD_CAST "union type");
   1616 	    else
   1617 		*buf = xmlStrcat(*buf, BAD_CAST "simple type");
   1618 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
   1619 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1620 		*buf = xmlStrcat(*buf, type->name);
   1621 		*buf = xmlStrcat(*buf, BAD_CAST "'");
   1622 	    }
   1623 	    }
   1624 	    break;
   1625 	case XML_SCHEMA_TYPE_COMPLEX: {
   1626 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
   1627 
   1628 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
   1629 		*buf = xmlStrdup(BAD_CAST "");
   1630 	    else
   1631 		*buf = xmlStrdup(BAD_CAST "local ");
   1632 	    *buf = xmlStrcat(*buf, BAD_CAST "complex type");
   1633 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
   1634 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1635 		*buf = xmlStrcat(*buf, type->name);
   1636 		*buf = xmlStrcat(*buf, BAD_CAST "'");
   1637 	    }
   1638 	    }
   1639 	    break;
   1640 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
   1641 		xmlSchemaAttributeUsePtr ause;
   1642 
   1643 		ause = WXS_ATTR_USE_CAST item;
   1644 		*buf = xmlStrdup(BAD_CAST "attribute use ");
   1645 		if (WXS_ATTRUSE_DECL(ause) != NULL) {
   1646 		    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1647 		    *buf = xmlStrcat(*buf,
   1648 			xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
   1649 		    FREE_AND_NULL(str)
   1650 			*buf = xmlStrcat(*buf, BAD_CAST "'");
   1651 		} else {
   1652 		    *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
   1653 		}
   1654 	    }
   1655 	    break;
   1656 	case XML_SCHEMA_TYPE_ATTRIBUTE: {
   1657 		xmlSchemaAttributePtr attr;
   1658 
   1659 		attr = (xmlSchemaAttributePtr) item;
   1660 		*buf = xmlStrdup(BAD_CAST "attribute decl.");
   1661 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1662 		*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
   1663 		    attr->targetNamespace, attr->name));
   1664 		FREE_AND_NULL(str)
   1665 		    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1666 	    }
   1667 	    break;
   1668 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1669 	    xmlSchemaGetComponentDesignation(buf, item);
   1670 	    break;
   1671 	case XML_SCHEMA_TYPE_ELEMENT: {
   1672 		xmlSchemaElementPtr elem;
   1673 
   1674 		elem = (xmlSchemaElementPtr) item;
   1675 		*buf = xmlStrdup(BAD_CAST "element decl.");
   1676 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1677 		*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
   1678 		    elem->targetNamespace, elem->name));
   1679 		*buf = xmlStrcat(*buf, BAD_CAST "'");
   1680 	    }
   1681 	    break;
   1682 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1683 	case XML_SCHEMA_TYPE_IDC_KEY:
   1684 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1685 	    if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
   1686 		*buf = xmlStrdup(BAD_CAST "unique '");
   1687 	    else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
   1688 		*buf = xmlStrdup(BAD_CAST "key '");
   1689 	    else
   1690 		*buf = xmlStrdup(BAD_CAST "keyRef '");
   1691 	    *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
   1692 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1693 	    break;
   1694 	case XML_SCHEMA_TYPE_ANY:
   1695 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   1696 	    *buf = xmlStrdup(xmlSchemaWildcardPCToString(
   1697 		    ((xmlSchemaWildcardPtr) item)->processContents));
   1698 	    *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
   1699 	    break;
   1700 	case XML_SCHEMA_FACET_MININCLUSIVE:
   1701 	case XML_SCHEMA_FACET_MINEXCLUSIVE:
   1702 	case XML_SCHEMA_FACET_MAXINCLUSIVE:
   1703 	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   1704 	case XML_SCHEMA_FACET_TOTALDIGITS:
   1705 	case XML_SCHEMA_FACET_FRACTIONDIGITS:
   1706 	case XML_SCHEMA_FACET_PATTERN:
   1707 	case XML_SCHEMA_FACET_ENUMERATION:
   1708 	case XML_SCHEMA_FACET_WHITESPACE:
   1709 	case XML_SCHEMA_FACET_LENGTH:
   1710 	case XML_SCHEMA_FACET_MAXLENGTH:
   1711 	case XML_SCHEMA_FACET_MINLENGTH:
   1712 	    *buf = xmlStrdup(BAD_CAST "facet '");
   1713 	    *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
   1714 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1715 	    break;
   1716 	case XML_SCHEMA_TYPE_GROUP: {
   1717 		*buf = xmlStrdup(BAD_CAST "model group def.");
   1718 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1719 		*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
   1720 		*buf = xmlStrcat(*buf, BAD_CAST "'");
   1721 		FREE_AND_NULL(str)
   1722 	    }
   1723 	    break;
   1724 	case XML_SCHEMA_TYPE_SEQUENCE:
   1725 	case XML_SCHEMA_TYPE_CHOICE:
   1726 	case XML_SCHEMA_TYPE_ALL:
   1727 	case XML_SCHEMA_TYPE_PARTICLE:
   1728 	    *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
   1729 	    break;
   1730 	case XML_SCHEMA_TYPE_NOTATION: {
   1731 		*buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
   1732 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1733 		*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
   1734 		*buf = xmlStrcat(*buf, BAD_CAST "'");
   1735 		FREE_AND_NULL(str);
   1736 	    }
   1737 	default:
   1738 	    named = 0;
   1739 	}
   1740     } else
   1741 	named = 0;
   1742 
   1743     if ((named == 0) && (itemNode != NULL)) {
   1744 	xmlNodePtr elem;
   1745 
   1746 	if (itemNode->type == XML_ATTRIBUTE_NODE)
   1747 	    elem = itemNode->parent;
   1748 	else
   1749 	    elem = itemNode;
   1750 	*buf = xmlStrdup(BAD_CAST "Element '");
   1751 	if (elem->ns != NULL) {
   1752 	    *buf = xmlStrcat(*buf,
   1753 		xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
   1754 	    FREE_AND_NULL(str)
   1755 	} else
   1756 	    *buf = xmlStrcat(*buf, elem->name);
   1757 	*buf = xmlStrcat(*buf, BAD_CAST "'");
   1758 
   1759     }
   1760     if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
   1761 	*buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
   1762 	if (itemNode->ns != NULL) {
   1763 	    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
   1764 		itemNode->ns->href, itemNode->name));
   1765 	    FREE_AND_NULL(str)
   1766 	} else
   1767 	    *buf = xmlStrcat(*buf, itemNode->name);
   1768 	*buf = xmlStrcat(*buf, BAD_CAST "'");
   1769     }
   1770     FREE_AND_NULL(str)
   1771 
   1772     return (*buf);
   1773 }
   1774 
   1775 /**
   1776  * xmlSchemaFormatFacetEnumSet:
   1777  * @buf: the string buffer
   1778  * @type: the type holding the enumeration facets
   1779  *
   1780  * Builds a string consisting of all enumeration elements.
   1781  *
   1782  * Returns a string of all enumeration elements.
   1783  */
   1784 static const xmlChar *
   1785 xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
   1786 			    xmlChar **buf, xmlSchemaTypePtr type)
   1787 {
   1788     xmlSchemaFacetPtr facet;
   1789     xmlSchemaWhitespaceValueType ws;
   1790     xmlChar *value = NULL;
   1791     int res, found = 0;
   1792 
   1793     if (*buf != NULL)
   1794 	xmlFree(*buf);
   1795     *buf = NULL;
   1796 
   1797     do {
   1798 	/*
   1799 	* Use the whitespace type of the base type.
   1800 	*/
   1801 	ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
   1802 	for (facet = type->facets; facet != NULL; facet = facet->next) {
   1803 	    if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
   1804 		continue;
   1805 	    found = 1;
   1806 	    res = xmlSchemaGetCanonValueWhtspExt(facet->val,
   1807 		ws, &value);
   1808 	    if (res == -1) {
   1809 		xmlSchemaInternalErr(actxt,
   1810 		    "xmlSchemaFormatFacetEnumSet",
   1811 		    "compute the canonical lexical representation");
   1812 		if (*buf != NULL)
   1813 		    xmlFree(*buf);
   1814 		*buf = NULL;
   1815 		return (NULL);
   1816 	    }
   1817 	    if (*buf == NULL)
   1818 		*buf = xmlStrdup(BAD_CAST "'");
   1819 	    else
   1820 		*buf = xmlStrcat(*buf, BAD_CAST ", '");
   1821 	    *buf = xmlStrcat(*buf, BAD_CAST value);
   1822 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1823 	    if (value != NULL) {
   1824 		xmlFree((xmlChar *)value);
   1825 		value = NULL;
   1826 	    }
   1827 	}
   1828 	/*
   1829 	* The enumeration facet of a type restricts the enumeration
   1830 	* facet of the ancestor type; i.e., such restricted enumerations
   1831 	* do not belong to the set of the given type. Thus we break
   1832 	* on the first found enumeration.
   1833 	*/
   1834 	if (found)
   1835 	    break;
   1836 	type = type->baseType;
   1837     } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
   1838 
   1839     return ((const xmlChar *) *buf);
   1840 }
   1841 
   1842 /************************************************************************
   1843  *									*
   1844  *			Error functions				        *
   1845  *									*
   1846  ************************************************************************/
   1847 
   1848 #if 0
   1849 static void
   1850 xmlSchemaErrMemory(const char *msg)
   1851 {
   1852     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
   1853                      msg);
   1854 }
   1855 #endif
   1856 
   1857 static void
   1858 xmlSchemaPSimpleErr(const char *msg)
   1859 {
   1860     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
   1861                      msg);
   1862 }
   1863 
   1864 /**
   1865  * xmlSchemaPErrMemory:
   1866  * @node: a context node
   1867  * @extra:  extra informations
   1868  *
   1869  * Handle an out of memory condition
   1870  */
   1871 static void
   1872 xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
   1873                     const char *extra, xmlNodePtr node)
   1874 {
   1875     if (ctxt != NULL)
   1876         ctxt->nberrors++;
   1877     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
   1878                      extra);
   1879 }
   1880 
   1881 /**
   1882  * xmlSchemaPErr:
   1883  * @ctxt: the parsing context
   1884  * @node: the context node
   1885  * @error: the error code
   1886  * @msg: the error message
   1887  * @str1: extra data
   1888  * @str2: extra data
   1889  *
   1890  * Handle a parser error
   1891  */
   1892 static void
   1893 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
   1894               const char *msg, const xmlChar * str1, const xmlChar * str2)
   1895 {
   1896     xmlGenericErrorFunc channel = NULL;
   1897     xmlStructuredErrorFunc schannel = NULL;
   1898     void *data = NULL;
   1899 
   1900     if (ctxt != NULL) {
   1901         ctxt->nberrors++;
   1902 	ctxt->err = error;
   1903         channel = ctxt->error;
   1904         data = ctxt->errCtxt;
   1905 	schannel = ctxt->serror;
   1906     }
   1907     __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
   1908                     error, XML_ERR_ERROR, NULL, 0,
   1909                     (const char *) str1, (const char *) str2, NULL, 0, 0,
   1910                     msg, str1, str2);
   1911 }
   1912 
   1913 /**
   1914  * xmlSchemaPErr2:
   1915  * @ctxt: the parsing context
   1916  * @node: the context node
   1917  * @node: the current child
   1918  * @error: the error code
   1919  * @msg: the error message
   1920  * @str1: extra data
   1921  * @str2: extra data
   1922  *
   1923  * Handle a parser error
   1924  */
   1925 static void
   1926 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
   1927                xmlNodePtr child, int error,
   1928                const char *msg, const xmlChar * str1, const xmlChar * str2)
   1929 {
   1930     if (child != NULL)
   1931         xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
   1932     else
   1933         xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
   1934 }
   1935 
   1936 
   1937 /**
   1938  * xmlSchemaPErrExt:
   1939  * @ctxt: the parsing context
   1940  * @node: the context node
   1941  * @error: the error code
   1942  * @strData1: extra data
   1943  * @strData2: extra data
   1944  * @strData3: extra data
   1945  * @msg: the message
   1946  * @str1:  extra parameter for the message display
   1947  * @str2:  extra parameter for the message display
   1948  * @str3:  extra parameter for the message display
   1949  * @str4:  extra parameter for the message display
   1950  * @str5:  extra parameter for the message display
   1951  *
   1952  * Handle a parser error
   1953  */
   1954 static void
   1955 xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
   1956 		const xmlChar * strData1, const xmlChar * strData2,
   1957 		const xmlChar * strData3, const char *msg, const xmlChar * str1,
   1958 		const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
   1959 		const xmlChar * str5)
   1960 {
   1961 
   1962     xmlGenericErrorFunc channel = NULL;
   1963     xmlStructuredErrorFunc schannel = NULL;
   1964     void *data = NULL;
   1965 
   1966     if (ctxt != NULL) {
   1967         ctxt->nberrors++;
   1968 	ctxt->err = error;
   1969         channel = ctxt->error;
   1970         data = ctxt->errCtxt;
   1971 	schannel = ctxt->serror;
   1972     }
   1973     __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
   1974                     error, XML_ERR_ERROR, NULL, 0,
   1975                     (const char *) strData1, (const char *) strData2,
   1976 		    (const char *) strData3, 0, 0, msg, str1, str2,
   1977 		    str3, str4, str5);
   1978 }
   1979 
   1980 /************************************************************************
   1981  *									*
   1982  *			Allround error functions			*
   1983  *									*
   1984  ************************************************************************/
   1985 
   1986 /**
   1987  * xmlSchemaVTypeErrMemory:
   1988  * @node: a context node
   1989  * @extra:  extra informations
   1990  *
   1991  * Handle an out of memory condition
   1992  */
   1993 static void
   1994 xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
   1995                     const char *extra, xmlNodePtr node)
   1996 {
   1997     if (ctxt != NULL) {
   1998         ctxt->nberrors++;
   1999         ctxt->err = XML_SCHEMAV_INTERNAL;
   2000     }
   2001     __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
   2002                      extra);
   2003 }
   2004 
   2005 static void
   2006 xmlSchemaPSimpleInternalErr(xmlNodePtr node,
   2007 			    const char *msg, const xmlChar *str)
   2008 {
   2009      __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
   2010 	 msg, (const char *) str);
   2011 }
   2012 
   2013 #define WXS_ERROR_TYPE_ERROR 1
   2014 #define WXS_ERROR_TYPE_WARNING 2
   2015 /**
   2016  * xmlSchemaErr3:
   2017  * @ctxt: the validation context
   2018  * @node: the context node
   2019  * @error: the error code
   2020  * @msg: the error message
   2021  * @str1: extra data
   2022  * @str2: extra data
   2023  * @str3: extra data
   2024  *
   2025  * Handle a validation error
   2026  */
   2027 static void
   2028 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
   2029 		  xmlErrorLevel errorLevel,
   2030 		  int error, xmlNodePtr node, int line, const char *msg,
   2031 		  const xmlChar *str1, const xmlChar *str2,
   2032 		  const xmlChar *str3, const xmlChar *str4)
   2033 {
   2034     xmlStructuredErrorFunc schannel = NULL;
   2035     xmlGenericErrorFunc channel = NULL;
   2036     void *data = NULL;
   2037 
   2038     if (ctxt != NULL) {
   2039 	if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
   2040 	    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
   2041 	    const char *file = NULL;
   2042 	    int col = 0;
   2043 	    if (errorLevel != XML_ERR_WARNING) {
   2044 		vctxt->nberrors++;
   2045 		vctxt->err = error;
   2046 		channel = vctxt->error;
   2047 	    } else {
   2048 		channel = vctxt->warning;
   2049 	    }
   2050 	    schannel = vctxt->serror;
   2051 	    data = vctxt->errCtxt;
   2052 
   2053 	    /*
   2054 	    * Error node. If we specify a line number, then
   2055 	    * do not channel any node to the error function.
   2056 	    */
   2057 	    if (line == 0) {
   2058 		if ((node == NULL) &&
   2059 		    (vctxt->depth >= 0) &&
   2060 		    (vctxt->inode != NULL)) {
   2061 		    node = vctxt->inode->node;
   2062 		}
   2063 		/*
   2064 		* Get filename and line if no node-tree.
   2065 		*/
   2066 		if ((node == NULL) &&
   2067 		    (vctxt->parserCtxt != NULL) &&
   2068 		    (vctxt->parserCtxt->input != NULL)) {
   2069 		    file = vctxt->parserCtxt->input->filename;
   2070 		    line = vctxt->parserCtxt->input->line;
   2071 		    col = vctxt->parserCtxt->input->col;
   2072 		}
   2073 	    } else {
   2074 		/*
   2075 		* Override the given node's (if any) position
   2076 		* and channel only the given line number.
   2077 		*/
   2078 		node = NULL;
   2079 		/*
   2080 		* Get filename.
   2081 		*/
   2082 		if (vctxt->doc != NULL)
   2083 		    file = (const char *) vctxt->doc->URL;
   2084 		else if ((vctxt->parserCtxt != NULL) &&
   2085 		    (vctxt->parserCtxt->input != NULL))
   2086 		    file = vctxt->parserCtxt->input->filename;
   2087 	    }
   2088 	    if (vctxt->locFunc != NULL) {
   2089 	        if ((file == NULL) || (line == 0)) {
   2090 		    unsigned long l;
   2091 		    const char *f;
   2092 		    vctxt->locFunc(vctxt->locCtxt, &f, &l);
   2093 		    if (file == NULL)
   2094 		        file = f;
   2095 		    if (line == 0)
   2096 		        line = (int) l;
   2097 		}
   2098 	    }
   2099 	    if ((file == NULL) && (vctxt->filename != NULL))
   2100 	        file = vctxt->filename;
   2101 
   2102 	    __xmlRaiseError(schannel, channel, data, ctxt,
   2103 		node, XML_FROM_SCHEMASV,
   2104 		error, errorLevel, file, line,
   2105 		(const char *) str1, (const char *) str2,
   2106 		(const char *) str3, 0, col, msg, str1, str2, str3, str4);
   2107 
   2108 	} else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
   2109 	    xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
   2110 	    if (errorLevel != XML_ERR_WARNING) {
   2111 		pctxt->nberrors++;
   2112 		pctxt->err = error;
   2113 		channel = pctxt->error;
   2114 	    } else {
   2115 		channel = pctxt->warning;
   2116 	    }
   2117 	    schannel = pctxt->serror;
   2118 	    data = pctxt->errCtxt;
   2119 	    __xmlRaiseError(schannel, channel, data, ctxt,
   2120 		node, XML_FROM_SCHEMASP, error,
   2121 		errorLevel, NULL, 0,
   2122 		(const char *) str1, (const char *) str2,
   2123 		(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
   2124 	} else {
   2125 	    TODO
   2126 	}
   2127     }
   2128 }
   2129 
   2130 /**
   2131  * xmlSchemaErr3:
   2132  * @ctxt: the validation context
   2133  * @node: the context node
   2134  * @error: the error code
   2135  * @msg: the error message
   2136  * @str1: extra data
   2137  * @str2: extra data
   2138  * @str3: extra data
   2139  *
   2140  * Handle a validation error
   2141  */
   2142 static void
   2143 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
   2144 	      int error, xmlNodePtr node, const char *msg,
   2145 	      const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
   2146 {
   2147     xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
   2148 	msg, str1, str2, str3, NULL);
   2149 }
   2150 
   2151 static void
   2152 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
   2153 	      int error, xmlNodePtr node, const char *msg,
   2154 	      const xmlChar *str1, const xmlChar *str2,
   2155 	      const xmlChar *str3, const xmlChar *str4)
   2156 {
   2157     xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
   2158 	msg, str1, str2, str3, str4);
   2159 }
   2160 
   2161 static void
   2162 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
   2163 	     int error, xmlNodePtr node, const char *msg,
   2164 	     const xmlChar *str1, const xmlChar *str2)
   2165 {
   2166     xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
   2167 }
   2168 
   2169 static xmlChar *
   2170 xmlSchemaFormatNodeForError(xmlChar ** msg,
   2171 			    xmlSchemaAbstractCtxtPtr actxt,
   2172 			    xmlNodePtr node)
   2173 {
   2174     xmlChar *str = NULL;
   2175 
   2176     *msg = NULL;
   2177     if ((node != NULL) &&
   2178 	(node->type != XML_ELEMENT_NODE) &&
   2179 	(node->type != XML_ATTRIBUTE_NODE))
   2180     {
   2181 	/*
   2182 	* Don't try to format other nodes than element and
   2183 	* attribute nodes.
   2184 	* Play save and return an empty string.
   2185 	*/
   2186 	*msg = xmlStrdup(BAD_CAST "");
   2187 	return(*msg);
   2188     }
   2189     if (node != NULL) {
   2190 	/*
   2191 	* Work on tree nodes.
   2192 	*/
   2193 	if (node->type == XML_ATTRIBUTE_NODE) {
   2194 	    xmlNodePtr elem = node->parent;
   2195 
   2196 	    *msg = xmlStrdup(BAD_CAST "Element '");
   2197 	    if (elem->ns != NULL)
   2198 		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2199 		    elem->ns->href, elem->name));
   2200 	    else
   2201 		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2202 		    NULL, elem->name));
   2203 	    FREE_AND_NULL(str);
   2204 	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
   2205 	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
   2206 	} else {
   2207 	    *msg = xmlStrdup(BAD_CAST "Element '");
   2208 	}
   2209 	if (node->ns != NULL)
   2210 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2211 	    node->ns->href, node->name));
   2212 	else
   2213 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2214 	    NULL, node->name));
   2215 	FREE_AND_NULL(str);
   2216 	*msg = xmlStrcat(*msg, BAD_CAST "': ");
   2217     } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
   2218 	xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
   2219 	/*
   2220 	* Work on node infos.
   2221 	*/
   2222 	if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
   2223 	    xmlSchemaNodeInfoPtr ielem =
   2224 		vctxt->elemInfos[vctxt->depth];
   2225 
   2226 	    *msg = xmlStrdup(BAD_CAST "Element '");
   2227 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2228 		ielem->nsName, ielem->localName));
   2229 	    FREE_AND_NULL(str);
   2230 	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
   2231 	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
   2232 	} else {
   2233 	    *msg = xmlStrdup(BAD_CAST "Element '");
   2234 	}
   2235 	*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2236 	    vctxt->inode->nsName, vctxt->inode->localName));
   2237 	FREE_AND_NULL(str);
   2238 	*msg = xmlStrcat(*msg, BAD_CAST "': ");
   2239     } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
   2240 	/*
   2241 	* Hmm, no node while parsing?
   2242 	* Return an empty string, in case NULL will break something.
   2243 	*/
   2244 	*msg = xmlStrdup(BAD_CAST "");
   2245     } else {
   2246 	TODO
   2247 	return (NULL);
   2248     }
   2249     /*
   2250     * VAL TODO: The output of the given schema component is currently
   2251     * disabled.
   2252     */
   2253 #if 0
   2254     if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
   2255 	*msg = xmlStrcat(*msg, BAD_CAST " [");
   2256 	*msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
   2257 	    NULL, type, NULL, 0));
   2258 	FREE_AND_NULL(str)
   2259 	*msg = xmlStrcat(*msg, BAD_CAST "]");
   2260     }
   2261 #endif
   2262     return (*msg);
   2263 }
   2264 
   2265 static void
   2266 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
   2267 		     const char *funcName,
   2268 		     const char *message,
   2269 		     const xmlChar *str1,
   2270 		     const xmlChar *str2)
   2271 {
   2272     xmlChar *msg = NULL;
   2273 
   2274     if (actxt == NULL)
   2275         return;
   2276     msg = xmlStrdup(BAD_CAST "Internal error: ");
   2277     msg = xmlStrcat(msg, BAD_CAST funcName);
   2278     msg = xmlStrcat(msg, BAD_CAST ", ");
   2279     msg = xmlStrcat(msg, BAD_CAST message);
   2280     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2281 
   2282     if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
   2283 	xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL,
   2284 	    (const char *) msg, str1, str2);
   2285 
   2286     else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
   2287 	xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL,
   2288 	    (const char *) msg, str1, str2);
   2289 
   2290     FREE_AND_NULL(msg)
   2291 }
   2292 
   2293 static void
   2294 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
   2295 		     const char *funcName,
   2296 		     const char *message)
   2297 {
   2298     xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
   2299 }
   2300 
   2301 #if 0
   2302 static void
   2303 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
   2304 		     const char *funcName,
   2305 		     const char *message,
   2306 		     const xmlChar *str1,
   2307 		     const xmlChar *str2)
   2308 {
   2309     xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
   2310 	str1, str2);
   2311 }
   2312 #endif
   2313 
   2314 static void
   2315 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
   2316 		   xmlParserErrors error,
   2317 		   xmlNodePtr node,
   2318 		   xmlSchemaBasicItemPtr item,
   2319 		   const char *message,
   2320 		   const xmlChar *str1, const xmlChar *str2,
   2321 		   const xmlChar *str3, const xmlChar *str4)
   2322 {
   2323     xmlChar *msg = NULL;
   2324 
   2325     if ((node == NULL) && (item != NULL) &&
   2326 	(actxt->type == XML_SCHEMA_CTXT_PARSER)) {
   2327 	node = WXS_ITEM_NODE(item);
   2328 	xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
   2329 	msg = xmlStrcat(msg, BAD_CAST ": ");
   2330     } else
   2331 	xmlSchemaFormatNodeForError(&msg, actxt, node);
   2332     msg = xmlStrcat(msg, (const xmlChar *) message);
   2333     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2334     xmlSchemaErr4(actxt, error, node,
   2335 	(const char *) msg, str1, str2, str3, str4);
   2336     FREE_AND_NULL(msg)
   2337 }
   2338 
   2339 static void
   2340 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
   2341 		   xmlParserErrors error,
   2342 		   xmlNodePtr node,
   2343 		   xmlSchemaBasicItemPtr item,
   2344 		   const char *message,
   2345 		   const xmlChar *str1,
   2346 		   const xmlChar *str2)
   2347 {
   2348     xmlSchemaCustomErr4(actxt, error, node, item,
   2349 	message, str1, str2, NULL, NULL);
   2350 }
   2351 
   2352 
   2353 
   2354 static void
   2355 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
   2356 		   xmlParserErrors error,
   2357 		   xmlNodePtr node,
   2358 		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
   2359 		   const char *message,
   2360 		   const xmlChar *str1,
   2361 		   const xmlChar *str2,
   2362 		   const xmlChar *str3)
   2363 {
   2364     xmlChar *msg = NULL;
   2365 
   2366     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2367     msg = xmlStrcat(msg, (const xmlChar *) message);
   2368     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2369 
   2370     /* URGENT TODO: Set the error code to something sane. */
   2371     xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
   2372 	(const char *) msg, str1, str2, str3, NULL);
   2373 
   2374     FREE_AND_NULL(msg)
   2375 }
   2376 
   2377 
   2378 
   2379 static void
   2380 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
   2381 		   xmlParserErrors error,
   2382 		   xmlSchemaPSVIIDCNodePtr idcNode,
   2383 		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
   2384 		   const char *message,
   2385 		   const xmlChar *str1,
   2386 		   const xmlChar *str2)
   2387 {
   2388     xmlChar *msg = NULL, *qname = NULL;
   2389 
   2390     msg = xmlStrdup(BAD_CAST "Element '%s': ");
   2391     msg = xmlStrcat(msg, (const xmlChar *) message);
   2392     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2393     xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
   2394 	error, NULL, idcNode->nodeLine, (const char *) msg,
   2395 	xmlSchemaFormatQName(&qname,
   2396 	    vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
   2397 	    vctxt->nodeQNames->items[idcNode->nodeQNameID]),
   2398 	str1, str2, NULL);
   2399     FREE_AND_NULL(qname);
   2400     FREE_AND_NULL(msg);
   2401 }
   2402 
   2403 static int
   2404 xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
   2405 			   xmlNodePtr node)
   2406 {
   2407     if (node != NULL)
   2408 	return (node->type);
   2409     if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
   2410 	(((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
   2411 	return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
   2412     return (-1);
   2413 }
   2414 
   2415 static int
   2416 xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
   2417 {
   2418     switch (item->type) {
   2419 	case XML_SCHEMA_TYPE_COMPLEX:
   2420 	case XML_SCHEMA_TYPE_SIMPLE:
   2421 	    if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
   2422 		return(1);
   2423 	    break;
   2424 	case XML_SCHEMA_TYPE_GROUP:
   2425 	    return (1);
   2426 	case XML_SCHEMA_TYPE_ELEMENT:
   2427 	    if ( ((xmlSchemaElementPtr) item)->flags &
   2428 		XML_SCHEMAS_ELEM_GLOBAL)
   2429 		return(1);
   2430 	    break;
   2431 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   2432 	    if ( ((xmlSchemaAttributePtr) item)->flags &
   2433 		XML_SCHEMAS_ATTR_GLOBAL)
   2434 		return(1);
   2435 	    break;
   2436 	/* Note that attribute groups are always global. */
   2437 	default:
   2438 	    return(1);
   2439     }
   2440     return (0);
   2441 }
   2442 
   2443 static void
   2444 xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
   2445 		       xmlParserErrors error,
   2446 		       xmlNodePtr node,
   2447 		       const xmlChar *value,
   2448 		       xmlSchemaTypePtr type,
   2449 		       int displayValue)
   2450 {
   2451     xmlChar *msg = NULL;
   2452 
   2453     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2454 
   2455     if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
   2456 	    XML_ATTRIBUTE_NODE))
   2457 	msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
   2458     else
   2459 	msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
   2460 	    "value of ");
   2461 
   2462     if (! xmlSchemaIsGlobalItem(type))
   2463 	msg = xmlStrcat(msg, BAD_CAST "the local ");
   2464     else
   2465 	msg = xmlStrcat(msg, BAD_CAST "the ");
   2466 
   2467     if (WXS_IS_ATOMIC(type))
   2468 	msg = xmlStrcat(msg, BAD_CAST "atomic type");
   2469     else if (WXS_IS_LIST(type))
   2470 	msg = xmlStrcat(msg, BAD_CAST "list type");
   2471     else if (WXS_IS_UNION(type))
   2472 	msg = xmlStrcat(msg, BAD_CAST "union type");
   2473 
   2474     if (xmlSchemaIsGlobalItem(type)) {
   2475 	xmlChar *str = NULL;
   2476 	msg = xmlStrcat(msg, BAD_CAST " '");
   2477 	if (type->builtInType != 0) {
   2478 	    msg = xmlStrcat(msg, BAD_CAST "xs:");
   2479 	    msg = xmlStrcat(msg, type->name);
   2480 	} else
   2481 	    msg = xmlStrcat(msg,
   2482 		xmlSchemaFormatQName(&str,
   2483 		    type->targetNamespace, type->name));
   2484 	msg = xmlStrcat(msg, BAD_CAST "'");
   2485 	FREE_AND_NULL(str);
   2486     }
   2487     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2488     if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
   2489 	    XML_ATTRIBUTE_NODE))
   2490 	xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
   2491     else
   2492 	xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
   2493     FREE_AND_NULL(msg)
   2494 }
   2495 
   2496 static const xmlChar *
   2497 xmlSchemaFormatErrorNodeQName(xmlChar ** str,
   2498 			      xmlSchemaNodeInfoPtr ni,
   2499 			      xmlNodePtr node)
   2500 {
   2501     if (node != NULL) {
   2502 	if (node->ns != NULL)
   2503 	    return (xmlSchemaFormatQName(str, node->ns->href, node->name));
   2504 	else
   2505 	    return (xmlSchemaFormatQName(str, NULL, node->name));
   2506     } else if (ni != NULL)
   2507 	return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
   2508     return (NULL);
   2509 }
   2510 
   2511 static void
   2512 xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
   2513 			xmlParserErrors error,
   2514 			xmlSchemaAttrInfoPtr ni,
   2515 			xmlNodePtr node)
   2516 {
   2517     xmlChar *msg = NULL, *str = NULL;
   2518 
   2519     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2520     msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
   2521     xmlSchemaErr(actxt, error, node, (const char *) msg,
   2522 	xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
   2523 	NULL);
   2524     FREE_AND_NULL(str)
   2525     FREE_AND_NULL(msg)
   2526 }
   2527 
   2528 static void
   2529 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
   2530 		        xmlParserErrors error,
   2531 		        xmlNodePtr node,
   2532 			xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
   2533 			const char *message,
   2534 			int nbval,
   2535 			int nbneg,
   2536 			xmlChar **values)
   2537 {
   2538     xmlChar *str = NULL, *msg = NULL;
   2539     xmlChar *localName, *nsName;
   2540     const xmlChar *cur, *end;
   2541     int i;
   2542 
   2543     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2544     msg = xmlStrcat(msg, (const xmlChar *) message);
   2545     msg = xmlStrcat(msg, BAD_CAST ".");
   2546     /*
   2547     * Note that is does not make sense to report that we have a
   2548     * wildcard here, since the wildcard might be unfolded into
   2549     * multiple transitions.
   2550     */
   2551     if (nbval + nbneg > 0) {
   2552 	if (nbval + nbneg > 1) {
   2553 	    str = xmlStrdup(BAD_CAST " Expected is one of ( ");
   2554 	} else
   2555 	    str = xmlStrdup(BAD_CAST " Expected is ( ");
   2556 	nsName = NULL;
   2557 
   2558 	for (i = 0; i < nbval + nbneg; i++) {
   2559 	    cur = values[i];
   2560 	    if (cur == NULL)
   2561 	        continue;
   2562 	    if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
   2563 	        (cur[3] == ' ')) {
   2564 		cur += 4;
   2565 		str = xmlStrcat(str, BAD_CAST "##other");
   2566 	    }
   2567 	    /*
   2568 	    * Get the local name.
   2569 	    */
   2570 	    localName = NULL;
   2571 
   2572 	    end = cur;
   2573 	    if (*end == '*') {
   2574 		localName = xmlStrdup(BAD_CAST "*");
   2575 		end++;
   2576 	    } else {
   2577 		while ((*end != 0) && (*end != '|'))
   2578 		    end++;
   2579 		localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
   2580 	    }
   2581 	    if (*end != 0) {
   2582 		end++;
   2583 		/*
   2584 		* Skip "*|*" if they come with negated expressions, since
   2585 		* they represent the same negated wildcard.
   2586 		*/
   2587 		if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
   2588 		    /*
   2589 		    * Get the namespace name.
   2590 		    */
   2591 		    cur = end;
   2592 		    if (*end == '*') {
   2593 			nsName = xmlStrdup(BAD_CAST "{*}");
   2594 		    } else {
   2595 			while (*end != 0)
   2596 			    end++;
   2597 
   2598 			if (i >= nbval)
   2599 			    nsName = xmlStrdup(BAD_CAST "{##other:");
   2600 			else
   2601 			    nsName = xmlStrdup(BAD_CAST "{");
   2602 
   2603 			nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
   2604 			nsName = xmlStrcat(nsName, BAD_CAST "}");
   2605 		    }
   2606 		    str = xmlStrcat(str, BAD_CAST nsName);
   2607 		    FREE_AND_NULL(nsName)
   2608 		} else {
   2609 		    FREE_AND_NULL(localName);
   2610 		    continue;
   2611 		}
   2612 	    }
   2613 	    str = xmlStrcat(str, BAD_CAST localName);
   2614 	    FREE_AND_NULL(localName);
   2615 
   2616 	    if (i < nbval + nbneg -1)
   2617 		str = xmlStrcat(str, BAD_CAST ", ");
   2618 	}
   2619 	str = xmlStrcat(str, BAD_CAST " ).\n");
   2620 	msg = xmlStrcat(msg, BAD_CAST str);
   2621 	FREE_AND_NULL(str)
   2622     } else
   2623       msg = xmlStrcat(msg, BAD_CAST "\n");
   2624     xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
   2625     xmlFree(msg);
   2626 }
   2627 
   2628 static void
   2629 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
   2630 		  xmlParserErrors error,
   2631 		  xmlNodePtr node,
   2632 		  const xmlChar *value,
   2633 		  unsigned long length,
   2634 		  xmlSchemaTypePtr type,
   2635 		  xmlSchemaFacetPtr facet,
   2636 		  const char *message,
   2637 		  const xmlChar *str1,
   2638 		  const xmlChar *str2)
   2639 {
   2640     xmlChar *str = NULL, *msg = NULL;
   2641     xmlSchemaTypeType facetType;
   2642     int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
   2643 
   2644     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2645     if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
   2646 	facetType = XML_SCHEMA_FACET_ENUMERATION;
   2647 	/*
   2648 	* If enumerations are validated, one must not expect the
   2649 	* facet to be given.
   2650 	*/
   2651     } else
   2652 	facetType = facet->type;
   2653     msg = xmlStrcat(msg, BAD_CAST "[");
   2654     msg = xmlStrcat(msg, BAD_CAST "facet '");
   2655     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
   2656     msg = xmlStrcat(msg, BAD_CAST "'] ");
   2657     if (message == NULL) {
   2658 	/*
   2659 	* Use a default message.
   2660 	*/
   2661 	if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
   2662 	    (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
   2663 	    (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
   2664 
   2665 	    char len[25], actLen[25];
   2666 
   2667 	    /* FIXME, TODO: What is the max expected string length of the
   2668 	    * this value?
   2669 	    */
   2670 	    if (nodeType == XML_ATTRIBUTE_NODE)
   2671 		msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
   2672 	    else
   2673 		msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
   2674 
   2675 	    snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
   2676 	    snprintf(actLen, 24, "%lu", length);
   2677 
   2678 	    if (facetType == XML_SCHEMA_FACET_LENGTH)
   2679 		msg = xmlStrcat(msg,
   2680 		BAD_CAST "this differs from the allowed length of '%s'.\n");
   2681 	    else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
   2682 		msg = xmlStrcat(msg,
   2683 		BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
   2684 	    else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
   2685 		msg = xmlStrcat(msg,
   2686 		BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
   2687 
   2688 	    if (nodeType == XML_ATTRIBUTE_NODE)
   2689 		xmlSchemaErr3(actxt, error, node, (const char *) msg,
   2690 		    value, (const xmlChar *) actLen, (const xmlChar *) len);
   2691 	    else
   2692 		xmlSchemaErr(actxt, error, node, (const char *) msg,
   2693 		    (const xmlChar *) actLen, (const xmlChar *) len);
   2694 
   2695 	} else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
   2696 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
   2697 		"of the set {%s}.\n");
   2698 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2699 		xmlSchemaFormatFacetEnumSet(actxt, &str, type));
   2700 	} else if (facetType == XML_SCHEMA_FACET_PATTERN) {
   2701 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
   2702 		"by the pattern '%s'.\n");
   2703 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2704 		facet->value);
   2705 	} else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
   2706 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
   2707 		"minimum value allowed ('%s').\n");
   2708 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2709 		facet->value);
   2710 	} else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
   2711 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
   2712 		"maximum value allowed ('%s').\n");
   2713 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2714 		facet->value);
   2715 	} else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
   2716 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
   2717 		"'%s'.\n");
   2718 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2719 		facet->value);
   2720 	} else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
   2721 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
   2722 		"'%s'.\n");
   2723 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2724 		facet->value);
   2725 	} else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
   2726 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
   2727 		"digits than are allowed ('%s').\n");
   2728 	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
   2729 		facet->value);
   2730 	} else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
   2731 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
   2732 		"digits than are allowed ('%s').\n");
   2733 	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
   2734 		facet->value);
   2735 	} else if (nodeType == XML_ATTRIBUTE_NODE) {
   2736 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
   2737 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
   2738 	} else {
   2739 	    msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
   2740 	    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
   2741 	}
   2742     } else {
   2743 	msg = xmlStrcat(msg, (const xmlChar *) message);
   2744 	msg = xmlStrcat(msg, BAD_CAST ".\n");
   2745 	xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
   2746     }
   2747     FREE_AND_NULL(str)
   2748     xmlFree(msg);
   2749 }
   2750 
   2751 #define VERROR(err, type, msg) \
   2752     xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
   2753 
   2754 #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
   2755 
   2756 #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
   2757 #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
   2758 
   2759 #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
   2760 
   2761 
   2762 /**
   2763  * xmlSchemaPMissingAttrErr:
   2764  * @ctxt: the schema validation context
   2765  * @ownerDes: the designation of  the owner
   2766  * @ownerName: the name of the owner
   2767  * @ownerItem: the owner as a schema object
   2768  * @ownerElem: the owner as an element node
   2769  * @node: the parent element node of the missing attribute node
   2770  * @type: the corresponding type of the attribute node
   2771  *
   2772  * Reports an illegal attribute.
   2773  */
   2774 static void
   2775 xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
   2776 			 xmlParserErrors error,
   2777 			 xmlSchemaBasicItemPtr ownerItem,
   2778 			 xmlNodePtr ownerElem,
   2779 			 const char *name,
   2780 			 const char *message)
   2781 {
   2782     xmlChar *des = NULL;
   2783 
   2784     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
   2785 
   2786     if (message != NULL)
   2787 	xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
   2788     else
   2789 	xmlSchemaPErr(ctxt, ownerElem, error,
   2790 	    "%s: The attribute '%s' is required but missing.\n",
   2791 	    BAD_CAST des, BAD_CAST name);
   2792     FREE_AND_NULL(des);
   2793 }
   2794 
   2795 
   2796 /**
   2797  * xmlSchemaPResCompAttrErr:
   2798  * @ctxt: the schema validation context
   2799  * @error: the error code
   2800  * @ownerDes: the designation of  the owner
   2801  * @ownerItem: the owner as a schema object
   2802  * @ownerElem: the owner as an element node
   2803  * @name: the name of the attribute holding the QName
   2804  * @refName: the referenced local name
   2805  * @refURI: the referenced namespace URI
   2806  * @message: optional message
   2807  *
   2808  * Used to report QName attribute values that failed to resolve
   2809  * to schema components.
   2810  */
   2811 static void
   2812 xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
   2813 			 xmlParserErrors error,
   2814 			 xmlSchemaBasicItemPtr ownerItem,
   2815 			 xmlNodePtr ownerElem,
   2816 			 const char *name,
   2817 			 const xmlChar *refName,
   2818 			 const xmlChar *refURI,
   2819 			 xmlSchemaTypeType refType,
   2820 			 const char *refTypeStr)
   2821 {
   2822     xmlChar *des = NULL, *strA = NULL;
   2823 
   2824     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
   2825     if (refTypeStr == NULL)
   2826 	refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
   2827 	xmlSchemaPErrExt(ctxt, ownerElem, error,
   2828 	    NULL, NULL, NULL,
   2829 	    "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
   2830 	    "%s.\n", BAD_CAST des, BAD_CAST name,
   2831 	    xmlSchemaFormatQName(&strA, refURI, refName),
   2832 	    BAD_CAST refTypeStr, NULL);
   2833     FREE_AND_NULL(des)
   2834     FREE_AND_NULL(strA)
   2835 }
   2836 
   2837 /**
   2838  * xmlSchemaPCustomAttrErr:
   2839  * @ctxt: the schema parser context
   2840  * @error: the error code
   2841  * @ownerDes: the designation of the owner
   2842  * @ownerItem: the owner as a schema object
   2843  * @attr: the illegal attribute node
   2844  *
   2845  * Reports an illegal attribute during the parse.
   2846  */
   2847 static void
   2848 xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
   2849 			xmlParserErrors error,
   2850 			xmlChar **ownerDes,
   2851 			xmlSchemaBasicItemPtr ownerItem,
   2852 			xmlAttrPtr attr,
   2853 			const char *msg)
   2854 {
   2855     xmlChar *des = NULL;
   2856 
   2857     if (ownerDes == NULL)
   2858 	xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
   2859     else if (*ownerDes == NULL) {
   2860 	xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
   2861 	des = *ownerDes;
   2862     } else
   2863 	des = *ownerDes;
   2864     if (attr == NULL) {
   2865 	xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
   2866 	    "%s, attribute '%s': %s.\n",
   2867 	    BAD_CAST des, (const xmlChar *) "Unknown",
   2868 	    (const xmlChar *) msg, NULL, NULL);
   2869     } else {
   2870 	xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
   2871 	    "%s, attribute '%s': %s.\n",
   2872 	    BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
   2873     }
   2874     if (ownerDes == NULL)
   2875 	FREE_AND_NULL(des);
   2876 }
   2877 
   2878 /**
   2879  * xmlSchemaPIllegalAttrErr:
   2880  * @ctxt: the schema parser context
   2881  * @error: the error code
   2882  * @ownerDes: the designation of the attribute's owner
   2883  * @ownerItem: the attribute's owner item
   2884  * @attr: the illegal attribute node
   2885  *
   2886  * Reports an illegal attribute during the parse.
   2887  */
   2888 static void
   2889 xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
   2890 			 xmlParserErrors error,
   2891 			 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
   2892 			 xmlAttrPtr attr)
   2893 {
   2894     xmlChar *strA = NULL, *strB = NULL;
   2895 
   2896     xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
   2897     xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
   2898 	"%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
   2899 	xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
   2900 	NULL, NULL);
   2901     FREE_AND_NULL(strA);
   2902     FREE_AND_NULL(strB);
   2903 }
   2904 
   2905 /**
   2906  * xmlSchemaPCustomErr:
   2907  * @ctxt: the schema parser context
   2908  * @error: the error code
   2909  * @itemDes: the designation of the schema item
   2910  * @item: the schema item
   2911  * @itemElem: the node of the schema item
   2912  * @message: the error message
   2913  * @str1: an optional param for the error message
   2914  * @str2: an optional param for the error message
   2915  * @str3: an optional param for the error message
   2916  *
   2917  * Reports an error during parsing.
   2918  */
   2919 static void
   2920 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
   2921 		    xmlParserErrors error,
   2922 		    xmlSchemaBasicItemPtr item,
   2923 		    xmlNodePtr itemElem,
   2924 		    const char *message,
   2925 		    const xmlChar *str1,
   2926 		    const xmlChar *str2,
   2927 		    const xmlChar *str3)
   2928 {
   2929     xmlChar *des = NULL, *msg = NULL;
   2930 
   2931     xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
   2932     msg = xmlStrdup(BAD_CAST "%s: ");
   2933     msg = xmlStrcat(msg, (const xmlChar *) message);
   2934     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2935     if ((itemElem == NULL) && (item != NULL))
   2936 	itemElem = WXS_ITEM_NODE(item);
   2937     xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
   2938 	(const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
   2939     FREE_AND_NULL(des);
   2940     FREE_AND_NULL(msg);
   2941 }
   2942 
   2943 /**
   2944  * xmlSchemaPCustomErr:
   2945  * @ctxt: the schema parser context
   2946  * @error: the error code
   2947  * @itemDes: the designation of the schema item
   2948  * @item: the schema item
   2949  * @itemElem: the node of the schema item
   2950  * @message: the error message
   2951  * @str1: the optional param for the error message
   2952  *
   2953  * Reports an error during parsing.
   2954  */
   2955 static void
   2956 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
   2957 		    xmlParserErrors error,
   2958 		    xmlSchemaBasicItemPtr item,
   2959 		    xmlNodePtr itemElem,
   2960 		    const char *message,
   2961 		    const xmlChar *str1)
   2962 {
   2963     xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
   2964 	str1, NULL, NULL);
   2965 }
   2966 
   2967 /**
   2968  * xmlSchemaPAttrUseErr:
   2969  * @ctxt: the schema parser context
   2970  * @error: the error code
   2971  * @itemDes: the designation of the schema type
   2972  * @item: the schema type
   2973  * @itemElem: the node of the schema type
   2974  * @attr: the invalid schema attribute
   2975  * @message: the error message
   2976  * @str1: the optional param for the error message
   2977  *
   2978  * Reports an attribute use error during parsing.
   2979  */
   2980 static void
   2981 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
   2982 		    xmlParserErrors error,
   2983 		    xmlNodePtr node,
   2984 		    xmlSchemaBasicItemPtr ownerItem,
   2985 		    const xmlSchemaAttributeUsePtr attruse,
   2986 		    const char *message,
   2987 		    const xmlChar *str1, const xmlChar *str2,
   2988 		    const xmlChar *str3,const xmlChar *str4)
   2989 {
   2990     xmlChar *str = NULL, *msg = NULL;
   2991 
   2992     xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
   2993     msg = xmlStrcat(msg, BAD_CAST ", ");
   2994     msg = xmlStrcat(msg,
   2995 	BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
   2996 	WXS_BASIC_CAST attruse, NULL));
   2997     FREE_AND_NULL(str);
   2998     msg = xmlStrcat(msg, BAD_CAST ": ");
   2999     msg = xmlStrcat(msg, (const xmlChar *) message);
   3000     msg = xmlStrcat(msg, BAD_CAST ".\n");
   3001     xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
   3002 	(const char *) msg, str1, str2, str3, str4);
   3003     xmlFree(msg);
   3004 }
   3005 
   3006 /**
   3007  * xmlSchemaPIllegalFacetAtomicErr:
   3008  * @ctxt: the schema parser context
   3009  * @error: the error code
   3010  * @type: the schema type
   3011  * @baseType: the base type of type
   3012  * @facet: the illegal facet
   3013  *
   3014  * Reports an illegal facet for atomic simple types.
   3015  */
   3016 static void
   3017 xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
   3018 			  xmlParserErrors error,
   3019 			  xmlSchemaTypePtr type,
   3020 			  xmlSchemaTypePtr baseType,
   3021 			  xmlSchemaFacetPtr facet)
   3022 {
   3023     xmlChar *des = NULL, *strT = NULL;
   3024 
   3025     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
   3026     xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
   3027 	"%s: The facet '%s' is not allowed on types derived from the "
   3028 	"type %s.\n",
   3029 	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
   3030 	xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
   3031 	NULL, NULL);
   3032     FREE_AND_NULL(des);
   3033     FREE_AND_NULL(strT);
   3034 }
   3035 
   3036 /**
   3037  * xmlSchemaPIllegalFacetListUnionErr:
   3038  * @ctxt: the schema parser context
   3039  * @error: the error code
   3040  * @itemDes: the designation of the schema item involved
   3041  * @item: the schema item involved
   3042  * @facet: the illegal facet
   3043  *
   3044  * Reports an illegal facet for <list> and <union>.
   3045  */
   3046 static void
   3047 xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
   3048 			  xmlParserErrors error,
   3049 			  xmlSchemaTypePtr type,
   3050 			  xmlSchemaFacetPtr facet)
   3051 {
   3052     xmlChar *des = NULL;
   3053 
   3054     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
   3055 	type->node);
   3056     xmlSchemaPErr(ctxt, type->node, error,
   3057 	"%s: The facet '%s' is not allowed.\n",
   3058 	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
   3059     FREE_AND_NULL(des);
   3060 }
   3061 
   3062 /**
   3063  * xmlSchemaPMutualExclAttrErr:
   3064  * @ctxt: the schema validation context
   3065  * @error: the error code
   3066  * @elemDes: the designation of the parent element node
   3067  * @attr: the bad attribute node
   3068  * @type: the corresponding type of the attribute node
   3069  *
   3070  * Reports an illegal attribute.
   3071  */
   3072 static void
   3073 xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
   3074 			 xmlParserErrors error,
   3075 			 xmlSchemaBasicItemPtr ownerItem,
   3076 			 xmlAttrPtr attr,
   3077 			 const char *name1,
   3078 			 const char *name2)
   3079 {
   3080     xmlChar *des = NULL;
   3081 
   3082     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
   3083     xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
   3084 	"%s: The attributes '%s' and '%s' are mutually exclusive.\n",
   3085 	BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
   3086     FREE_AND_NULL(des);
   3087 }
   3088 
   3089 /**
   3090  * xmlSchemaPSimpleTypeErr:
   3091  * @ctxt:  the schema validation context
   3092  * @error: the error code
   3093  * @type: the type specifier
   3094  * @ownerDes: the designation of the owner
   3095  * @ownerItem: the schema object if existent
   3096  * @node: the validated node
   3097  * @value: the validated value
   3098  *
   3099  * Reports a simple type validation error.
   3100  * TODO: Should this report the value of an element as well?
   3101  */
   3102 static void
   3103 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
   3104 			xmlParserErrors error,
   3105 			xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
   3106 			xmlNodePtr node,
   3107 			xmlSchemaTypePtr type,
   3108 			const char *expected,
   3109 			const xmlChar *value,
   3110 			const char *message,
   3111 			const xmlChar *str1,
   3112 			const xmlChar *str2)
   3113 {
   3114     xmlChar *msg = NULL;
   3115 
   3116     xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
   3117     if (message == NULL) {
   3118 	/*
   3119 	* Use default messages.
   3120 	*/
   3121 	if (type != NULL) {
   3122 	    if (node->type == XML_ATTRIBUTE_NODE)
   3123 		msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
   3124 	    else
   3125 		msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
   3126 		"valid value of ");
   3127 	    if (! xmlSchemaIsGlobalItem(type))
   3128 		msg = xmlStrcat(msg, BAD_CAST "the local ");
   3129 	    else
   3130 		msg = xmlStrcat(msg, BAD_CAST "the ");
   3131 
   3132 	    if (WXS_IS_ATOMIC(type))
   3133 		msg = xmlStrcat(msg, BAD_CAST "atomic type");
   3134 	    else if (WXS_IS_LIST(type))
   3135 		msg = xmlStrcat(msg, BAD_CAST "list type");
   3136 	    else if (WXS_IS_UNION(type))
   3137 		msg = xmlStrcat(msg, BAD_CAST "union type");
   3138 
   3139 	    if (xmlSchemaIsGlobalItem(type)) {
   3140 		xmlChar *str = NULL;
   3141 		msg = xmlStrcat(msg, BAD_CAST " '");
   3142 		if (type->builtInType != 0) {
   3143 		    msg = xmlStrcat(msg, BAD_CAST "xs:");
   3144 		    msg = xmlStrcat(msg, type->name);
   3145 		} else
   3146 		    msg = xmlStrcat(msg,
   3147 			xmlSchemaFormatQName(&str,
   3148 			    type->targetNamespace, type->name));
   3149 		msg = xmlStrcat(msg, BAD_CAST "'.");
   3150 		FREE_AND_NULL(str);
   3151 	    }
   3152 	} else {
   3153 	    if (node->type == XML_ATTRIBUTE_NODE)
   3154 		msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
   3155 	    else
   3156 		msg = xmlStrcat(msg, BAD_CAST "The character content is not "
   3157 		"valid.");
   3158 	}
   3159 	if (expected) {
   3160 	    msg = xmlStrcat(msg, BAD_CAST " Expected is '");
   3161 	    msg = xmlStrcat(msg, BAD_CAST expected);
   3162 	    msg = xmlStrcat(msg, BAD_CAST "'.\n");
   3163 	} else
   3164 	    msg = xmlStrcat(msg, BAD_CAST "\n");
   3165 	if (node->type == XML_ATTRIBUTE_NODE)
   3166 	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
   3167 	else
   3168 	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
   3169     } else {
   3170 	msg = xmlStrcat(msg, BAD_CAST message);
   3171 	msg = xmlStrcat(msg, BAD_CAST ".\n");
   3172 	xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
   3173 	     (const char*) msg, str1, str2, NULL, NULL, NULL);
   3174     }
   3175     /* Cleanup. */
   3176     FREE_AND_NULL(msg)
   3177 }
   3178 
   3179 /**
   3180  * xmlSchemaPContentErr:
   3181  * @ctxt: the schema parser context
   3182  * @error: the error code
   3183  * @onwerDes: the designation of the holder of the content
   3184  * @ownerItem: the owner item of the holder of the content
   3185  * @ownerElem: the node of the holder of the content
   3186  * @child: the invalid child node
   3187  * @message: the optional error message
   3188  * @content: the optional string describing the correct content
   3189  *
   3190  * Reports an error concerning the content of a schema element.
   3191  */
   3192 static void
   3193 xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
   3194 		     xmlParserErrors error,
   3195 		     xmlSchemaBasicItemPtr ownerItem,
   3196 		     xmlNodePtr ownerElem,
   3197 		     xmlNodePtr child,
   3198 		     const char *message,
   3199 		     const char *content)
   3200 {
   3201     xmlChar *des = NULL;
   3202 
   3203     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
   3204     if (message != NULL)
   3205 	xmlSchemaPErr2(ctxt, ownerElem, child, error,
   3206 	    "%s: %s.\n",
   3207 	    BAD_CAST des, BAD_CAST message);
   3208     else {
   3209 	if (content != NULL) {
   3210 	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
   3211 		"%s: The content is not valid. Expected is %s.\n",
   3212 		BAD_CAST des, BAD_CAST content);
   3213 	} else {
   3214 	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
   3215 		"%s: The content is not valid.\n",
   3216 		BAD_CAST des, NULL);
   3217 	}
   3218     }
   3219     FREE_AND_NULL(des)
   3220 }
   3221 
   3222 /************************************************************************
   3223  *									*
   3224  *			Streamable error functions                      *
   3225  *									*
   3226  ************************************************************************/
   3227 
   3228 
   3229 
   3230 
   3231 /************************************************************************
   3232  *									*
   3233  *			Validation helper functions			*
   3234  *									*
   3235  ************************************************************************/
   3236 
   3237 
   3238 /************************************************************************
   3239  *									*
   3240  *			Allocation functions				*
   3241  *									*
   3242  ************************************************************************/
   3243 
   3244 /**
   3245  * xmlSchemaNewSchemaForParserCtxt:
   3246  * @ctxt:  a schema validation context
   3247  *
   3248  * Allocate a new Schema structure.
   3249  *
   3250  * Returns the newly allocated structure or NULL in case or error
   3251  */
   3252 static xmlSchemaPtr
   3253 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
   3254 {
   3255     xmlSchemaPtr ret;
   3256 
   3257     ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
   3258     if (ret == NULL) {
   3259         xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
   3260         return (NULL);
   3261     }
   3262     memset(ret, 0, sizeof(xmlSchema));
   3263     ret->dict = ctxt->dict;
   3264     xmlDictReference(ret->dict);
   3265 
   3266     return (ret);
   3267 }
   3268 
   3269 /**
   3270  * xmlSchemaNewFacet:
   3271  *
   3272  * Allocate a new Facet structure.
   3273  *
   3274  * Returns the newly allocated structure or NULL in case or error
   3275  */
   3276 xmlSchemaFacetPtr
   3277 xmlSchemaNewFacet(void)
   3278 {
   3279     xmlSchemaFacetPtr ret;
   3280 
   3281     ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
   3282     if (ret == NULL) {
   3283         return (NULL);
   3284     }
   3285     memset(ret, 0, sizeof(xmlSchemaFacet));
   3286 
   3287     return (ret);
   3288 }
   3289 
   3290 /**
   3291  * xmlSchemaNewAnnot:
   3292  * @ctxt:  a schema validation context
   3293  * @node:  a node
   3294  *
   3295  * Allocate a new annotation structure.
   3296  *
   3297  * Returns the newly allocated structure or NULL in case or error
   3298  */
   3299 static xmlSchemaAnnotPtr
   3300 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
   3301 {
   3302     xmlSchemaAnnotPtr ret;
   3303 
   3304     ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
   3305     if (ret == NULL) {
   3306         xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
   3307         return (NULL);
   3308     }
   3309     memset(ret, 0, sizeof(xmlSchemaAnnot));
   3310     ret->content = node;
   3311     return (ret);
   3312 }
   3313 
   3314 static xmlSchemaItemListPtr
   3315 xmlSchemaItemListCreate(void)
   3316 {
   3317     xmlSchemaItemListPtr ret;
   3318 
   3319     ret = xmlMalloc(sizeof(xmlSchemaItemList));
   3320     if (ret == NULL) {
   3321 	xmlSchemaPErrMemory(NULL,
   3322 	    "allocating an item list structure", NULL);
   3323 	return (NULL);
   3324     }
   3325     memset(ret, 0, sizeof(xmlSchemaItemList));
   3326     return (ret);
   3327 }
   3328 
   3329 static void
   3330 xmlSchemaItemListClear(xmlSchemaItemListPtr list)
   3331 {
   3332     if (list->items != NULL) {
   3333 	xmlFree(list->items);
   3334 	list->items = NULL;
   3335     }
   3336     list->nbItems = 0;
   3337     list->sizeItems = 0;
   3338 }
   3339 
   3340 static int
   3341 xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
   3342 {
   3343     if (list->items == NULL) {
   3344 	list->items = (void **) xmlMalloc(
   3345 	    20 * sizeof(void *));
   3346 	if (list->items == NULL) {
   3347 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
   3348 	    return(-1);
   3349 	}
   3350 	list->sizeItems = 20;
   3351     } else if (list->sizeItems <= list->nbItems) {
   3352 	list->sizeItems *= 2;
   3353 	list->items = (void **) xmlRealloc(list->items,
   3354 	    list->sizeItems * sizeof(void *));
   3355 	if (list->items == NULL) {
   3356 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
   3357 	    list->sizeItems = 0;
   3358 	    return(-1);
   3359 	}
   3360     }
   3361     list->items[list->nbItems++] = item;
   3362     return(0);
   3363 }
   3364 
   3365 static int
   3366 xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
   3367 			 int initialSize,
   3368 			 void *item)
   3369 {
   3370     if (list->items == NULL) {
   3371 	if (initialSize <= 0)
   3372 	    initialSize = 1;
   3373 	list->items = (void **) xmlMalloc(
   3374 	    initialSize * sizeof(void *));
   3375 	if (list->items == NULL) {
   3376 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
   3377 	    return(-1);
   3378 	}
   3379 	list->sizeItems = initialSize;
   3380     } else if (list->sizeItems <= list->nbItems) {
   3381 	list->sizeItems *= 2;
   3382 	list->items = (void **) xmlRealloc(list->items,
   3383 	    list->sizeItems * sizeof(void *));
   3384 	if (list->items == NULL) {
   3385 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
   3386 	    list->sizeItems = 0;
   3387 	    return(-1);
   3388 	}
   3389     }
   3390     list->items[list->nbItems++] = item;
   3391     return(0);
   3392 }
   3393 
   3394 static int
   3395 xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
   3396 {
   3397     if (list->items == NULL) {
   3398 	list->items = (void **) xmlMalloc(
   3399 	    20 * sizeof(void *));
   3400 	if (list->items == NULL) {
   3401 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
   3402 	    return(-1);
   3403 	}
   3404 	list->sizeItems = 20;
   3405     } else if (list->sizeItems <= list->nbItems) {
   3406 	list->sizeItems *= 2;
   3407 	list->items = (void **) xmlRealloc(list->items,
   3408 	    list->sizeItems * sizeof(void *));
   3409 	if (list->items == NULL) {
   3410 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
   3411 	    list->sizeItems = 0;
   3412 	    return(-1);
   3413 	}
   3414     }
   3415     /*
   3416     * Just append if the index is greater/equal than the item count.
   3417     */
   3418     if (idx >= list->nbItems) {
   3419 	list->items[list->nbItems++] = item;
   3420     } else {
   3421 	int i;
   3422 	for (i = list->nbItems; i > idx; i--)
   3423 	    list->items[i] = list->items[i-1];
   3424 	list->items[idx] = item;
   3425 	list->nbItems++;
   3426     }
   3427     return(0);
   3428 }
   3429 
   3430 #if 0 /* enable if ever needed */
   3431 static int
   3432 xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
   3433 			    int initialSize,
   3434 			    void *item,
   3435 			    int idx)
   3436 {
   3437     if (list->items == NULL) {
   3438 	if (initialSize <= 0)
   3439 	    initialSize = 1;
   3440 	list->items = (void **) xmlMalloc(
   3441 	    initialSize * sizeof(void *));
   3442 	if (list->items == NULL) {
   3443 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
   3444 	    return(-1);
   3445 	}
   3446 	list->sizeItems = initialSize;
   3447     } else if (list->sizeItems <= list->nbItems) {
   3448 	list->sizeItems *= 2;
   3449 	list->items = (void **) xmlRealloc(list->items,
   3450 	    list->sizeItems * sizeof(void *));
   3451 	if (list->items == NULL) {
   3452 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
   3453 	    list->sizeItems = 0;
   3454 	    return(-1);
   3455 	}
   3456     }
   3457     /*
   3458     * Just append if the index is greater/equal than the item count.
   3459     */
   3460     if (idx >= list->nbItems) {
   3461 	list->items[list->nbItems++] = item;
   3462     } else {
   3463 	int i;
   3464 	for (i = list->nbItems; i > idx; i--)
   3465 	    list->items[i] = list->items[i-1];
   3466 	list->items[idx] = item;
   3467 	list->nbItems++;
   3468     }
   3469     return(0);
   3470 }
   3471 #endif
   3472 
   3473 static int
   3474 xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
   3475 {
   3476     int i;
   3477     if ((list->items == NULL) || (idx >= list->nbItems)) {
   3478 	xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
   3479 	    "index error.\n");
   3480 	return(-1);
   3481     }
   3482 
   3483     if (list->nbItems == 1) {
   3484 	/* TODO: Really free the list? */
   3485 	xmlFree(list->items);
   3486 	list->items = NULL;
   3487 	list->nbItems = 0;
   3488 	list->sizeItems = 0;
   3489     } else if (list->nbItems -1 == idx) {
   3490 	list->nbItems--;
   3491     } else {
   3492 	for (i = idx; i < list->nbItems -1; i++)
   3493 	    list->items[i] = list->items[i+1];
   3494 	list->nbItems--;
   3495     }
   3496     return(0);
   3497 }
   3498 
   3499 /**
   3500  * xmlSchemaItemListFree:
   3501  * @annot:  a schema type structure
   3502  *
   3503  * Deallocate a annotation structure
   3504  */
   3505 static void
   3506 xmlSchemaItemListFree(xmlSchemaItemListPtr list)
   3507 {
   3508     if (list == NULL)
   3509 	return;
   3510     if (list->items != NULL)
   3511 	xmlFree(list->items);
   3512     xmlFree(list);
   3513 }
   3514 
   3515 static void
   3516 xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
   3517 {
   3518     if (bucket == NULL)
   3519 	return;
   3520     if (bucket->globals != NULL) {
   3521 	xmlSchemaComponentListFree(bucket->globals);
   3522 	xmlSchemaItemListFree(bucket->globals);
   3523     }
   3524     if (bucket->locals != NULL) {
   3525 	xmlSchemaComponentListFree(bucket->locals);
   3526 	xmlSchemaItemListFree(bucket->locals);
   3527     }
   3528     if (bucket->relations != NULL) {
   3529 	xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
   3530 	do {
   3531 	    prev = cur;
   3532 	    cur = cur->next;
   3533 	    xmlFree(prev);
   3534 	} while (cur != NULL);
   3535     }
   3536     if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
   3537 	xmlFreeDoc(bucket->doc);
   3538     }
   3539     if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
   3540 	if (WXS_IMPBUCKET(bucket)->schema != NULL)
   3541 	    xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
   3542     }
   3543     xmlFree(bucket);
   3544 }
   3545 
   3546 static xmlSchemaBucketPtr
   3547 xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
   3548 			 int type, const xmlChar *targetNamespace)
   3549 {
   3550     xmlSchemaBucketPtr ret;
   3551     int size;
   3552     xmlSchemaPtr mainSchema;
   3553 
   3554     if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
   3555 	PERROR_INT("xmlSchemaBucketCreate",
   3556 	    "no main schema on constructor");
   3557 	return(NULL);
   3558     }
   3559     mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
   3560     /* Create the schema bucket. */
   3561     if (WXS_IS_BUCKET_INCREDEF(type))
   3562 	size = sizeof(xmlSchemaInclude);
   3563     else
   3564 	size = sizeof(xmlSchemaImport);
   3565     ret = (xmlSchemaBucketPtr) xmlMalloc(size);
   3566     if (ret == NULL) {
   3567 	xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
   3568 	return(NULL);
   3569     }
   3570     memset(ret, 0, size);
   3571     ret->targetNamespace = targetNamespace;
   3572     ret->type = type;
   3573     ret->globals = xmlSchemaItemListCreate();
   3574     if (ret->globals == NULL) {
   3575 	xmlFree(ret);
   3576 	return(NULL);
   3577     }
   3578     ret->locals = xmlSchemaItemListCreate();
   3579     if (ret->locals == NULL) {
   3580 	xmlFree(ret);
   3581 	return(NULL);
   3582     }
   3583     /*
   3584     * The following will assure that only the first bucket is marked as
   3585     * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
   3586     * For each following import buckets an xmlSchema will be created.
   3587     * An xmlSchema will be created for every distinct targetNamespace.
   3588     * We assign the targetNamespace to the schemata here.
   3589     */
   3590     if (! WXS_HAS_BUCKETS(pctxt)) {
   3591 	if (WXS_IS_BUCKET_INCREDEF(type)) {
   3592 	    PERROR_INT("xmlSchemaBucketCreate",
   3593 		"first bucket but it's an include or redefine");
   3594 	    xmlSchemaBucketFree(ret);
   3595 	    return(NULL);
   3596 	}
   3597 	/* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
   3598 	ret->type = XML_SCHEMA_SCHEMA_MAIN;
   3599 	/* Point to the *main* schema. */
   3600 	WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
   3601 	WXS_IMPBUCKET(ret)->schema = mainSchema;
   3602 	/*
   3603 	* Ensure that the main schema gets a targetNamespace.
   3604 	*/
   3605 	mainSchema->targetNamespace = targetNamespace;
   3606     } else {
   3607 	if (type == XML_SCHEMA_SCHEMA_MAIN) {
   3608 	    PERROR_INT("xmlSchemaBucketCreate",
   3609 		"main bucket but it's not the first one");
   3610 	    xmlSchemaBucketFree(ret);
   3611 	    return(NULL);
   3612 	} else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
   3613 	    /*
   3614 	    * Create a schema for imports and assign the
   3615 	    * targetNamespace.
   3616 	    */
   3617 	    WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
   3618 	    if (WXS_IMPBUCKET(ret)->schema == NULL) {
   3619 		xmlSchemaBucketFree(ret);
   3620 		return(NULL);
   3621 	    }
   3622 	    WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
   3623 	}
   3624     }
   3625     if (WXS_IS_BUCKET_IMPMAIN(type)) {
   3626 	int res;
   3627 	/*
   3628 	* Imports go into the "schemasImports" slot of the main *schema*.
   3629 	* Note that we create an import entry for the main schema as well; i.e.,
   3630 	* even if there's only one schema, we'll get an import.
   3631 	*/
   3632 	if (mainSchema->schemasImports == NULL) {
   3633 	    mainSchema->schemasImports = xmlHashCreateDict(5,
   3634 		WXS_CONSTRUCTOR(pctxt)->dict);
   3635 	    if (mainSchema->schemasImports == NULL) {
   3636 		xmlSchemaBucketFree(ret);
   3637 		return(NULL);
   3638 	    }
   3639 	}
   3640 	if (targetNamespace == NULL)
   3641 	    res = xmlHashAddEntry(mainSchema->schemasImports,
   3642 		XML_SCHEMAS_NO_NAMESPACE, ret);
   3643 	else
   3644 	    res = xmlHashAddEntry(mainSchema->schemasImports,
   3645 		targetNamespace, ret);
   3646 	if (res != 0) {
   3647 	    PERROR_INT("xmlSchemaBucketCreate",
   3648 		"failed to add the schema bucket to the hash");
   3649 	    xmlSchemaBucketFree(ret);
   3650 	    return(NULL);
   3651 	}
   3652     } else {
   3653 	/* Set the @ownerImport of an include bucket. */
   3654 	if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
   3655 	    WXS_INCBUCKET(ret)->ownerImport =
   3656 		WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
   3657 	else
   3658 	    WXS_INCBUCKET(ret)->ownerImport =
   3659 		WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
   3660 
   3661 	/* Includes got into the "includes" slot of the *main* schema. */
   3662 	if (mainSchema->includes == NULL) {
   3663 	    mainSchema->includes = xmlSchemaItemListCreate();
   3664 	    if (mainSchema->includes == NULL) {
   3665 		xmlSchemaBucketFree(ret);
   3666 		return(NULL);
   3667 	    }
   3668 	}
   3669 	xmlSchemaItemListAdd(mainSchema->includes, ret);
   3670     }
   3671     /*
   3672     * Add to list of all buckets; this is used for lookup
   3673     * during schema construction time only.
   3674     */
   3675     if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
   3676 	return(NULL);
   3677     return(ret);
   3678 }
   3679 
   3680 static int
   3681 xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
   3682 {
   3683     if (*list == NULL) {
   3684 	*list = xmlSchemaItemListCreate();
   3685 	if (*list == NULL)
   3686 	    return(-1);
   3687     }
   3688     xmlSchemaItemListAddSize(*list, initialSize, item);
   3689     return(0);
   3690 }
   3691 
   3692 /**
   3693  * xmlSchemaFreeAnnot:
   3694  * @annot:  a schema type structure
   3695  *
   3696  * Deallocate a annotation structure
   3697  */
   3698 static void
   3699 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
   3700 {
   3701     if (annot == NULL)
   3702         return;
   3703     if (annot->next == NULL) {
   3704 	xmlFree(annot);
   3705     } else {
   3706 	xmlSchemaAnnotPtr prev;
   3707 
   3708 	do {
   3709 	    prev = annot;
   3710 	    annot = annot->next;
   3711 	    xmlFree(prev);
   3712 	} while (annot != NULL);
   3713     }
   3714 }
   3715 
   3716 /**
   3717  * xmlSchemaFreeNotation:
   3718  * @schema:  a schema notation structure
   3719  *
   3720  * Deallocate a Schema Notation structure.
   3721  */
   3722 static void
   3723 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
   3724 {
   3725     if (nota == NULL)
   3726         return;
   3727     xmlFree(nota);
   3728 }
   3729 
   3730 /**
   3731  * xmlSchemaFreeAttribute:
   3732  * @attr:  an attribute declaration
   3733  *
   3734  * Deallocates an attribute declaration structure.
   3735  */
   3736 static void
   3737 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
   3738 {
   3739     if (attr == NULL)
   3740         return;
   3741     if (attr->annot != NULL)
   3742 	xmlSchemaFreeAnnot(attr->annot);
   3743     if (attr->defVal != NULL)
   3744 	xmlSchemaFreeValue(attr->defVal);
   3745     xmlFree(attr);
   3746 }
   3747 
   3748 /**
   3749  * xmlSchemaFreeAttributeUse:
   3750  * @use:  an attribute use
   3751  *
   3752  * Deallocates an attribute use structure.
   3753  */
   3754 static void
   3755 xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
   3756 {
   3757     if (use == NULL)
   3758         return;
   3759     if (use->annot != NULL)
   3760 	xmlSchemaFreeAnnot(use->annot);
   3761     if (use->defVal != NULL)
   3762 	xmlSchemaFreeValue(use->defVal);
   3763     xmlFree(use);
   3764 }
   3765 
   3766 /**
   3767  * xmlSchemaFreeAttributeUseProhib:
   3768  * @prohib:  an attribute use prohibition
   3769  *
   3770  * Deallocates an attribute use structure.
   3771  */
   3772 static void
   3773 xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
   3774 {
   3775     if (prohib == NULL)
   3776         return;
   3777     xmlFree(prohib);
   3778 }
   3779 
   3780 /**
   3781  * xmlSchemaFreeWildcardNsSet:
   3782  * set:  a schema wildcard namespace
   3783  *
   3784  * Deallocates a list of wildcard constraint structures.
   3785  */
   3786 static void
   3787 xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
   3788 {
   3789     xmlSchemaWildcardNsPtr next;
   3790 
   3791     while (set != NULL) {
   3792 	next = set->next;
   3793 	xmlFree(set);
   3794 	set = next;
   3795     }
   3796 }
   3797 
   3798 /**
   3799  * xmlSchemaFreeWildcard:
   3800  * @wildcard:  a wildcard structure
   3801  *
   3802  * Deallocates a wildcard structure.
   3803  */
   3804 void
   3805 xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
   3806 {
   3807     if (wildcard == NULL)
   3808         return;
   3809     if (wildcard->annot != NULL)
   3810         xmlSchemaFreeAnnot(wildcard->annot);
   3811     if (wildcard->nsSet != NULL)
   3812 	xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
   3813     if (wildcard->negNsSet != NULL)
   3814 	xmlFree(wildcard->negNsSet);
   3815     xmlFree(wildcard);
   3816 }
   3817 
   3818 /**
   3819  * xmlSchemaFreeAttributeGroup:
   3820  * @schema:  a schema attribute group structure
   3821  *
   3822  * Deallocate a Schema Attribute Group structure.
   3823  */
   3824 static void
   3825 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
   3826 {
   3827     if (attrGr == NULL)
   3828         return;
   3829     if (attrGr->annot != NULL)
   3830         xmlSchemaFreeAnnot(attrGr->annot);
   3831     if (attrGr->attrUses != NULL)
   3832 	xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
   3833     xmlFree(attrGr);
   3834 }
   3835 
   3836 /**
   3837  * xmlSchemaFreeQNameRef:
   3838  * @item: a QName reference structure
   3839  *
   3840  * Deallocatea a QName reference structure.
   3841  */
   3842 static void
   3843 xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
   3844 {
   3845     xmlFree(item);
   3846 }
   3847 
   3848 /**
   3849  * xmlSchemaFreeTypeLinkList:
   3850  * @alink: a type link
   3851  *
   3852  * Deallocate a list of types.
   3853  */
   3854 static void
   3855 xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
   3856 {
   3857     xmlSchemaTypeLinkPtr next;
   3858 
   3859     while (link != NULL) {
   3860 	next = link->next;
   3861 	xmlFree(link);
   3862 	link = next;
   3863     }
   3864 }
   3865 
   3866 static void
   3867 xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
   3868 {
   3869     xmlSchemaIDCStateObjPtr next;
   3870     while (sto != NULL) {
   3871 	next = sto->next;
   3872 	if (sto->history != NULL)
   3873 	    xmlFree(sto->history);
   3874 	if (sto->xpathCtxt != NULL)
   3875 	    xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
   3876 	xmlFree(sto);
   3877 	sto = next;
   3878     }
   3879 }
   3880 
   3881 /**
   3882  * xmlSchemaFreeIDC:
   3883  * @idc: a identity-constraint definition
   3884  *
   3885  * Deallocates an identity-constraint definition.
   3886  */
   3887 static void
   3888 xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
   3889 {
   3890     xmlSchemaIDCSelectPtr cur, prev;
   3891 
   3892     if (idcDef == NULL)
   3893 	return;
   3894     if (idcDef->annot != NULL)
   3895         xmlSchemaFreeAnnot(idcDef->annot);
   3896     /* Selector */
   3897     if (idcDef->selector != NULL) {
   3898 	if (idcDef->selector->xpathComp != NULL)
   3899 	    xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
   3900 	xmlFree(idcDef->selector);
   3901     }
   3902     /* Fields */
   3903     if (idcDef->fields != NULL) {
   3904 	cur = idcDef->fields;
   3905 	do {
   3906 	    prev = cur;
   3907 	    cur = cur->next;
   3908 	    if (prev->xpathComp != NULL)
   3909 		xmlFreePattern((xmlPatternPtr) prev->xpathComp);
   3910 	    xmlFree(prev);
   3911 	} while (cur != NULL);
   3912     }
   3913     xmlFree(idcDef);
   3914 }
   3915 
   3916 /**
   3917  * xmlSchemaFreeElement:
   3918  * @schema:  a schema element structure
   3919  *
   3920  * Deallocate a Schema Element structure.
   3921  */
   3922 static void
   3923 xmlSchemaFreeElement(xmlSchemaElementPtr elem)
   3924 {
   3925     if (elem == NULL)
   3926         return;
   3927     if (elem->annot != NULL)
   3928         xmlSchemaFreeAnnot(elem->annot);
   3929     if (elem->contModel != NULL)
   3930         xmlRegFreeRegexp(elem->contModel);
   3931     if (elem->defVal != NULL)
   3932 	xmlSchemaFreeValue(elem->defVal);
   3933     xmlFree(elem);
   3934 }
   3935 
   3936 /**
   3937  * xmlSchemaFreeFacet:
   3938  * @facet:  a schema facet structure
   3939  *
   3940  * Deallocate a Schema Facet structure.
   3941  */
   3942 void
   3943 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
   3944 {
   3945     if (facet == NULL)
   3946         return;
   3947     if (facet->val != NULL)
   3948         xmlSchemaFreeValue(facet->val);
   3949     if (facet->regexp != NULL)
   3950         xmlRegFreeRegexp(facet->regexp);
   3951     if (facet->annot != NULL)
   3952         xmlSchemaFreeAnnot(facet->annot);
   3953     xmlFree(facet);
   3954 }
   3955 
   3956 /**
   3957  * xmlSchemaFreeType:
   3958  * @type:  a schema type structure
   3959  *
   3960  * Deallocate a Schema Type structure.
   3961  */
   3962 void
   3963 xmlSchemaFreeType(xmlSchemaTypePtr type)
   3964 {
   3965     if (type == NULL)
   3966         return;
   3967     if (type->annot != NULL)
   3968         xmlSchemaFreeAnnot(type->annot);
   3969     if (type->facets != NULL) {
   3970         xmlSchemaFacetPtr facet, next;
   3971 
   3972         facet = type->facets;
   3973         while (facet != NULL) {
   3974             next = facet->next;
   3975             xmlSchemaFreeFacet(facet);
   3976             facet = next;
   3977         }
   3978     }
   3979     if (type->attrUses != NULL)
   3980 	xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
   3981     if (type->memberTypes != NULL)
   3982 	xmlSchemaFreeTypeLinkList(type->memberTypes);
   3983     if (type->facetSet != NULL) {
   3984 	xmlSchemaFacetLinkPtr next, link;
   3985 
   3986 	link = type->facetSet;
   3987 	do {
   3988 	    next = link->next;
   3989 	    xmlFree(link);
   3990 	    link = next;
   3991 	} while (link != NULL);
   3992     }
   3993     if (type->contModel != NULL)
   3994         xmlRegFreeRegexp(type->contModel);
   3995     xmlFree(type);
   3996 }
   3997 
   3998 /**
   3999  * xmlSchemaFreeModelGroupDef:
   4000  * @item:  a schema model group definition
   4001  *
   4002  * Deallocates a schema model group definition.
   4003  */
   4004 static void
   4005 xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
   4006 {
   4007     if (item->annot != NULL)
   4008 	xmlSchemaFreeAnnot(item->annot);
   4009     xmlFree(item);
   4010 }
   4011 
   4012 /**
   4013  * xmlSchemaFreeModelGroup:
   4014  * @item:  a schema model group
   4015  *
   4016  * Deallocates a schema model group structure.
   4017  */
   4018 static void
   4019 xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
   4020 {
   4021     if (item->annot != NULL)
   4022 	xmlSchemaFreeAnnot(item->annot);
   4023     xmlFree(item);
   4024 }
   4025 
   4026 static void
   4027 xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
   4028 {
   4029     if ((list == NULL) || (list->nbItems == 0))
   4030 	return;
   4031     {
   4032 	xmlSchemaTreeItemPtr item;
   4033 	xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
   4034 	int i;
   4035 
   4036 	for (i = 0; i < list->nbItems; i++) {
   4037 	    item = items[i];
   4038 	    if (item == NULL)
   4039 		continue;
   4040 	    switch (item->type) {
   4041 		case XML_SCHEMA_TYPE_SIMPLE:
   4042 		case XML_SCHEMA_TYPE_COMPLEX:
   4043 		    xmlSchemaFreeType((xmlSchemaTypePtr) item);
   4044 		    break;
   4045 		case XML_SCHEMA_TYPE_ATTRIBUTE:
   4046 		    xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
   4047 		    break;
   4048 		case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   4049 		    xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
   4050 		    break;
   4051 		case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
   4052 		    xmlSchemaFreeAttributeUseProhib(
   4053 			(xmlSchemaAttributeUseProhibPtr) item);
   4054 		    break;
   4055 		case XML_SCHEMA_TYPE_ELEMENT:
   4056 		    xmlSchemaFreeElement((xmlSchemaElementPtr) item);
   4057 		    break;
   4058 		case XML_SCHEMA_TYPE_PARTICLE:
   4059 		    if (item->annot != NULL)
   4060 			xmlSchemaFreeAnnot(item->annot);
   4061 		    xmlFree(item);
   4062 		    break;
   4063 		case XML_SCHEMA_TYPE_SEQUENCE:
   4064 		case XML_SCHEMA_TYPE_CHOICE:
   4065 		case XML_SCHEMA_TYPE_ALL:
   4066 		    xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
   4067 		    break;
   4068 		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   4069 		    xmlSchemaFreeAttributeGroup(
   4070 			(xmlSchemaAttributeGroupPtr) item);
   4071 		    break;
   4072 		case XML_SCHEMA_TYPE_GROUP:
   4073 		    xmlSchemaFreeModelGroupDef(
   4074 			(xmlSchemaModelGroupDefPtr) item);
   4075 		    break;
   4076 		case XML_SCHEMA_TYPE_ANY:
   4077 		case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   4078 		    xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
   4079 		    break;
   4080 		case XML_SCHEMA_TYPE_IDC_KEY:
   4081 		case XML_SCHEMA_TYPE_IDC_UNIQUE:
   4082 		case XML_SCHEMA_TYPE_IDC_KEYREF:
   4083 		    xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
   4084 		    break;
   4085 		case XML_SCHEMA_TYPE_NOTATION:
   4086 		    xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
   4087 		    break;
   4088 		case XML_SCHEMA_EXTRA_QNAMEREF:
   4089 		    xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
   4090 		    break;
   4091 		default: {
   4092 		    /* TODO: This should never be hit. */
   4093 		    xmlSchemaPSimpleInternalErr(NULL,
   4094 			"Internal error: xmlSchemaComponentListFree, "
   4095 			"unexpected component type '%s'\n",
   4096 			(const xmlChar *) WXS_ITEM_TYPE_NAME(item));
   4097 			 }
   4098 		    break;
   4099 	    }
   4100 	}
   4101 	list->nbItems = 0;
   4102     }
   4103 }
   4104 
   4105 /**
   4106  * xmlSchemaFree:
   4107  * @schema:  a schema structure
   4108  *
   4109  * Deallocate a Schema structure.
   4110  */
   4111 void
   4112 xmlSchemaFree(xmlSchemaPtr schema)
   4113 {
   4114     if (schema == NULL)
   4115         return;
   4116     /* @volatiles is not used anymore :-/ */
   4117     if (schema->volatiles != NULL)
   4118 	TODO
   4119     /*
   4120     * Note that those slots are not responsible for freeing
   4121     * schema components anymore; this will now be done by
   4122     * the schema buckets.
   4123     */
   4124     if (schema->notaDecl != NULL)
   4125         xmlHashFree(schema->notaDecl, NULL);
   4126     if (schema->attrDecl != NULL)
   4127         xmlHashFree(schema->attrDecl, NULL);
   4128     if (schema->attrgrpDecl != NULL)
   4129         xmlHashFree(schema->attrgrpDecl, NULL);
   4130     if (schema->elemDecl != NULL)
   4131         xmlHashFree(schema->elemDecl, NULL);
   4132     if (schema->typeDecl != NULL)
   4133         xmlHashFree(schema->typeDecl, NULL);
   4134     if (schema->groupDecl != NULL)
   4135         xmlHashFree(schema->groupDecl, NULL);
   4136     if (schema->idcDef != NULL)
   4137         xmlHashFree(schema->idcDef, NULL);
   4138 
   4139     if (schema->schemasImports != NULL)
   4140 	xmlHashFree(schema->schemasImports,
   4141 		    (xmlHashDeallocator) xmlSchemaBucketFree);
   4142     if (schema->includes != NULL) {
   4143 	xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
   4144 	int i;
   4145 	for (i = 0; i < list->nbItems; i++) {
   4146 	    xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
   4147 	}
   4148 	xmlSchemaItemListFree(list);
   4149     }
   4150     if (schema->annot != NULL)
   4151         xmlSchemaFreeAnnot(schema->annot);
   4152     /* Never free the doc here, since this will be done by the buckets. */
   4153 
   4154     xmlDictFree(schema->dict);
   4155     xmlFree(schema);
   4156 }
   4157 
   4158 /************************************************************************
   4159  *									*
   4160  *			Debug functions					*
   4161  *									*
   4162  ************************************************************************/
   4163 
   4164 #ifdef LIBXML_OUTPUT_ENABLED
   4165 
   4166 static void
   4167 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
   4168 
   4169 /**
   4170  * xmlSchemaElementDump:
   4171  * @elem:  an element
   4172  * @output:  the file output
   4173  *
   4174  * Dump the element
   4175  */
   4176 static void
   4177 xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output,
   4178                      const xmlChar * name ATTRIBUTE_UNUSED,
   4179 		     const xmlChar * namespace ATTRIBUTE_UNUSED,
   4180                      const xmlChar * context ATTRIBUTE_UNUSED)
   4181 {
   4182     if (elem == NULL)
   4183         return;
   4184 
   4185 
   4186     fprintf(output, "Element");
   4187     if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
   4188 	fprintf(output, " (global)");
   4189     fprintf(output, ": '%s' ", elem->name);
   4190     if (namespace != NULL)
   4191 	fprintf(output, "ns '%s'", namespace);
   4192     fprintf(output, "\n");
   4193 #if 0
   4194     if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
   4195 	fprintf(output, "  min %d ", elem->minOccurs);
   4196         if (elem->maxOccurs >= UNBOUNDED)
   4197             fprintf(output, "max: unbounded\n");
   4198         else if (elem->maxOccurs != 1)
   4199             fprintf(output, "max: %d\n", elem->maxOccurs);
   4200         else
   4201             fprintf(output, "\n");
   4202     }
   4203 #endif
   4204     /*
   4205     * Misc other properties.
   4206     */
   4207     if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
   4208 	(elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
   4209 	(elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
   4210 	(elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
   4211 	fprintf(output, "  props: ");
   4212 	if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
   4213 	    fprintf(output, "[fixed] ");
   4214 	if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
   4215 	    fprintf(output, "[default] ");
   4216 	if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
   4217 	    fprintf(output, "[abstract] ");
   4218 	if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
   4219 	    fprintf(output, "[nillable] ");
   4220 	fprintf(output, "\n");
   4221     }
   4222     /*
   4223     * Default/fixed value.
   4224     */
   4225     if (elem->value != NULL)
   4226 	fprintf(output, "  value: '%s'\n", elem->value);
   4227     /*
   4228     * Type.
   4229     */
   4230     if (elem->namedType != NULL) {
   4231 	fprintf(output, "  type: '%s' ", elem->namedType);
   4232 	if (elem->namedTypeNs != NULL)
   4233 	    fprintf(output, "ns '%s'\n", elem->namedTypeNs);
   4234 	else
   4235 	    fprintf(output, "\n");
   4236     } else if (elem->subtypes != NULL) {
   4237 	/*
   4238 	* Dump local types.
   4239 	*/
   4240 	xmlSchemaTypeDump(elem->subtypes, output);
   4241     }
   4242     /*
   4243     * Substitution group.
   4244     */
   4245     if (elem->substGroup != NULL) {
   4246 	fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
   4247 	if (elem->substGroupNs != NULL)
   4248 	    fprintf(output, "ns '%s'\n", elem->substGroupNs);
   4249 	else
   4250 	    fprintf(output, "\n");
   4251     }
   4252 }
   4253 
   4254 /**
   4255  * xmlSchemaAnnotDump:
   4256  * @output:  the file output
   4257  * @annot:  a annotation
   4258  *
   4259  * Dump the annotation
   4260  */
   4261 static void
   4262 xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
   4263 {
   4264     xmlChar *content;
   4265 
   4266     if (annot == NULL)
   4267         return;
   4268 
   4269     content = xmlNodeGetContent(annot->content);
   4270     if (content != NULL) {
   4271         fprintf(output, "  Annot: %s\n", content);
   4272         xmlFree(content);
   4273     } else
   4274         fprintf(output, "  Annot: empty\n");
   4275 }
   4276 
   4277 /**
   4278  * xmlSchemaContentModelDump:
   4279  * @particle: the schema particle
   4280  * @output: the file output
   4281  * @depth: the depth used for intentation
   4282  *
   4283  * Dump a SchemaType structure
   4284  */
   4285 static void
   4286 xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
   4287 {
   4288     xmlChar *str = NULL;
   4289     xmlSchemaTreeItemPtr term;
   4290     char shift[100];
   4291     int i;
   4292 
   4293     if (particle == NULL)
   4294 	return;
   4295     for (i = 0;((i < depth) && (i < 25));i++)
   4296         shift[2 * i] = shift[2 * i + 1] = ' ';
   4297     shift[2 * i] = shift[2 * i + 1] = 0;
   4298     fprintf(output, "%s", shift);
   4299     if (particle->children == NULL) {
   4300 	fprintf(output, "MISSING particle term\n");
   4301 	return;
   4302     }
   4303     term = particle->children;
   4304     if (term == NULL) {
   4305 	fprintf(output, "(NULL)");
   4306     } else {
   4307 	switch (term->type) {
   4308 	    case XML_SCHEMA_TYPE_ELEMENT:
   4309 		fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
   4310 		    ((xmlSchemaElementPtr)term)->targetNamespace,
   4311 		    ((xmlSchemaElementPtr)term)->name));
   4312 		FREE_AND_NULL(str);
   4313 		break;
   4314 	    case XML_SCHEMA_TYPE_SEQUENCE:
   4315 		fprintf(output, "SEQUENCE");
   4316 		break;
   4317 	    case XML_SCHEMA_TYPE_CHOICE:
   4318 		fprintf(output, "CHOICE");
   4319 		break;
   4320 	    case XML_SCHEMA_TYPE_ALL:
   4321 		fprintf(output, "ALL");
   4322 		break;
   4323 	    case XML_SCHEMA_TYPE_ANY:
   4324 		fprintf(output, "ANY");
   4325 		break;
   4326 	    default:
   4327 		fprintf(output, "UNKNOWN\n");
   4328 		return;
   4329 	}
   4330     }
   4331     if (particle->minOccurs != 1)
   4332 	fprintf(output, " min: %d", particle->minOccurs);
   4333     if (particle->maxOccurs >= UNBOUNDED)
   4334 	fprintf(output, " max: unbounded");
   4335     else if (particle->maxOccurs != 1)
   4336 	fprintf(output, " max: %d", particle->maxOccurs);
   4337     fprintf(output, "\n");
   4338     if (term &&
   4339 	((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
   4340 	 (term->type == XML_SCHEMA_TYPE_CHOICE) ||
   4341 	 (term->type == XML_SCHEMA_TYPE_ALL)) &&
   4342 	 (term->children != NULL)) {
   4343 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
   4344 	    output, depth +1);
   4345     }
   4346     if (particle->next != NULL)
   4347 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
   4348 		output, depth);
   4349 }
   4350 
   4351 /**
   4352  * xmlSchemaAttrUsesDump:
   4353  * @uses:  attribute uses list
   4354  * @output:  the file output
   4355  *
   4356  * Dumps a list of attribute use components.
   4357  */
   4358 static void
   4359 xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
   4360 {
   4361     xmlSchemaAttributeUsePtr use;
   4362     xmlSchemaAttributeUseProhibPtr prohib;
   4363     xmlSchemaQNameRefPtr ref;
   4364     const xmlChar *name, *tns;
   4365     xmlChar *str = NULL;
   4366     int i;
   4367 
   4368     if ((uses == NULL) || (uses->nbItems == 0))
   4369         return;
   4370 
   4371     fprintf(output, "  attributes:\n");
   4372     for (i = 0; i < uses->nbItems; i++) {
   4373 	use = uses->items[i];
   4374 	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
   4375 	    fprintf(output, "  [prohibition] ");
   4376 	    prohib = (xmlSchemaAttributeUseProhibPtr) use;
   4377 	    name = prohib->name;
   4378 	    tns = prohib->targetNamespace;
   4379 	} else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
   4380 	    fprintf(output, "  [reference] ");
   4381 	    ref = (xmlSchemaQNameRefPtr) use;
   4382 	    name = ref->name;
   4383 	    tns = ref->targetNamespace;
   4384 	} else {
   4385 	    fprintf(output, "  [use] ");
   4386 	    name = WXS_ATTRUSE_DECL_NAME(use);
   4387 	    tns = WXS_ATTRUSE_DECL_TNS(use);
   4388 	}
   4389 	fprintf(output, "'%s'\n",
   4390 	    (const char *) xmlSchemaFormatQName(&str, tns, name));
   4391 	FREE_AND_NULL(str);
   4392     }
   4393 }
   4394 
   4395 /**
   4396  * xmlSchemaTypeDump:
   4397  * @output:  the file output
   4398  * @type:  a type structure
   4399  *
   4400  * Dump a SchemaType structure
   4401  */
   4402 static void
   4403 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
   4404 {
   4405     if (type == NULL) {
   4406         fprintf(output, "Type: NULL\n");
   4407         return;
   4408     }
   4409     fprintf(output, "Type: ");
   4410     if (type->name != NULL)
   4411         fprintf(output, "'%s' ", type->name);
   4412     else
   4413         fprintf(output, "(no name) ");
   4414     if (type->targetNamespace != NULL)
   4415 	fprintf(output, "ns '%s' ", type->targetNamespace);
   4416     switch (type->type) {
   4417         case XML_SCHEMA_TYPE_BASIC:
   4418             fprintf(output, "[basic] ");
   4419             break;
   4420         case XML_SCHEMA_TYPE_SIMPLE:
   4421             fprintf(output, "[simple] ");
   4422             break;
   4423         case XML_SCHEMA_TYPE_COMPLEX:
   4424             fprintf(output, "[complex] ");
   4425             break;
   4426         case XML_SCHEMA_TYPE_SEQUENCE:
   4427             fprintf(output, "[sequence] ");
   4428             break;
   4429         case XML_SCHEMA_TYPE_CHOICE:
   4430             fprintf(output, "[choice] ");
   4431             break;
   4432         case XML_SCHEMA_TYPE_ALL:
   4433             fprintf(output, "[all] ");
   4434             break;
   4435         case XML_SCHEMA_TYPE_UR:
   4436             fprintf(output, "[ur] ");
   4437             break;
   4438         case XML_SCHEMA_TYPE_RESTRICTION:
   4439             fprintf(output, "[restriction] ");
   4440             break;
   4441         case XML_SCHEMA_TYPE_EXTENSION:
   4442             fprintf(output, "[extension] ");
   4443             break;
   4444         default:
   4445             fprintf(output, "[unknown type %d] ", type->type);
   4446             break;
   4447     }
   4448     fprintf(output, "content: ");
   4449     switch (type->contentType) {
   4450         case XML_SCHEMA_CONTENT_UNKNOWN:
   4451             fprintf(output, "[unknown] ");
   4452             break;
   4453         case XML_SCHEMA_CONTENT_EMPTY:
   4454             fprintf(output, "[empty] ");
   4455             break;
   4456         case XML_SCHEMA_CONTENT_ELEMENTS:
   4457             fprintf(output, "[element] ");
   4458             break;
   4459         case XML_SCHEMA_CONTENT_MIXED:
   4460             fprintf(output, "[mixed] ");
   4461             break;
   4462         case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
   4463 	/* not used. */
   4464             break;
   4465         case XML_SCHEMA_CONTENT_BASIC:
   4466             fprintf(output, "[basic] ");
   4467             break;
   4468         case XML_SCHEMA_CONTENT_SIMPLE:
   4469             fprintf(output, "[simple] ");
   4470             break;
   4471         case XML_SCHEMA_CONTENT_ANY:
   4472             fprintf(output, "[any] ");
   4473             break;
   4474     }
   4475     fprintf(output, "\n");
   4476     if (type->base != NULL) {
   4477         fprintf(output, "  base type: '%s'", type->base);
   4478 	if (type->baseNs != NULL)
   4479 	    fprintf(output, " ns '%s'\n", type->baseNs);
   4480 	else
   4481 	    fprintf(output, "\n");
   4482     }
   4483     if (type->attrUses != NULL)
   4484 	xmlSchemaAttrUsesDump(type->attrUses, output);
   4485     if (type->annot != NULL)
   4486         xmlSchemaAnnotDump(output, type->annot);
   4487 #ifdef DUMP_CONTENT_MODEL
   4488     if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
   4489 	(type->subtypes != NULL)) {
   4490 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
   4491 	    output, 1);
   4492     }
   4493 #endif
   4494 }
   4495 
   4496 /**
   4497  * xmlSchemaDump:
   4498  * @output:  the file output
   4499  * @schema:  a schema structure
   4500  *
   4501  * Dump a Schema structure.
   4502  */
   4503 void
   4504 xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
   4505 {
   4506     if (output == NULL)
   4507         return;
   4508     if (schema == NULL) {
   4509         fprintf(output, "Schemas: NULL\n");
   4510         return;
   4511     }
   4512     fprintf(output, "Schemas: ");
   4513     if (schema->name != NULL)
   4514         fprintf(output, "%s, ", schema->name);
   4515     else
   4516         fprintf(output, "no name, ");
   4517     if (schema->targetNamespace != NULL)
   4518         fprintf(output, "%s", (const char *) schema->targetNamespace);
   4519     else
   4520         fprintf(output, "no target namespace");
   4521     fprintf(output, "\n");
   4522     if (schema->annot != NULL)
   4523         xmlSchemaAnnotDump(output, schema->annot);
   4524     xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump,
   4525                 output);
   4526     xmlHashScanFull(schema->elemDecl,
   4527                     (xmlHashScannerFull) xmlSchemaElementDump, output);
   4528 }
   4529 
   4530 #ifdef DEBUG_IDC_NODE_TABLE
   4531 /**
   4532  * xmlSchemaDebugDumpIDCTable:
   4533  * @vctxt: the WXS validation context
   4534  *
   4535  * Displays the current IDC table for debug purposes.
   4536  */
   4537 static void
   4538 xmlSchemaDebugDumpIDCTable(FILE * output,
   4539 			   const xmlChar *namespaceName,
   4540 			   const xmlChar *localName,
   4541 			   xmlSchemaPSVIIDCBindingPtr bind)
   4542 {
   4543     xmlChar *str = NULL;
   4544     const xmlChar *value;
   4545     xmlSchemaPSVIIDCNodePtr tab;
   4546     xmlSchemaPSVIIDCKeyPtr key;
   4547     int i, j, res;
   4548 
   4549     fprintf(output, "IDC: TABLES on '%s'\n",
   4550 	xmlSchemaFormatQName(&str, namespaceName, localName));
   4551     FREE_AND_NULL(str)
   4552 
   4553     if (bind == NULL)
   4554 	return;
   4555     do {
   4556 	fprintf(output, "IDC:   BINDING '%s' (%d)\n",
   4557 	    xmlSchemaGetComponentQName(&str,
   4558 		bind->definition), bind->nbNodes);
   4559 	FREE_AND_NULL(str)
   4560 	for (i = 0; i < bind->nbNodes; i++) {
   4561 	    tab = bind->nodeTable[i];
   4562 	    fprintf(output, "         ( ");
   4563 	    for (j = 0; j < bind->definition->nbFields; j++) {
   4564 		key = tab->keys[j];
   4565 		if ((key != NULL) && (key->val != NULL)) {
   4566 		    res = xmlSchemaGetCanonValue(key->val, &value);
   4567 		    if (res >= 0)
   4568 			fprintf(output, "'%s' ", value);
   4569 		    else
   4570 			fprintf(output, "CANON-VALUE-FAILED ");
   4571 		    if (res == 0)
   4572 			FREE_AND_NULL(value)
   4573 		} else if (key != NULL)
   4574 		    fprintf(output, "(no val), ");
   4575 		else
   4576 		    fprintf(output, "(key missing), ");
   4577 	    }
   4578 	    fprintf(output, ")\n");
   4579 	}
   4580 	if (bind->dupls && bind->dupls->nbItems) {
   4581 	    fprintf(output, "IDC:     dupls (%d):\n", bind->dupls->nbItems);
   4582 	    for (i = 0; i < bind->dupls->nbItems; i++) {
   4583 		tab = bind->dupls->items[i];
   4584 		fprintf(output, "         ( ");
   4585 		for (j = 0; j < bind->definition->nbFields; j++) {
   4586 		    key = tab->keys[j];
   4587 		    if ((key != NULL) && (key->val != NULL)) {
   4588 			res = xmlSchemaGetCanonValue(key->val, &value);
   4589 			if (res >= 0)
   4590 			    fprintf(output, "'%s' ", value);
   4591 			else
   4592 			    fprintf(output, "CANON-VALUE-FAILED ");
   4593 			if (res == 0)
   4594 			    FREE_AND_NULL(value)
   4595 		    } else if (key != NULL)
   4596 		    fprintf(output, "(no val), ");
   4597 			else
   4598 			    fprintf(output, "(key missing), ");
   4599 		}
   4600 		fprintf(output, ")\n");
   4601 	    }
   4602 	}
   4603 	bind = bind->next;
   4604     } while (bind != NULL);
   4605 }
   4606 #endif /* DEBUG_IDC */
   4607 #endif /* LIBXML_OUTPUT_ENABLED */
   4608 
   4609 /************************************************************************
   4610  *									*
   4611  *			Utilities					*
   4612  *									*
   4613  ************************************************************************/
   4614 
   4615 /**
   4616  * xmlSchemaGetPropNode:
   4617  * @node: the element node
   4618  * @name: the name of the attribute
   4619  *
   4620  * Seeks an attribute with a name of @name in
   4621  * no namespace.
   4622  *
   4623  * Returns the attribute or NULL if not present.
   4624  */
   4625 static xmlAttrPtr
   4626 xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
   4627 {
   4628     xmlAttrPtr prop;
   4629 
   4630     if ((node == NULL) || (name == NULL))
   4631 	return(NULL);
   4632     prop = node->properties;
   4633     while (prop != NULL) {
   4634         if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
   4635 	    return(prop);
   4636 	prop = prop->next;
   4637     }
   4638     return (NULL);
   4639 }
   4640 
   4641 /**
   4642  * xmlSchemaGetPropNodeNs:
   4643  * @node: the element node
   4644  * @uri: the uri
   4645  * @name: the name of the attribute
   4646  *
   4647  * Seeks an attribute with a local name of @name and
   4648  * a namespace URI of @uri.
   4649  *
   4650  * Returns the attribute or NULL if not present.
   4651  */
   4652 static xmlAttrPtr
   4653 xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
   4654 {
   4655     xmlAttrPtr prop;
   4656 
   4657     if ((node == NULL) || (name == NULL))
   4658 	return(NULL);
   4659     prop = node->properties;
   4660     while (prop != NULL) {
   4661 	if ((prop->ns != NULL) &&
   4662 	    xmlStrEqual(prop->name, BAD_CAST name) &&
   4663 	    xmlStrEqual(prop->ns->href, BAD_CAST uri))
   4664 	    return(prop);
   4665 	prop = prop->next;
   4666     }
   4667     return (NULL);
   4668 }
   4669 
   4670 static const xmlChar *
   4671 xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
   4672 {
   4673     xmlChar *val;
   4674     const xmlChar *ret;
   4675 
   4676     val = xmlNodeGetContent(node);
   4677     if (val == NULL)
   4678 	val = xmlStrdup((xmlChar *)"");
   4679     ret = xmlDictLookup(ctxt->dict, val, -1);
   4680     xmlFree(val);
   4681     return(ret);
   4682 }
   4683 
   4684 static const xmlChar *
   4685 xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
   4686 {
   4687     return((const xmlChar*) xmlNodeGetContent(node));
   4688 }
   4689 
   4690 /**
   4691  * xmlSchemaGetProp:
   4692  * @ctxt: the parser context
   4693  * @node: the node
   4694  * @name: the property name
   4695  *
   4696  * Read a attribute value and internalize the string
   4697  *
   4698  * Returns the string or NULL if not present.
   4699  */
   4700 static const xmlChar *
   4701 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
   4702                  const char *name)
   4703 {
   4704     xmlChar *val;
   4705     const xmlChar *ret;
   4706 
   4707     val = xmlGetNoNsProp(node, BAD_CAST name);
   4708     if (val == NULL)
   4709         return(NULL);
   4710     ret = xmlDictLookup(ctxt->dict, val, -1);
   4711     xmlFree(val);
   4712     return(ret);
   4713 }
   4714 
   4715 /************************************************************************
   4716  *									*
   4717  *			Parsing functions				*
   4718  *									*
   4719  ************************************************************************/
   4720 
   4721 #define WXS_FIND_GLOBAL_ITEM(slot)			\
   4722     if (xmlStrEqual(nsName, schema->targetNamespace)) { \
   4723 	ret = xmlHashLookup(schema->slot, name); \
   4724 	if (ret != NULL) goto exit; \
   4725     } \
   4726     if (xmlHashSize(schema->schemasImports) > 1) { \
   4727 	xmlSchemaImportPtr import; \
   4728 	if (nsName == NULL) \
   4729 	    import = xmlHashLookup(schema->schemasImports, \
   4730 		XML_SCHEMAS_NO_NAMESPACE); \
   4731 	else \
   4732 	    import = xmlHashLookup(schema->schemasImports, nsName); \
   4733 	if (import == NULL) \
   4734 	    goto exit; \
   4735 	ret = xmlHashLookup(import->schema->slot, name); \
   4736     }
   4737 
   4738 /**
   4739  * xmlSchemaGetElem:
   4740  * @schema:  the schema context
   4741  * @name:  the element name
   4742  * @ns:  the element namespace
   4743  *
   4744  * Lookup a global element declaration in the schema.
   4745  *
   4746  * Returns the element declaration or NULL if not found.
   4747  */
   4748 static xmlSchemaElementPtr
   4749 xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
   4750                  const xmlChar * nsName)
   4751 {
   4752     xmlSchemaElementPtr ret = NULL;
   4753 
   4754     if ((name == NULL) || (schema == NULL))
   4755         return(NULL);
   4756     if (schema != NULL) {
   4757 	WXS_FIND_GLOBAL_ITEM(elemDecl)
   4758     }
   4759 exit:
   4760 #ifdef DEBUG
   4761     if (ret == NULL) {
   4762         if (nsName == NULL)
   4763             fprintf(stderr, "Unable to lookup element decl. %s", name);
   4764         else
   4765             fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
   4766                     nsName);
   4767     }
   4768 #endif
   4769     return (ret);
   4770 }
   4771 
   4772 /**
   4773  * xmlSchemaGetType:
   4774  * @schema:  the main schema
   4775  * @name:  the type's name
   4776  * nsName:  the type's namespace
   4777  *
   4778  * Lookup a type in the schemas or the predefined types
   4779  *
   4780  * Returns the group definition or NULL if not found.
   4781  */
   4782 static xmlSchemaTypePtr
   4783 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
   4784                  const xmlChar * nsName)
   4785 {
   4786     xmlSchemaTypePtr ret = NULL;
   4787 
   4788     if (name == NULL)
   4789         return (NULL);
   4790     /* First try the built-in types. */
   4791     if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
   4792 	ret = xmlSchemaGetPredefinedType(name, nsName);
   4793 	if (ret != NULL)
   4794 	    goto exit;
   4795 	/*
   4796 	* Note that we try the parsed schemas as well here
   4797 	* since one might have parsed the S4S, which contain more
   4798 	* than the built-in types.
   4799 	* TODO: Can we optimize this?
   4800 	*/
   4801     }
   4802     if (schema != NULL) {
   4803 	WXS_FIND_GLOBAL_ITEM(typeDecl)
   4804     }
   4805 exit:
   4806 
   4807 #ifdef DEBUG
   4808     if (ret == NULL) {
   4809         if (nsName == NULL)
   4810             fprintf(stderr, "Unable to lookup type %s", name);
   4811         else
   4812             fprintf(stderr, "Unable to lookup type %s:%s", name,
   4813                     nsName);
   4814     }
   4815 #endif
   4816     return (ret);
   4817 }
   4818 
   4819 /**
   4820  * xmlSchemaGetAttributeDecl:
   4821  * @schema:  the context of the schema
   4822  * @name:  the name of the attribute
   4823  * @ns:  the target namespace of the attribute
   4824  *
   4825  * Lookup a an attribute in the schema or imported schemas
   4826  *
   4827  * Returns the attribute declaration or NULL if not found.
   4828  */
   4829 static xmlSchemaAttributePtr
   4830 xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
   4831                  const xmlChar * nsName)
   4832 {
   4833     xmlSchemaAttributePtr ret = NULL;
   4834 
   4835     if ((name == NULL) || (schema == NULL))
   4836         return (NULL);
   4837     if (schema != NULL) {
   4838 	WXS_FIND_GLOBAL_ITEM(attrDecl)
   4839     }
   4840 exit:
   4841 #ifdef DEBUG
   4842     if (ret == NULL) {
   4843         if (nsName == NULL)
   4844             fprintf(stderr, "Unable to lookup attribute %s", name);
   4845         else
   4846             fprintf(stderr, "Unable to lookup attribute %s:%s", name,
   4847                     nsName);
   4848     }
   4849 #endif
   4850     return (ret);
   4851 }
   4852 
   4853 /**
   4854  * xmlSchemaGetAttributeGroup:
   4855  * @schema:  the context of the schema
   4856  * @name:  the name of the attribute group
   4857  * @ns:  the target namespace of the attribute group
   4858  *
   4859  * Lookup a an attribute group in the schema or imported schemas
   4860  *
   4861  * Returns the attribute group definition or NULL if not found.
   4862  */
   4863 static xmlSchemaAttributeGroupPtr
   4864 xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
   4865                  const xmlChar * nsName)
   4866 {
   4867     xmlSchemaAttributeGroupPtr ret = NULL;
   4868 
   4869     if ((name == NULL) || (schema == NULL))
   4870         return (NULL);
   4871     if (schema != NULL) {
   4872 	WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
   4873     }
   4874 exit:
   4875     /* TODO:
   4876     if ((ret != NULL) && (ret->redef != NULL)) {
   4877 	* Return the last redefinition. *
   4878 	ret = ret->redef;
   4879     }
   4880     */
   4881 #ifdef DEBUG
   4882     if (ret == NULL) {
   4883         if (nsName == NULL)
   4884             fprintf(stderr, "Unable to lookup attribute group %s", name);
   4885         else
   4886             fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
   4887                     nsName);
   4888     }
   4889 #endif
   4890     return (ret);
   4891 }
   4892 
   4893 /**
   4894  * xmlSchemaGetGroup:
   4895  * @schema:  the context of the schema
   4896  * @name:  the name of the group
   4897  * @ns:  the target namespace of the group
   4898  *
   4899  * Lookup a group in the schema or imported schemas
   4900  *
   4901  * Returns the group definition or NULL if not found.
   4902  */
   4903 static xmlSchemaModelGroupDefPtr
   4904 xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
   4905                  const xmlChar * nsName)
   4906 {
   4907     xmlSchemaModelGroupDefPtr ret = NULL;
   4908 
   4909     if ((name == NULL) || (schema == NULL))
   4910         return (NULL);
   4911     if (schema != NULL) {
   4912 	WXS_FIND_GLOBAL_ITEM(groupDecl)
   4913     }
   4914 exit:
   4915 
   4916 #ifdef DEBUG
   4917     if (ret == NULL) {
   4918         if (nsName == NULL)
   4919             fprintf(stderr, "Unable to lookup group %s", name);
   4920         else
   4921             fprintf(stderr, "Unable to lookup group %s:%s", name,
   4922                     nsName);
   4923     }
   4924 #endif
   4925     return (ret);
   4926 }
   4927 
   4928 static xmlSchemaNotationPtr
   4929 xmlSchemaGetNotation(xmlSchemaPtr schema,
   4930 		     const xmlChar *name,
   4931 		     const xmlChar *nsName)
   4932 {
   4933     xmlSchemaNotationPtr ret = NULL;
   4934 
   4935     if ((name == NULL) || (schema == NULL))
   4936         return (NULL);
   4937     if (schema != NULL) {
   4938 	WXS_FIND_GLOBAL_ITEM(notaDecl)
   4939     }
   4940 exit:
   4941     return (ret);
   4942 }
   4943 
   4944 static xmlSchemaIDCPtr
   4945 xmlSchemaGetIDC(xmlSchemaPtr schema,
   4946 		const xmlChar *name,
   4947 		const xmlChar *nsName)
   4948 {
   4949     xmlSchemaIDCPtr ret = NULL;
   4950 
   4951     if ((name == NULL) || (schema == NULL))
   4952         return (NULL);
   4953     if (schema != NULL) {
   4954 	WXS_FIND_GLOBAL_ITEM(idcDef)
   4955     }
   4956 exit:
   4957     return (ret);
   4958 }
   4959 
   4960 /**
   4961  * xmlSchemaGetNamedComponent:
   4962  * @schema:  the schema
   4963  * @name:  the name of the group
   4964  * @ns:  the target namespace of the group
   4965  *
   4966  * Lookup a group in the schema or imported schemas
   4967  *
   4968  * Returns the group definition or NULL if not found.
   4969  */
   4970 static xmlSchemaBasicItemPtr
   4971 xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
   4972 			   xmlSchemaTypeType itemType,
   4973 			   const xmlChar *name,
   4974 			   const xmlChar *targetNs)
   4975 {
   4976     switch (itemType) {
   4977 	case XML_SCHEMA_TYPE_GROUP:
   4978 	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
   4979 		name, targetNs));
   4980 	case XML_SCHEMA_TYPE_ELEMENT:
   4981 	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
   4982 		name, targetNs));
   4983 	default:
   4984 	    TODO
   4985 	    return (NULL);
   4986     }
   4987 }
   4988 
   4989 /************************************************************************
   4990  *									*
   4991  *			Parsing functions				*
   4992  *									*
   4993  ************************************************************************/
   4994 
   4995 #define IS_BLANK_NODE(n)						\
   4996     (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
   4997 
   4998 /**
   4999  * xmlSchemaIsBlank:
   5000  * @str:  a string
   5001  * @len: the length of the string or -1
   5002  *
   5003  * Check if a string is ignorable
   5004  *
   5005  * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
   5006  */
   5007 static int
   5008 xmlSchemaIsBlank(xmlChar * str, int len)
   5009 {
   5010     if (str == NULL)
   5011         return (1);
   5012     if (len < 0) {
   5013 	while (*str != 0) {
   5014 	    if (!(IS_BLANK_CH(*str)))
   5015 		return (0);
   5016 	    str++;
   5017 	}
   5018     } else while ((*str != 0) && (len != 0)) {
   5019 	if (!(IS_BLANK_CH(*str)))
   5020 	    return (0);
   5021 	str++;
   5022 	len--;
   5023     }
   5024 
   5025     return (1);
   5026 }
   5027 
   5028 #define WXS_COMP_NAME(c, t) ((t) (c))->name
   5029 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
   5030 /*
   5031 * xmlSchemaFindRedefCompInGraph:
   5032 * ATTENTION TODO: This uses pointer comp. for strings.
   5033 */
   5034 static xmlSchemaBasicItemPtr
   5035 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
   5036 			      xmlSchemaTypeType type,
   5037 			      const xmlChar *name,
   5038 			      const xmlChar *nsName)
   5039 {
   5040     xmlSchemaBasicItemPtr ret;
   5041     int i;
   5042 
   5043     if ((bucket == NULL) || (name == NULL))
   5044 	return(NULL);
   5045     if ((bucket->globals == NULL) ||
   5046 	(bucket->globals->nbItems == 0))
   5047 	goto subschemas;
   5048     /*
   5049     * Search in global components.
   5050     */
   5051     for (i = 0; i < bucket->globals->nbItems; i++) {
   5052 	ret = bucket->globals->items[i];
   5053 	if (ret->type == type) {
   5054 	    switch (type) {
   5055 		case XML_SCHEMA_TYPE_COMPLEX:
   5056 		case XML_SCHEMA_TYPE_SIMPLE:
   5057 		    if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
   5058 			(WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
   5059 			nsName))
   5060 		    {
   5061 			return(ret);
   5062 		    }
   5063 		    break;
   5064 		case XML_SCHEMA_TYPE_GROUP:
   5065 		    if ((WXS_COMP_NAME(ret,
   5066 			    xmlSchemaModelGroupDefPtr) == name) &&
   5067 			(WXS_COMP_TNS(ret,
   5068 			    xmlSchemaModelGroupDefPtr) == nsName))
   5069 		    {
   5070 			return(ret);
   5071 		    }
   5072 		    break;
   5073 		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   5074 		    if ((WXS_COMP_NAME(ret,
   5075 			    xmlSchemaAttributeGroupPtr) == name) &&
   5076 			(WXS_COMP_TNS(ret,
   5077 			    xmlSchemaAttributeGroupPtr) == nsName))
   5078 		    {
   5079 			return(ret);
   5080 		    }
   5081 		    break;
   5082 		default:
   5083 		    /* Should not be hit. */
   5084 		    return(NULL);
   5085 	    }
   5086 	}
   5087     }
   5088 subschemas:
   5089     /*
   5090     * Process imported/included schemas.
   5091     */
   5092     if (bucket->relations != NULL) {
   5093 	xmlSchemaSchemaRelationPtr rel = bucket->relations;
   5094 
   5095 	/*
   5096 	* TODO: Marking the bucket will not avoid multiple searches
   5097 	* in the same schema, but avoids at least circularity.
   5098 	*/
   5099 	bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
   5100 	do {
   5101 	    if ((rel->bucket != NULL) &&
   5102 		((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
   5103 		ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
   5104 		    type, name, nsName);
   5105 		if (ret != NULL)
   5106 		    return(ret);
   5107 	    }
   5108 	    rel = rel->next;
   5109 	} while (rel != NULL);
   5110 	 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
   5111     }
   5112     return(NULL);
   5113 }
   5114 
   5115 /**
   5116  * xmlSchemaAddNotation:
   5117  * @ctxt:  a schema parser context
   5118  * @schema:  the schema being built
   5119  * @name:  the item name
   5120  *
   5121  * Add an XML schema annotation declaration
   5122  * *WARNING* this interface is highly subject to change
   5123  *
   5124  * Returns the new struture or NULL in case of error
   5125  */
   5126 static xmlSchemaNotationPtr
   5127 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5128                      const xmlChar *name, const xmlChar *nsName,
   5129 		     xmlNodePtr node ATTRIBUTE_UNUSED)
   5130 {
   5131     xmlSchemaNotationPtr ret = NULL;
   5132 
   5133     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
   5134         return (NULL);
   5135 
   5136     ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
   5137     if (ret == NULL) {
   5138         xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
   5139         return (NULL);
   5140     }
   5141     memset(ret, 0, sizeof(xmlSchemaNotation));
   5142     ret->type = XML_SCHEMA_TYPE_NOTATION;
   5143     ret->name = name;
   5144     ret->targetNamespace = nsName;
   5145     /* TODO: do we need the node to be set?
   5146     * ret->node = node;*/
   5147     WXS_ADD_GLOBAL(ctxt, ret);
   5148     return (ret);
   5149 }
   5150 
   5151 /**
   5152  * xmlSchemaAddAttribute:
   5153  * @ctxt:  a schema parser context
   5154  * @schema:  the schema being built
   5155  * @name:  the item name
   5156  * @namespace:  the namespace
   5157  *
   5158  * Add an XML schema Attrribute declaration
   5159  * *WARNING* this interface is highly subject to change
   5160  *
   5161  * Returns the new struture or NULL in case of error
   5162  */
   5163 static xmlSchemaAttributePtr
   5164 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5165                       const xmlChar * name, const xmlChar * nsName,
   5166 		      xmlNodePtr node, int topLevel)
   5167 {
   5168     xmlSchemaAttributePtr ret = NULL;
   5169 
   5170     if ((ctxt == NULL) || (schema == NULL))
   5171         return (NULL);
   5172 
   5173     ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
   5174     if (ret == NULL) {
   5175         xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
   5176         return (NULL);
   5177     }
   5178     memset(ret, 0, sizeof(xmlSchemaAttribute));
   5179     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
   5180     ret->node = node;
   5181     ret->name = name;
   5182     ret->targetNamespace = nsName;
   5183 
   5184     if (topLevel)
   5185 	WXS_ADD_GLOBAL(ctxt, ret);
   5186     else
   5187 	WXS_ADD_LOCAL(ctxt, ret);
   5188     WXS_ADD_PENDING(ctxt, ret);
   5189     return (ret);
   5190 }
   5191 
   5192 /**
   5193  * xmlSchemaAddAttributeUse:
   5194  * @ctxt:  a schema parser context
   5195  * @schema:  the schema being built
   5196  * @name:  the item name
   5197  * @namespace:  the namespace
   5198  *
   5199  * Add an XML schema Attrribute declaration
   5200  * *WARNING* this interface is highly subject to change
   5201  *
   5202  * Returns the new struture or NULL in case of error
   5203  */
   5204 static xmlSchemaAttributeUsePtr
   5205 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
   5206 			 xmlNodePtr node)
   5207 {
   5208     xmlSchemaAttributeUsePtr ret = NULL;
   5209 
   5210     if (pctxt == NULL)
   5211         return (NULL);
   5212 
   5213     ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
   5214     if (ret == NULL) {
   5215         xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
   5216         return (NULL);
   5217     }
   5218     memset(ret, 0, sizeof(xmlSchemaAttributeUse));
   5219     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
   5220     ret->node = node;
   5221 
   5222     WXS_ADD_LOCAL(pctxt, ret);
   5223     return (ret);
   5224 }
   5225 
   5226 /*
   5227 * xmlSchemaAddRedef:
   5228 *
   5229 * Adds a redefinition information. This is used at a later stage to:
   5230 * resolve references to the redefined components and to check constraints.
   5231 */
   5232 static xmlSchemaRedefPtr
   5233 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
   5234 		  xmlSchemaBucketPtr targetBucket,
   5235 		  void *item,
   5236 		  const xmlChar *refName,
   5237 		  const xmlChar *refTargetNs)
   5238 {
   5239     xmlSchemaRedefPtr ret;
   5240 
   5241     ret = (xmlSchemaRedefPtr)
   5242 	xmlMalloc(sizeof(xmlSchemaRedef));
   5243     if (ret == NULL) {
   5244 	xmlSchemaPErrMemory(pctxt,
   5245 	    "allocating redefinition info", NULL);
   5246 	return (NULL);
   5247     }
   5248     memset(ret, 0, sizeof(xmlSchemaRedef));
   5249     ret->item = item;
   5250     ret->targetBucket = targetBucket;
   5251     ret->refName = refName;
   5252     ret->refTargetNs = refTargetNs;
   5253     if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
   5254 	WXS_CONSTRUCTOR(pctxt)->redefs = ret;
   5255     else
   5256 	WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
   5257     WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
   5258 
   5259     return (ret);
   5260 }
   5261 
   5262 /**
   5263  * xmlSchemaAddAttributeGroupDefinition:
   5264  * @ctxt:  a schema parser context
   5265  * @schema:  the schema being built
   5266  * @name:  the item name
   5267  * @nsName:  the target namespace
   5268  * @node: the corresponding node
   5269  *
   5270  * Add an XML schema Attrribute Group definition.
   5271  *
   5272  * Returns the new struture or NULL in case of error
   5273  */
   5274 static xmlSchemaAttributeGroupPtr
   5275 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
   5276                            xmlSchemaPtr schema ATTRIBUTE_UNUSED,
   5277 			   const xmlChar *name,
   5278 			   const xmlChar *nsName,
   5279 			   xmlNodePtr node)
   5280 {
   5281     xmlSchemaAttributeGroupPtr ret = NULL;
   5282 
   5283     if ((pctxt == NULL) || (name == NULL))
   5284         return (NULL);
   5285 
   5286     ret = (xmlSchemaAttributeGroupPtr)
   5287         xmlMalloc(sizeof(xmlSchemaAttributeGroup));
   5288     if (ret == NULL) {
   5289 	xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
   5290 	return (NULL);
   5291     }
   5292     memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
   5293     ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
   5294     ret->name = name;
   5295     ret->targetNamespace = nsName;
   5296     ret->node = node;
   5297 
   5298     /* TODO: Remove the flag. */
   5299     ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
   5300     if (pctxt->isRedefine) {
   5301 	pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
   5302 	    ret, name, nsName);
   5303 	if (pctxt->redef == NULL) {
   5304 	    xmlFree(ret);
   5305 	    return(NULL);
   5306 	}
   5307 	pctxt->redefCounter = 0;
   5308     }
   5309     WXS_ADD_GLOBAL(pctxt, ret);
   5310     WXS_ADD_PENDING(pctxt, ret);
   5311     return (ret);
   5312 }
   5313 
   5314 /**
   5315  * xmlSchemaAddElement:
   5316  * @ctxt:  a schema parser context
   5317  * @schema:  the schema being built
   5318  * @name:  the type name
   5319  * @namespace:  the type namespace
   5320  *
   5321  * Add an XML schema Element declaration
   5322  * *WARNING* this interface is highly subject to change
   5323  *
   5324  * Returns the new struture or NULL in case of error
   5325  */
   5326 static xmlSchemaElementPtr
   5327 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
   5328                     const xmlChar * name, const xmlChar * nsName,
   5329 		    xmlNodePtr node, int topLevel)
   5330 {
   5331     xmlSchemaElementPtr ret = NULL;
   5332 
   5333     if ((ctxt == NULL) || (name == NULL))
   5334         return (NULL);
   5335 
   5336     ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
   5337     if (ret == NULL) {
   5338         xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
   5339         return (NULL);
   5340     }
   5341     memset(ret, 0, sizeof(xmlSchemaElement));
   5342     ret->type = XML_SCHEMA_TYPE_ELEMENT;
   5343     ret->name = name;
   5344     ret->targetNamespace = nsName;
   5345     ret->node = node;
   5346 
   5347     if (topLevel)
   5348 	WXS_ADD_GLOBAL(ctxt, ret);
   5349     else
   5350 	WXS_ADD_LOCAL(ctxt, ret);
   5351     WXS_ADD_PENDING(ctxt, ret);
   5352     return (ret);
   5353 }
   5354 
   5355 /**
   5356  * xmlSchemaAddType:
   5357  * @ctxt:  a schema parser context
   5358  * @schema:  the schema being built
   5359  * @name:  the item name
   5360  * @namespace:  the namespace
   5361  *
   5362  * Add an XML schema item
   5363  * *WARNING* this interface is highly subject to change
   5364  *
   5365  * Returns the new struture or NULL in case of error
   5366  */
   5367 static xmlSchemaTypePtr
   5368 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5369 		 xmlSchemaTypeType type,
   5370                  const xmlChar * name, const xmlChar * nsName,
   5371 		 xmlNodePtr node, int topLevel)
   5372 {
   5373     xmlSchemaTypePtr ret = NULL;
   5374 
   5375     if ((ctxt == NULL) || (schema == NULL))
   5376         return (NULL);
   5377 
   5378     ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
   5379     if (ret == NULL) {
   5380         xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
   5381         return (NULL);
   5382     }
   5383     memset(ret, 0, sizeof(xmlSchemaType));
   5384     ret->type = type;
   5385     ret->name = name;
   5386     ret->targetNamespace = nsName;
   5387     ret->node = node;
   5388     if (topLevel) {
   5389 	if (ctxt->isRedefine) {
   5390 	    ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
   5391 		ret, name, nsName);
   5392 	    if (ctxt->redef == NULL) {
   5393 		xmlFree(ret);
   5394 		return(NULL);
   5395 	    }
   5396 	    ctxt->redefCounter = 0;
   5397 	}
   5398 	WXS_ADD_GLOBAL(ctxt, ret);
   5399     } else
   5400 	WXS_ADD_LOCAL(ctxt, ret);
   5401     WXS_ADD_PENDING(ctxt, ret);
   5402     return (ret);
   5403 }
   5404 
   5405 static xmlSchemaQNameRefPtr
   5406 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
   5407 		     xmlSchemaTypeType refType,
   5408 		     const xmlChar *refName,
   5409 		     const xmlChar *refNs)
   5410 {
   5411     xmlSchemaQNameRefPtr ret;
   5412 
   5413     ret = (xmlSchemaQNameRefPtr)
   5414 	xmlMalloc(sizeof(xmlSchemaQNameRef));
   5415     if (ret == NULL) {
   5416 	xmlSchemaPErrMemory(pctxt,
   5417 	    "allocating QName reference item", NULL);
   5418 	return (NULL);
   5419     }
   5420     ret->node = NULL;
   5421     ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
   5422     ret->name = refName;
   5423     ret->targetNamespace = refNs;
   5424     ret->item = NULL;
   5425     ret->itemType = refType;
   5426     /*
   5427     * Store the reference item in the schema.
   5428     */
   5429     WXS_ADD_LOCAL(pctxt, ret);
   5430     return (ret);
   5431 }
   5432 
   5433 static xmlSchemaAttributeUseProhibPtr
   5434 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
   5435 {
   5436     xmlSchemaAttributeUseProhibPtr ret;
   5437 
   5438     ret = (xmlSchemaAttributeUseProhibPtr)
   5439 	xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
   5440     if (ret == NULL) {
   5441 	xmlSchemaPErrMemory(pctxt,
   5442 	    "allocating attribute use prohibition", NULL);
   5443 	return (NULL);
   5444     }
   5445     memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
   5446     ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
   5447     WXS_ADD_LOCAL(pctxt, ret);
   5448     return (ret);
   5449 }
   5450 
   5451 
   5452 /**
   5453  * xmlSchemaAddModelGroup:
   5454  * @ctxt:  a schema parser context
   5455  * @schema:  the schema being built
   5456  * @type: the "compositor" type of the model group
   5457  * @node: the node in the schema doc
   5458  *
   5459  * Adds a schema model group
   5460  * *WARNING* this interface is highly subject to change
   5461  *
   5462  * Returns the new struture or NULL in case of error
   5463  */
   5464 static xmlSchemaModelGroupPtr
   5465 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
   5466 		       xmlSchemaPtr schema,
   5467 		       xmlSchemaTypeType type,
   5468 		       xmlNodePtr node)
   5469 {
   5470     xmlSchemaModelGroupPtr ret = NULL;
   5471 
   5472     if ((ctxt == NULL) || (schema == NULL))
   5473         return (NULL);
   5474 
   5475     ret = (xmlSchemaModelGroupPtr)
   5476 	xmlMalloc(sizeof(xmlSchemaModelGroup));
   5477     if (ret == NULL) {
   5478 	xmlSchemaPErrMemory(ctxt, "allocating model group component",
   5479 	    NULL);
   5480 	return (NULL);
   5481     }
   5482     memset(ret, 0, sizeof(xmlSchemaModelGroup));
   5483     ret->type = type;
   5484     ret->node = node;
   5485     WXS_ADD_LOCAL(ctxt, ret);
   5486     if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
   5487 	(type == XML_SCHEMA_TYPE_CHOICE))
   5488 	WXS_ADD_PENDING(ctxt, ret);
   5489     return (ret);
   5490 }
   5491 
   5492 
   5493 /**
   5494  * xmlSchemaAddParticle:
   5495  * @ctxt:  a schema parser context
   5496  * @schema:  the schema being built
   5497  * @node: the corresponding node in the schema doc
   5498  * @min: the minOccurs
   5499  * @max: the maxOccurs
   5500  *
   5501  * Adds an XML schema particle component.
   5502  * *WARNING* this interface is highly subject to change
   5503  *
   5504  * Returns the new struture or NULL in case of error
   5505  */
   5506 static xmlSchemaParticlePtr
   5507 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
   5508 		     xmlNodePtr node, int min, int max)
   5509 {
   5510     xmlSchemaParticlePtr ret = NULL;
   5511     if (ctxt == NULL)
   5512         return (NULL);
   5513 
   5514 #ifdef DEBUG
   5515     fprintf(stderr, "Adding particle component\n");
   5516 #endif
   5517     ret = (xmlSchemaParticlePtr)
   5518 	xmlMalloc(sizeof(xmlSchemaParticle));
   5519     if (ret == NULL) {
   5520 	xmlSchemaPErrMemory(ctxt, "allocating particle component",
   5521 	    NULL);
   5522 	return (NULL);
   5523     }
   5524     ret->type = XML_SCHEMA_TYPE_PARTICLE;
   5525     ret->annot = NULL;
   5526     ret->node = node;
   5527     ret->minOccurs = min;
   5528     ret->maxOccurs = max;
   5529     ret->next = NULL;
   5530     ret->children = NULL;
   5531 
   5532     WXS_ADD_LOCAL(ctxt, ret);
   5533     /*
   5534     * Note that addition to pending components will be done locally
   5535     * to the specific parsing function, since the most particles
   5536     * need not to be fixed up (i.e. the reference to be resolved).
   5537     * REMOVED: WXS_ADD_PENDING(ctxt, ret);
   5538     */
   5539     return (ret);
   5540 }
   5541 
   5542 /**
   5543  * xmlSchemaAddModelGroupDefinition:
   5544  * @ctxt:  a schema validation context
   5545  * @schema:  the schema being built
   5546  * @name:  the group name
   5547  *
   5548  * Add an XML schema Group definition
   5549  *
   5550  * Returns the new struture or NULL in case of error
   5551  */
   5552 static xmlSchemaModelGroupDefPtr
   5553 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
   5554 				 xmlSchemaPtr schema,
   5555 				 const xmlChar *name,
   5556 				 const xmlChar *nsName,
   5557 				 xmlNodePtr node)
   5558 {
   5559     xmlSchemaModelGroupDefPtr ret = NULL;
   5560 
   5561     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
   5562         return (NULL);
   5563 
   5564     ret = (xmlSchemaModelGroupDefPtr)
   5565 	xmlMalloc(sizeof(xmlSchemaModelGroupDef));
   5566     if (ret == NULL) {
   5567         xmlSchemaPErrMemory(ctxt, "adding group", NULL);
   5568         return (NULL);
   5569     }
   5570     memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
   5571     ret->name = name;
   5572     ret->type = XML_SCHEMA_TYPE_GROUP;
   5573     ret->node = node;
   5574     ret->targetNamespace = nsName;
   5575 
   5576     if (ctxt->isRedefine) {
   5577 	ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
   5578 	    ret, name, nsName);
   5579 	if (ctxt->redef == NULL) {
   5580 	    xmlFree(ret);
   5581 	    return(NULL);
   5582 	}
   5583 	ctxt->redefCounter = 0;
   5584     }
   5585     WXS_ADD_GLOBAL(ctxt, ret);
   5586     WXS_ADD_PENDING(ctxt, ret);
   5587     return (ret);
   5588 }
   5589 
   5590 /**
   5591  * xmlSchemaNewWildcardNs:
   5592  * @ctxt:  a schema validation context
   5593  *
   5594  * Creates a new wildcard namespace constraint.
   5595  *
   5596  * Returns the new struture or NULL in case of error
   5597  */
   5598 static xmlSchemaWildcardNsPtr
   5599 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
   5600 {
   5601     xmlSchemaWildcardNsPtr ret;
   5602 
   5603     ret = (xmlSchemaWildcardNsPtr)
   5604 	xmlMalloc(sizeof(xmlSchemaWildcardNs));
   5605     if (ret == NULL) {
   5606 	xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
   5607 	return (NULL);
   5608     }
   5609     ret->value = NULL;
   5610     ret->next = NULL;
   5611     return (ret);
   5612 }
   5613 
   5614 static xmlSchemaIDCPtr
   5615 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5616                   const xmlChar *name, const xmlChar *nsName,
   5617 		  int category, xmlNodePtr node)
   5618 {
   5619     xmlSchemaIDCPtr ret = NULL;
   5620 
   5621     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
   5622         return (NULL);
   5623 
   5624     ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
   5625     if (ret == NULL) {
   5626         xmlSchemaPErrMemory(ctxt,
   5627 	    "allocating an identity-constraint definition", NULL);
   5628         return (NULL);
   5629     }
   5630     memset(ret, 0, sizeof(xmlSchemaIDC));
   5631     /* The target namespace of the parent element declaration. */
   5632     ret->targetNamespace = nsName;
   5633     ret->name = name;
   5634     ret->type = category;
   5635     ret->node = node;
   5636 
   5637     WXS_ADD_GLOBAL(ctxt, ret);
   5638     /*
   5639     * Only keyrefs need to be fixup up.
   5640     */
   5641     if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
   5642 	WXS_ADD_PENDING(ctxt, ret);
   5643     return (ret);
   5644 }
   5645 
   5646 /**
   5647  * xmlSchemaAddWildcard:
   5648  * @ctxt:  a schema validation context
   5649  * @schema: a schema
   5650  *
   5651  * Adds a wildcard.
   5652  * It corresponds to a xsd:anyAttribute and xsd:any.
   5653  *
   5654  * Returns the new struture or NULL in case of error
   5655  */
   5656 static xmlSchemaWildcardPtr
   5657 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5658 		     xmlSchemaTypeType type, xmlNodePtr node)
   5659 {
   5660     xmlSchemaWildcardPtr ret = NULL;
   5661 
   5662     if ((ctxt == NULL) || (schema == NULL))
   5663         return (NULL);
   5664 
   5665     ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
   5666     if (ret == NULL) {
   5667         xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
   5668         return (NULL);
   5669     }
   5670     memset(ret, 0, sizeof(xmlSchemaWildcard));
   5671     ret->type = type;
   5672     ret->node = node;
   5673     WXS_ADD_LOCAL(ctxt, ret);
   5674     return (ret);
   5675 }
   5676 
   5677 static void
   5678 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
   5679 {
   5680     if (group == NULL)
   5681 	return;
   5682     if (group->members != NULL)
   5683 	xmlSchemaItemListFree(group->members);
   5684     xmlFree(group);
   5685 }
   5686 
   5687 static xmlSchemaSubstGroupPtr
   5688 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
   5689 		       xmlSchemaElementPtr head)
   5690 {
   5691     xmlSchemaSubstGroupPtr ret;
   5692 
   5693     /* Init subst group hash. */
   5694     if (WXS_SUBST_GROUPS(pctxt) == NULL) {
   5695 	WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
   5696 	if (WXS_SUBST_GROUPS(pctxt) == NULL)
   5697 	    return(NULL);
   5698     }
   5699     /* Create a new substitution group. */
   5700     ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
   5701     if (ret == NULL) {
   5702 	xmlSchemaPErrMemory(NULL,
   5703 	    "allocating a substitution group container", NULL);
   5704 	return(NULL);
   5705     }
   5706     memset(ret, 0, sizeof(xmlSchemaSubstGroup));
   5707     ret->head = head;
   5708     /* Create list of members. */
   5709     ret->members = xmlSchemaItemListCreate();
   5710     if (ret->members == NULL) {
   5711 	xmlSchemaSubstGroupFree(ret);
   5712 	return(NULL);
   5713     }
   5714     /* Add subst group to hash. */
   5715     if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
   5716 	head->name, head->targetNamespace, ret) != 0) {
   5717 	PERROR_INT("xmlSchemaSubstGroupAdd",
   5718 	    "failed to add a new substitution container");
   5719 	xmlSchemaSubstGroupFree(ret);
   5720 	return(NULL);
   5721     }
   5722     return(ret);
   5723 }
   5724 
   5725 static xmlSchemaSubstGroupPtr
   5726 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
   5727 		       xmlSchemaElementPtr head)
   5728 {
   5729     if (WXS_SUBST_GROUPS(pctxt) == NULL)
   5730 	return(NULL);
   5731     return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
   5732 	head->name, head->targetNamespace));
   5733 
   5734 }
   5735 
   5736 /**
   5737  * xmlSchemaAddElementSubstitutionMember:
   5738  * @pctxt:  a schema parser context
   5739  * @head:  the head of the substitution group
   5740  * @member: the new member of the substitution group
   5741  *
   5742  * Allocate a new annotation structure.
   5743  *
   5744  * Returns the newly allocated structure or NULL in case or error
   5745  */
   5746 static int
   5747 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
   5748 				      xmlSchemaElementPtr head,
   5749 				      xmlSchemaElementPtr member)
   5750 {
   5751     xmlSchemaSubstGroupPtr substGroup = NULL;
   5752 
   5753     if ((pctxt == NULL) || (head == NULL) || (member == NULL))
   5754 	return (-1);
   5755 
   5756     substGroup = xmlSchemaSubstGroupGet(pctxt, head);
   5757     if (substGroup == NULL)
   5758 	substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
   5759     if (substGroup == NULL)
   5760 	return(-1);
   5761     if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
   5762 	return(-1);
   5763     return(0);
   5764 }
   5765 
   5766 /************************************************************************
   5767  *									*
   5768  *		Utilities for parsing					*
   5769  *									*
   5770  ************************************************************************/
   5771 
   5772 /**
   5773  * xmlSchemaPValAttrNodeQNameValue:
   5774  * @ctxt:  a schema parser context
   5775  * @schema: the schema context
   5776  * @ownerDes: the designation of the parent element
   5777  * @ownerItem: the parent as a schema object
   5778  * @value:  the QName value
   5779  * @local: the resulting local part if found, the attribute value otherwise
   5780  * @uri:  the resulting namespace URI if found
   5781  *
   5782  * Extracts the local name and the URI of a QName value and validates it.
   5783  * This one is intended to be used on attribute values that
   5784  * should resolve to schema components.
   5785  *
   5786  * Returns 0, in case the QName is valid, a positive error code
   5787  * if not valid and -1 if an internal error occurs.
   5788  */
   5789 static int
   5790 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
   5791 				       xmlSchemaPtr schema,
   5792 				       xmlSchemaBasicItemPtr ownerItem,
   5793 				       xmlAttrPtr attr,
   5794 				       const xmlChar *value,
   5795 				       const xmlChar **uri,
   5796 				       const xmlChar **local)
   5797 {
   5798     const xmlChar *pref;
   5799     xmlNsPtr ns;
   5800     int len, ret;
   5801 
   5802     *uri = NULL;
   5803     *local = NULL;
   5804     ret = xmlValidateQName(value, 1);
   5805     if (ret > 0) {
   5806 	xmlSchemaPSimpleTypeErr(ctxt,
   5807 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5808 	    ownerItem, (xmlNodePtr) attr,
   5809 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
   5810 	    NULL, value, NULL, NULL, NULL);
   5811 	*local = value;
   5812 	return (ctxt->err);
   5813     } else if (ret < 0)
   5814 	return (-1);
   5815 
   5816     if (!strchr((char *) value, ':')) {
   5817 	ns = xmlSearchNs(attr->doc, attr->parent, NULL);
   5818 	if (ns)
   5819 	    *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
   5820 	else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
   5821 	    /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
   5822 	    * parser context. */
   5823 	    /*
   5824 	    * This one takes care of included schemas with no
   5825 	    * target namespace.
   5826 	    */
   5827 	    *uri = ctxt->targetNamespace;
   5828 	}
   5829 	*local = xmlDictLookup(ctxt->dict, value, -1);
   5830 	return (0);
   5831     }
   5832     /*
   5833     * At this point xmlSplitQName3 has to return a local name.
   5834     */
   5835     *local = xmlSplitQName3(value, &len);
   5836     *local = xmlDictLookup(ctxt->dict, *local, -1);
   5837     pref = xmlDictLookup(ctxt->dict, value, len);
   5838     ns = xmlSearchNs(attr->doc, attr->parent, pref);
   5839     if (ns == NULL) {
   5840 	xmlSchemaPSimpleTypeErr(ctxt,
   5841 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5842 	    ownerItem, (xmlNodePtr) attr,
   5843 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
   5844 	    "The value '%s' of simple type 'xs:QName' has no "
   5845 	    "corresponding namespace declaration in scope", value, NULL);
   5846 	return (ctxt->err);
   5847     } else {
   5848         *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
   5849     }
   5850     return (0);
   5851 }
   5852 
   5853 /**
   5854  * xmlSchemaPValAttrNodeQName:
   5855  * @ctxt:  a schema parser context
   5856  * @schema: the schema context
   5857  * @ownerDes: the designation of the owner element
   5858  * @ownerItem: the owner as a schema object
   5859  * @attr:  the attribute node
   5860  * @local: the resulting local part if found, the attribute value otherwise
   5861  * @uri:  the resulting namespace URI if found
   5862  *
   5863  * Extracts and validates the QName of an attribute value.
   5864  * This one is intended to be used on attribute values that
   5865  * should resolve to schema components.
   5866  *
   5867  * Returns 0, in case the QName is valid, a positive error code
   5868  * if not valid and -1 if an internal error occurs.
   5869  */
   5870 static int
   5871 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
   5872 				       xmlSchemaPtr schema,
   5873 				       xmlSchemaBasicItemPtr ownerItem,
   5874 				       xmlAttrPtr attr,
   5875 				       const xmlChar **uri,
   5876 				       const xmlChar **local)
   5877 {
   5878     const xmlChar *value;
   5879 
   5880     value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   5881     return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
   5882 	ownerItem, attr, value, uri, local));
   5883 }
   5884 
   5885 /**
   5886  * xmlSchemaPValAttrQName:
   5887  * @ctxt:  a schema parser context
   5888  * @schema: the schema context
   5889  * @ownerDes: the designation of the parent element
   5890  * @ownerItem: the owner as a schema object
   5891  * @ownerElem:  the parent node of the attribute
   5892  * @name:  the name of the attribute
   5893  * @local: the resulting local part if found, the attribute value otherwise
   5894  * @uri:  the resulting namespace URI if found
   5895  *
   5896  * Extracts and validates the QName of an attribute value.
   5897  *
   5898  * Returns 0, in case the QName is valid, a positive error code
   5899  * if not valid and -1 if an internal error occurs.
   5900  */
   5901 static int
   5902 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
   5903 				   xmlSchemaPtr schema,
   5904 				   xmlSchemaBasicItemPtr ownerItem,
   5905 				   xmlNodePtr ownerElem,
   5906 				   const char *name,
   5907 				   const xmlChar **uri,
   5908 				   const xmlChar **local)
   5909 {
   5910     xmlAttrPtr attr;
   5911 
   5912     attr = xmlSchemaGetPropNode(ownerElem, name);
   5913     if (attr == NULL) {
   5914 	*local = NULL;
   5915 	*uri = NULL;
   5916 	return (0);
   5917     }
   5918     return (xmlSchemaPValAttrNodeQName(ctxt, schema,
   5919 	ownerItem, attr, uri, local));
   5920 }
   5921 
   5922 /**
   5923  * xmlSchemaPValAttrID:
   5924  * @ctxt:  a schema parser context
   5925  * @schema: the schema context
   5926  * @ownerDes: the designation of the parent element
   5927  * @ownerItem: the owner as a schema object
   5928  * @ownerElem:  the parent node of the attribute
   5929  * @name:  the name of the attribute
   5930  *
   5931  * Extracts and validates the ID of an attribute value.
   5932  *
   5933  * Returns 0, in case the ID is valid, a positive error code
   5934  * if not valid and -1 if an internal error occurs.
   5935  */
   5936 static int
   5937 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
   5938 {
   5939     int ret;
   5940     const xmlChar *value;
   5941 
   5942     if (attr == NULL)
   5943 	return(0);
   5944     value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
   5945     ret = xmlValidateNCName(value, 1);
   5946     if (ret == 0) {
   5947 	/*
   5948 	* NOTE: the IDness might have already be declared in the DTD
   5949 	*/
   5950 	if (attr->atype != XML_ATTRIBUTE_ID) {
   5951 	    xmlIDPtr res;
   5952 	    xmlChar *strip;
   5953 
   5954 	    /*
   5955 	    * TODO: Use xmlSchemaStrip here; it's not exported at this
   5956 	    * moment.
   5957 	    */
   5958 	    strip = xmlSchemaCollapseString(value);
   5959 	    if (strip != NULL) {
   5960 		xmlFree((xmlChar *) value);
   5961 		value = strip;
   5962 	    }
   5963 	    res = xmlAddID(NULL, attr->doc, value, attr);
   5964 	    if (res == NULL) {
   5965 		ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   5966 		xmlSchemaPSimpleTypeErr(ctxt,
   5967 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5968 		    NULL, (xmlNodePtr) attr,
   5969 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
   5970 		    NULL, NULL, "Duplicate value '%s' of simple "
   5971 		    "type 'xs:ID'", value, NULL);
   5972 	    } else
   5973 		attr->atype = XML_ATTRIBUTE_ID;
   5974 	}
   5975     } else if (ret > 0) {
   5976 	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   5977 	xmlSchemaPSimpleTypeErr(ctxt,
   5978 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5979 	    NULL, (xmlNodePtr) attr,
   5980 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
   5981 	    NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
   5982 	    "not a valid 'xs:NCName'",
   5983 	    value, NULL);
   5984     }
   5985     if (value != NULL)
   5986 	xmlFree((xmlChar *)value);
   5987 
   5988     return (ret);
   5989 }
   5990 
   5991 static int
   5992 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
   5993 		    xmlNodePtr ownerElem,
   5994 		    const xmlChar *name)
   5995 {
   5996     xmlAttrPtr attr;
   5997 
   5998     attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
   5999     if (attr == NULL)
   6000 	return(0);
   6001     return(xmlSchemaPValAttrNodeID(ctxt, attr));
   6002 
   6003 }
   6004 
   6005 /**
   6006  * xmlGetMaxOccurs:
   6007  * @ctxt:  a schema validation context
   6008  * @node:  a subtree containing XML Schema informations
   6009  *
   6010  * Get the maxOccurs property
   6011  *
   6012  * Returns the default if not found, or the value
   6013  */
   6014 static int
   6015 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
   6016 		int min, int max, int def, const char *expected)
   6017 {
   6018     const xmlChar *val, *cur;
   6019     int ret = 0;
   6020     xmlAttrPtr attr;
   6021 
   6022     attr = xmlSchemaGetPropNode(node, "maxOccurs");
   6023     if (attr == NULL)
   6024 	return (def);
   6025     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6026 
   6027     if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
   6028 	if (max != UNBOUNDED) {
   6029 	    xmlSchemaPSimpleTypeErr(ctxt,
   6030 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6031 		/* XML_SCHEMAP_INVALID_MINOCCURS, */
   6032 		NULL, (xmlNodePtr) attr, NULL, expected,
   6033 		val, NULL, NULL, NULL);
   6034 	    return (def);
   6035 	} else
   6036 	    return (UNBOUNDED);  /* encoding it with -1 might be another option */
   6037     }
   6038 
   6039     cur = val;
   6040     while (IS_BLANK_CH(*cur))
   6041         cur++;
   6042     if (*cur == 0) {
   6043         xmlSchemaPSimpleTypeErr(ctxt,
   6044 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6045 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6046 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6047 	    val, NULL, NULL, NULL);
   6048 	return (def);
   6049     }
   6050     while ((*cur >= '0') && (*cur <= '9')) {
   6051         ret = ret * 10 + (*cur - '0');
   6052         cur++;
   6053     }
   6054     while (IS_BLANK_CH(*cur))
   6055         cur++;
   6056     /*
   6057     * TODO: Restrict the maximal value to Integer.
   6058     */
   6059     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
   6060 	xmlSchemaPSimpleTypeErr(ctxt,
   6061 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6062 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6063 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6064 	    val, NULL, NULL, NULL);
   6065         return (def);
   6066     }
   6067     return (ret);
   6068 }
   6069 
   6070 /**
   6071  * xmlGetMinOccurs:
   6072  * @ctxt:  a schema validation context
   6073  * @node:  a subtree containing XML Schema informations
   6074  *
   6075  * Get the minOccurs property
   6076  *
   6077  * Returns the default if not found, or the value
   6078  */
   6079 static int
   6080 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
   6081 		int min, int max, int def, const char *expected)
   6082 {
   6083     const xmlChar *val, *cur;
   6084     int ret = 0;
   6085     xmlAttrPtr attr;
   6086 
   6087     attr = xmlSchemaGetPropNode(node, "minOccurs");
   6088     if (attr == NULL)
   6089 	return (def);
   6090     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6091     cur = val;
   6092     while (IS_BLANK_CH(*cur))
   6093         cur++;
   6094     if (*cur == 0) {
   6095         xmlSchemaPSimpleTypeErr(ctxt,
   6096 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6097 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6098 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6099 	    val, NULL, NULL, NULL);
   6100         return (def);
   6101     }
   6102     while ((*cur >= '0') && (*cur <= '9')) {
   6103         ret = ret * 10 + (*cur - '0');
   6104         cur++;
   6105     }
   6106     while (IS_BLANK_CH(*cur))
   6107         cur++;
   6108     /*
   6109     * TODO: Restrict the maximal value to Integer.
   6110     */
   6111     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
   6112 	xmlSchemaPSimpleTypeErr(ctxt,
   6113 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6114 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6115 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6116 	    val, NULL, NULL, NULL);
   6117         return (def);
   6118     }
   6119     return (ret);
   6120 }
   6121 
   6122 /**
   6123  * xmlSchemaPGetBoolNodeValue:
   6124  * @ctxt:  a schema validation context
   6125  * @ownerDes:  owner designation
   6126  * @ownerItem:  the owner as a schema item
   6127  * @node: the node holding the value
   6128  *
   6129  * Converts a boolean string value into 1 or 0.
   6130  *
   6131  * Returns 0 or 1.
   6132  */
   6133 static int
   6134 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
   6135 			   xmlSchemaBasicItemPtr ownerItem,
   6136 			   xmlNodePtr node)
   6137 {
   6138     xmlChar *value = NULL;
   6139     int res = 0;
   6140 
   6141     value = xmlNodeGetContent(node);
   6142     /*
   6143     * 3.2.2.1 Lexical representation
   6144     * An instance of a datatype that is defined as `boolean`
   6145     * can have the following legal literals {true, false, 1, 0}.
   6146     */
   6147     if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
   6148         res = 1;
   6149     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
   6150         res = 0;
   6151     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
   6152 	res = 1;
   6153     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
   6154         res = 0;
   6155     else {
   6156         xmlSchemaPSimpleTypeErr(ctxt,
   6157 	    XML_SCHEMAP_INVALID_BOOLEAN,
   6158 	    ownerItem, node,
   6159 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
   6160 	    NULL, BAD_CAST value,
   6161 	    NULL, NULL, NULL);
   6162     }
   6163     if (value != NULL)
   6164 	xmlFree(value);
   6165     return (res);
   6166 }
   6167 
   6168 /**
   6169  * xmlGetBooleanProp:
   6170  * @ctxt:  a schema validation context
   6171  * @node:  a subtree containing XML Schema informations
   6172  * @name:  the attribute name
   6173  * @def:  the default value
   6174  *
   6175  * Evaluate if a boolean property is set
   6176  *
   6177  * Returns the default if not found, 0 if found to be false,
   6178  * 1 if found to be true
   6179  */
   6180 static int
   6181 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
   6182 		  xmlNodePtr node,
   6183                   const char *name, int def)
   6184 {
   6185     const xmlChar *val;
   6186 
   6187     val = xmlSchemaGetProp(ctxt, node, name);
   6188     if (val == NULL)
   6189         return (def);
   6190     /*
   6191     * 3.2.2.1 Lexical representation
   6192     * An instance of a datatype that is defined as `boolean`
   6193     * can have the following legal literals {true, false, 1, 0}.
   6194     */
   6195     if (xmlStrEqual(val, BAD_CAST "true"))
   6196         def = 1;
   6197     else if (xmlStrEqual(val, BAD_CAST "false"))
   6198         def = 0;
   6199     else if (xmlStrEqual(val, BAD_CAST "1"))
   6200 	def = 1;
   6201     else if (xmlStrEqual(val, BAD_CAST "0"))
   6202         def = 0;
   6203     else {
   6204         xmlSchemaPSimpleTypeErr(ctxt,
   6205 	    XML_SCHEMAP_INVALID_BOOLEAN,
   6206 	    NULL,
   6207 	    (xmlNodePtr) xmlSchemaGetPropNode(node, name),
   6208 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
   6209 	    NULL, val, NULL, NULL, NULL);
   6210     }
   6211     return (def);
   6212 }
   6213 
   6214 /************************************************************************
   6215  *									*
   6216  *		Shema extraction from an Infoset			*
   6217  *									*
   6218  ************************************************************************/
   6219 static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
   6220                                                  ctxt, xmlSchemaPtr schema,
   6221                                                  xmlNodePtr node,
   6222 						 int topLevel);
   6223 static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
   6224                                                   ctxt,
   6225                                                   xmlSchemaPtr schema,
   6226                                                   xmlNodePtr node,
   6227 						  int topLevel);
   6228 static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
   6229                                                   ctxt,
   6230                                                   xmlSchemaPtr schema,
   6231                                                   xmlNodePtr node,
   6232 						  xmlSchemaTypeType parentType);
   6233 static xmlSchemaBasicItemPtr
   6234 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
   6235 			     xmlSchemaPtr schema,
   6236 			     xmlNodePtr node,
   6237 			     xmlSchemaItemListPtr uses,
   6238 			     int parentType);
   6239 static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
   6240                                            xmlSchemaPtr schema,
   6241                                            xmlNodePtr node);
   6242 static xmlSchemaWildcardPtr
   6243 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
   6244                            xmlSchemaPtr schema, xmlNodePtr node);
   6245 
   6246 /**
   6247  * xmlSchemaPValAttrNodeValue:
   6248  *
   6249  * @ctxt:  a schema parser context
   6250  * @ownerDes: the designation of the parent element
   6251  * @ownerItem: the schema object owner if existent
   6252  * @attr:  the schema attribute node being validated
   6253  * @value: the value
   6254  * @type: the built-in type to be validated against
   6255  *
   6256  * Validates a value against the given built-in type.
   6257  * This one is intended to be used internally for validation
   6258  * of schema attribute values during parsing of the schema.
   6259  *
   6260  * Returns 0 if the value is valid, a positive error code
   6261  * number otherwise and -1 in case of an internal or API error.
   6262  */
   6263 static int
   6264 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
   6265 			   xmlSchemaBasicItemPtr ownerItem,
   6266 			   xmlAttrPtr attr,
   6267 			   const xmlChar *value,
   6268 			   xmlSchemaTypePtr type)
   6269 {
   6270 
   6271     int ret = 0;
   6272 
   6273     /*
   6274     * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
   6275     * one is really meant to be used internally, so better not.
   6276     */
   6277     if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
   6278 	return (-1);
   6279     if (type->type != XML_SCHEMA_TYPE_BASIC) {
   6280 	PERROR_INT("xmlSchemaPValAttrNodeValue",
   6281 	    "the given type is not a built-in type");
   6282 	return (-1);
   6283     }
   6284     switch (type->builtInType) {
   6285 	case XML_SCHEMAS_NCNAME:
   6286 	case XML_SCHEMAS_QNAME:
   6287 	case XML_SCHEMAS_ANYURI:
   6288 	case XML_SCHEMAS_TOKEN:
   6289 	case XML_SCHEMAS_LANGUAGE:
   6290 	    ret = xmlSchemaValPredefTypeNode(type, value, NULL,
   6291 		(xmlNodePtr) attr);
   6292 	    break;
   6293 	default: {
   6294 	    PERROR_INT("xmlSchemaPValAttrNodeValue",
   6295 		"validation using the given type is not supported while "
   6296 		"parsing a schema");
   6297 	    return (-1);
   6298 	}
   6299     }
   6300     /*
   6301     * TODO: Should we use the S4S error codes instead?
   6302     */
   6303     if (ret < 0) {
   6304 	PERROR_INT("xmlSchemaPValAttrNodeValue",
   6305 	    "failed to validate a schema attribute value");
   6306 	return (-1);
   6307     } else if (ret > 0) {
   6308 	if (WXS_IS_LIST(type))
   6309 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   6310 	else
   6311 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
   6312 	xmlSchemaPSimpleTypeErr(pctxt,
   6313 	    ret, ownerItem, (xmlNodePtr) attr,
   6314 	    type, NULL, value, NULL, NULL, NULL);
   6315     }
   6316     return (ret);
   6317 }
   6318 
   6319 /**
   6320  * xmlSchemaPValAttrNode:
   6321  *
   6322  * @ctxt:  a schema parser context
   6323  * @ownerDes: the designation of the parent element
   6324  * @ownerItem: the schema object owner if existent
   6325  * @attr:  the schema attribute node being validated
   6326  * @type: the built-in type to be validated against
   6327  * @value: the resulting value if any
   6328  *
   6329  * Extracts and validates a value against the given built-in type.
   6330  * This one is intended to be used internally for validation
   6331  * of schema attribute values during parsing of the schema.
   6332  *
   6333  * Returns 0 if the value is valid, a positive error code
   6334  * number otherwise and -1 in case of an internal or API error.
   6335  */
   6336 static int
   6337 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
   6338 			   xmlSchemaBasicItemPtr ownerItem,
   6339 			   xmlAttrPtr attr,
   6340 			   xmlSchemaTypePtr type,
   6341 			   const xmlChar **value)
   6342 {
   6343     const xmlChar *val;
   6344 
   6345     if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
   6346 	return (-1);
   6347 
   6348     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6349     if (value != NULL)
   6350 	*value = val;
   6351 
   6352     return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
   6353 	val, type));
   6354 }
   6355 
   6356 /**
   6357  * xmlSchemaPValAttr:
   6358  *
   6359  * @ctxt:  a schema parser context
   6360  * @node: the element node of the attribute
   6361  * @ownerDes: the designation of the parent element
   6362  * @ownerItem: the schema object owner if existent
   6363  * @ownerElem: the owner element node
   6364  * @name:  the name of the schema attribute node
   6365  * @type: the built-in type to be validated against
   6366  * @value: the resulting value if any
   6367  *
   6368  * Extracts and validates a value against the given built-in type.
   6369  * This one is intended to be used internally for validation
   6370  * of schema attribute values during parsing of the schema.
   6371  *
   6372  * Returns 0 if the value is valid, a positive error code
   6373  * number otherwise and -1 in case of an internal or API error.
   6374  */
   6375 static int
   6376 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
   6377 		       xmlSchemaBasicItemPtr ownerItem,
   6378 		       xmlNodePtr ownerElem,
   6379 		       const char *name,
   6380 		       xmlSchemaTypePtr type,
   6381 		       const xmlChar **value)
   6382 {
   6383     xmlAttrPtr attr;
   6384 
   6385     if ((ctxt == NULL) || (type == NULL)) {
   6386 	if (value != NULL)
   6387 	    *value = NULL;
   6388 	return (-1);
   6389     }
   6390     if (type->type != XML_SCHEMA_TYPE_BASIC) {
   6391 	if (value != NULL)
   6392 	    *value = NULL;
   6393 	xmlSchemaPErr(ctxt, ownerElem,
   6394 	    XML_SCHEMAP_INTERNAL,
   6395 	    "Internal error: xmlSchemaPValAttr, the given "
   6396 	    "type '%s' is not a built-in type.\n",
   6397 	    type->name, NULL);
   6398 	return (-1);
   6399     }
   6400     attr = xmlSchemaGetPropNode(ownerElem, name);
   6401     if (attr == NULL) {
   6402 	if (value != NULL)
   6403 	    *value = NULL;
   6404 	return (0);
   6405     }
   6406     return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
   6407 	type, value));
   6408 }
   6409 
   6410 static int
   6411 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
   6412 		  xmlSchemaPtr schema ATTRIBUTE_UNUSED,
   6413 		  xmlNodePtr node,
   6414 		  xmlAttrPtr attr,
   6415 		  const xmlChar *namespaceName)
   6416 {
   6417     /* TODO: Pointer comparison instead? */
   6418     if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
   6419 	return (0);
   6420     if (xmlStrEqual(xmlSchemaNs, namespaceName))
   6421 	return (0);
   6422     /*
   6423     * Check if the referenced namespace was <import>ed.
   6424     */
   6425     if (WXS_BUCKET(pctxt)->relations != NULL) {
   6426 	xmlSchemaSchemaRelationPtr rel;
   6427 
   6428 	rel = WXS_BUCKET(pctxt)->relations;
   6429 	do {
   6430 	    if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
   6431 		xmlStrEqual(namespaceName, rel->importNamespace))
   6432 		return (0);
   6433 	    rel = rel->next;
   6434 	} while (rel != NULL);
   6435     }
   6436     /*
   6437     * No matching <import>ed namespace found.
   6438     */
   6439     {
   6440 	xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
   6441 
   6442 	if (namespaceName == NULL)
   6443 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   6444 		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
   6445 		"References from this schema to components in no "
   6446 		"namespace are not allowed, since not indicated by an "
   6447 		"import statement", NULL, NULL);
   6448 	else
   6449 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   6450 		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
   6451 		"References from this schema to components in the "
   6452 		"namespace '%s' are not allowed, since not indicated by an "
   6453 		"import statement", namespaceName, NULL);
   6454     }
   6455     return (XML_SCHEMAP_SRC_RESOLVE);
   6456 }
   6457 
   6458 /**
   6459  * xmlSchemaParseLocalAttributes:
   6460  * @ctxt:  a schema validation context
   6461  * @schema:  the schema being built
   6462  * @node:  a subtree containing XML Schema informations
   6463  * @type:  the hosting type where the attributes will be anchored
   6464  *
   6465  * Parses attribute uses and attribute declarations and
   6466  * attribute group references.
   6467  */
   6468 static int
   6469 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6470                         xmlNodePtr *child, xmlSchemaItemListPtr *list,
   6471 			int parentType, int *hasRefs)
   6472 {
   6473     void *item;
   6474 
   6475     while ((IS_SCHEMA((*child), "attribute")) ||
   6476            (IS_SCHEMA((*child), "attributeGroup"))) {
   6477         if (IS_SCHEMA((*child), "attribute")) {
   6478 	    item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
   6479 		*list, parentType);
   6480         } else {
   6481             item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
   6482 	    if ((item != NULL) && (hasRefs != NULL))
   6483 		*hasRefs = 1;
   6484         }
   6485 	if (item != NULL) {
   6486 	    if (*list == NULL) {
   6487 		/* TODO: Customize grow factor. */
   6488 		*list = xmlSchemaItemListCreate();
   6489 		if (*list == NULL)
   6490 		    return(-1);
   6491 	    }
   6492 	    if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
   6493 		return(-1);
   6494 	}
   6495         *child = (*child)->next;
   6496     }
   6497     return (0);
   6498 }
   6499 
   6500 /**
   6501  * xmlSchemaParseAnnotation:
   6502  * @ctxt:  a schema validation context
   6503  * @schema:  the schema being built
   6504  * @node:  a subtree containing XML Schema informations
   6505  *
   6506  * parse a XML schema Attrribute declaration
   6507  * *WARNING* this interface is highly subject to change
   6508  *
   6509  * Returns -1 in case of error, 0 if the declaration is improper and
   6510  *         1 in case of success.
   6511  */
   6512 static xmlSchemaAnnotPtr
   6513 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
   6514 {
   6515     xmlSchemaAnnotPtr ret;
   6516     xmlNodePtr child = NULL;
   6517     xmlAttrPtr attr;
   6518     int barked = 0;
   6519 
   6520     /*
   6521     * INFO: S4S completed.
   6522     */
   6523     /*
   6524     * id = ID
   6525     * {any attributes with non-schema namespace . . .}>
   6526     * Content: (appinfo | documentation)*
   6527     */
   6528     if ((ctxt == NULL) || (node == NULL))
   6529         return (NULL);
   6530     if (needed)
   6531 	ret = xmlSchemaNewAnnot(ctxt, node);
   6532     else
   6533 	ret = NULL;
   6534     attr = node->properties;
   6535     while (attr != NULL) {
   6536 	if (((attr->ns == NULL) &&
   6537 	    (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
   6538 	    ((attr->ns != NULL) &&
   6539 	    xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
   6540 
   6541 	    xmlSchemaPIllegalAttrErr(ctxt,
   6542 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6543 	}
   6544 	attr = attr->next;
   6545     }
   6546     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   6547     /*
   6548     * And now for the children...
   6549     */
   6550     child = node->children;
   6551     while (child != NULL) {
   6552 	if (IS_SCHEMA(child, "appinfo")) {
   6553 	    /* TODO: make available the content of "appinfo". */
   6554 	    /*
   6555 	    * source = anyURI
   6556 	    * {any attributes with non-schema namespace . . .}>
   6557 	    * Content: ({any})*
   6558 	    */
   6559 	    attr = child->properties;
   6560 	    while (attr != NULL) {
   6561 		if (((attr->ns == NULL) &&
   6562 		     (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
   6563 		     ((attr->ns != NULL) &&
   6564 		      xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
   6565 
   6566 		    xmlSchemaPIllegalAttrErr(ctxt,
   6567 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6568 		}
   6569 		attr = attr->next;
   6570 	    }
   6571 	    xmlSchemaPValAttr(ctxt, NULL, child, "source",
   6572 		xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
   6573 	    child = child->next;
   6574 	} else if (IS_SCHEMA(child, "documentation")) {
   6575 	    /* TODO: make available the content of "documentation". */
   6576 	    /*
   6577 	    * source = anyURI
   6578 	    * {any attributes with non-schema namespace . . .}>
   6579 	    * Content: ({any})*
   6580 	    */
   6581 	    attr = child->properties;
   6582 	    while (attr != NULL) {
   6583 		if (attr->ns == NULL) {
   6584 		    if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
   6585 			xmlSchemaPIllegalAttrErr(ctxt,
   6586 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6587 		    }
   6588 		} else {
   6589 		    if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
   6590 			(xmlStrEqual(attr->name, BAD_CAST "lang") &&
   6591 			(!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
   6592 
   6593 			xmlSchemaPIllegalAttrErr(ctxt,
   6594 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6595 		    }
   6596 		}
   6597 		attr = attr->next;
   6598 	    }
   6599 	    /*
   6600 	    * Attribute "xml:lang".
   6601 	    */
   6602 	    attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
   6603 	    if (attr != NULL)
   6604 		xmlSchemaPValAttrNode(ctxt, NULL, attr,
   6605 		xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
   6606 	    child = child->next;
   6607 	} else {
   6608 	    if (!barked)
   6609 		xmlSchemaPContentErr(ctxt,
   6610 		    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   6611 		    NULL, node, child, NULL, "(appinfo | documentation)*");
   6612 	    barked = 1;
   6613 	    child = child->next;
   6614 	}
   6615     }
   6616 
   6617     return (ret);
   6618 }
   6619 
   6620 /**
   6621  * xmlSchemaParseFacet:
   6622  * @ctxt:  a schema validation context
   6623  * @schema:  the schema being built
   6624  * @node:  a subtree containing XML Schema informations
   6625  *
   6626  * parse a XML schema Facet declaration
   6627  * *WARNING* this interface is highly subject to change
   6628  *
   6629  * Returns the new type structure or NULL in case of error
   6630  */
   6631 static xmlSchemaFacetPtr
   6632 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6633                     xmlNodePtr node)
   6634 {
   6635     xmlSchemaFacetPtr facet;
   6636     xmlNodePtr child = NULL;
   6637     const xmlChar *value;
   6638 
   6639     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   6640         return (NULL);
   6641 
   6642     facet = xmlSchemaNewFacet();
   6643     if (facet == NULL) {
   6644         xmlSchemaPErrMemory(ctxt, "allocating facet", node);
   6645         return (NULL);
   6646     }
   6647     facet->node = node;
   6648     value = xmlSchemaGetProp(ctxt, node, "value");
   6649     if (value == NULL) {
   6650         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
   6651                        "Facet %s has no value\n", node->name, NULL);
   6652         xmlSchemaFreeFacet(facet);
   6653         return (NULL);
   6654     }
   6655     if (IS_SCHEMA(node, "minInclusive")) {
   6656         facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
   6657     } else if (IS_SCHEMA(node, "minExclusive")) {
   6658         facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
   6659     } else if (IS_SCHEMA(node, "maxInclusive")) {
   6660         facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
   6661     } else if (IS_SCHEMA(node, "maxExclusive")) {
   6662         facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
   6663     } else if (IS_SCHEMA(node, "totalDigits")) {
   6664         facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
   6665     } else if (IS_SCHEMA(node, "fractionDigits")) {
   6666         facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
   6667     } else if (IS_SCHEMA(node, "pattern")) {
   6668         facet->type = XML_SCHEMA_FACET_PATTERN;
   6669     } else if (IS_SCHEMA(node, "enumeration")) {
   6670         facet->type = XML_SCHEMA_FACET_ENUMERATION;
   6671     } else if (IS_SCHEMA(node, "whiteSpace")) {
   6672         facet->type = XML_SCHEMA_FACET_WHITESPACE;
   6673     } else if (IS_SCHEMA(node, "length")) {
   6674         facet->type = XML_SCHEMA_FACET_LENGTH;
   6675     } else if (IS_SCHEMA(node, "maxLength")) {
   6676         facet->type = XML_SCHEMA_FACET_MAXLENGTH;
   6677     } else if (IS_SCHEMA(node, "minLength")) {
   6678         facet->type = XML_SCHEMA_FACET_MINLENGTH;
   6679     } else {
   6680         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
   6681                        "Unknown facet type %s\n", node->name, NULL);
   6682         xmlSchemaFreeFacet(facet);
   6683         return (NULL);
   6684     }
   6685     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   6686     facet->value = value;
   6687     if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
   6688 	(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
   6689 	const xmlChar *fixed;
   6690 
   6691 	fixed = xmlSchemaGetProp(ctxt, node, "fixed");
   6692 	if (fixed != NULL) {
   6693 	    if (xmlStrEqual(fixed, BAD_CAST "true"))
   6694 		facet->fixed = 1;
   6695 	}
   6696     }
   6697     child = node->children;
   6698 
   6699     if (IS_SCHEMA(child, "annotation")) {
   6700         facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   6701         child = child->next;
   6702     }
   6703     if (child != NULL) {
   6704         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
   6705                        "Facet %s has unexpected child content\n",
   6706                        node->name, NULL);
   6707     }
   6708     return (facet);
   6709 }
   6710 
   6711 /**
   6712  * xmlSchemaParseWildcardNs:
   6713  * @ctxt:  a schema parser context
   6714  * @wildc:  the wildcard, already created
   6715  * @node:  a subtree containing XML Schema informations
   6716  *
   6717  * Parses the attribute "processContents" and "namespace"
   6718  * of a xsd:anyAttribute and xsd:any.
   6719  * *WARNING* this interface is highly subject to change
   6720  *
   6721  * Returns 0 if everything goes fine, a positive error code
   6722  * if something is not valid and -1 if an internal error occurs.
   6723  */
   6724 static int
   6725 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
   6726 			 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
   6727 			 xmlSchemaWildcardPtr wildc,
   6728 			 xmlNodePtr node)
   6729 {
   6730     const xmlChar *pc, *ns, *dictnsItem;
   6731     int ret = 0;
   6732     xmlChar *nsItem;
   6733     xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
   6734     xmlAttrPtr attr;
   6735 
   6736     pc = xmlSchemaGetProp(ctxt, node, "processContents");
   6737     if ((pc == NULL)
   6738         || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
   6739         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
   6740     } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
   6741         wildc->processContents = XML_SCHEMAS_ANY_SKIP;
   6742     } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
   6743         wildc->processContents = XML_SCHEMAS_ANY_LAX;
   6744     } else {
   6745         xmlSchemaPSimpleTypeErr(ctxt,
   6746 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6747 	    NULL, node,
   6748 	    NULL, "(strict | skip | lax)", pc,
   6749 	    NULL, NULL, NULL);
   6750         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
   6751 	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   6752     }
   6753     /*
   6754      * Build the namespace constraints.
   6755      */
   6756     attr = xmlSchemaGetPropNode(node, "namespace");
   6757     ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6758     if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
   6759 	wildc->any = 1;
   6760     else if (xmlStrEqual(ns, BAD_CAST "##other")) {
   6761 	wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   6762 	if (wildc->negNsSet == NULL) {
   6763 	    return (-1);
   6764 	}
   6765 	wildc->negNsSet->value = ctxt->targetNamespace;
   6766     } else {
   6767 	const xmlChar *end, *cur;
   6768 
   6769 	cur = ns;
   6770 	do {
   6771 	    while (IS_BLANK_CH(*cur))
   6772 		cur++;
   6773 	    end = cur;
   6774 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   6775 		end++;
   6776 	    if (end == cur)
   6777 		break;
   6778 	    nsItem = xmlStrndup(cur, end - cur);
   6779 	    if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
   6780 		    (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
   6781 		xmlSchemaPSimpleTypeErr(ctxt,
   6782 		    XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
   6783 		    NULL, (xmlNodePtr) attr,
   6784 		    NULL,
   6785 		    "((##any | ##other) | List of (xs:anyURI | "
   6786 		    "(##targetNamespace | ##local)))",
   6787 		    nsItem, NULL, NULL, NULL);
   6788 		ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
   6789 	    } else {
   6790 		if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
   6791 		    dictnsItem = ctxt->targetNamespace;
   6792 		} else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
   6793 		    dictnsItem = NULL;
   6794 		} else {
   6795 		    /*
   6796 		    * Validate the item (anyURI).
   6797 		    */
   6798 		    xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
   6799 			nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
   6800 		    dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
   6801 		}
   6802 		/*
   6803 		* Avoid dublicate namespaces.
   6804 		*/
   6805 		tmp = wildc->nsSet;
   6806 		while (tmp != NULL) {
   6807 		    if (dictnsItem == tmp->value)
   6808 			break;
   6809 		    tmp = tmp->next;
   6810 		}
   6811 		if (tmp == NULL) {
   6812 		    tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
   6813 		    if (tmp == NULL) {
   6814 			xmlFree(nsItem);
   6815 			return (-1);
   6816 		    }
   6817 		    tmp->value = dictnsItem;
   6818 		    tmp->next = NULL;
   6819 		    if (wildc->nsSet == NULL)
   6820 			wildc->nsSet = tmp;
   6821 		    else if (lastNs != NULL)
   6822 			lastNs->next = tmp;
   6823 		    lastNs = tmp;
   6824 		}
   6825 
   6826 	    }
   6827 	    xmlFree(nsItem);
   6828 	    cur = end;
   6829 	} while (*cur != 0);
   6830     }
   6831     return (ret);
   6832 }
   6833 
   6834 static int
   6835 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
   6836 				 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
   6837 				 xmlNodePtr node,
   6838 				 int minOccurs,
   6839 				 int maxOccurs) {
   6840 
   6841     if ((maxOccurs == 0) && ( minOccurs == 0))
   6842 	return (0);
   6843     if (maxOccurs != UNBOUNDED) {
   6844 	/*
   6845 	* TODO: Maybe we should better not create the particle,
   6846 	* if min/max is invalid, since it could confuse the build of the
   6847 	* content model.
   6848 	*/
   6849 	/*
   6850 	* 3.9.6 Schema Component Constraint: Particle Correct
   6851 	*
   6852 	*/
   6853 	if (maxOccurs < 1) {
   6854 	    /*
   6855 	    * 2.2 {max occurs} must be greater than or equal to 1.
   6856 	    */
   6857 	    xmlSchemaPCustomAttrErr(ctxt,
   6858 		XML_SCHEMAP_P_PROPS_CORRECT_2_2,
   6859 		NULL, NULL,
   6860 		xmlSchemaGetPropNode(node, "maxOccurs"),
   6861 		"The value must be greater than or equal to 1");
   6862 	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
   6863 	} else if (minOccurs > maxOccurs) {
   6864 	    /*
   6865 	    * 2.1 {min occurs} must not be greater than {max occurs}.
   6866 	    */
   6867 	    xmlSchemaPCustomAttrErr(ctxt,
   6868 		XML_SCHEMAP_P_PROPS_CORRECT_2_1,
   6869 		NULL, NULL,
   6870 		xmlSchemaGetPropNode(node, "minOccurs"),
   6871 		"The value must not be greater than the value of 'maxOccurs'");
   6872 	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
   6873 	}
   6874     }
   6875     return (0);
   6876 }
   6877 
   6878 /**
   6879  * xmlSchemaParseAny:
   6880  * @ctxt:  a schema validation context
   6881  * @schema:  the schema being built
   6882  * @node:  a subtree containing XML Schema informations
   6883  *
   6884  * Parsea a XML schema <any> element. A particle and wildcard
   6885  * will be created (except if minOccurs==maxOccurs==0, in this case
   6886  * nothing will be created).
   6887  * *WARNING* this interface is highly subject to change
   6888  *
   6889  * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
   6890  */
   6891 static xmlSchemaParticlePtr
   6892 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6893                   xmlNodePtr node)
   6894 {
   6895     xmlSchemaParticlePtr particle;
   6896     xmlNodePtr child = NULL;
   6897     xmlSchemaWildcardPtr wild;
   6898     int min, max;
   6899     xmlAttrPtr attr;
   6900     xmlSchemaAnnotPtr annot = NULL;
   6901 
   6902     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   6903         return (NULL);
   6904     /*
   6905     * Check for illegal attributes.
   6906     */
   6907     attr = node->properties;
   6908     while (attr != NULL) {
   6909 	if (attr->ns == NULL) {
   6910 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   6911 		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
   6912 		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
   6913 	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
   6914 		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
   6915 		xmlSchemaPIllegalAttrErr(ctxt,
   6916 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6917 	    }
   6918 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   6919 	    xmlSchemaPIllegalAttrErr(ctxt,
   6920 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6921 	}
   6922 	attr = attr->next;
   6923     }
   6924     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   6925     /*
   6926     * minOccurs/maxOccurs.
   6927     */
   6928     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
   6929 	"(xs:nonNegativeInteger | unbounded)");
   6930     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
   6931 	"xs:nonNegativeInteger");
   6932     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
   6933     /*
   6934     * Create & parse the wildcard.
   6935     */
   6936     wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
   6937     if (wild == NULL)
   6938 	return (NULL);
   6939     xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
   6940     /*
   6941     * And now for the children...
   6942     */
   6943     child = node->children;
   6944     if (IS_SCHEMA(child, "annotation")) {
   6945         annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   6946         child = child->next;
   6947     }
   6948     if (child != NULL) {
   6949 	xmlSchemaPContentErr(ctxt,
   6950 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   6951 	    NULL, node, child,
   6952 	    NULL, "(annotation?)");
   6953     }
   6954     /*
   6955     * No component if minOccurs==maxOccurs==0.
   6956     */
   6957     if ((min == 0) && (max == 0)) {
   6958 	/* Don't free the wildcard, since it's already on the list. */
   6959 	return (NULL);
   6960     }
   6961     /*
   6962     * Create the particle.
   6963     */
   6964     particle = xmlSchemaAddParticle(ctxt, node, min, max);
   6965     if (particle == NULL)
   6966         return (NULL);
   6967     particle->annot = annot;
   6968     particle->children = (xmlSchemaTreeItemPtr) wild;
   6969 
   6970     return (particle);
   6971 }
   6972 
   6973 /**
   6974  * xmlSchemaParseNotation:
   6975  * @ctxt:  a schema validation context
   6976  * @schema:  the schema being built
   6977  * @node:  a subtree containing XML Schema informations
   6978  *
   6979  * parse a XML schema Notation declaration
   6980  *
   6981  * Returns the new structure or NULL in case of error
   6982  */
   6983 static xmlSchemaNotationPtr
   6984 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6985                        xmlNodePtr node)
   6986 {
   6987     const xmlChar *name;
   6988     xmlSchemaNotationPtr ret;
   6989     xmlNodePtr child = NULL;
   6990 
   6991     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   6992         return (NULL);
   6993     name = xmlSchemaGetProp(ctxt, node, "name");
   6994     if (name == NULL) {
   6995         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
   6996                        "Notation has no name\n", NULL, NULL);
   6997         return (NULL);
   6998     }
   6999     ret = xmlSchemaAddNotation(ctxt, schema, name,
   7000 	ctxt->targetNamespace, node);
   7001     if (ret == NULL)
   7002         return (NULL);
   7003     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   7004 
   7005     child = node->children;
   7006     if (IS_SCHEMA(child, "annotation")) {
   7007         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   7008         child = child->next;
   7009     }
   7010     if (child != NULL) {
   7011 	xmlSchemaPContentErr(ctxt,
   7012 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7013 	    NULL, node, child,
   7014 	    NULL, "(annotation?)");
   7015     }
   7016 
   7017     return (ret);
   7018 }
   7019 
   7020 /**
   7021  * xmlSchemaParseAnyAttribute:
   7022  * @ctxt:  a schema validation context
   7023  * @schema:  the schema being built
   7024  * @node:  a subtree containing XML Schema informations
   7025  *
   7026  * parse a XML schema AnyAttrribute declaration
   7027  * *WARNING* this interface is highly subject to change
   7028  *
   7029  * Returns a wildcard or NULL.
   7030  */
   7031 static xmlSchemaWildcardPtr
   7032 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
   7033                            xmlSchemaPtr schema, xmlNodePtr node)
   7034 {
   7035     xmlSchemaWildcardPtr ret;
   7036     xmlNodePtr child = NULL;
   7037     xmlAttrPtr attr;
   7038 
   7039     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   7040         return (NULL);
   7041 
   7042     ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
   7043 	node);
   7044     if (ret == NULL) {
   7045         return (NULL);
   7046     }
   7047     /*
   7048     * Check for illegal attributes.
   7049     */
   7050     attr = node->properties;
   7051     while (attr != NULL) {
   7052 	if (attr->ns == NULL) {
   7053 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   7054 	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
   7055 		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
   7056 		xmlSchemaPIllegalAttrErr(ctxt,
   7057 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7058 	    }
   7059 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7060 	    xmlSchemaPIllegalAttrErr(ctxt,
   7061 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7062 	}
   7063 	attr = attr->next;
   7064     }
   7065     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   7066     /*
   7067     * Parse the namespace list.
   7068     */
   7069     if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
   7070 	return (NULL);
   7071     /*
   7072     * And now for the children...
   7073     */
   7074     child = node->children;
   7075     if (IS_SCHEMA(child, "annotation")) {
   7076         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   7077         child = child->next;
   7078     }
   7079     if (child != NULL) {
   7080 	xmlSchemaPContentErr(ctxt,
   7081 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7082 	    NULL, node, child,
   7083 	    NULL, "(annotation?)");
   7084     }
   7085 
   7086     return (ret);
   7087 }
   7088 
   7089 
   7090 /**
   7091  * xmlSchemaParseAttribute:
   7092  * @ctxt:  a schema validation context
   7093  * @schema:  the schema being built
   7094  * @node:  a subtree containing XML Schema informations
   7095  *
   7096  * parse a XML schema Attrribute declaration
   7097  * *WARNING* this interface is highly subject to change
   7098  *
   7099  * Returns the attribute declaration.
   7100  */
   7101 static xmlSchemaBasicItemPtr
   7102 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
   7103 			     xmlSchemaPtr schema,
   7104 			     xmlNodePtr node,
   7105 			     xmlSchemaItemListPtr uses,
   7106 			     int parentType)
   7107 {
   7108     const xmlChar *attrValue, *name = NULL, *ns = NULL;
   7109     xmlSchemaAttributeUsePtr use = NULL;
   7110     xmlNodePtr child = NULL;
   7111     xmlAttrPtr attr;
   7112     const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
   7113     int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
   7114     int	nberrors, hasForm = 0, defValueType = 0;
   7115 
   7116 #define WXS_ATTR_DEF_VAL_DEFAULT 1
   7117 #define WXS_ATTR_DEF_VAL_FIXED 2
   7118 
   7119     /*
   7120      * 3.2.3 Constraints on XML Representations of Attribute Declarations
   7121      */
   7122 
   7123     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7124         return (NULL);
   7125     attr = xmlSchemaGetPropNode(node, "ref");
   7126     if (attr != NULL) {
   7127 	if (xmlSchemaPValAttrNodeQName(pctxt, schema,
   7128 	    NULL, attr, &tmpNs, &tmpName) != 0) {
   7129 	    return (NULL);
   7130 	}
   7131 	if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
   7132 	    return(NULL);
   7133 	isRef = 1;
   7134     }
   7135     nberrors = pctxt->nberrors;
   7136     /*
   7137     * Check for illegal attributes.
   7138     */
   7139     attr = node->properties;
   7140     while (attr != NULL) {
   7141 	if (attr->ns == NULL) {
   7142 	    if (isRef) {
   7143 		if (xmlStrEqual(attr->name, BAD_CAST "id")) {
   7144 		    xmlSchemaPValAttrNodeID(pctxt, attr);
   7145 		    goto attr_next;
   7146 		} else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
   7147 		    goto attr_next;
   7148 		}
   7149 	    } else {
   7150 		if (xmlStrEqual(attr->name, BAD_CAST "name")) {
   7151 		    goto attr_next;
   7152 		} else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
   7153 		    xmlSchemaPValAttrNodeID(pctxt, attr);
   7154 		    goto attr_next;
   7155 		} else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
   7156 		    xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
   7157 			attr, &tmpNs, &tmpName);
   7158 		    goto attr_next;
   7159 		} else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
   7160 		    /*
   7161 		    * Evaluate the target namespace
   7162 		    */
   7163 		    hasForm = 1;
   7164 		    attrValue = xmlSchemaGetNodeContent(pctxt,
   7165 			(xmlNodePtr) attr);
   7166 		    if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
   7167 			ns = pctxt->targetNamespace;
   7168 		    } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
   7169 		    {
   7170 			xmlSchemaPSimpleTypeErr(pctxt,
   7171 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   7172 			    NULL, (xmlNodePtr) attr,
   7173 			    NULL, "(qualified | unqualified)",
   7174 			    attrValue, NULL, NULL, NULL);
   7175 		    }
   7176 		    goto attr_next;
   7177 		}
   7178 	    }
   7179 	    if (xmlStrEqual(attr->name, BAD_CAST "use")) {
   7180 
   7181 		attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7182 		/* TODO: Maybe we need to normalize the value beforehand. */
   7183 		if (xmlStrEqual(attrValue, BAD_CAST "optional"))
   7184 		    occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
   7185 		else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
   7186 		    occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
   7187 		else if (xmlStrEqual(attrValue, BAD_CAST "required"))
   7188 		    occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
   7189 		else {
   7190 		    xmlSchemaPSimpleTypeErr(pctxt,
   7191 			XML_SCHEMAP_INVALID_ATTR_USE,
   7192 			NULL, (xmlNodePtr) attr,
   7193 			NULL, "(optional | prohibited | required)",
   7194 			attrValue, NULL, NULL, NULL);
   7195 		}
   7196 		goto attr_next;
   7197 	    } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
   7198 		/*
   7199 		* 3.2.3 : 1
   7200 		* default and fixed must not both be present.
   7201 		*/
   7202 		if (defValue) {
   7203 		    xmlSchemaPMutualExclAttrErr(pctxt,
   7204 			XML_SCHEMAP_SRC_ATTRIBUTE_1,
   7205 			NULL, attr, "default", "fixed");
   7206 		} else {
   7207 		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7208 		    defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
   7209 		}
   7210 		goto attr_next;
   7211 	    } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
   7212 		/*
   7213 		* 3.2.3 : 1
   7214 		* default and fixed must not both be present.
   7215 		*/
   7216 		if (defValue) {
   7217 		    xmlSchemaPMutualExclAttrErr(pctxt,
   7218 			XML_SCHEMAP_SRC_ATTRIBUTE_1,
   7219 			NULL, attr, "default", "fixed");
   7220 		} else {
   7221 		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7222 		    defValueType = WXS_ATTR_DEF_VAL_FIXED;
   7223 		}
   7224 		goto attr_next;
   7225 	    }
   7226 	} else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
   7227 	    goto attr_next;
   7228 
   7229 	xmlSchemaPIllegalAttrErr(pctxt,
   7230 	    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7231 
   7232 attr_next:
   7233 	attr = attr->next;
   7234     }
   7235     /*
   7236     * 3.2.3 : 2
   7237     * If default and use are both present, use must have
   7238     * the actual value optional.
   7239     */
   7240     if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
   7241 	(occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
   7242 	xmlSchemaPSimpleTypeErr(pctxt,
   7243 	    XML_SCHEMAP_SRC_ATTRIBUTE_2,
   7244 	    NULL, node, NULL,
   7245 	    "(optional | prohibited | required)", NULL,
   7246 	    "The value of the attribute 'use' must be 'optional' "
   7247 	    "if the attribute 'default' is present",
   7248 	    NULL, NULL);
   7249     }
   7250     /*
   7251     * We want correct attributes.
   7252     */
   7253     if (nberrors != pctxt->nberrors)
   7254 	return(NULL);
   7255     if (! isRef) {
   7256 	xmlSchemaAttributePtr attrDecl;
   7257 
   7258 	/* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
   7259 	if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
   7260 	    ns = pctxt->targetNamespace;
   7261 	/*
   7262 	* 3.2.6 Schema Component Constraint: xsi: Not Allowed
   7263 	* TODO: Move this to the component layer.
   7264 	*/
   7265 	if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
   7266 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   7267 		XML_SCHEMAP_NO_XSI,
   7268 		node, NULL,
   7269 		"The target namespace must not match '%s'",
   7270 		xmlSchemaInstanceNs, NULL);
   7271 	}
   7272 	attr = xmlSchemaGetPropNode(node, "name");
   7273 	if (attr == NULL) {
   7274 	    xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
   7275 		NULL, node, "name", NULL);
   7276 	    return (NULL);
   7277 	}
   7278 	if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
   7279 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   7280 	    return (NULL);
   7281 	}
   7282 	/*
   7283 	* 3.2.6 Schema Component Constraint: xmlns Not Allowed
   7284 	* TODO: Move this to the component layer.
   7285 	*/
   7286 	if (xmlStrEqual(name, BAD_CAST "xmlns")) {
   7287 	    xmlSchemaPSimpleTypeErr(pctxt,
   7288 		XML_SCHEMAP_NO_XMLNS,
   7289 		NULL, (xmlNodePtr) attr,
   7290 		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
   7291 		"The value of the attribute must not match 'xmlns'",
   7292 		NULL, NULL);
   7293 	    return (NULL);
   7294 	}
   7295 	if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
   7296 	    goto check_children;
   7297 	/*
   7298 	* Create the attribute use component.
   7299 	*/
   7300 	use = xmlSchemaAddAttributeUse(pctxt, node);
   7301 	if (use == NULL)
   7302 	    return(NULL);
   7303 	use->occurs = occurs;
   7304 	/*
   7305 	* Create the attribute declaration.
   7306 	*/
   7307 	attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
   7308 	if (attrDecl == NULL)
   7309 	    return (NULL);
   7310 	if (tmpName != NULL) {
   7311 	    attrDecl->typeName = tmpName;
   7312 	    attrDecl->typeNs = tmpNs;
   7313 	}
   7314 	use->attrDecl = attrDecl;
   7315 	/*
   7316 	* Value constraint.
   7317 	*/
   7318 	if (defValue != NULL) {
   7319 	    attrDecl->defValue = defValue;
   7320 	    if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
   7321 		attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
   7322 	}
   7323     } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
   7324 	xmlSchemaQNameRefPtr ref;
   7325 
   7326 	/*
   7327 	* Create the attribute use component.
   7328 	*/
   7329 	use = xmlSchemaAddAttributeUse(pctxt, node);
   7330 	if (use == NULL)
   7331 	    return(NULL);
   7332 	/*
   7333 	* We need to resolve the reference at later stage.
   7334 	*/
   7335 	WXS_ADD_PENDING(pctxt, use);
   7336 	use->occurs = occurs;
   7337 	/*
   7338 	* Create a QName reference to the attribute declaration.
   7339 	*/
   7340 	ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
   7341 	    tmpName, tmpNs);
   7342 	if (ref == NULL)
   7343 	    return(NULL);
   7344 	/*
   7345 	* Assign the reference. This will be substituted for the
   7346 	* referenced attribute declaration when the QName is resolved.
   7347 	*/
   7348 	use->attrDecl = WXS_ATTR_CAST ref;
   7349 	/*
   7350 	* Value constraint.
   7351 	*/
   7352 	if (defValue != NULL)
   7353 	    use->defValue = defValue;
   7354 	    if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
   7355 		use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
   7356     }
   7357 
   7358 check_children:
   7359     /*
   7360     * And now for the children...
   7361     */
   7362     child = node->children;
   7363     if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
   7364 	xmlSchemaAttributeUseProhibPtr prohib;
   7365 
   7366 	if (IS_SCHEMA(child, "annotation")) {
   7367 	    xmlSchemaParseAnnotation(pctxt, child, 0);
   7368 	    child = child->next;
   7369 	}
   7370 	if (child != NULL) {
   7371 	    xmlSchemaPContentErr(pctxt,
   7372 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7373 		NULL, node, child, NULL,
   7374 		"(annotation?)");
   7375 	}
   7376 	/*
   7377 	* Check for pointlessness of attribute prohibitions.
   7378 	*/
   7379 	if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
   7380 	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   7381 		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   7382 		node, NULL,
   7383 		"Skipping attribute use prohibition, since it is "
   7384 		"pointless inside an <attributeGroup>",
   7385 		NULL, NULL, NULL);
   7386 	    return(NULL);
   7387 	} else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
   7388 	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   7389 		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   7390 		node, NULL,
   7391 		"Skipping attribute use prohibition, since it is "
   7392 		"pointless when extending a type",
   7393 		NULL, NULL, NULL);
   7394 	    return(NULL);
   7395 	}
   7396 	if (! isRef) {
   7397 	    tmpName = name;
   7398 	    tmpNs = ns;
   7399 	}
   7400 	/*
   7401 	* Check for duplicate attribute prohibitions.
   7402 	*/
   7403 	if (uses) {
   7404 	    int i;
   7405 
   7406 	    for (i = 0; i < uses->nbItems; i++) {
   7407 		use = uses->items[i];
   7408 		if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
   7409 		    (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
   7410 		    (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
   7411 		{
   7412 		    xmlChar *str = NULL;
   7413 
   7414 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   7415 			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   7416 			node, NULL,
   7417 			"Skipping duplicate attribute use prohibition '%s'",
   7418 			xmlSchemaFormatQName(&str, tmpNs, tmpName),
   7419 			NULL, NULL);
   7420 		    FREE_AND_NULL(str)
   7421 		    return(NULL);
   7422 		}
   7423 	    }
   7424 	}
   7425 	/*
   7426 	* Create the attribute prohibition helper component.
   7427 	*/
   7428 	prohib = xmlSchemaAddAttributeUseProhib(pctxt);
   7429 	if (prohib == NULL)
   7430 	    return(NULL);
   7431 	prohib->node = node;
   7432 	prohib->name = tmpName;
   7433 	prohib->targetNamespace = tmpNs;
   7434 	if (isRef) {
   7435 	    /*
   7436 	    * We need at least to resolve to the attribute declaration.
   7437 	    */
   7438 	    WXS_ADD_PENDING(pctxt, prohib);
   7439 	}
   7440 	return(WXS_BASIC_CAST prohib);
   7441     } else {
   7442 	if (IS_SCHEMA(child, "annotation")) {
   7443 	    /*
   7444 	    * TODO: Should this go into the attr decl?
   7445 	    */
   7446 	    use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
   7447 	    child = child->next;
   7448 	}
   7449 	if (isRef) {
   7450 	    if (child != NULL) {
   7451 		if (IS_SCHEMA(child, "simpleType"))
   7452 		    /*
   7453 		    * 3.2.3 : 3.2
   7454 		    * If ref is present, then all of <simpleType>,
   7455 		    * form and type must be absent.
   7456 		    */
   7457 		    xmlSchemaPContentErr(pctxt,
   7458 			XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
   7459 			NULL, node, child, NULL,
   7460 			"(annotation?)");
   7461 		else
   7462 		    xmlSchemaPContentErr(pctxt,
   7463 			XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7464 			NULL, node, child, NULL,
   7465 			"(annotation?)");
   7466 	    }
   7467 	} else {
   7468 	    if (IS_SCHEMA(child, "simpleType")) {
   7469 		if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
   7470 		    /*
   7471 		    * 3.2.3 : 4
   7472 		    * type and <simpleType> must not both be present.
   7473 		    */
   7474 		    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
   7475 			NULL, node, child,
   7476 			"The attribute 'type' and the <simpleType> child "
   7477 			"are mutually exclusive", NULL);
   7478 		} else
   7479 		    WXS_ATTRUSE_TYPEDEF(use) =
   7480 			xmlSchemaParseSimpleType(pctxt, schema, child, 0);
   7481 		child = child->next;
   7482 	    }
   7483 	    if (child != NULL)
   7484 		xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7485 		NULL, node, child, NULL,
   7486 		"(annotation?, simpleType?)");
   7487 	}
   7488     }
   7489     return (WXS_BASIC_CAST use);
   7490 }
   7491 
   7492 
   7493 static xmlSchemaAttributePtr
   7494 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
   7495 			      xmlSchemaPtr schema,
   7496 			      xmlNodePtr node)
   7497 {
   7498     const xmlChar *attrValue;
   7499     xmlSchemaAttributePtr ret;
   7500     xmlNodePtr child = NULL;
   7501     xmlAttrPtr attr;
   7502 
   7503     /*
   7504      * Note that the w3c spec assumes the schema to be validated with schema
   7505      * for schemas beforehand.
   7506      *
   7507      * 3.2.3 Constraints on XML Representations of Attribute Declarations
   7508      */
   7509     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7510         return (NULL);
   7511     /*
   7512     * 3.2.3 : 3.1
   7513     * One of ref or name must be present, but not both
   7514     */
   7515     attr = xmlSchemaGetPropNode(node, "name");
   7516     if (attr == NULL) {
   7517 	xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
   7518 	    NULL, node, "name", NULL);
   7519 	return (NULL);
   7520     }
   7521     if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
   7522 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
   7523 	return (NULL);
   7524     }
   7525     /*
   7526     * 3.2.6 Schema Component Constraint: xmlns Not Allowed
   7527     * TODO: Move this to the component layer.
   7528     */
   7529     if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
   7530 	xmlSchemaPSimpleTypeErr(pctxt,
   7531 	    XML_SCHEMAP_NO_XMLNS,
   7532 	    NULL, (xmlNodePtr) attr,
   7533 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
   7534 	    "The value of the attribute must not match 'xmlns'",
   7535 	    NULL, NULL);
   7536 	return (NULL);
   7537     }
   7538     /*
   7539     * 3.2.6 Schema Component Constraint: xsi: Not Allowed
   7540     * TODO: Move this to the component layer.
   7541     *       Or better leave it here and add it to the component layer
   7542     *       if we have a schema construction API.
   7543     */
   7544     if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
   7545 	xmlSchemaCustomErr(ACTXT_CAST pctxt,
   7546 	    XML_SCHEMAP_NO_XSI, node, NULL,
   7547 	    "The target namespace must not match '%s'",
   7548 	    xmlSchemaInstanceNs, NULL);
   7549     }
   7550 
   7551     ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
   7552 	pctxt->targetNamespace, node, 1);
   7553     if (ret == NULL)
   7554 	return (NULL);
   7555     ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
   7556 
   7557     /*
   7558     * Check for illegal attributes.
   7559     */
   7560     attr = node->properties;
   7561     while (attr != NULL) {
   7562 	if (attr->ns == NULL) {
   7563 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   7564 		(!xmlStrEqual(attr->name, BAD_CAST "default")) &&
   7565 		(!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
   7566 		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   7567 		(!xmlStrEqual(attr->name, BAD_CAST "type")))
   7568 	    {
   7569 		xmlSchemaPIllegalAttrErr(pctxt,
   7570 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7571 	    }
   7572 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7573 	    xmlSchemaPIllegalAttrErr(pctxt,
   7574 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7575 	}
   7576 	attr = attr->next;
   7577     }
   7578     xmlSchemaPValAttrQName(pctxt, schema, NULL,
   7579 	node, "type", &ret->typeNs, &ret->typeName);
   7580 
   7581     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   7582     /*
   7583     * Attribute "fixed".
   7584     */
   7585     ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
   7586     if (ret->defValue != NULL)
   7587 	ret->flags |= XML_SCHEMAS_ATTR_FIXED;
   7588     /*
   7589     * Attribute "default".
   7590     */
   7591     attr = xmlSchemaGetPropNode(node, "default");
   7592     if (attr != NULL) {
   7593 	/*
   7594 	* 3.2.3 : 1
   7595 	* default and fixed must not both be present.
   7596 	*/
   7597 	if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
   7598 	    xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
   7599 		WXS_BASIC_CAST ret, attr, "default", "fixed");
   7600 	} else
   7601 	    ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7602     }
   7603     /*
   7604     * And now for the children...
   7605     */
   7606     child = node->children;
   7607     if (IS_SCHEMA(child, "annotation")) {
   7608         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
   7609         child = child->next;
   7610     }
   7611     if (IS_SCHEMA(child, "simpleType")) {
   7612 	if (ret->typeName != NULL) {
   7613 	    /*
   7614 	    * 3.2.3 : 4
   7615 	    * type and <simpleType> must not both be present.
   7616 	    */
   7617 	    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
   7618 		NULL, node, child,
   7619 		"The attribute 'type' and the <simpleType> child "
   7620 		"are mutually exclusive", NULL);
   7621 	} else
   7622 	    ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
   7623 	child = child->next;
   7624     }
   7625     if (child != NULL)
   7626 	xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7627 	    NULL, node, child, NULL,
   7628 	    "(annotation?, simpleType?)");
   7629 
   7630     return (ret);
   7631 }
   7632 
   7633 /**
   7634  * xmlSchemaParseAttributeGroupRef:
   7635  * @ctxt:  a schema validation context
   7636  * @schema:  the schema being built
   7637  * @node:  a subtree containing XML Schema informations
   7638  *
   7639  * Parse an attribute group definition reference.
   7640  * Note that a reference to an attribute group does not
   7641  * correspond to any component at all.
   7642  * *WARNING* this interface is highly subject to change
   7643  *
   7644  * Returns the attribute group or NULL in case of error.
   7645  */
   7646 static xmlSchemaQNameRefPtr
   7647 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
   7648 				xmlSchemaPtr schema,
   7649 				xmlNodePtr node)
   7650 {
   7651     xmlSchemaQNameRefPtr ret;
   7652     xmlNodePtr child = NULL;
   7653     xmlAttrPtr attr;
   7654     const xmlChar *refNs = NULL, *ref = NULL;
   7655 
   7656     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7657         return (NULL);
   7658 
   7659     attr = xmlSchemaGetPropNode(node, "ref");
   7660     if (attr == NULL) {
   7661 	xmlSchemaPMissingAttrErr(pctxt,
   7662 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   7663 	    NULL, node, "ref", NULL);
   7664 	return (NULL);
   7665     }
   7666     xmlSchemaPValAttrNodeQName(pctxt, schema,
   7667 	NULL, attr, &refNs, &ref);
   7668     if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
   7669 	return(NULL);
   7670 
   7671     /*
   7672     * Check for illegal attributes.
   7673     */
   7674     attr = node->properties;
   7675     while (attr != NULL) {
   7676 	if (attr->ns == NULL) {
   7677 	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
   7678 		(!xmlStrEqual(attr->name, BAD_CAST "id")))
   7679 	    {
   7680 		xmlSchemaPIllegalAttrErr(pctxt,
   7681 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7682 	    }
   7683 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7684 	    xmlSchemaPIllegalAttrErr(pctxt,
   7685 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7686 	}
   7687 	attr = attr->next;
   7688     }
   7689     /* Attribute ID */
   7690     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   7691 
   7692     /*
   7693     * And now for the children...
   7694     */
   7695     child = node->children;
   7696     if (IS_SCHEMA(child, "annotation")) {
   7697 	/*
   7698 	* TODO: We do not have a place to store the annotation, do we?
   7699 	*/
   7700         xmlSchemaParseAnnotation(pctxt, child, 0);
   7701         child = child->next;
   7702     }
   7703     if (child != NULL) {
   7704 	xmlSchemaPContentErr(pctxt,
   7705 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7706 	    NULL, node, child, NULL,
   7707 	    "(annotation?)");
   7708     }
   7709 
   7710     /*
   7711     * Handle attribute group redefinitions.
   7712     */
   7713     if (pctxt->isRedefine && pctxt->redef &&
   7714 	(pctxt->redef->item->type ==
   7715 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
   7716 	(ref == pctxt->redef->refName) &&
   7717 	(refNs == pctxt->redef->refTargetNs))
   7718     {
   7719 	/*
   7720 	* SPEC src-redefine:
   7721 	* (7.1) "If it has an <attributeGroup> among its contents
   7722 	* the `actual value` of whose ref [attribute] is the same
   7723 	* as the `actual value` of its own name attribute plus
   7724 	* target namespace, then it must have exactly one such group."
   7725 	*/
   7726 	if (pctxt->redefCounter != 0) {
   7727 	    xmlChar *str = NULL;
   7728 
   7729 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   7730 		XML_SCHEMAP_SRC_REDEFINE, node, NULL,
   7731 		"The redefining attribute group definition "
   7732 		"'%s' must not contain more than one "
   7733 		"reference to the redefined definition",
   7734 		xmlSchemaFormatQName(&str, refNs, ref), NULL);
   7735 	    FREE_AND_NULL(str);
   7736 	    return(NULL);
   7737 	}
   7738 	pctxt->redefCounter++;
   7739 	/*
   7740 	* URGENT TODO: How to ensure that the reference will not be
   7741 	* handled by the normal component resolution mechanism?
   7742 	*/
   7743 	ret = xmlSchemaNewQNameRef(pctxt,
   7744 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
   7745 	if (ret == NULL)
   7746 	    return(NULL);
   7747 	ret->node = node;
   7748 	pctxt->redef->reference = WXS_BASIC_CAST ret;
   7749     } else {
   7750 	/*
   7751 	* Create a QName-reference helper component. We will substitute this
   7752 	* component for the attribute uses of the referenced attribute group
   7753 	* definition.
   7754 	*/
   7755 	ret = xmlSchemaNewQNameRef(pctxt,
   7756 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
   7757 	if (ret == NULL)
   7758 	    return(NULL);
   7759 	ret->node = node;
   7760 	/* Add to pending items, to be able to resolve the reference. */
   7761 	WXS_ADD_PENDING(pctxt, ret);
   7762     }
   7763     return (ret);
   7764 }
   7765 
   7766 /**
   7767  * xmlSchemaParseAttributeGroupDefinition:
   7768  * @pctxt:  a schema validation context
   7769  * @schema:  the schema being built
   7770  * @node:  a subtree containing XML Schema informations
   7771  *
   7772  * parse a XML schema Attribute Group declaration
   7773  * *WARNING* this interface is highly subject to change
   7774  *
   7775  * Returns the attribute group definition or NULL in case of error.
   7776  */
   7777 static xmlSchemaAttributeGroupPtr
   7778 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
   7779 				       xmlSchemaPtr schema,
   7780 				       xmlNodePtr node)
   7781 {
   7782     const xmlChar *name;
   7783     xmlSchemaAttributeGroupPtr ret;
   7784     xmlNodePtr child = NULL;
   7785     xmlAttrPtr attr;
   7786     int hasRefs = 0;
   7787 
   7788     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7789         return (NULL);
   7790 
   7791     attr = xmlSchemaGetPropNode(node, "name");
   7792     if (attr == NULL) {
   7793 	xmlSchemaPMissingAttrErr(pctxt,
   7794 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   7795 	    NULL, node, "name", NULL);
   7796 	return (NULL);
   7797     }
   7798     /*
   7799     * The name is crucial, exit if invalid.
   7800     */
   7801     if (xmlSchemaPValAttrNode(pctxt,
   7802 	NULL, attr,
   7803 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   7804 	return (NULL);
   7805     }
   7806     ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
   7807 	name, pctxt->targetNamespace, node);
   7808     if (ret == NULL)
   7809 	return (NULL);
   7810     /*
   7811     * Check for illegal attributes.
   7812     */
   7813     attr = node->properties;
   7814     while (attr != NULL) {
   7815 	if (attr->ns == NULL) {
   7816 	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   7817 		(!xmlStrEqual(attr->name, BAD_CAST "id")))
   7818 	    {
   7819 		xmlSchemaPIllegalAttrErr(pctxt,
   7820 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7821 	    }
   7822 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7823 	    xmlSchemaPIllegalAttrErr(pctxt,
   7824 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7825 	}
   7826 	attr = attr->next;
   7827     }
   7828     /* Attribute ID */
   7829     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   7830     /*
   7831     * And now for the children...
   7832     */
   7833     child = node->children;
   7834     if (IS_SCHEMA(child, "annotation")) {
   7835         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
   7836         child = child->next;
   7837     }
   7838     /*
   7839     * Parse contained attribute decls/refs.
   7840     */
   7841     if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
   7842 	(xmlSchemaItemListPtr *) &(ret->attrUses),
   7843 	XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
   7844 	return(NULL);
   7845     if (hasRefs)
   7846 	ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
   7847     /*
   7848     * Parse the attribute wildcard.
   7849     */
   7850     if (IS_SCHEMA(child, "anyAttribute")) {
   7851 	ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
   7852 	    schema, child);
   7853 	child = child->next;
   7854     }
   7855     if (child != NULL) {
   7856 	xmlSchemaPContentErr(pctxt,
   7857 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7858 	    NULL, node, child, NULL,
   7859 	    "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
   7860     }
   7861     return (ret);
   7862 }
   7863 
   7864 /**
   7865  * xmlSchemaPValAttrFormDefault:
   7866  * @value:  the value
   7867  * @flags: the flags to be modified
   7868  * @flagQualified: the specific flag for "qualified"
   7869  *
   7870  * Returns 0 if the value is valid, 1 otherwise.
   7871  */
   7872 static int
   7873 xmlSchemaPValAttrFormDefault(const xmlChar *value,
   7874 			     int *flags,
   7875 			     int flagQualified)
   7876 {
   7877     if (xmlStrEqual(value, BAD_CAST "qualified")) {
   7878 	if  ((*flags & flagQualified) == 0)
   7879 	    *flags |= flagQualified;
   7880     } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
   7881 	return (1);
   7882 
   7883     return (0);
   7884 }
   7885 
   7886 /**
   7887  * xmlSchemaPValAttrBlockFinal:
   7888  * @value:  the value
   7889  * @flags: the flags to be modified
   7890  * @flagAll: the specific flag for "#all"
   7891  * @flagExtension: the specific flag for "extension"
   7892  * @flagRestriction: the specific flag for "restriction"
   7893  * @flagSubstitution: the specific flag for "substitution"
   7894  * @flagList: the specific flag for "list"
   7895  * @flagUnion: the specific flag for "union"
   7896  *
   7897  * Validates the value of the attribute "final" and "block". The value
   7898  * is converted into the specified flag values and returned in @flags.
   7899  *
   7900  * Returns 0 if the value is valid, 1 otherwise.
   7901  */
   7902 
   7903 static int
   7904 xmlSchemaPValAttrBlockFinal(const xmlChar *value,
   7905 			    int *flags,
   7906 			    int flagAll,
   7907 			    int flagExtension,
   7908 			    int flagRestriction,
   7909 			    int flagSubstitution,
   7910 			    int flagList,
   7911 			    int flagUnion)
   7912 {
   7913     int ret = 0;
   7914 
   7915     /*
   7916     * TODO: This does not check for dublicate entries.
   7917     */
   7918     if ((flags == NULL) || (value == NULL))
   7919 	return (-1);
   7920     if (value[0] == 0)
   7921 	return (0);
   7922     if (xmlStrEqual(value, BAD_CAST "#all")) {
   7923 	if (flagAll != -1)
   7924 	    *flags |= flagAll;
   7925 	else {
   7926 	    if (flagExtension != -1)
   7927 		*flags |= flagExtension;
   7928 	    if (flagRestriction != -1)
   7929 		*flags |= flagRestriction;
   7930 	    if (flagSubstitution != -1)
   7931 		*flags |= flagSubstitution;
   7932 	    if (flagList != -1)
   7933 		*flags |= flagList;
   7934 	    if (flagUnion != -1)
   7935 		*flags |= flagUnion;
   7936 	}
   7937     } else {
   7938 	const xmlChar *end, *cur = value;
   7939 	xmlChar *item;
   7940 
   7941 	do {
   7942 	    while (IS_BLANK_CH(*cur))
   7943 		cur++;
   7944 	    end = cur;
   7945 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   7946 		end++;
   7947 	    if (end == cur)
   7948 		break;
   7949 	    item = xmlStrndup(cur, end - cur);
   7950 	    if (xmlStrEqual(item, BAD_CAST "extension")) {
   7951 		if (flagExtension != -1) {
   7952 		    if ((*flags & flagExtension) == 0)
   7953 			*flags |= flagExtension;
   7954 		} else
   7955 		    ret = 1;
   7956 	    } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
   7957 		if (flagRestriction != -1) {
   7958 		    if ((*flags & flagRestriction) == 0)
   7959 			*flags |= flagRestriction;
   7960 		} else
   7961 		    ret = 1;
   7962 	    } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
   7963 		if (flagSubstitution != -1) {
   7964 		    if ((*flags & flagSubstitution) == 0)
   7965 			*flags |= flagSubstitution;
   7966 		} else
   7967 		    ret = 1;
   7968 	    } else if (xmlStrEqual(item, BAD_CAST "list")) {
   7969 		if (flagList != -1) {
   7970 		    if ((*flags & flagList) == 0)
   7971 			*flags |= flagList;
   7972 		} else
   7973 		    ret = 1;
   7974 	    } else if (xmlStrEqual(item, BAD_CAST "union")) {
   7975 		if (flagUnion != -1) {
   7976 		    if ((*flags & flagUnion) == 0)
   7977 			*flags |= flagUnion;
   7978 		} else
   7979 		    ret = 1;
   7980 	    } else
   7981 		ret = 1;
   7982 	    if (item != NULL)
   7983 		xmlFree(item);
   7984 	    cur = end;
   7985 	} while ((ret == 0) && (*cur != 0));
   7986     }
   7987 
   7988     return (ret);
   7989 }
   7990 
   7991 static int
   7992 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
   7993 			     xmlSchemaIDCPtr idc,
   7994 			     xmlSchemaIDCSelectPtr selector,
   7995 			     xmlAttrPtr attr,
   7996 			     int isField)
   7997 {
   7998     xmlNodePtr node;
   7999 
   8000     /*
   8001     * c-selector-xpath:
   8002     * Schema Component Constraint: Selector Value OK
   8003     *
   8004     * TODO: 1 The {selector} must be a valid XPath expression, as defined
   8005     * in [XPath].
   8006     */
   8007     if (selector == NULL) {
   8008 	xmlSchemaPErr(ctxt, idc->node,
   8009 	    XML_SCHEMAP_INTERNAL,
   8010 	    "Internal error: xmlSchemaCheckCSelectorXPath, "
   8011 	    "the selector is not specified.\n", NULL, NULL);
   8012 	return (-1);
   8013     }
   8014     if (attr == NULL)
   8015 	node = idc->node;
   8016     else
   8017 	node = (xmlNodePtr) attr;
   8018     if (selector->xpath == NULL) {
   8019 	xmlSchemaPCustomErr(ctxt,
   8020 	    /* TODO: Adjust error code. */
   8021 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8022 	    NULL, node,
   8023 	    "The XPath expression of the selector is not valid", NULL);
   8024 	return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
   8025     } else {
   8026 	const xmlChar **nsArray = NULL;
   8027 	xmlNsPtr *nsList = NULL;
   8028 	/*
   8029 	* Compile the XPath expression.
   8030 	*/
   8031 	/*
   8032 	* TODO: We need the array of in-scope namespaces for compilation.
   8033 	* TODO: Call xmlPatterncompile with different options for selector/
   8034 	* field.
   8035 	*/
   8036 	if (attr == NULL)
   8037 	    nsList = NULL;
   8038 	else
   8039 	    nsList = xmlGetNsList(attr->doc, attr->parent);
   8040 	/*
   8041 	* Build an array of prefixes and namespaces.
   8042 	*/
   8043 	if (nsList != NULL) {
   8044 	    int i, count = 0;
   8045 
   8046 	    for (i = 0; nsList[i] != NULL; i++)
   8047 		count++;
   8048 
   8049 	    nsArray = (const xmlChar **) xmlMalloc(
   8050 		(count * 2 + 1) * sizeof(const xmlChar *));
   8051 	    if (nsArray == NULL) {
   8052 		xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
   8053 		    NULL);
   8054 		xmlFree(nsList);
   8055 		return (-1);
   8056 	    }
   8057 	    for (i = 0; i < count; i++) {
   8058 		nsArray[2 * i] = nsList[i]->href;
   8059 		nsArray[2 * i + 1] = nsList[i]->prefix;
   8060 	    }
   8061 	    nsArray[count * 2] = NULL;
   8062 	    xmlFree(nsList);
   8063 	}
   8064 	/*
   8065 	* TODO: Differentiate between "selector" and "field".
   8066 	*/
   8067 	if (isField)
   8068 	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
   8069 		NULL, XML_PATTERN_XSFIELD, nsArray);
   8070 	else
   8071 	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
   8072 		NULL, XML_PATTERN_XSSEL, nsArray);
   8073 	if (nsArray != NULL)
   8074 	    xmlFree((xmlChar **) nsArray);
   8075 
   8076 	if (selector->xpathComp == NULL) {
   8077 	    xmlSchemaPCustomErr(ctxt,
   8078 		/* TODO: Adjust error code? */
   8079 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8080 		NULL, node,
   8081 		"The XPath expression '%s' could not be "
   8082 		"compiled", selector->xpath);
   8083 	    return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
   8084 	}
   8085     }
   8086     return (0);
   8087 }
   8088 
   8089 #define ADD_ANNOTATION(annot)   \
   8090     xmlSchemaAnnotPtr cur = item->annot; \
   8091     if (item->annot == NULL) {  \
   8092 	item->annot = annot;    \
   8093 	return (annot);         \
   8094     }                           \
   8095     cur = item->annot;          \
   8096     if (cur->next != NULL) {    \
   8097 	cur = cur->next;	\
   8098     }                           \
   8099     cur->next = annot;
   8100 
   8101 /**
   8102  * xmlSchemaAssignAnnotation:
   8103  * @item: the schema component
   8104  * @annot: the annotation
   8105  *
   8106  * Adds the annotation to the given schema component.
   8107  *
   8108  * Returns the given annotaion.
   8109  */
   8110 static xmlSchemaAnnotPtr
   8111 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
   8112 		       xmlSchemaAnnotPtr annot)
   8113 {
   8114     if ((annItem == NULL) || (annot == NULL))
   8115 	return (NULL);
   8116     switch (annItem->type) {
   8117 	case XML_SCHEMA_TYPE_ELEMENT: {
   8118 		xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
   8119 		ADD_ANNOTATION(annot)
   8120 	    }
   8121 	    break;
   8122 	case XML_SCHEMA_TYPE_ATTRIBUTE: {
   8123 		xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
   8124 		ADD_ANNOTATION(annot)
   8125 	    }
   8126 	    break;
   8127 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   8128 	case XML_SCHEMA_TYPE_ANY: {
   8129 		xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
   8130 		ADD_ANNOTATION(annot)
   8131 	    }
   8132 	    break;
   8133 	case XML_SCHEMA_TYPE_PARTICLE:
   8134 	case XML_SCHEMA_TYPE_IDC_KEY:
   8135 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   8136 	case XML_SCHEMA_TYPE_IDC_UNIQUE: {
   8137 		xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
   8138 		ADD_ANNOTATION(annot)
   8139 	    }
   8140 	    break;
   8141 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
   8142 		xmlSchemaAttributeGroupPtr item =
   8143 		    (xmlSchemaAttributeGroupPtr) annItem;
   8144 		ADD_ANNOTATION(annot)
   8145 	    }
   8146 	    break;
   8147 	case XML_SCHEMA_TYPE_NOTATION: {
   8148 		xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
   8149 		ADD_ANNOTATION(annot)
   8150 	    }
   8151 	    break;
   8152 	case XML_SCHEMA_FACET_MININCLUSIVE:
   8153 	case XML_SCHEMA_FACET_MINEXCLUSIVE:
   8154 	case XML_SCHEMA_FACET_MAXINCLUSIVE:
   8155 	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   8156 	case XML_SCHEMA_FACET_TOTALDIGITS:
   8157 	case XML_SCHEMA_FACET_FRACTIONDIGITS:
   8158 	case XML_SCHEMA_FACET_PATTERN:
   8159 	case XML_SCHEMA_FACET_ENUMERATION:
   8160 	case XML_SCHEMA_FACET_WHITESPACE:
   8161 	case XML_SCHEMA_FACET_LENGTH:
   8162 	case XML_SCHEMA_FACET_MAXLENGTH:
   8163 	case XML_SCHEMA_FACET_MINLENGTH: {
   8164 		xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
   8165 		ADD_ANNOTATION(annot)
   8166 	    }
   8167 	    break;
   8168 	case XML_SCHEMA_TYPE_SIMPLE:
   8169 	case XML_SCHEMA_TYPE_COMPLEX: {
   8170 		xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
   8171 		ADD_ANNOTATION(annot)
   8172 	    }
   8173 	    break;
   8174 	case XML_SCHEMA_TYPE_GROUP: {
   8175 		xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
   8176 		ADD_ANNOTATION(annot)
   8177 	    }
   8178 	    break;
   8179 	case XML_SCHEMA_TYPE_SEQUENCE:
   8180 	case XML_SCHEMA_TYPE_CHOICE:
   8181 	case XML_SCHEMA_TYPE_ALL: {
   8182 		xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
   8183 		ADD_ANNOTATION(annot)
   8184 	    }
   8185 	    break;
   8186 	default:
   8187 	     xmlSchemaPCustomErr(NULL,
   8188 		XML_SCHEMAP_INTERNAL,
   8189 		NULL, NULL,
   8190 		"Internal error: xmlSchemaAddAnnotation, "
   8191 		"The item is not a annotated schema component", NULL);
   8192 	     break;
   8193     }
   8194     return (annot);
   8195 }
   8196 
   8197 /**
   8198  * xmlSchemaParseIDCSelectorAndField:
   8199  * @ctxt:  a schema validation context
   8200  * @schema:  the schema being built
   8201  * @node:  a subtree containing XML Schema informations
   8202  *
   8203  * Parses a XML Schema identity-contraint definition's
   8204  * <selector> and <field> elements.
   8205  *
   8206  * Returns the parsed identity-constraint definition.
   8207  */
   8208 static xmlSchemaIDCSelectPtr
   8209 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
   8210 			  xmlSchemaIDCPtr idc,
   8211 			  xmlNodePtr node,
   8212 			  int isField)
   8213 {
   8214     xmlSchemaIDCSelectPtr item;
   8215     xmlNodePtr child = NULL;
   8216     xmlAttrPtr attr;
   8217 
   8218     /*
   8219     * Check for illegal attributes.
   8220     */
   8221     attr = node->properties;
   8222     while (attr != NULL) {
   8223 	if (attr->ns == NULL) {
   8224 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8225 		(!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
   8226 		xmlSchemaPIllegalAttrErr(ctxt,
   8227 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8228 	    }
   8229 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8230 	    xmlSchemaPIllegalAttrErr(ctxt,
   8231 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8232 	}
   8233 	attr = attr->next;
   8234     }
   8235     /*
   8236     * Create the item.
   8237     */
   8238     item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
   8239     if (item == NULL) {
   8240         xmlSchemaPErrMemory(ctxt,
   8241 	    "allocating a 'selector' of an identity-constraint definition",
   8242 	    NULL);
   8243         return (NULL);
   8244     }
   8245     memset(item, 0, sizeof(xmlSchemaIDCSelect));
   8246     /*
   8247     * Attribute "xpath" (mandatory).
   8248     */
   8249     attr = xmlSchemaGetPropNode(node, "xpath");
   8250     if (attr == NULL) {
   8251 	xmlSchemaPMissingAttrErr(ctxt,
   8252 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   8253 	    NULL, node,
   8254 	    "name", NULL);
   8255     } else {
   8256 	item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8257 	/*
   8258 	* URGENT TODO: "field"s have an other syntax than "selector"s.
   8259 	*/
   8260 
   8261 	if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
   8262 	    isField) == -1) {
   8263 	    xmlSchemaPErr(ctxt,
   8264 		(xmlNodePtr) attr,
   8265 		XML_SCHEMAP_INTERNAL,
   8266 		"Internal error: xmlSchemaParseIDCSelectorAndField, "
   8267 		"validating the XPath expression of a IDC selector.\n",
   8268 		NULL, NULL);
   8269 	}
   8270 
   8271     }
   8272     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8273     /*
   8274     * And now for the children...
   8275     */
   8276     child = node->children;
   8277     if (IS_SCHEMA(child, "annotation")) {
   8278 	/*
   8279 	* Add the annotation to the parent IDC.
   8280 	*/
   8281 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
   8282 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   8283 	child = child->next;
   8284     }
   8285     if (child != NULL) {
   8286 	xmlSchemaPContentErr(ctxt,
   8287 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8288 	    NULL, node, child,
   8289 	    NULL, "(annotation?)");
   8290     }
   8291 
   8292     return (item);
   8293 }
   8294 
   8295 /**
   8296  * xmlSchemaParseIDC:
   8297  * @ctxt:  a schema validation context
   8298  * @schema:  the schema being built
   8299  * @node:  a subtree containing XML Schema informations
   8300  *
   8301  * Parses a XML Schema identity-contraint definition.
   8302  *
   8303  * Returns the parsed identity-constraint definition.
   8304  */
   8305 static xmlSchemaIDCPtr
   8306 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
   8307 		  xmlSchemaPtr schema,
   8308 		  xmlNodePtr node,
   8309 		  xmlSchemaTypeType idcCategory,
   8310 		  const xmlChar *targetNamespace)
   8311 {
   8312     xmlSchemaIDCPtr item = NULL;
   8313     xmlNodePtr child = NULL;
   8314     xmlAttrPtr attr;
   8315     const xmlChar *name = NULL;
   8316     xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
   8317 
   8318     /*
   8319     * Check for illegal attributes.
   8320     */
   8321     attr = node->properties;
   8322     while (attr != NULL) {
   8323 	if (attr->ns == NULL) {
   8324 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8325 		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   8326 		((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
   8327 		 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
   8328 		xmlSchemaPIllegalAttrErr(ctxt,
   8329 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8330 	    }
   8331 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8332 	    xmlSchemaPIllegalAttrErr(ctxt,
   8333 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8334 	}
   8335 	attr = attr->next;
   8336     }
   8337     /*
   8338     * Attribute "name" (mandatory).
   8339     */
   8340     attr = xmlSchemaGetPropNode(node, "name");
   8341     if (attr == NULL) {
   8342 	xmlSchemaPMissingAttrErr(ctxt,
   8343 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   8344 	    NULL, node,
   8345 	    "name", NULL);
   8346 	return (NULL);
   8347     } else if (xmlSchemaPValAttrNode(ctxt,
   8348 	NULL, attr,
   8349 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   8350 	return (NULL);
   8351     }
   8352     /* Create the component. */
   8353     item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
   8354 	idcCategory, node);
   8355     if (item == NULL)
   8356 	return(NULL);
   8357 
   8358     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8359     if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
   8360 	/*
   8361 	* Attribute "refer" (mandatory).
   8362 	*/
   8363 	attr = xmlSchemaGetPropNode(node, "refer");
   8364 	if (attr == NULL) {
   8365 	    xmlSchemaPMissingAttrErr(ctxt,
   8366 		XML_SCHEMAP_S4S_ATTR_MISSING,
   8367 		NULL, node,
   8368 		"refer", NULL);
   8369 	} else {
   8370 	    /*
   8371 	    * Create a reference item.
   8372 	    */
   8373 	    item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
   8374 		NULL, NULL);
   8375 	    if (item->ref == NULL)
   8376 		return (NULL);
   8377 	    xmlSchemaPValAttrNodeQName(ctxt, schema,
   8378 		NULL, attr,
   8379 		&(item->ref->targetNamespace),
   8380 		&(item->ref->name));
   8381 	    xmlSchemaCheckReference(ctxt, schema, node, attr,
   8382 		item->ref->targetNamespace);
   8383 	}
   8384     }
   8385     /*
   8386     * And now for the children...
   8387     */
   8388     child = node->children;
   8389     if (IS_SCHEMA(child, "annotation")) {
   8390 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   8391 	child = child->next;
   8392     }
   8393     if (child == NULL) {
   8394 	xmlSchemaPContentErr(ctxt,
   8395 		XML_SCHEMAP_S4S_ELEM_MISSING,
   8396 		NULL, node, child,
   8397 		"A child element is missing",
   8398 		"(annotation?, (selector, field+))");
   8399     }
   8400     /*
   8401     * Child element <selector>.
   8402     */
   8403     if (IS_SCHEMA(child, "selector")) {
   8404 	item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
   8405 	    item, child, 0);
   8406 	child = child->next;
   8407 	/*
   8408 	* Child elements <field>.
   8409 	*/
   8410 	if (IS_SCHEMA(child, "field")) {
   8411 	    do {
   8412 		field = xmlSchemaParseIDCSelectorAndField(ctxt,
   8413 		    item, child, 1);
   8414 		if (field != NULL) {
   8415 		    field->index = item->nbFields;
   8416 		    item->nbFields++;
   8417 		    if (lastField != NULL)
   8418 			lastField->next = field;
   8419 		    else
   8420 			item->fields = field;
   8421 		    lastField = field;
   8422 		}
   8423 		child = child->next;
   8424 	    } while (IS_SCHEMA(child, "field"));
   8425 	} else {
   8426 	    xmlSchemaPContentErr(ctxt,
   8427 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8428 		NULL, node, child,
   8429 		NULL, "(annotation?, (selector, field+))");
   8430 	}
   8431     }
   8432     if (child != NULL) {
   8433 	xmlSchemaPContentErr(ctxt,
   8434 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8435 	    NULL, node, child,
   8436 	    NULL, "(annotation?, (selector, field+))");
   8437     }
   8438 
   8439     return (item);
   8440 }
   8441 
   8442 /**
   8443  * xmlSchemaParseElement:
   8444  * @ctxt:  a schema validation context
   8445  * @schema:  the schema being built
   8446  * @node:  a subtree containing XML Schema informations
   8447  * @topLevel: indicates if this is global declaration
   8448  *
   8449  * Parses a XML schema element declaration.
   8450  * *WARNING* this interface is highly subject to change
   8451  *
   8452  * Returns the element declaration or a particle; NULL in case
   8453  * of an error or if the particle has minOccurs==maxOccurs==0.
   8454  */
   8455 static xmlSchemaBasicItemPtr
   8456 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   8457                       xmlNodePtr node, int *isElemRef, int topLevel)
   8458 {
   8459     xmlSchemaElementPtr decl = NULL;
   8460     xmlSchemaParticlePtr particle = NULL;
   8461     xmlSchemaAnnotPtr annot = NULL;
   8462     xmlNodePtr child = NULL;
   8463     xmlAttrPtr attr, nameAttr;
   8464     int min, max, isRef = 0;
   8465     xmlChar *des = NULL;
   8466 
   8467     /* 3.3.3 Constraints on XML Representations of Element Declarations */
   8468     /* TODO: Complete implementation of 3.3.6 */
   8469 
   8470     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   8471         return (NULL);
   8472 
   8473     if (isElemRef != NULL)
   8474 	*isElemRef = 0;
   8475     /*
   8476     * If we get a "ref" attribute on a local <element> we will assume it's
   8477     * a reference - even if there's a "name" attribute; this seems to be more
   8478     * robust.
   8479     */
   8480     nameAttr = xmlSchemaGetPropNode(node, "name");
   8481     attr = xmlSchemaGetPropNode(node, "ref");
   8482     if ((topLevel) || (attr == NULL)) {
   8483 	if (nameAttr == NULL) {
   8484 	    xmlSchemaPMissingAttrErr(ctxt,
   8485 		XML_SCHEMAP_S4S_ATTR_MISSING,
   8486 		NULL, node, "name", NULL);
   8487 	    return (NULL);
   8488 	}
   8489     } else
   8490 	isRef = 1;
   8491 
   8492     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8493     child = node->children;
   8494     if (IS_SCHEMA(child, "annotation")) {
   8495 	annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   8496 	child = child->next;
   8497     }
   8498     /*
   8499     * Skip particle part if a global declaration.
   8500     */
   8501     if (topLevel)
   8502 	goto declaration_part;
   8503     /*
   8504     * The particle part ==================================================
   8505     */
   8506     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
   8507     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
   8508     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
   8509     particle = xmlSchemaAddParticle(ctxt, node, min, max);
   8510     if (particle == NULL)
   8511 	goto return_null;
   8512 
   8513     /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
   8514 
   8515     if (isRef) {
   8516 	const xmlChar *refNs = NULL, *ref = NULL;
   8517 	xmlSchemaQNameRefPtr refer = NULL;
   8518 	/*
   8519 	* The reference part =============================================
   8520 	*/
   8521 	if (isElemRef != NULL)
   8522 	    *isElemRef = 1;
   8523 
   8524 	xmlSchemaPValAttrNodeQName(ctxt, schema,
   8525 	    NULL, attr, &refNs, &ref);
   8526 	xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
   8527 	/*
   8528 	* SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
   8529 	*/
   8530 	if (nameAttr != NULL) {
   8531 	    xmlSchemaPMutualExclAttrErr(ctxt,
   8532 		XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
   8533 	}
   8534 	/*
   8535 	* Check for illegal attributes.
   8536 	*/
   8537 	attr = node->properties;
   8538 	while (attr != NULL) {
   8539 	    if (attr->ns == NULL) {
   8540 		if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
   8541 		    xmlStrEqual(attr->name, BAD_CAST "name") ||
   8542 		    xmlStrEqual(attr->name, BAD_CAST "id") ||
   8543 		    xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
   8544 		    xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
   8545 		{
   8546 		    attr = attr->next;
   8547 		    continue;
   8548 		} else {
   8549 		    /* SPEC (3.3.3 : 2.2) */
   8550 		    xmlSchemaPCustomAttrErr(ctxt,
   8551 			XML_SCHEMAP_SRC_ELEMENT_2_2,
   8552 			NULL, NULL, attr,
   8553 			"Only the attributes 'minOccurs', 'maxOccurs' and "
   8554 			"'id' are allowed in addition to 'ref'");
   8555 		    break;
   8556 		}
   8557 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8558 		xmlSchemaPIllegalAttrErr(ctxt,
   8559 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8560 	    }
   8561 	    attr = attr->next;
   8562 	}
   8563 	/*
   8564 	* No children except <annotation> expected.
   8565 	*/
   8566 	if (child != NULL) {
   8567 	    xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8568 		NULL, node, child, NULL, "(annotation?)");
   8569 	}
   8570 	if ((min == 0) && (max == 0))
   8571 	    goto return_null;
   8572 	/*
   8573 	* Create the reference item and attach it to the particle.
   8574 	*/
   8575 	refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
   8576 	    ref, refNs);
   8577 	if (refer == NULL)
   8578 	    goto return_null;
   8579 	particle->children = (xmlSchemaTreeItemPtr) refer;
   8580 	particle->annot = annot;
   8581 	/*
   8582 	* Add the particle to pending components, since the reference
   8583 	* need to be resolved.
   8584 	*/
   8585 	WXS_ADD_PENDING(ctxt, particle);
   8586 	return ((xmlSchemaBasicItemPtr) particle);
   8587     }
   8588     /*
   8589     * The declaration part ===============================================
   8590     */
   8591 declaration_part:
   8592     {
   8593 	const xmlChar *ns = NULL, *fixed, *name, *attrValue;
   8594 	xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
   8595 
   8596 	if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
   8597 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
   8598 	    goto return_null;
   8599 	/*
   8600 	* Evaluate the target namespace.
   8601 	*/
   8602 	if (topLevel) {
   8603 	    ns = ctxt->targetNamespace;
   8604 	} else {
   8605 	    attr = xmlSchemaGetPropNode(node, "form");
   8606 	    if (attr != NULL) {
   8607 		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8608 		if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
   8609 		    ns = ctxt->targetNamespace;
   8610 		} else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
   8611 		    xmlSchemaPSimpleTypeErr(ctxt,
   8612 			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8613 			NULL, (xmlNodePtr) attr,
   8614 			NULL, "(qualified | unqualified)",
   8615 			attrValue, NULL, NULL, NULL);
   8616 		}
   8617 	    } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
   8618 		ns = ctxt->targetNamespace;
   8619 	}
   8620 	decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
   8621 	if (decl == NULL) {
   8622 	    goto return_null;
   8623 	}
   8624 	/*
   8625 	* Check for illegal attributes.
   8626 	*/
   8627 	attr = node->properties;
   8628 	while (attr != NULL) {
   8629 	    if (attr->ns == NULL) {
   8630 		if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   8631 		    (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
   8632 		    (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8633 		    (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
   8634 		    (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
   8635 		    (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
   8636 		    (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
   8637 		{
   8638 		    if (topLevel == 0) {
   8639 			if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
   8640 			    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
   8641 			    (!xmlStrEqual(attr->name, BAD_CAST "form")))
   8642 			{
   8643 			    xmlSchemaPIllegalAttrErr(ctxt,
   8644 				XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8645 			}
   8646 		    } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
   8647 			(!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
   8648 			(!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
   8649 
   8650 			xmlSchemaPIllegalAttrErr(ctxt,
   8651 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8652 		    }
   8653 		}
   8654 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8655 
   8656 		xmlSchemaPIllegalAttrErr(ctxt,
   8657 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8658 	    }
   8659 	    attr = attr->next;
   8660 	}
   8661 	/*
   8662 	* Extract/validate attributes.
   8663 	*/
   8664 	if (topLevel) {
   8665 	    /*
   8666 	    * Process top attributes of global element declarations here.
   8667 	    */
   8668 	    decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
   8669 	    decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
   8670 	    xmlSchemaPValAttrQName(ctxt, schema,
   8671 		NULL, node, "substitutionGroup",
   8672 		&(decl->substGroupNs), &(decl->substGroup));
   8673 	    if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
   8674 		decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
   8675 	    /*
   8676 	    * Attribute "final".
   8677 	    */
   8678 	    attr = xmlSchemaGetPropNode(node, "final");
   8679 	    if (attr == NULL) {
   8680 		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
   8681 		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
   8682 		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   8683 		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
   8684 	    } else {
   8685 		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8686 		if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
   8687 		    -1,
   8688 		    XML_SCHEMAS_ELEM_FINAL_EXTENSION,
   8689 		    XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
   8690 		    xmlSchemaPSimpleTypeErr(ctxt,
   8691 			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8692 			NULL, (xmlNodePtr) attr,
   8693 			NULL, "(#all | List of (extension | restriction))",
   8694 			attrValue, NULL, NULL, NULL);
   8695 		}
   8696 	    }
   8697 	}
   8698 	/*
   8699 	* Attribute "block".
   8700 	*/
   8701 	attr = xmlSchemaGetPropNode(node, "block");
   8702 	if (attr == NULL) {
   8703 	    /*
   8704 	    * Apply default "block" values.
   8705 	    */
   8706 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
   8707 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
   8708 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
   8709 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
   8710 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
   8711 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
   8712 	} else {
   8713 	    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8714 	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
   8715 		-1,
   8716 		XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
   8717 		XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
   8718 		XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
   8719 		xmlSchemaPSimpleTypeErr(ctxt,
   8720 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8721 		    NULL, (xmlNodePtr) attr,
   8722 		    NULL, "(#all | List of (extension | "
   8723 		    "restriction | substitution))", attrValue,
   8724 		    NULL, NULL, NULL);
   8725 	    }
   8726 	}
   8727 	if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
   8728 	    decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
   8729 
   8730 	attr = xmlSchemaGetPropNode(node, "type");
   8731 	if (attr != NULL) {
   8732 	    xmlSchemaPValAttrNodeQName(ctxt, schema,
   8733 		NULL, attr,
   8734 		&(decl->namedTypeNs), &(decl->namedType));
   8735 	    xmlSchemaCheckReference(ctxt, schema, node,
   8736 		attr, decl->namedTypeNs);
   8737 	}
   8738 	decl->value = xmlSchemaGetProp(ctxt, node, "default");
   8739 	attr = xmlSchemaGetPropNode(node, "fixed");
   8740 	if (attr != NULL) {
   8741 	    fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8742 	    if (decl->value != NULL) {
   8743 		/*
   8744 		* 3.3.3 : 1
   8745 		* default and fixed must not both be present.
   8746 		*/
   8747 		xmlSchemaPMutualExclAttrErr(ctxt,
   8748 		    XML_SCHEMAP_SRC_ELEMENT_1,
   8749 		    NULL, attr, "default", "fixed");
   8750 	    } else {
   8751 		decl->flags |= XML_SCHEMAS_ELEM_FIXED;
   8752 		decl->value = fixed;
   8753 	    }
   8754 	}
   8755 	/*
   8756 	* And now for the children...
   8757 	*/
   8758 	if (IS_SCHEMA(child, "complexType")) {
   8759 	    /*
   8760 	    * 3.3.3 : 3
   8761 	    * "type" and either <simpleType> or <complexType> are mutually
   8762 	    * exclusive
   8763 	    */
   8764 	    if (decl->namedType != NULL) {
   8765 		xmlSchemaPContentErr(ctxt,
   8766 		    XML_SCHEMAP_SRC_ELEMENT_3,
   8767 		    NULL, node, child,
   8768 		    "The attribute 'type' and the <complexType> child are "
   8769 		    "mutually exclusive", NULL);
   8770 	    } else
   8771 		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
   8772 	    child = child->next;
   8773 	} else if (IS_SCHEMA(child, "simpleType")) {
   8774 	    /*
   8775 	    * 3.3.3 : 3
   8776 	    * "type" and either <simpleType> or <complexType> are
   8777 	    * mutually exclusive
   8778 	    */
   8779 	    if (decl->namedType != NULL) {
   8780 		xmlSchemaPContentErr(ctxt,
   8781 		    XML_SCHEMAP_SRC_ELEMENT_3,
   8782 		    NULL, node, child,
   8783 		    "The attribute 'type' and the <simpleType> child are "
   8784 		    "mutually exclusive", NULL);
   8785 	    } else
   8786 		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   8787 	    child = child->next;
   8788 	}
   8789 	while ((IS_SCHEMA(child, "unique")) ||
   8790 	    (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
   8791 	    if (IS_SCHEMA(child, "unique")) {
   8792 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
   8793 		    XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
   8794 	    } else if (IS_SCHEMA(child, "key")) {
   8795 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
   8796 		    XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
   8797 	    } else if (IS_SCHEMA(child, "keyref")) {
   8798 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
   8799 		    XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
   8800 	    }
   8801 	    if (lastIDC != NULL)
   8802 		lastIDC->next = curIDC;
   8803 	    else
   8804 		decl->idcs = (void *) curIDC;
   8805 	    lastIDC = curIDC;
   8806 	    child = child->next;
   8807 	}
   8808 	if (child != NULL) {
   8809 	    xmlSchemaPContentErr(ctxt,
   8810 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8811 		NULL, node, child,
   8812 		NULL, "(annotation?, ((simpleType | complexType)?, "
   8813 		"(unique | key | keyref)*))");
   8814 	}
   8815 	decl->annot = annot;
   8816     }
   8817     /*
   8818     * NOTE: Element Declaration Representation OK 4. will be checked at a
   8819     * different layer.
   8820     */
   8821     FREE_AND_NULL(des)
   8822     if (topLevel)
   8823 	return ((xmlSchemaBasicItemPtr) decl);
   8824     else {
   8825 	particle->children = (xmlSchemaTreeItemPtr) decl;
   8826 	return ((xmlSchemaBasicItemPtr) particle);
   8827     }
   8828 
   8829 return_null:
   8830     FREE_AND_NULL(des);
   8831     if (annot != NULL) {
   8832 	if (particle != NULL)
   8833 	    particle->annot = NULL;
   8834 	if (decl != NULL)
   8835 	    decl->annot = NULL;
   8836 	xmlSchemaFreeAnnot(annot);
   8837     }
   8838     return (NULL);
   8839 }
   8840 
   8841 /**
   8842  * xmlSchemaParseUnion:
   8843  * @ctxt:  a schema validation context
   8844  * @schema:  the schema being built
   8845  * @node:  a subtree containing XML Schema informations
   8846  *
   8847  * parse a XML schema Union definition
   8848  * *WARNING* this interface is highly subject to change
   8849  *
   8850  * Returns -1 in case of internal error, 0 in case of success and a positive
   8851  * error code otherwise.
   8852  */
   8853 static int
   8854 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   8855                     xmlNodePtr node)
   8856 {
   8857     xmlSchemaTypePtr type;
   8858     xmlNodePtr child = NULL;
   8859     xmlAttrPtr attr;
   8860     const xmlChar *cur = NULL;
   8861 
   8862     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   8863         return (-1);
   8864     /* Not a component, don't create it. */
   8865     type = ctxt->ctxtType;
   8866     /*
   8867     * Mark the simple type as being of variety "union".
   8868     */
   8869     type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
   8870     /*
   8871     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
   8872     * then the `simple ur-type definition`."
   8873     */
   8874     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
   8875     /*
   8876     * Check for illegal attributes.
   8877     */
   8878     attr = node->properties;
   8879     while (attr != NULL) {
   8880 	if (attr->ns == NULL) {
   8881 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8882 		(!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
   8883 		xmlSchemaPIllegalAttrErr(ctxt,
   8884 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8885 	    }
   8886 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8887 	    xmlSchemaPIllegalAttrErr(ctxt,
   8888 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8889 	}
   8890 	attr = attr->next;
   8891     }
   8892     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8893     /*
   8894     * Attribute "memberTypes". This is a list of QNames.
   8895     * TODO: Check the value to contain anything.
   8896     */
   8897     attr = xmlSchemaGetPropNode(node, "memberTypes");
   8898     if (attr != NULL) {
   8899 	const xmlChar *end;
   8900 	xmlChar *tmp;
   8901 	const xmlChar *localName, *nsName;
   8902 	xmlSchemaTypeLinkPtr link, lastLink = NULL;
   8903 	xmlSchemaQNameRefPtr ref;
   8904 
   8905 	cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8906 	type->base = cur;
   8907 	do {
   8908 	    while (IS_BLANK_CH(*cur))
   8909 		cur++;
   8910 	    end = cur;
   8911 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   8912 		end++;
   8913 	    if (end == cur)
   8914 		break;
   8915 	    tmp = xmlStrndup(cur, end - cur);
   8916 	    if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
   8917 		NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
   8918 		/*
   8919 		* Create the member type link.
   8920 		*/
   8921 		link = (xmlSchemaTypeLinkPtr)
   8922 		    xmlMalloc(sizeof(xmlSchemaTypeLink));
   8923 		if (link == NULL) {
   8924 		    xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
   8925 			"allocating a type link", NULL);
   8926 		    return (-1);
   8927 		}
   8928 		link->type = NULL;
   8929 		link->next = NULL;
   8930 		if (lastLink == NULL)
   8931 		    type->memberTypes = link;
   8932 		else
   8933 		    lastLink->next = link;
   8934 		lastLink = link;
   8935 		/*
   8936 		* Create a reference item.
   8937 		*/
   8938 		ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
   8939 		    localName, nsName);
   8940 		if (ref == NULL) {
   8941 		    FREE_AND_NULL(tmp)
   8942 		    return (-1);
   8943 		}
   8944 		/*
   8945 		* Assign the reference to the link, it will be resolved
   8946 		* later during fixup of the union simple type.
   8947 		*/
   8948 		link->type = (xmlSchemaTypePtr) ref;
   8949 	    }
   8950 	    FREE_AND_NULL(tmp)
   8951 	    cur = end;
   8952 	} while (*cur != 0);
   8953 
   8954     }
   8955     /*
   8956     * And now for the children...
   8957     */
   8958     child = node->children;
   8959     if (IS_SCHEMA(child, "annotation")) {
   8960 	/*
   8961 	* Add the annotation to the simple type ancestor.
   8962 	*/
   8963 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   8964 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   8965         child = child->next;
   8966     }
   8967     if (IS_SCHEMA(child, "simpleType")) {
   8968 	xmlSchemaTypePtr subtype, last = NULL;
   8969 
   8970 	/*
   8971 	* Anchor the member types in the "subtypes" field of the
   8972 	* simple type.
   8973 	*/
   8974 	while (IS_SCHEMA(child, "simpleType")) {
   8975 	    subtype = (xmlSchemaTypePtr)
   8976 		xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   8977 	    if (subtype != NULL) {
   8978 		if (last == NULL) {
   8979 		    type->subtypes = subtype;
   8980 		    last = subtype;
   8981 		} else {
   8982 		    last->next = subtype;
   8983 		    last = subtype;
   8984 		}
   8985 		last->next = NULL;
   8986 	    }
   8987 	    child = child->next;
   8988 	}
   8989     }
   8990     if (child != NULL) {
   8991 	xmlSchemaPContentErr(ctxt,
   8992 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8993 	    NULL, node, child, NULL, "(annotation?, simpleType*)");
   8994     }
   8995     if ((attr == NULL) && (type->subtypes == NULL)) {
   8996 	 /*
   8997 	* src-union-memberTypes-or-simpleTypes
   8998 	* Either the memberTypes [attribute] of the <union> element must
   8999 	* be non-empty or there must be at least one simpleType [child].
   9000 	*/
   9001 	xmlSchemaPCustomErr(ctxt,
   9002 	    XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
   9003 	    NULL, node,
   9004 	    "Either the attribute 'memberTypes' or "
   9005 	    "at least one <simpleType> child must be present", NULL);
   9006     }
   9007     return (0);
   9008 }
   9009 
   9010 /**
   9011  * xmlSchemaParseList:
   9012  * @ctxt:  a schema validation context
   9013  * @schema:  the schema being built
   9014  * @node:  a subtree containing XML Schema informations
   9015  *
   9016  * parse a XML schema List definition
   9017  * *WARNING* this interface is highly subject to change
   9018  *
   9019  * Returns -1 in case of error, 0 if the declaration is improper and
   9020  *         1 in case of success.
   9021  */
   9022 static xmlSchemaTypePtr
   9023 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   9024                    xmlNodePtr node)
   9025 {
   9026     xmlSchemaTypePtr type;
   9027     xmlNodePtr child = NULL;
   9028     xmlAttrPtr attr;
   9029 
   9030     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9031         return (NULL);
   9032     /* Not a component, don't create it. */
   9033     type = ctxt->ctxtType;
   9034     /*
   9035     * Mark the type as being of variety "list".
   9036     */
   9037     type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
   9038     /*
   9039     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
   9040     * then the `simple ur-type definition`."
   9041     */
   9042     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
   9043     /*
   9044     * Check for illegal attributes.
   9045     */
   9046     attr = node->properties;
   9047     while (attr != NULL) {
   9048 	if (attr->ns == NULL) {
   9049 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   9050 		(!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
   9051 		xmlSchemaPIllegalAttrErr(ctxt,
   9052 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9053 	    }
   9054 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9055 	    xmlSchemaPIllegalAttrErr(ctxt,
   9056 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9057 	}
   9058 	attr = attr->next;
   9059     }
   9060 
   9061     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9062 
   9063     /*
   9064     * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
   9065     * fields for holding the reference to the itemType.
   9066     *
   9067     * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
   9068     * the "ref" fields.
   9069     */
   9070     xmlSchemaPValAttrQName(ctxt, schema, NULL,
   9071 	node, "itemType", &(type->baseNs), &(type->base));
   9072     /*
   9073     * And now for the children...
   9074     */
   9075     child = node->children;
   9076     if (IS_SCHEMA(child, "annotation")) {
   9077 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   9078 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   9079         child = child->next;
   9080     }
   9081     if (IS_SCHEMA(child, "simpleType")) {
   9082 	/*
   9083 	* src-list-itemType-or-simpleType
   9084 	* Either the itemType [attribute] or the <simpleType> [child] of
   9085 	* the <list> element must be present, but not both.
   9086 	*/
   9087 	if (type->base != NULL) {
   9088 	    xmlSchemaPCustomErr(ctxt,
   9089 		XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   9090 		NULL, node,
   9091 		"The attribute 'itemType' and the <simpleType> child "
   9092 		"are mutually exclusive", NULL);
   9093 	} else {
   9094 	    type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   9095 	}
   9096         child = child->next;
   9097     } else if (type->base == NULL) {
   9098 	xmlSchemaPCustomErr(ctxt,
   9099 	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   9100 	    NULL, node,
   9101 	    "Either the attribute 'itemType' or the <simpleType> child "
   9102 	    "must be present", NULL);
   9103     }
   9104     if (child != NULL) {
   9105 	xmlSchemaPContentErr(ctxt,
   9106 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9107 	    NULL, node, child, NULL, "(annotation?, simpleType?)");
   9108     }
   9109     if ((type->base == NULL) &&
   9110 	(type->subtypes == NULL) &&
   9111 	(xmlSchemaGetPropNode(node, "itemType") == NULL)) {
   9112 	xmlSchemaPCustomErr(ctxt,
   9113 	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   9114 	    NULL, node,
   9115 	    "Either the attribute 'itemType' or the <simpleType> child "
   9116 	    "must be present", NULL);
   9117     }
   9118     return (NULL);
   9119 }
   9120 
   9121 /**
   9122  * xmlSchemaParseSimpleType:
   9123  * @ctxt:  a schema validation context
   9124  * @schema:  the schema being built
   9125  * @node:  a subtree containing XML Schema informations
   9126  *
   9127  * parse a XML schema Simple Type definition
   9128  * *WARNING* this interface is highly subject to change
   9129  *
   9130  * Returns -1 in case of error, 0 if the declaration is improper and
   9131  * 1 in case of success.
   9132  */
   9133 static xmlSchemaTypePtr
   9134 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   9135                          xmlNodePtr node, int topLevel)
   9136 {
   9137     xmlSchemaTypePtr type, oldCtxtType;
   9138     xmlNodePtr child = NULL;
   9139     const xmlChar *attrValue = NULL;
   9140     xmlAttrPtr attr;
   9141     int hasRestriction = 0;
   9142 
   9143     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9144         return (NULL);
   9145 
   9146     if (topLevel) {
   9147 	attr = xmlSchemaGetPropNode(node, "name");
   9148 	if (attr == NULL) {
   9149 	    xmlSchemaPMissingAttrErr(ctxt,
   9150 		XML_SCHEMAP_S4S_ATTR_MISSING,
   9151 		NULL, node,
   9152 		"name", NULL);
   9153 	    return (NULL);
   9154 	} else {
   9155 	    if (xmlSchemaPValAttrNode(ctxt,
   9156 		NULL, attr,
   9157 		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
   9158 		return (NULL);
   9159 	    /*
   9160 	    * Skip built-in types.
   9161 	    */
   9162 	    if (ctxt->isS4S) {
   9163 		xmlSchemaTypePtr biType;
   9164 
   9165 		if (ctxt->isRedefine) {
   9166 		    /*
   9167 		    * REDEFINE: Disallow redefinition of built-in-types.
   9168 		    * TODO: It seems that the spec does not say anything
   9169 		    * about this case.
   9170 		    */
   9171 		    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   9172 			NULL, node,
   9173 			"Redefinition of built-in simple types is not "
   9174 			"supported", NULL);
   9175 		    return(NULL);
   9176 		}
   9177 		biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
   9178 		if (biType != NULL)
   9179 		    return (biType);
   9180 	    }
   9181 	}
   9182     }
   9183     /*
   9184     * TargetNamespace:
   9185     * SPEC "The `actual value` of the targetNamespace [attribute]
   9186     * of the <schema> ancestor element information item if present,
   9187     * otherwise `absent`.
   9188     */
   9189     if (topLevel == 0) {
   9190 #ifdef ENABLE_NAMED_LOCALS
   9191         char buf[40];
   9192 #endif
   9193 	/*
   9194 	* Parse as local simple type definition.
   9195 	*/
   9196 #ifdef ENABLE_NAMED_LOCALS
   9197         snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
   9198 	type = xmlSchemaAddType(ctxt, schema,
   9199 	    XML_SCHEMA_TYPE_SIMPLE,
   9200 	    xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
   9201 	    ctxt->targetNamespace, node, 0);
   9202 #else
   9203 	type = xmlSchemaAddType(ctxt, schema,
   9204 	    XML_SCHEMA_TYPE_SIMPLE,
   9205 	    NULL, ctxt->targetNamespace, node, 0);
   9206 #endif
   9207 	if (type == NULL)
   9208 	    return (NULL);
   9209 	type->type = XML_SCHEMA_TYPE_SIMPLE;
   9210 	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   9211 	/*
   9212 	* Check for illegal attributes.
   9213 	*/
   9214 	attr = node->properties;
   9215 	while (attr != NULL) {
   9216 	    if (attr->ns == NULL) {
   9217 		if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
   9218 		    xmlSchemaPIllegalAttrErr(ctxt,
   9219 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9220 		}
   9221 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9222 		    xmlSchemaPIllegalAttrErr(ctxt,
   9223 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9224 	    }
   9225 	    attr = attr->next;
   9226 	}
   9227     } else {
   9228 	/*
   9229 	* Parse as global simple type definition.
   9230 	*
   9231 	* Note that attrValue is the value of the attribute "name" here.
   9232 	*/
   9233 	type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
   9234 	    attrValue, ctxt->targetNamespace, node, 1);
   9235 	if (type == NULL)
   9236 	    return (NULL);
   9237 	type->type = XML_SCHEMA_TYPE_SIMPLE;
   9238 	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   9239 	type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
   9240 	/*
   9241 	* Check for illegal attributes.
   9242 	*/
   9243 	attr = node->properties;
   9244 	while (attr != NULL) {
   9245 	    if (attr->ns == NULL) {
   9246 		if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   9247 		    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   9248 		    (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
   9249 		    xmlSchemaPIllegalAttrErr(ctxt,
   9250 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9251 		}
   9252 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9253 		xmlSchemaPIllegalAttrErr(ctxt,
   9254 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9255 	    }
   9256 	    attr = attr->next;
   9257 	}
   9258 	/*
   9259 	* Attribute "final".
   9260 	*/
   9261 	attr = xmlSchemaGetPropNode(node, "final");
   9262 	if (attr == NULL) {
   9263 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   9264 		type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
   9265 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
   9266 		type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
   9267 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
   9268 		type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
   9269 	} else {
   9270 	    attrValue = xmlSchemaGetProp(ctxt, node, "final");
   9271 	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
   9272 		-1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
   9273 		XML_SCHEMAS_TYPE_FINAL_LIST,
   9274 		XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
   9275 
   9276 		xmlSchemaPSimpleTypeErr(ctxt,
   9277 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   9278 		    WXS_BASIC_CAST type, (xmlNodePtr) attr,
   9279 		    NULL, "(#all | List of (list | union | restriction)",
   9280 		    attrValue, NULL, NULL, NULL);
   9281 	    }
   9282 	}
   9283     }
   9284     type->targetNamespace = ctxt->targetNamespace;
   9285     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9286     /*
   9287     * And now for the children...
   9288     */
   9289     oldCtxtType = ctxt->ctxtType;
   9290 
   9291     ctxt->ctxtType = type;
   9292 
   9293     child = node->children;
   9294     if (IS_SCHEMA(child, "annotation")) {
   9295         type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9296         child = child->next;
   9297     }
   9298     if (child == NULL) {
   9299 	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
   9300 	    NULL, node, child, NULL,
   9301 	    "(annotation?, (restriction | list | union))");
   9302     } else if (IS_SCHEMA(child, "restriction")) {
   9303         xmlSchemaParseRestriction(ctxt, schema, child,
   9304 	    XML_SCHEMA_TYPE_SIMPLE);
   9305 	hasRestriction = 1;
   9306         child = child->next;
   9307     } else if (IS_SCHEMA(child, "list")) {
   9308         xmlSchemaParseList(ctxt, schema, child);
   9309         child = child->next;
   9310     } else if (IS_SCHEMA(child, "union")) {
   9311         xmlSchemaParseUnion(ctxt, schema, child);
   9312         child = child->next;
   9313     }
   9314     if (child != NULL) {
   9315 	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9316 	    NULL, node, child, NULL,
   9317 	    "(annotation?, (restriction | list | union))");
   9318     }
   9319     /*
   9320     * REDEFINE: SPEC src-redefine (5)
   9321     * "Within the [children], each <simpleType> must have a
   9322     * <restriction> among its [children] ... the `actual value` of whose
   9323     * base [attribute] must be the same as the `actual value` of its own
   9324     * name attribute plus target namespace;"
   9325     */
   9326     if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
   9327 	xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   9328 	    NULL, node, "This is a redefinition, thus the "
   9329 	    "<simpleType> must have a <restriction> child", NULL);
   9330     }
   9331 
   9332     ctxt->ctxtType = oldCtxtType;
   9333     return (type);
   9334 }
   9335 
   9336 /**
   9337  * xmlSchemaParseModelGroupDefRef:
   9338  * @ctxt:  the parser context
   9339  * @schema: the schema being built
   9340  * @node:  the node
   9341  *
   9342  * Parses a reference to a model group definition.
   9343  *
   9344  * We will return a particle component with a qname-component or
   9345  * NULL in case of an error.
   9346  */
   9347 static xmlSchemaTreeItemPtr
   9348 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
   9349 			       xmlSchemaPtr schema,
   9350 			       xmlNodePtr node)
   9351 {
   9352     xmlSchemaParticlePtr item;
   9353     xmlNodePtr child = NULL;
   9354     xmlAttrPtr attr;
   9355     const xmlChar *ref = NULL, *refNs = NULL;
   9356     int min, max;
   9357 
   9358     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9359         return (NULL);
   9360 
   9361     attr = xmlSchemaGetPropNode(node, "ref");
   9362     if (attr == NULL) {
   9363 	xmlSchemaPMissingAttrErr(ctxt,
   9364 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   9365 	    NULL, node, "ref", NULL);
   9366 	return (NULL);
   9367     } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
   9368 	attr, &refNs, &ref) != 0) {
   9369 	return (NULL);
   9370     }
   9371     xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
   9372     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
   9373     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
   9374 	"(xs:nonNegativeInteger | unbounded)");
   9375     /*
   9376     * Check for illegal attributes.
   9377     */
   9378     attr = node->properties;
   9379     while (attr != NULL) {
   9380 	if (attr->ns == NULL) {
   9381 	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
   9382 		(!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   9383 		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
   9384 		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
   9385 		xmlSchemaPIllegalAttrErr(ctxt,
   9386 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9387 	    }
   9388 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9389 	    xmlSchemaPIllegalAttrErr(ctxt,
   9390 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9391 	}
   9392 	attr = attr->next;
   9393     }
   9394     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9395     item = xmlSchemaAddParticle(ctxt, node, min, max);
   9396     if (item == NULL)
   9397 	return (NULL);
   9398     /*
   9399     * Create a qname-reference and set as the term; it will be substituted
   9400     * for the model group after the reference has been resolved.
   9401     */
   9402     item->children = (xmlSchemaTreeItemPtr)
   9403 	xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
   9404     xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
   9405     /*
   9406     * And now for the children...
   9407     */
   9408     child = node->children;
   9409     /* TODO: Is annotation even allowed for a model group reference? */
   9410     if (IS_SCHEMA(child, "annotation")) {
   9411 	/*
   9412 	* TODO: What to do exactly with the annotation?
   9413 	*/
   9414 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9415 	child = child->next;
   9416     }
   9417     if (child != NULL) {
   9418 	xmlSchemaPContentErr(ctxt,
   9419 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9420 	    NULL, node, child, NULL,
   9421 	    "(annotation?)");
   9422     }
   9423     /*
   9424     * Corresponds to no component at all if minOccurs==maxOccurs==0.
   9425     */
   9426     if ((min == 0) && (max == 0))
   9427 	return (NULL);
   9428 
   9429     return ((xmlSchemaTreeItemPtr) item);
   9430 }
   9431 
   9432 /**
   9433  * xmlSchemaParseModelGroupDefinition:
   9434  * @ctxt:  a schema validation context
   9435  * @schema:  the schema being built
   9436  * @node:  a subtree containing XML Schema informations
   9437  *
   9438  * Parses a XML schema model group definition.
   9439  *
   9440  * Note that the contraint src-redefine (6.2) can't be applied until
   9441  * references have been resolved. So we will do this at the
   9442  * component fixup level.
   9443  *
   9444  * *WARNING* this interface is highly subject to change
   9445  *
   9446  * Returns -1 in case of error, 0 if the declaration is improper and
   9447  *         1 in case of success.
   9448  */
   9449 static xmlSchemaModelGroupDefPtr
   9450 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
   9451 				   xmlSchemaPtr schema,
   9452 				   xmlNodePtr node)
   9453 {
   9454     xmlSchemaModelGroupDefPtr item;
   9455     xmlNodePtr child = NULL;
   9456     xmlAttrPtr attr;
   9457     const xmlChar *name;
   9458 
   9459     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9460         return (NULL);
   9461 
   9462     attr = xmlSchemaGetPropNode(node, "name");
   9463     if (attr == NULL) {
   9464 	xmlSchemaPMissingAttrErr(ctxt,
   9465 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   9466 	    NULL, node,
   9467 	    "name", NULL);
   9468 	return (NULL);
   9469     } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
   9470 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   9471 	return (NULL);
   9472     }
   9473     item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
   9474 	ctxt->targetNamespace, node);
   9475     if (item == NULL)
   9476 	return (NULL);
   9477     /*
   9478     * Check for illegal attributes.
   9479     */
   9480     attr = node->properties;
   9481     while (attr != NULL) {
   9482 	if (attr->ns == NULL) {
   9483 	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   9484 		(!xmlStrEqual(attr->name, BAD_CAST "id"))) {
   9485 		xmlSchemaPIllegalAttrErr(ctxt,
   9486 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9487 	    }
   9488 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9489 	    xmlSchemaPIllegalAttrErr(ctxt,
   9490 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9491 	}
   9492 	attr = attr->next;
   9493     }
   9494     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9495     /*
   9496     * And now for the children...
   9497     */
   9498     child = node->children;
   9499     if (IS_SCHEMA(child, "annotation")) {
   9500 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9501 	child = child->next;
   9502     }
   9503     if (IS_SCHEMA(child, "all")) {
   9504 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
   9505 	    XML_SCHEMA_TYPE_ALL, 0);
   9506 	child = child->next;
   9507     } else if (IS_SCHEMA(child, "choice")) {
   9508 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
   9509 	    XML_SCHEMA_TYPE_CHOICE, 0);
   9510 	child = child->next;
   9511     } else if (IS_SCHEMA(child, "sequence")) {
   9512 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
   9513 	    XML_SCHEMA_TYPE_SEQUENCE, 0);
   9514 	child = child->next;
   9515     }
   9516 
   9517 
   9518 
   9519     if (child != NULL) {
   9520 	xmlSchemaPContentErr(ctxt,
   9521 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9522 	    NULL, node, child, NULL,
   9523 	    "(annotation?, (all | choice | sequence)?)");
   9524     }
   9525     return (item);
   9526 }
   9527 
   9528 /**
   9529  * xmlSchemaCleanupDoc:
   9530  * @ctxt:  a schema validation context
   9531  * @node:  the root of the document.
   9532  *
   9533  * removes unwanted nodes in a schemas document tree
   9534  */
   9535 static void
   9536 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
   9537 {
   9538     xmlNodePtr delete, cur;
   9539 
   9540     if ((ctxt == NULL) || (root == NULL)) return;
   9541 
   9542     /*
   9543      * Remove all the blank text nodes
   9544      */
   9545     delete = NULL;
   9546     cur = root;
   9547     while (cur != NULL) {
   9548         if (delete != NULL) {
   9549             xmlUnlinkNode(delete);
   9550             xmlFreeNode(delete);
   9551             delete = NULL;
   9552         }
   9553         if (cur->type == XML_TEXT_NODE) {
   9554             if (IS_BLANK_NODE(cur)) {
   9555                 if (xmlNodeGetSpacePreserve(cur) != 1) {
   9556                     delete = cur;
   9557                 }
   9558             }
   9559         } else if ((cur->type != XML_ELEMENT_NODE) &&
   9560                    (cur->type != XML_CDATA_SECTION_NODE)) {
   9561             delete = cur;
   9562             goto skip_children;
   9563         }
   9564 
   9565         /*
   9566          * Skip to next node
   9567          */
   9568         if (cur->children != NULL) {
   9569             if ((cur->children->type != XML_ENTITY_DECL) &&
   9570                 (cur->children->type != XML_ENTITY_REF_NODE) &&
   9571                 (cur->children->type != XML_ENTITY_NODE)) {
   9572                 cur = cur->children;
   9573                 continue;
   9574             }
   9575         }
   9576       skip_children:
   9577         if (cur->next != NULL) {
   9578             cur = cur->next;
   9579             continue;
   9580         }
   9581 
   9582         do {
   9583             cur = cur->parent;
   9584             if (cur == NULL)
   9585                 break;
   9586             if (cur == root) {
   9587                 cur = NULL;
   9588                 break;
   9589             }
   9590             if (cur->next != NULL) {
   9591                 cur = cur->next;
   9592                 break;
   9593             }
   9594         } while (cur != NULL);
   9595     }
   9596     if (delete != NULL) {
   9597         xmlUnlinkNode(delete);
   9598         xmlFreeNode(delete);
   9599         delete = NULL;
   9600     }
   9601 }
   9602 
   9603 
   9604 static void
   9605 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
   9606 {
   9607     if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
   9608 	schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
   9609 
   9610     if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
   9611 	schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
   9612 
   9613     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
   9614 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
   9615     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   9616 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
   9617     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
   9618 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
   9619     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
   9620 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
   9621 
   9622     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
   9623 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
   9624     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
   9625 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
   9626     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
   9627 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
   9628 }
   9629 
   9630 static int
   9631 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
   9632 			     xmlSchemaPtr schema,
   9633 			     xmlNodePtr node)
   9634 {
   9635     xmlAttrPtr attr;
   9636     const xmlChar *val;
   9637     int res = 0, oldErrs = ctxt->nberrors;
   9638 
   9639     /*
   9640     * Those flags should be moved to the parser context flags,
   9641     * since they are not visible at the component level. I.e.
   9642     * they are used if processing schema *documents* only.
   9643     */
   9644     res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9645     HFAILURE;
   9646 
   9647     /*
   9648     * Since the version is of type xs:token, we won't bother to
   9649     * check it.
   9650     */
   9651     /* REMOVED:
   9652     attr = xmlSchemaGetPropNode(node, "version");
   9653     if (attr != NULL) {
   9654 	res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
   9655 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
   9656 	HFAILURE;
   9657     }
   9658     */
   9659     attr = xmlSchemaGetPropNode(node, "targetNamespace");
   9660     if (attr != NULL) {
   9661 	res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
   9662 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
   9663 	HFAILURE;
   9664 	if (res != 0) {
   9665 	    ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   9666 	    goto exit;
   9667 	}
   9668     }
   9669     attr = xmlSchemaGetPropNode(node, "elementFormDefault");
   9670     if (attr != NULL) {
   9671 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9672 	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
   9673 	    XML_SCHEMAS_QUALIF_ELEM);
   9674 	HFAILURE;
   9675 	if (res != 0) {
   9676 	    xmlSchemaPSimpleTypeErr(ctxt,
   9677 		XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
   9678 		NULL, (xmlNodePtr) attr, NULL,
   9679 		"(qualified | unqualified)", val, NULL, NULL, NULL);
   9680 	}
   9681     }
   9682     attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
   9683     if (attr != NULL) {
   9684 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9685 	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
   9686 	    XML_SCHEMAS_QUALIF_ATTR);
   9687 	HFAILURE;
   9688 	if (res != 0) {
   9689 	    xmlSchemaPSimpleTypeErr(ctxt,
   9690 		XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
   9691 		NULL, (xmlNodePtr) attr, NULL,
   9692 		"(qualified | unqualified)", val, NULL, NULL, NULL);
   9693 	}
   9694     }
   9695     attr = xmlSchemaGetPropNode(node, "finalDefault");
   9696     if (attr != NULL) {
   9697 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9698 	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
   9699 	    XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
   9700 	    XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
   9701 	    -1,
   9702 	    XML_SCHEMAS_FINAL_DEFAULT_LIST,
   9703 	    XML_SCHEMAS_FINAL_DEFAULT_UNION);
   9704 	HFAILURE;
   9705 	if (res != 0) {
   9706 	    xmlSchemaPSimpleTypeErr(ctxt,
   9707 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   9708 		NULL, (xmlNodePtr) attr, NULL,
   9709 		"(#all | List of (extension | restriction | list | union))",
   9710 		val, NULL, NULL, NULL);
   9711 	}
   9712     }
   9713     attr = xmlSchemaGetPropNode(node, "blockDefault");
   9714     if (attr != NULL) {
   9715 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9716 	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
   9717 	    XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
   9718 	    XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
   9719 	    XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
   9720 	HFAILURE;
   9721 	if (res != 0) {
   9722 	    xmlSchemaPSimpleTypeErr(ctxt,
   9723 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   9724 		NULL, (xmlNodePtr) attr, NULL,
   9725 		"(#all | List of (extension | restriction | substitution))",
   9726 		val, NULL, NULL, NULL);
   9727 	}
   9728     }
   9729 
   9730 exit:
   9731     if (oldErrs != ctxt->nberrors)
   9732 	res = ctxt->err;
   9733     return(res);
   9734 exit_failure:
   9735     return(-1);
   9736 }
   9737 
   9738 /**
   9739  * xmlSchemaParseSchemaTopLevel:
   9740  * @ctxt:  a schema validation context
   9741  * @schema:  the schemas
   9742  * @nodes:  the list of top level nodes
   9743  *
   9744  * Returns the internal XML Schema structure built from the resource or
   9745  *         NULL in case of error
   9746  */
   9747 static int
   9748 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
   9749                              xmlSchemaPtr schema, xmlNodePtr nodes)
   9750 {
   9751     xmlNodePtr child;
   9752     xmlSchemaAnnotPtr annot;
   9753     int res = 0, oldErrs, tmpOldErrs;
   9754 
   9755     if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
   9756         return(-1);
   9757 
   9758     oldErrs = ctxt->nberrors;
   9759     child = nodes;
   9760     while ((IS_SCHEMA(child, "include")) ||
   9761 	   (IS_SCHEMA(child, "import")) ||
   9762 	   (IS_SCHEMA(child, "redefine")) ||
   9763 	   (IS_SCHEMA(child, "annotation"))) {
   9764 	if (IS_SCHEMA(child, "annotation")) {
   9765 	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9766 	    if (schema->annot == NULL)
   9767 		schema->annot = annot;
   9768 	    else
   9769 		xmlSchemaFreeAnnot(annot);
   9770 	} else if (IS_SCHEMA(child, "import")) {
   9771 	    tmpOldErrs = ctxt->nberrors;
   9772 	    res = xmlSchemaParseImport(ctxt, schema, child);
   9773 	    HFAILURE;
   9774 	    HSTOP(ctxt);
   9775 	    if (tmpOldErrs != ctxt->nberrors)
   9776 		goto exit;
   9777 	} else if (IS_SCHEMA(child, "include")) {
   9778 	    tmpOldErrs = ctxt->nberrors;
   9779 	    res = xmlSchemaParseInclude(ctxt, schema, child);
   9780 	    HFAILURE;
   9781 	    HSTOP(ctxt);
   9782 	    if (tmpOldErrs != ctxt->nberrors)
   9783 		goto exit;
   9784 	} else if (IS_SCHEMA(child, "redefine")) {
   9785 	    tmpOldErrs = ctxt->nberrors;
   9786 	    res = xmlSchemaParseRedefine(ctxt, schema, child);
   9787 	    HFAILURE;
   9788 	    HSTOP(ctxt);
   9789 	    if (tmpOldErrs != ctxt->nberrors)
   9790 		goto exit;
   9791 	}
   9792 	child = child->next;
   9793     }
   9794     /*
   9795     * URGENT TODO: Change the functions to return int results.
   9796     * We need especially to catch internal errors.
   9797     */
   9798     while (child != NULL) {
   9799 	if (IS_SCHEMA(child, "complexType")) {
   9800 	    xmlSchemaParseComplexType(ctxt, schema, child, 1);
   9801 	    child = child->next;
   9802 	} else if (IS_SCHEMA(child, "simpleType")) {
   9803 	    xmlSchemaParseSimpleType(ctxt, schema, child, 1);
   9804 	    child = child->next;
   9805 	} else if (IS_SCHEMA(child, "element")) {
   9806 	    xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
   9807 	    child = child->next;
   9808 	} else if (IS_SCHEMA(child, "attribute")) {
   9809 	    xmlSchemaParseGlobalAttribute(ctxt, schema, child);
   9810 	    child = child->next;
   9811 	} else if (IS_SCHEMA(child, "attributeGroup")) {
   9812 	    xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
   9813 	    child = child->next;
   9814 	} else if (IS_SCHEMA(child, "group")) {
   9815 	    xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
   9816 	    child = child->next;
   9817 	} else if (IS_SCHEMA(child, "notation")) {
   9818 	    xmlSchemaParseNotation(ctxt, schema, child);
   9819 	    child = child->next;
   9820 	} else {
   9821 	    xmlSchemaPContentErr(ctxt,
   9822 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9823 		NULL, child->parent, child,
   9824 		NULL, "((include | import | redefine | annotation)*, "
   9825 		"(((simpleType | complexType | group | attributeGroup) "
   9826 		"| element | attribute | notation), annotation*)*)");
   9827 	    child = child->next;
   9828 	}
   9829 	while (IS_SCHEMA(child, "annotation")) {
   9830 	    /*
   9831 	    * TODO: We should add all annotations.
   9832 	    */
   9833 	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9834 	    if (schema->annot == NULL)
   9835 		schema->annot = annot;
   9836 	    else
   9837 		xmlSchemaFreeAnnot(annot);
   9838 	    child = child->next;
   9839 	}
   9840     }
   9841 exit:
   9842     ctxt->ctxtType = NULL;
   9843     if (oldErrs != ctxt->nberrors)
   9844 	res = ctxt->err;
   9845     return(res);
   9846 exit_failure:
   9847     return(-1);
   9848 }
   9849 
   9850 static xmlSchemaSchemaRelationPtr
   9851 xmlSchemaSchemaRelationCreate(void)
   9852 {
   9853     xmlSchemaSchemaRelationPtr ret;
   9854 
   9855     ret = (xmlSchemaSchemaRelationPtr)
   9856 	xmlMalloc(sizeof(xmlSchemaSchemaRelation));
   9857     if (ret == NULL) {
   9858 	xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
   9859 	return(NULL);
   9860     }
   9861     memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
   9862     return(ret);
   9863 }
   9864 
   9865 #if 0
   9866 static void
   9867 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
   9868 {
   9869     xmlFree(rel);
   9870 }
   9871 #endif
   9872 
   9873 static void
   9874 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
   9875 {
   9876     xmlSchemaRedefPtr prev;
   9877 
   9878     while (redef != NULL) {
   9879 	prev = redef;
   9880 	redef = redef->next;
   9881 	xmlFree(prev);
   9882     }
   9883 }
   9884 
   9885 static void
   9886 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
   9887 {
   9888     /*
   9889     * After the construction context has been freed, there will be
   9890     * no schema graph available any more. Only the schema buckets
   9891     * will stay alive, which are put into the "schemasImports" and
   9892     * "includes" slots of the xmlSchema.
   9893     */
   9894     if (con->buckets != NULL)
   9895 	xmlSchemaItemListFree(con->buckets);
   9896     if (con->pending != NULL)
   9897 	xmlSchemaItemListFree(con->pending);
   9898     if (con->substGroups != NULL)
   9899 	xmlHashFree(con->substGroups,
   9900 	    (xmlHashDeallocator) xmlSchemaSubstGroupFree);
   9901     if (con->redefs != NULL)
   9902 	xmlSchemaRedefListFree(con->redefs);
   9903     if (con->dict != NULL)
   9904 	xmlDictFree(con->dict);
   9905     xmlFree(con);
   9906 }
   9907 
   9908 static xmlSchemaConstructionCtxtPtr
   9909 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
   9910 {
   9911     xmlSchemaConstructionCtxtPtr ret;
   9912 
   9913     ret = (xmlSchemaConstructionCtxtPtr)
   9914 	xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
   9915     if (ret == NULL) {
   9916         xmlSchemaPErrMemory(NULL,
   9917 	    "allocating schema construction context", NULL);
   9918         return (NULL);
   9919     }
   9920     memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
   9921 
   9922     ret->buckets = xmlSchemaItemListCreate();
   9923     if (ret->buckets == NULL) {
   9924 	xmlSchemaPErrMemory(NULL,
   9925 	    "allocating list of schema buckets", NULL);
   9926 	xmlFree(ret);
   9927         return (NULL);
   9928     }
   9929     ret->pending = xmlSchemaItemListCreate();
   9930     if (ret->pending == NULL) {
   9931 	xmlSchemaPErrMemory(NULL,
   9932 	    "allocating list of pending global components", NULL);
   9933 	xmlSchemaConstructionCtxtFree(ret);
   9934         return (NULL);
   9935     }
   9936     ret->dict = dict;
   9937     xmlDictReference(dict);
   9938     return(ret);
   9939 }
   9940 
   9941 static xmlSchemaParserCtxtPtr
   9942 xmlSchemaParserCtxtCreate(void)
   9943 {
   9944     xmlSchemaParserCtxtPtr ret;
   9945 
   9946     ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
   9947     if (ret == NULL) {
   9948         xmlSchemaPErrMemory(NULL, "allocating schema parser context",
   9949                             NULL);
   9950         return (NULL);
   9951     }
   9952     memset(ret, 0, sizeof(xmlSchemaParserCtxt));
   9953     ret->type = XML_SCHEMA_CTXT_PARSER;
   9954     ret->attrProhibs = xmlSchemaItemListCreate();
   9955     if (ret->attrProhibs == NULL) {
   9956 	xmlFree(ret);
   9957 	return(NULL);
   9958     }
   9959     return(ret);
   9960 }
   9961 
   9962 /**
   9963  * xmlSchemaNewParserCtxtUseDict:
   9964  * @URL:  the location of the schema
   9965  * @dict: the dictionary to be used
   9966  *
   9967  * Create an XML Schemas parse context for that file/resource expected
   9968  * to contain an XML Schemas file.
   9969  *
   9970  * Returns the parser context or NULL in case of error
   9971  */
   9972 static xmlSchemaParserCtxtPtr
   9973 xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
   9974 {
   9975     xmlSchemaParserCtxtPtr ret;
   9976 
   9977     ret = xmlSchemaParserCtxtCreate();
   9978     if (ret == NULL)
   9979         return (NULL);
   9980     ret->dict = dict;
   9981     xmlDictReference(dict);
   9982     if (URL != NULL)
   9983 	ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
   9984     return (ret);
   9985 }
   9986 
   9987 static int
   9988 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
   9989 {
   9990     if (vctxt->pctxt == NULL) {
   9991         if (vctxt->schema != NULL)
   9992 	    vctxt->pctxt =
   9993 		xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
   9994 	else
   9995 	    vctxt->pctxt = xmlSchemaNewParserCtxt("*");
   9996 	if (vctxt->pctxt == NULL) {
   9997 	    VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
   9998 		"failed to create a temp. parser context");
   9999 	    return (-1);
   10000 	}
   10001 	/* TODO: Pass user data. */
   10002 	xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
   10003 	    vctxt->warning, vctxt->errCtxt);
   10004 	xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
   10005 	    vctxt->errCtxt);
   10006     }
   10007     return (0);
   10008 }
   10009 
   10010 /**
   10011  * xmlSchemaGetSchemaBucket:
   10012  * @pctxt: the schema parser context
   10013  * @schemaLocation: the URI of the schema document
   10014  *
   10015  * Returns a schema bucket if it was already parsed.
   10016  *
   10017  * Returns a schema bucket if it was already parsed from
   10018  *         @schemaLocation, NULL otherwise.
   10019  */
   10020 static xmlSchemaBucketPtr
   10021 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
   10022 			    const xmlChar *schemaLocation)
   10023 {
   10024     xmlSchemaBucketPtr cur;
   10025     xmlSchemaItemListPtr list;
   10026 
   10027     list = pctxt->constructor->buckets;
   10028     if (list->nbItems == 0)
   10029 	return(NULL);
   10030     else {
   10031 	int i;
   10032 	for (i = 0; i < list->nbItems; i++) {
   10033 	    cur = (xmlSchemaBucketPtr) list->items[i];
   10034 	    /* Pointer comparison! */
   10035 	    if (cur->schemaLocation == schemaLocation)
   10036 		return(cur);
   10037 	}
   10038     }
   10039     return(NULL);
   10040 }
   10041 
   10042 static xmlSchemaBucketPtr
   10043 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
   10044 				     const xmlChar *schemaLocation,
   10045 				     const xmlChar *targetNamespace)
   10046 {
   10047     xmlSchemaBucketPtr cur;
   10048     xmlSchemaItemListPtr list;
   10049 
   10050     list = pctxt->constructor->buckets;
   10051     if (list->nbItems == 0)
   10052 	return(NULL);
   10053     else {
   10054 	int i;
   10055 	for (i = 0; i < list->nbItems; i++) {
   10056 	    cur = (xmlSchemaBucketPtr) list->items[i];
   10057 	    /* Pointer comparison! */
   10058 	    if ((cur->origTargetNamespace == NULL) &&
   10059 		(cur->schemaLocation == schemaLocation) &&
   10060 		(cur->targetNamespace == targetNamespace))
   10061 		return(cur);
   10062 	}
   10063     }
   10064     return(NULL);
   10065 }
   10066 
   10067 
   10068 #define IS_BAD_SCHEMA_DOC(b) \
   10069     (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
   10070 
   10071 static xmlSchemaBucketPtr
   10072 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
   10073 				 const xmlChar *targetNamespace,
   10074 				 int imported)
   10075 {
   10076     xmlSchemaBucketPtr cur;
   10077     xmlSchemaItemListPtr list;
   10078 
   10079     list = pctxt->constructor->buckets;
   10080     if (list->nbItems == 0)
   10081 	return(NULL);
   10082     else {
   10083 	int i;
   10084 	for (i = 0; i < list->nbItems; i++) {
   10085 	    cur = (xmlSchemaBucketPtr) list->items[i];
   10086 	    if ((! IS_BAD_SCHEMA_DOC(cur)) &&
   10087 		(cur->origTargetNamespace == targetNamespace) &&
   10088 		((imported && cur->imported) ||
   10089 		 ((!imported) && (!cur->imported))))
   10090 		return(cur);
   10091 	}
   10092     }
   10093     return(NULL);
   10094 }
   10095 
   10096 static int
   10097 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
   10098 		     xmlSchemaPtr schema,
   10099 		     xmlSchemaBucketPtr bucket)
   10100 {
   10101     int oldFlags;
   10102     xmlDocPtr oldDoc;
   10103     xmlNodePtr node;
   10104     int ret, oldErrs;
   10105     xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
   10106 
   10107     /*
   10108     * Save old values; reset the *main* schema.
   10109     * URGENT TODO: This is not good; move the per-document information
   10110     * to the parser. Get rid of passing the main schema to the
   10111     * parsing functions.
   10112     */
   10113     oldFlags = schema->flags;
   10114     oldDoc = schema->doc;
   10115     if (schema->flags != 0)
   10116 	xmlSchemaClearSchemaDefaults(schema);
   10117     schema->doc = bucket->doc;
   10118     pctxt->schema = schema;
   10119     /*
   10120     * Keep the current target namespace on the parser *not* on the
   10121     * main schema.
   10122     */
   10123     pctxt->targetNamespace = bucket->targetNamespace;
   10124     WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
   10125 
   10126     if ((bucket->targetNamespace != NULL) &&
   10127 	xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
   10128 	/*
   10129 	* We are parsing the schema for schemas!
   10130 	*/
   10131 	pctxt->isS4S = 1;
   10132     }
   10133     /* Mark it as parsed, even if parsing fails. */
   10134     bucket->parsed++;
   10135     /* Compile the schema doc. */
   10136     node = xmlDocGetRootElement(bucket->doc);
   10137     ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
   10138     if (ret != 0)
   10139 	goto exit;
   10140     /* An empty schema; just get out. */
   10141     if (node->children == NULL)
   10142 	goto exit;
   10143     oldErrs = pctxt->nberrors;
   10144     ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
   10145     if (ret != 0)
   10146 	goto exit;
   10147     /*
   10148     * TODO: Not nice, but I'm not 100% sure we will get always an error
   10149     * as a result of the obove functions; so better rely on pctxt->err
   10150     * as well.
   10151     */
   10152     if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
   10153 	ret = pctxt->err;
   10154 	goto exit;
   10155     }
   10156 
   10157 exit:
   10158     WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
   10159     /* Restore schema values. */
   10160     schema->doc = oldDoc;
   10161     schema->flags = oldFlags;
   10162     return(ret);
   10163 }
   10164 
   10165 static int
   10166 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
   10167 		     xmlSchemaPtr schema,
   10168 		     xmlSchemaBucketPtr bucket)
   10169 {
   10170     xmlSchemaParserCtxtPtr newpctxt;
   10171     int res = 0;
   10172 
   10173     if (bucket == NULL)
   10174 	return(0);
   10175     if (bucket->parsed) {
   10176 	PERROR_INT("xmlSchemaParseNewDoc",
   10177 	    "reparsing a schema doc");
   10178 	return(-1);
   10179     }
   10180     if (bucket->doc == NULL) {
   10181 	PERROR_INT("xmlSchemaParseNewDoc",
   10182 	    "parsing a schema doc, but there's no doc");
   10183 	return(-1);
   10184     }
   10185     if (pctxt->constructor == NULL) {
   10186 	PERROR_INT("xmlSchemaParseNewDoc",
   10187 	    "no constructor");
   10188 	return(-1);
   10189     }
   10190     /* Create and init the temporary parser context. */
   10191     newpctxt = xmlSchemaNewParserCtxtUseDict(
   10192 	(const char *) bucket->schemaLocation, pctxt->dict);
   10193     if (newpctxt == NULL)
   10194 	return(-1);
   10195     newpctxt->constructor = pctxt->constructor;
   10196     /*
   10197     * TODO: Can we avoid that the parser knows about the main schema?
   10198     * It would be better if he knows about the current schema bucket
   10199     * only.
   10200     */
   10201     newpctxt->schema = schema;
   10202     xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
   10203 	pctxt->errCtxt);
   10204     xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
   10205 	pctxt->errCtxt);
   10206     newpctxt->counter = pctxt->counter;
   10207 
   10208 
   10209     res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
   10210 
   10211     /* Channel back errors and cleanup the temporary parser context. */
   10212     if (res != 0)
   10213 	pctxt->err = res;
   10214     pctxt->nberrors += newpctxt->nberrors;
   10215     pctxt->counter = newpctxt->counter;
   10216     newpctxt->constructor = NULL;
   10217     /* Free the parser context. */
   10218     xmlSchemaFreeParserCtxt(newpctxt);
   10219     return(res);
   10220 }
   10221 
   10222 static void
   10223 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
   10224 				xmlSchemaSchemaRelationPtr rel)
   10225 {
   10226     xmlSchemaSchemaRelationPtr cur = bucket->relations;
   10227 
   10228     if (cur == NULL) {
   10229 	bucket->relations = rel;
   10230 	return;
   10231     }
   10232     while (cur->next != NULL)
   10233 	cur = cur->next;
   10234     cur->next = rel;
   10235 }
   10236 
   10237 
   10238 static const xmlChar *
   10239 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
   10240 			  xmlNodePtr ctxtNode)
   10241 {
   10242     /*
   10243     * Build an absolue location URI.
   10244     */
   10245     if (location != NULL) {
   10246 	if (ctxtNode == NULL)
   10247 	    return(location);
   10248 	else {
   10249 	    xmlChar *base, *URI;
   10250 	    const xmlChar *ret = NULL;
   10251 
   10252 	    base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
   10253 	    if (base == NULL) {
   10254 		URI = xmlBuildURI(location, ctxtNode->doc->URL);
   10255 	    } else {
   10256 		URI = xmlBuildURI(location, base);
   10257 		xmlFree(base);
   10258 	    }
   10259 	    if (URI != NULL) {
   10260 		ret = xmlDictLookup(dict, URI, -1);
   10261 		xmlFree(URI);
   10262 		return(ret);
   10263 	    }
   10264 	}
   10265     }
   10266     return(NULL);
   10267 }
   10268 
   10269 
   10270 
   10271 /**
   10272  * xmlSchemaAddSchemaDoc:
   10273  * @pctxt:  a schema validation context
   10274  * @schema:  the schema being built
   10275  * @node:  a subtree containing XML Schema informations
   10276  *
   10277  * Parse an included (and to-be-redefined) XML schema document.
   10278  *
   10279  * Returns 0 on success, a positive error code on errors and
   10280  *         -1 in case of an internal or API error.
   10281  */
   10282 
   10283 static int
   10284 xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
   10285 		int type, /* import or include or redefine */
   10286 		const xmlChar *schemaLocation,
   10287 		xmlDocPtr schemaDoc,
   10288 		const char *schemaBuffer,
   10289 		int schemaBufferLen,
   10290 		xmlNodePtr invokingNode,
   10291 		const xmlChar *sourceTargetNamespace,
   10292 		const xmlChar *importNamespace,
   10293 		xmlSchemaBucketPtr *bucket)
   10294 {
   10295     const xmlChar *targetNamespace = NULL;
   10296     xmlSchemaSchemaRelationPtr relation = NULL;
   10297     xmlDocPtr doc = NULL;
   10298     int res = 0, err = 0, located = 0, preserveDoc = 0;
   10299     xmlSchemaBucketPtr bkt = NULL;
   10300 
   10301     if (bucket != NULL)
   10302 	*bucket = NULL;
   10303 
   10304     switch (type) {
   10305 	case XML_SCHEMA_SCHEMA_IMPORT:
   10306 	case XML_SCHEMA_SCHEMA_MAIN:
   10307 	    err = XML_SCHEMAP_SRC_IMPORT;
   10308 	    break;
   10309 	case XML_SCHEMA_SCHEMA_INCLUDE:
   10310 	    err = XML_SCHEMAP_SRC_INCLUDE;
   10311 	    break;
   10312 	case XML_SCHEMA_SCHEMA_REDEFINE:
   10313 	    err = XML_SCHEMAP_SRC_REDEFINE;
   10314 	    break;
   10315     }
   10316 
   10317 
   10318     /* Special handling for the main schema:
   10319     * skip the location and relation logic and just parse the doc.
   10320     * We need just a bucket to be returned in this case.
   10321     */
   10322     if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
   10323 	goto doc_load;
   10324 
   10325     /* Note that we expect the location to be an absulute URI. */
   10326     if (schemaLocation != NULL) {
   10327 	bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
   10328 	if ((bkt != NULL) &&
   10329 	    (pctxt->constructor->bucket == bkt)) {
   10330 	    /* Report self-imports/inclusions/redefinitions. */
   10331 
   10332 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
   10333 		invokingNode, NULL,
   10334 		"The schema must not import/include/redefine itself",
   10335 		NULL, NULL);
   10336 	    goto exit;
   10337 	}
   10338     }
   10339     /*
   10340     * Create a relation for the graph of schemas.
   10341     */
   10342     relation = xmlSchemaSchemaRelationCreate();
   10343     if (relation == NULL)
   10344 	return(-1);
   10345     xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
   10346 	relation);
   10347     relation->type = type;
   10348 
   10349     /*
   10350     * Save the namespace import information.
   10351     */
   10352     if (WXS_IS_BUCKET_IMPMAIN(type)) {
   10353 	relation->importNamespace = importNamespace;
   10354 	if (schemaLocation == NULL) {
   10355 	    /*
   10356 	    * No location; this is just an import of the namespace.
   10357 	    * Note that we don't assign a bucket to the relation
   10358 	    * in this case.
   10359 	    */
   10360 	    goto exit;
   10361 	}
   10362 	targetNamespace = importNamespace;
   10363     }
   10364 
   10365     /* Did we already fetch the doc? */
   10366     if (bkt != NULL) {
   10367 	if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
   10368 	    /*
   10369 	    * We included/redefined and then try to import a schema,
   10370 	    * but the new location provided for import was different.
   10371 	    */
   10372 	    if (schemaLocation == NULL)
   10373 		schemaLocation = BAD_CAST "in_memory_buffer";
   10374 	    if (!xmlStrEqual(schemaLocation,
   10375 		bkt->schemaLocation)) {
   10376 		xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
   10377 		    invokingNode, NULL,
   10378 		    "The schema document '%s' cannot be imported, since "
   10379 		    "it was already included or redefined",
   10380 		    schemaLocation, NULL);
   10381 		goto exit;
   10382 	    }
   10383 	} else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
   10384 	    /*
   10385 	    * We imported and then try to include/redefine a schema,
   10386 	    * but the new location provided for the include/redefine
   10387 	    * was different.
   10388 	    */
   10389 	    if (schemaLocation == NULL)
   10390 		schemaLocation = BAD_CAST "in_memory_buffer";
   10391 	    if (!xmlStrEqual(schemaLocation,
   10392 		bkt->schemaLocation)) {
   10393 		xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
   10394 		    invokingNode, NULL,
   10395 		    "The schema document '%s' cannot be included or "
   10396 		    "redefined, since it was already imported",
   10397 		    schemaLocation, NULL);
   10398 		goto exit;
   10399 	    }
   10400 	}
   10401     }
   10402 
   10403     if (WXS_IS_BUCKET_IMPMAIN(type)) {
   10404 	/*
   10405 	* Given that the schemaLocation [attribute] is only a hint, it is open
   10406 	* to applications to ignore all but the first <import> for a given
   10407 	* namespace, regardless of the `actual value` of schemaLocation, but
   10408 	* such a strategy risks missing useful information when new
   10409 	* schemaLocations are offered.
   10410 	*
   10411 	* We will use the first <import> that comes with a location.
   10412 	* Further <import>s *with* a location, will result in an error.
   10413 	* TODO: Better would be to just report a warning here, but
   10414 	* we'll try it this way until someone complains.
   10415 	*
   10416 	* Schema Document Location Strategy:
   10417 	* 3 Based on the namespace name, identify an existing schema document,
   10418 	* either as a resource which is an XML document or a <schema> element
   10419 	* information item, in some local schema repository;
   10420 	* 5 Attempt to resolve the namespace name to locate such a resource.
   10421 	*
   10422 	* NOTE: (3) and (5) are not supported.
   10423 	*/
   10424 	if (bkt != NULL) {
   10425 	    relation->bucket = bkt;
   10426 	    goto exit;
   10427 	}
   10428 	bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
   10429 	    importNamespace, 1);
   10430 
   10431 	if (bkt != NULL) {
   10432 	    relation->bucket = bkt;
   10433 	    if (bkt->schemaLocation == NULL) {
   10434 		/* First given location of the schema; load the doc. */
   10435 		bkt->schemaLocation = schemaLocation;
   10436 	    } else {
   10437 		if (!xmlStrEqual(schemaLocation,
   10438 		    bkt->schemaLocation)) {
   10439 		    /*
   10440 		    * Additional location given; just skip it.
   10441 		    * URGENT TODO: We should report a warning here.
   10442 		    * res = XML_SCHEMAP_SRC_IMPORT;
   10443 		    */
   10444 		    if (schemaLocation == NULL)
   10445 			schemaLocation = BAD_CAST "in_memory_buffer";
   10446 
   10447 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   10448 			XML_SCHEMAP_WARN_SKIP_SCHEMA,
   10449 			invokingNode, NULL,
   10450 			"Skipping import of schema located at '%s' for the "
   10451 			"namespace '%s', since this namespace was already "
   10452 			"imported with the schema located at '%s'",
   10453 			schemaLocation, importNamespace, bkt->schemaLocation);
   10454 		}
   10455 		goto exit;
   10456 	    }
   10457 	}
   10458 	/*
   10459 	* No bucket + first location: load the doc and create a
   10460 	* bucket.
   10461 	*/
   10462     } else {
   10463 	/* <include> and <redefine> */
   10464 	if (bkt != NULL) {
   10465 
   10466 	    if ((bkt->origTargetNamespace == NULL) &&
   10467 		(bkt->targetNamespace != sourceTargetNamespace)) {
   10468 		xmlSchemaBucketPtr chamel;
   10469 
   10470 		/*
   10471 		* Chameleon include/redefine: skip loading only if it was
   10472 		* aleady build for the targetNamespace of the including
   10473 		* schema.
   10474 		*/
   10475 		/*
   10476 		* URGENT TODO: If the schema is a chameleon-include then copy
   10477 		* the components into the including schema and modify the
   10478 		* targetNamespace of those components, do nothing otherwise.
   10479 		* NOTE: This is currently worked-around by compiling the
   10480 		* chameleon for every destinct including targetNamespace; thus
   10481 		* not performant at the moment.
   10482 		* TODO: Check when the namespace in wildcards for chameleons
   10483 		* needs to be converted: before we built wildcard intersections
   10484 		* or after.
   10485 		*   Answer: after!
   10486 		*/
   10487 		chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
   10488 		    schemaLocation, sourceTargetNamespace);
   10489 		if (chamel != NULL) {
   10490 		    /* A fitting chameleon was already parsed; NOP. */
   10491 		    relation->bucket = chamel;
   10492 		    goto exit;
   10493 		}
   10494 		/*
   10495 		* We need to parse the chameleon again for a different
   10496 		* targetNamespace.
   10497 		* CHAMELEON TODO: Optimize this by only parsing the
   10498 		* chameleon once, and then copying the components to
   10499 		* the new targetNamespace.
   10500 		*/
   10501 		bkt = NULL;
   10502 	    } else {
   10503 		relation->bucket = bkt;
   10504 		goto exit;
   10505 	    }
   10506 	}
   10507     }
   10508     if ((bkt != NULL) && (bkt->doc != NULL)) {
   10509 	PERROR_INT("xmlSchemaAddSchemaDoc",
   10510 	    "trying to load a schema doc, but a doc is already "
   10511 	    "assigned to the schema bucket");
   10512 	goto exit_failure;
   10513     }
   10514 
   10515 doc_load:
   10516     /*
   10517     * Load the document.
   10518     */
   10519     if (schemaDoc != NULL) {
   10520 	doc = schemaDoc;
   10521 	/* Don' free this one, since it was provided by the caller. */
   10522 	preserveDoc = 1;
   10523 	/* TODO: Does the context or the doc hold the location? */
   10524 	if (schemaDoc->URL != NULL)
   10525 	    schemaLocation = xmlDictLookup(pctxt->dict,
   10526 		schemaDoc->URL, -1);
   10527         else
   10528 	    schemaLocation = BAD_CAST "in_memory_buffer";
   10529     } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
   10530 	xmlParserCtxtPtr parserCtxt;
   10531 
   10532 	parserCtxt = xmlNewParserCtxt();
   10533 	if (parserCtxt == NULL) {
   10534 	    xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
   10535 		"allocating a parser context", NULL);
   10536 	    goto exit_failure;
   10537 	}
   10538 	if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
   10539 	    /*
   10540 	    * TODO: Do we have to burden the schema parser dict with all
   10541 	    * the content of the schema doc?
   10542 	    */
   10543 	    xmlDictFree(parserCtxt->dict);
   10544 	    parserCtxt->dict = pctxt->dict;
   10545 	    xmlDictReference(parserCtxt->dict);
   10546 	}
   10547 	if (schemaLocation != NULL) {
   10548 	    /* Parse from file. */
   10549 	    doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
   10550 		NULL, SCHEMAS_PARSE_OPTIONS);
   10551 	} else if (schemaBuffer != NULL) {
   10552 	    /* Parse from memory buffer. */
   10553 	    doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
   10554 		NULL, NULL, SCHEMAS_PARSE_OPTIONS);
   10555 	    schemaLocation = BAD_CAST "in_memory_buffer";
   10556 	    if (doc != NULL)
   10557 		doc->URL = xmlStrdup(schemaLocation);
   10558 	}
   10559 	/*
   10560 	* For <import>:
   10561 	* 2.1 The referent is (a fragment of) a resource which is an
   10562 	* XML document (see clause 1.1), which in turn corresponds to
   10563 	* a <schema> element information item in a well-formed information
   10564 	* set, which in turn corresponds to a valid schema.
   10565 	* TODO: (2.1) fragments of XML documents are not supported.
   10566 	*
   10567 	* 2.2 The referent is a <schema> element information item in
   10568 	* a well-formed information set, which in turn corresponds
   10569 	* to a valid schema.
   10570 	* TODO: (2.2) is not supported.
   10571 	*/
   10572 	if (doc == NULL) {
   10573 	    xmlErrorPtr lerr;
   10574 	    lerr = xmlGetLastError();
   10575 	    /*
   10576 	    * Check if this a parser error, or if the document could
   10577 	    * just not be located.
   10578 	    * TODO: Try to find specific error codes to react only on
   10579 	    * localisation failures.
   10580 	    */
   10581 	    if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
   10582 		/*
   10583 		* We assume a parser error here.
   10584 		*/
   10585 		located = 1;
   10586 		/* TODO: Error code ?? */
   10587 		res = XML_SCHEMAP_SRC_IMPORT_2_1;
   10588 		xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
   10589 		    invokingNode, NULL,
   10590 		    "Failed to parse the XML resource '%s'",
   10591 		    schemaLocation, NULL);
   10592 	    }
   10593 	}
   10594 	xmlFreeParserCtxt(parserCtxt);
   10595 	if ((doc == NULL) && located)
   10596 	    goto exit_error;
   10597     } else {
   10598 	xmlSchemaPErr(pctxt, NULL,
   10599 	    XML_SCHEMAP_NOTHING_TO_PARSE,
   10600 	    "No information for parsing was provided with the "
   10601 	    "given schema parser context.\n",
   10602 	    NULL, NULL);
   10603 	goto exit_failure;
   10604     }
   10605     /*
   10606     * Preprocess the document.
   10607     */
   10608     if (doc != NULL) {
   10609 	xmlNodePtr docElem = NULL;
   10610 
   10611 	located = 1;
   10612 	docElem = xmlDocGetRootElement(doc);
   10613 	if (docElem == NULL) {
   10614 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
   10615 		invokingNode, NULL,
   10616 		"The document '%s' has no document element",
   10617 		schemaLocation, NULL);
   10618 	    goto exit_error;
   10619 	}
   10620 	/*
   10621 	* Remove all the blank text nodes.
   10622 	*/
   10623 	xmlSchemaCleanupDoc(pctxt, docElem);
   10624 	/*
   10625 	* Check the schema's top level element.
   10626 	*/
   10627 	if (!IS_SCHEMA(docElem, "schema")) {
   10628 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
   10629 		invokingNode, NULL,
   10630 		"The XML document '%s' is not a schema document",
   10631 		schemaLocation, NULL);
   10632 	    goto exit_error;
   10633 	}
   10634 	/*
   10635 	* Note that we don't apply a type check for the
   10636 	* targetNamespace value here.
   10637 	*/
   10638 	targetNamespace = xmlSchemaGetProp(pctxt, docElem,
   10639 	    "targetNamespace");
   10640     }
   10641 
   10642 /* after_doc_loading: */
   10643     if ((bkt == NULL) && located) {
   10644 	/* Only create a bucket if the schema was located. */
   10645         bkt = xmlSchemaBucketCreate(pctxt, type,
   10646 	    targetNamespace);
   10647 	if (bkt == NULL)
   10648 	    goto exit_failure;
   10649     }
   10650     if (bkt != NULL) {
   10651 	bkt->schemaLocation = schemaLocation;
   10652 	bkt->located = located;
   10653 	if (doc != NULL) {
   10654 	    bkt->doc = doc;
   10655 	    bkt->targetNamespace = targetNamespace;
   10656 	    bkt->origTargetNamespace = targetNamespace;
   10657 	    if (preserveDoc)
   10658 		bkt->preserveDoc = 1;
   10659 	}
   10660 	if (WXS_IS_BUCKET_IMPMAIN(type))
   10661 	    bkt->imported++;
   10662 	    /*
   10663 	    * Add it to the graph of schemas.
   10664 	    */
   10665 	if (relation != NULL)
   10666 	    relation->bucket = bkt;
   10667     }
   10668 
   10669 exit:
   10670     /*
   10671     * Return the bucket explicitely; this is needed for the
   10672     * main schema.
   10673     */
   10674     if (bucket != NULL)
   10675 	*bucket = bkt;
   10676     return (0);
   10677 
   10678 exit_error:
   10679     if ((doc != NULL) && (! preserveDoc)) {
   10680 	xmlFreeDoc(doc);
   10681 	if (bkt != NULL)
   10682 	    bkt->doc = NULL;
   10683     }
   10684     return(pctxt->err);
   10685 
   10686 exit_failure:
   10687     if ((doc != NULL) && (! preserveDoc)) {
   10688 	xmlFreeDoc(doc);
   10689 	if (bkt != NULL)
   10690 	    bkt->doc = NULL;
   10691     }
   10692     return (-1);
   10693 }
   10694 
   10695 /**
   10696  * xmlSchemaParseImport:
   10697  * @ctxt:  a schema validation context
   10698  * @schema:  the schema being built
   10699  * @node:  a subtree containing XML Schema informations
   10700  *
   10701  * parse a XML schema Import definition
   10702  * *WARNING* this interface is highly subject to change
   10703  *
   10704  * Returns 0 in case of success, a positive error code if
   10705  * not valid and -1 in case of an internal error.
   10706  */
   10707 static int
   10708 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
   10709                      xmlNodePtr node)
   10710 {
   10711     xmlNodePtr child;
   10712     const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
   10713     const xmlChar *thisTargetNamespace;
   10714     xmlAttrPtr attr;
   10715     int ret = 0;
   10716     xmlSchemaBucketPtr bucket = NULL;
   10717 
   10718     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   10719         return (-1);
   10720 
   10721     /*
   10722     * Check for illegal attributes.
   10723     */
   10724     attr = node->properties;
   10725     while (attr != NULL) {
   10726 	if (attr->ns == NULL) {
   10727 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   10728 		(!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
   10729 		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
   10730 		xmlSchemaPIllegalAttrErr(pctxt,
   10731 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10732 	    }
   10733 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   10734 	    xmlSchemaPIllegalAttrErr(pctxt,
   10735 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10736 	}
   10737 	attr = attr->next;
   10738     }
   10739     /*
   10740     * Extract and validate attributes.
   10741     */
   10742     if (xmlSchemaPValAttr(pctxt, NULL, node,
   10743 	"namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10744 	&namespaceName) != 0) {
   10745 	xmlSchemaPSimpleTypeErr(pctxt,
   10746 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   10747 	    NULL, node,
   10748 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10749 	    NULL, namespaceName, NULL, NULL, NULL);
   10750 	return (pctxt->err);
   10751     }
   10752 
   10753     if (xmlSchemaPValAttr(pctxt, NULL, node,
   10754 	"schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10755 	&schemaLocation) != 0) {
   10756 	xmlSchemaPSimpleTypeErr(pctxt,
   10757 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   10758 	    NULL, node,
   10759 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10760 	    NULL, schemaLocation, NULL, NULL, NULL);
   10761 	return (pctxt->err);
   10762     }
   10763     /*
   10764     * And now for the children...
   10765     */
   10766     child = node->children;
   10767     if (IS_SCHEMA(child, "annotation")) {
   10768         /*
   10769          * the annotation here is simply discarded ...
   10770 	 * TODO: really?
   10771          */
   10772         child = child->next;
   10773     }
   10774     if (child != NULL) {
   10775 	xmlSchemaPContentErr(pctxt,
   10776 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   10777 	    NULL, node, child, NULL,
   10778 	    "(annotation?)");
   10779     }
   10780     /*
   10781     * Apply additional constraints.
   10782     *
   10783     * Note that it is important to use the original @targetNamespace
   10784     * (or none at all), to rule out imports of schemas _with_ a
   10785     * @targetNamespace if the importing schema is a chameleon schema
   10786     * (with no @targetNamespace).
   10787     */
   10788     thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
   10789     if (namespaceName != NULL) {
   10790 	/*
   10791 	* 1.1 If the namespace [attribute] is present, then its `actual value`
   10792 	* must not match the `actual value` of the enclosing <schema>'s
   10793 	* targetNamespace [attribute].
   10794 	*/
   10795 	if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
   10796 	    xmlSchemaPCustomErr(pctxt,
   10797 		XML_SCHEMAP_SRC_IMPORT_1_1,
   10798 		NULL, node,
   10799 		"The value of the attribute 'namespace' must not match "
   10800 		"the target namespace '%s' of the importing schema",
   10801 		thisTargetNamespace);
   10802 	    return (pctxt->err);
   10803 	}
   10804     } else {
   10805 	/*
   10806 	* 1.2 If the namespace [attribute] is not present, then the enclosing
   10807 	* <schema> must have a targetNamespace [attribute].
   10808 	*/
   10809 	if (thisTargetNamespace == NULL) {
   10810 	    xmlSchemaPCustomErr(pctxt,
   10811 		XML_SCHEMAP_SRC_IMPORT_1_2,
   10812 		NULL, node,
   10813 		"The attribute 'namespace' must be existent if "
   10814 		"the importing schema has no target namespace",
   10815 		NULL);
   10816 	    return (pctxt->err);
   10817 	}
   10818     }
   10819     /*
   10820     * Locate and acquire the schema document.
   10821     */
   10822     if (schemaLocation != NULL)
   10823 	schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
   10824 	    schemaLocation, node);
   10825     ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
   10826 	schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
   10827 	namespaceName, &bucket);
   10828 
   10829     if (ret != 0)
   10830 	return(ret);
   10831 
   10832     /*
   10833     * For <import>: "It is *not* an error for the application
   10834     * schema reference strategy to fail."
   10835     * So just don't parse if no schema document was found.
   10836     * Note that we will get no bucket if the schema could not be
   10837     * located or if there was no schemaLocation.
   10838     */
   10839     if ((bucket == NULL) && (schemaLocation != NULL)) {
   10840 	xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   10841 	    XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
   10842 	    node, NULL,
   10843 	    "Failed to locate a schema at location '%s'. "
   10844 	    "Skipping the import", schemaLocation, NULL, NULL);
   10845     }
   10846 
   10847     if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
   10848 	ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
   10849     }
   10850 
   10851     return (ret);
   10852 }
   10853 
   10854 static int
   10855 xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
   10856 				     xmlSchemaPtr schema,
   10857 				     xmlNodePtr node,
   10858 				     xmlChar **schemaLocation,
   10859 				     int type)
   10860 {
   10861     xmlAttrPtr attr;
   10862 
   10863     if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
   10864 	(schemaLocation == NULL))
   10865         return (-1);
   10866 
   10867     *schemaLocation = NULL;
   10868     /*
   10869     * Check for illegal attributes.
   10870     * Applies for both <include> and <redefine>.
   10871     */
   10872     attr = node->properties;
   10873     while (attr != NULL) {
   10874 	if (attr->ns == NULL) {
   10875 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   10876 		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
   10877 		xmlSchemaPIllegalAttrErr(pctxt,
   10878 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10879 	    }
   10880 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   10881 	    xmlSchemaPIllegalAttrErr(pctxt,
   10882 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10883 	}
   10884 	attr = attr->next;
   10885     }
   10886     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   10887     /*
   10888     * Preliminary step, extract the URI-Reference and make an URI
   10889     * from the base.
   10890     */
   10891     /*
   10892     * Attribute "schemaLocation" is mandatory.
   10893     */
   10894     attr = xmlSchemaGetPropNode(node, "schemaLocation");
   10895     if (attr != NULL) {
   10896         xmlChar *base = NULL;
   10897         xmlChar *uri = NULL;
   10898 
   10899 	if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
   10900 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10901 	    (const xmlChar **) schemaLocation) != 0)
   10902 	    goto exit_error;
   10903 	base = xmlNodeGetBase(node->doc, node);
   10904 	if (base == NULL) {
   10905 	    uri = xmlBuildURI(*schemaLocation, node->doc->URL);
   10906 	} else {
   10907 	    uri = xmlBuildURI(*schemaLocation, base);
   10908 	    xmlFree(base);
   10909 	}
   10910 	if (uri == NULL) {
   10911 	    PERROR_INT("xmlSchemaParseIncludeOrRedefine",
   10912 		"could not build an URI from the schemaLocation")
   10913 	    goto exit_failure;
   10914 	}
   10915 	(*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
   10916 	xmlFree(uri);
   10917     } else {
   10918 	xmlSchemaPMissingAttrErr(pctxt,
   10919 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   10920 	    NULL, node, "schemaLocation", NULL);
   10921 	goto exit_error;
   10922     }
   10923     /*
   10924     * Report self-inclusion and self-redefinition.
   10925     */
   10926     if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
   10927 	if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
   10928 	    xmlSchemaPCustomErr(pctxt,
   10929 		XML_SCHEMAP_SRC_REDEFINE,
   10930 		NULL, node,
   10931 		"The schema document '%s' cannot redefine itself.",
   10932 		*schemaLocation);
   10933 	} else {
   10934 	    xmlSchemaPCustomErr(pctxt,
   10935 		XML_SCHEMAP_SRC_INCLUDE,
   10936 		NULL, node,
   10937 		"The schema document '%s' cannot include itself.",
   10938 		*schemaLocation);
   10939 	}
   10940 	goto exit_error;
   10941     }
   10942 
   10943     return(0);
   10944 exit_error:
   10945     return(pctxt->err);
   10946 exit_failure:
   10947     return(-1);
   10948 }
   10949 
   10950 static int
   10951 xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
   10952 				xmlSchemaPtr schema,
   10953 				xmlNodePtr node,
   10954 				int type)
   10955 {
   10956     xmlNodePtr child = NULL;
   10957     const xmlChar *schemaLocation = NULL;
   10958     int res = 0; /* hasRedefinitions = 0 */
   10959     int isChameleon = 0, wasChameleon = 0;
   10960     xmlSchemaBucketPtr bucket = NULL;
   10961 
   10962     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   10963         return (-1);
   10964 
   10965     /*
   10966     * Parse attributes. Note that the returned schemaLocation will
   10967     * be already converted to an absolute URI.
   10968     */
   10969     res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
   10970 	node, (xmlChar **) (&schemaLocation), type);
   10971     if (res != 0)
   10972 	return(res);
   10973     /*
   10974     * Load and add the schema document.
   10975     */
   10976     res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
   10977 	NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
   10978     if (res != 0)
   10979 	return(res);
   10980     /*
   10981     * If we get no schema bucket back, then this means that the schema
   10982     * document could not be located or was broken XML or was not
   10983     * a schema document.
   10984     */
   10985     if ((bucket == NULL) || (bucket->doc == NULL)) {
   10986 	if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
   10987 	    /*
   10988 	    * WARNING for <include>:
   10989 	    * We will raise an error if the schema cannot be located
   10990 	    * for inclusions, since the that was the feedback from the
   10991 	    * schema people. I.e. the following spec piece will *not* be
   10992 	    * satisfied:
   10993 	    * SPEC src-include: "It is not an error for the `actual value` of the
   10994 	    * schemaLocation [attribute] to fail to resolve it all, in which
   10995 	    * case no corresponding inclusion is performed.
   10996 	    * So do we need a warning report here?"
   10997 	    */
   10998 	    res = XML_SCHEMAP_SRC_INCLUDE;
   10999 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
   11000 		node, NULL,
   11001 		"Failed to load the document '%s' for inclusion",
   11002 		schemaLocation, NULL);
   11003 	} else {
   11004 	    /*
   11005 	    * NOTE: This was changed to raise an error even if no redefinitions
   11006 	    * are specified.
   11007 	    *
   11008 	    * SPEC src-redefine (1)
   11009 	    * "If there are any element information items among the [children]
   11010 	    * other than <annotation> then the `actual value` of the
   11011 	    * schemaLocation [attribute] must successfully resolve."
   11012 	    * TODO: Ask the WG if a the location has always to resolve
   11013 	    * here as well!
   11014 	    */
   11015 	    res = XML_SCHEMAP_SRC_REDEFINE;
   11016 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
   11017 		node, NULL,
   11018 		"Failed to load the document '%s' for redefinition",
   11019 		schemaLocation, NULL);
   11020 	}
   11021     } else {
   11022 	/*
   11023 	* Check targetNamespace sanity before parsing the new schema.
   11024 	* TODO: Note that we won't check further content if the
   11025 	* targetNamespace was bad.
   11026 	*/
   11027 	if (bucket->origTargetNamespace != NULL) {
   11028 	    /*
   11029 	    * SPEC src-include (2.1)
   11030 	    * "SII has a targetNamespace [attribute], and its `actual
   11031 	    * value` is identical to the `actual value` of the targetNamespace
   11032 	    * [attribute] of SII' (which must have such an [attribute])."
   11033 	    */
   11034 	    if (pctxt->targetNamespace == NULL) {
   11035 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   11036 		    XML_SCHEMAP_SRC_INCLUDE,
   11037 		    node, NULL,
   11038 		    "The target namespace of the included/redefined schema "
   11039 		    "'%s' has to be absent, since the including/redefining "
   11040 		    "schema has no target namespace",
   11041 		    schemaLocation, NULL);
   11042 		goto exit_error;
   11043 	    } else if (!xmlStrEqual(bucket->origTargetNamespace,
   11044 		pctxt->targetNamespace)) {
   11045 		/* TODO: Change error function. */
   11046 		xmlSchemaPCustomErrExt(pctxt,
   11047 		    XML_SCHEMAP_SRC_INCLUDE,
   11048 		    NULL, node,
   11049 		    "The target namespace '%s' of the included/redefined "
   11050 		    "schema '%s' differs from '%s' of the "
   11051 		    "including/redefining schema",
   11052 		    bucket->origTargetNamespace, schemaLocation,
   11053 		    pctxt->targetNamespace);
   11054 		goto exit_error;
   11055 	    }
   11056 	} else if (pctxt->targetNamespace != NULL) {
   11057 	    /*
   11058 	    * Chameleons: the original target namespace will
   11059 	    * differ from the resulting namespace.
   11060 	    */
   11061 	    isChameleon = 1;
   11062 	    if (bucket->parsed &&
   11063 		bucket->origTargetNamespace != NULL) {
   11064 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   11065 		    XML_SCHEMAP_SRC_INCLUDE,
   11066 		    node, NULL,
   11067 		    "The target namespace of the included/redefined schema "
   11068 		    "'%s' has to be absent or the same as the "
   11069 		    "including/redefining schema's target namespace",
   11070 		    schemaLocation, NULL);
   11071 		goto exit_error;
   11072 	    }
   11073 	    bucket->targetNamespace = pctxt->targetNamespace;
   11074 	}
   11075     }
   11076     /*
   11077     * Parse the schema.
   11078     */
   11079     if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
   11080 	if (isChameleon) {
   11081 	    /* TODO: Get rid of this flag on the schema itself. */
   11082 	    if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
   11083 		schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
   11084 	    } else
   11085 		wasChameleon = 1;
   11086 	}
   11087 	xmlSchemaParseNewDoc(pctxt, schema, bucket);
   11088 	/* Restore chameleon flag. */
   11089 	if (isChameleon && (!wasChameleon))
   11090 	    schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
   11091     }
   11092     /*
   11093     * And now for the children...
   11094     */
   11095     child = node->children;
   11096     if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
   11097 	/*
   11098 	* Parse (simpleType | complexType | group | attributeGroup))*
   11099 	*/
   11100 	pctxt->redefined = bucket;
   11101 	/*
   11102 	* How to proceed if the redefined schema was not located?
   11103 	*/
   11104 	pctxt->isRedefine = 1;
   11105 	while (IS_SCHEMA(child, "annotation") ||
   11106 	    IS_SCHEMA(child, "simpleType") ||
   11107 	    IS_SCHEMA(child, "complexType") ||
   11108 	    IS_SCHEMA(child, "group") ||
   11109 	    IS_SCHEMA(child, "attributeGroup")) {
   11110 	    if (IS_SCHEMA(child, "annotation")) {
   11111 		/*
   11112 		* TODO: discard or not?
   11113 		*/
   11114 	    } else if (IS_SCHEMA(child, "simpleType")) {
   11115 		xmlSchemaParseSimpleType(pctxt, schema, child, 1);
   11116 	    } else if (IS_SCHEMA(child, "complexType")) {
   11117 		xmlSchemaParseComplexType(pctxt, schema, child, 1);
   11118 		/* hasRedefinitions = 1; */
   11119 	    } else if (IS_SCHEMA(child, "group")) {
   11120 		/* hasRedefinitions = 1; */
   11121 		xmlSchemaParseModelGroupDefinition(pctxt,
   11122 		    schema, child);
   11123 	    } else if (IS_SCHEMA(child, "attributeGroup")) {
   11124 		/* hasRedefinitions = 1; */
   11125 		xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
   11126 		    child);
   11127 	    }
   11128 	    child = child->next;
   11129 	}
   11130 	pctxt->redefined = NULL;
   11131 	pctxt->isRedefine = 0;
   11132     } else {
   11133 	if (IS_SCHEMA(child, "annotation")) {
   11134 	    /*
   11135 	    * TODO: discard or not?
   11136 	    */
   11137 	    child = child->next;
   11138 	}
   11139     }
   11140     if (child != NULL) {
   11141 	res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
   11142 	if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
   11143 	    xmlSchemaPContentErr(pctxt, res,
   11144 		NULL, node, child, NULL,
   11145 		"(annotation | (simpleType | complexType | group | attributeGroup))*");
   11146 	} else {
   11147 	     xmlSchemaPContentErr(pctxt, res,
   11148 		NULL, node, child, NULL,
   11149 		"(annotation?)");
   11150 	}
   11151     }
   11152     return(res);
   11153 
   11154 exit_error:
   11155     return(pctxt->err);
   11156 }
   11157 
   11158 static int
   11159 xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
   11160                        xmlNodePtr node)
   11161 {
   11162     int res;
   11163 #ifndef ENABLE_REDEFINE
   11164     TODO
   11165     return(0);
   11166 #endif
   11167     res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
   11168 	XML_SCHEMA_SCHEMA_REDEFINE);
   11169     if (res != 0)
   11170 	return(res);
   11171     return(0);
   11172 }
   11173 
   11174 static int
   11175 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
   11176                        xmlNodePtr node)
   11177 {
   11178     int res;
   11179 
   11180     res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
   11181 	XML_SCHEMA_SCHEMA_INCLUDE);
   11182     if (res != 0)
   11183 	return(res);
   11184     return(0);
   11185 }
   11186 
   11187 /**
   11188  * xmlSchemaParseModelGroup:
   11189  * @ctxt:  a schema validation context
   11190  * @schema:  the schema being built
   11191  * @node:  a subtree containing XML Schema informations
   11192  * @type: the "compositor" type
   11193  * @particleNeeded: if a a model group with a particle
   11194  *
   11195  * parse a XML schema Sequence definition.
   11196  * Applies parts of:
   11197  *   Schema Representation Constraint:
   11198  *     Redefinition Constraints and Semantics (src-redefine)
   11199  *     (6.1), (6.1.1), (6.1.2)
   11200  *
   11201  *   Schema Component Constraint:
   11202  *     All Group Limited (cos-all-limited) (2)
   11203  *     TODO: Actually this should go to component-level checks,
   11204  *     but is done here due to performance. Move it to an other layer
   11205  *     is schema construction via an API is implemented.
   11206  *
   11207  * *WARNING* this interface is highly subject to change
   11208  *
   11209  * Returns -1 in case of error, 0 if the declaration is improper and
   11210  *         1 in case of success.
   11211  */
   11212 static xmlSchemaTreeItemPtr
   11213 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   11214 			 xmlNodePtr node, xmlSchemaTypeType type,
   11215 			 int withParticle)
   11216 {
   11217     xmlSchemaModelGroupPtr item;
   11218     xmlSchemaParticlePtr particle = NULL;
   11219     xmlNodePtr child = NULL;
   11220     xmlAttrPtr attr;
   11221     int min = 1, max = 1, isElemRef, hasRefs = 0;
   11222 
   11223     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   11224         return (NULL);
   11225     /*
   11226     * Create a model group with the given compositor.
   11227     */
   11228     item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
   11229     if (item == NULL)
   11230 	return (NULL);
   11231 
   11232     if (withParticle) {
   11233 	if (type == XML_SCHEMA_TYPE_ALL) {
   11234 	    min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
   11235 	    max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
   11236 	} else {
   11237 	    /* choice + sequence */
   11238 	    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
   11239 	    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
   11240 		"(xs:nonNegativeInteger | unbounded)");
   11241 	}
   11242 	xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
   11243 	/*
   11244 	* Create a particle
   11245 	*/
   11246 	particle = xmlSchemaAddParticle(ctxt, node, min, max);
   11247 	if (particle == NULL)
   11248 	    return (NULL);
   11249 	particle->children = (xmlSchemaTreeItemPtr) item;
   11250 	/*
   11251 	* Check for illegal attributes.
   11252 	*/
   11253 	attr = node->properties;
   11254 	while (attr != NULL) {
   11255 	    if (attr->ns == NULL) {
   11256 		if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   11257 		    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
   11258 		    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
   11259 		    xmlSchemaPIllegalAttrErr(ctxt,
   11260 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11261 		}
   11262 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11263 		xmlSchemaPIllegalAttrErr(ctxt,
   11264 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11265 	    }
   11266 	    attr = attr->next;
   11267 	}
   11268     } else {
   11269 	/*
   11270 	* Check for illegal attributes.
   11271 	*/
   11272 	attr = node->properties;
   11273 	while (attr != NULL) {
   11274 	    if (attr->ns == NULL) {
   11275 		if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
   11276 		    xmlSchemaPIllegalAttrErr(ctxt,
   11277 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11278 		}
   11279 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11280 		xmlSchemaPIllegalAttrErr(ctxt,
   11281 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11282 	    }
   11283 	    attr = attr->next;
   11284 	}
   11285     }
   11286 
   11287     /*
   11288     * Extract and validate attributes.
   11289     */
   11290     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   11291     /*
   11292     * And now for the children...
   11293     */
   11294     child = node->children;
   11295     if (IS_SCHEMA(child, "annotation")) {
   11296         item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   11297         child = child->next;
   11298     }
   11299     if (type == XML_SCHEMA_TYPE_ALL) {
   11300 	xmlSchemaParticlePtr part, last = NULL;
   11301 
   11302 	while (IS_SCHEMA(child, "element")) {
   11303 	    part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
   11304 		schema, child, &isElemRef, 0);
   11305 	    /*
   11306 	    * SPEC cos-all-limited (2)
   11307 	    * "The {max occurs} of all the particles in the {particles}
   11308 	    * of the ('all') group must be 0 or 1.
   11309 	    */
   11310 	    if (part != NULL) {
   11311 		if (isElemRef)
   11312 		    hasRefs++;
   11313 		if (part->minOccurs > 1) {
   11314 		    xmlSchemaPCustomErr(ctxt,
   11315 			XML_SCHEMAP_COS_ALL_LIMITED,
   11316 			NULL, child,
   11317 			"Invalid value for minOccurs (must be 0 or 1)",
   11318 			NULL);
   11319 		    /* Reset to 1. */
   11320 		    part->minOccurs = 1;
   11321 		}
   11322 		if (part->maxOccurs > 1) {
   11323 		    xmlSchemaPCustomErr(ctxt,
   11324 			XML_SCHEMAP_COS_ALL_LIMITED,
   11325 			NULL, child,
   11326 			"Invalid value for maxOccurs (must be 0 or 1)",
   11327 			NULL);
   11328 		    /* Reset to 1. */
   11329 		    part->maxOccurs = 1;
   11330 		}
   11331 		if (last == NULL)
   11332 		    item->children = (xmlSchemaTreeItemPtr) part;
   11333 		else
   11334 		    last->next = (xmlSchemaTreeItemPtr) part;
   11335 		last = part;
   11336 	    }
   11337 	    child = child->next;
   11338 	}
   11339 	if (child != NULL) {
   11340 	    xmlSchemaPContentErr(ctxt,
   11341 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11342 		NULL, node, child, NULL,
   11343 		"(annotation?, (annotation?, element*)");
   11344 	}
   11345     } else {
   11346 	/* choice + sequence */
   11347 	xmlSchemaTreeItemPtr part = NULL, last = NULL;
   11348 
   11349 	while ((IS_SCHEMA(child, "element")) ||
   11350 	    (IS_SCHEMA(child, "group")) ||
   11351 	    (IS_SCHEMA(child, "any")) ||
   11352 	    (IS_SCHEMA(child, "choice")) ||
   11353 	    (IS_SCHEMA(child, "sequence"))) {
   11354 
   11355 	    if (IS_SCHEMA(child, "element")) {
   11356 		part = (xmlSchemaTreeItemPtr)
   11357 		    xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
   11358 		if (part && isElemRef)
   11359 		    hasRefs++;
   11360 	    } else if (IS_SCHEMA(child, "group")) {
   11361 		part =
   11362 		    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
   11363 		if (part != NULL)
   11364 		    hasRefs++;
   11365 		/*
   11366 		* Handle redefinitions.
   11367 		*/
   11368 		if (ctxt->isRedefine && ctxt->redef &&
   11369 		    (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
   11370 		    part && part->children)
   11371 		{
   11372 		    if ((xmlSchemaGetQNameRefName(part->children) ==
   11373 			    ctxt->redef->refName) &&
   11374 			(xmlSchemaGetQNameRefTargetNs(part->children) ==
   11375 			    ctxt->redef->refTargetNs))
   11376 		    {
   11377 			/*
   11378 			* SPEC src-redefine:
   11379 			* (6.1) "If it has a <group> among its contents at
   11380 			* some level the `actual value` of whose ref
   11381 			* [attribute] is the same as the `actual value` of
   11382 			* its own name attribute plus target namespace, then
   11383 			* all of the following must be true:"
   11384 			* (6.1.1) "It must have exactly one such group."
   11385 			*/
   11386 			if (ctxt->redefCounter != 0) {
   11387 			    xmlChar *str = NULL;
   11388 
   11389 			    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   11390 				XML_SCHEMAP_SRC_REDEFINE, child, NULL,
   11391 				"The redefining model group definition "
   11392 				"'%s' must not contain more than one "
   11393 				"reference to the redefined definition",
   11394 				xmlSchemaFormatQName(&str,
   11395 				    ctxt->redef->refTargetNs,
   11396 				    ctxt->redef->refName),
   11397 				NULL);
   11398 			    FREE_AND_NULL(str)
   11399 			    part = NULL;
   11400 			} else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
   11401 			    ((WXS_PARTICLE(part))->maxOccurs != 1))
   11402 			{
   11403 			    xmlChar *str = NULL;
   11404 			    /*
   11405 			    * SPEC src-redefine:
   11406 			    * (6.1.2) "The `actual value` of both that
   11407 			    * group's minOccurs and maxOccurs [attribute]
   11408 			    * must be 1 (or `absent`).
   11409 			    */
   11410 			    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   11411 				XML_SCHEMAP_SRC_REDEFINE, child, NULL,
   11412 				"The redefining model group definition "
   11413 				"'%s' must not contain a reference to the "
   11414 				"redefined definition with a "
   11415 				"maxOccurs/minOccurs other than 1",
   11416 				xmlSchemaFormatQName(&str,
   11417 				    ctxt->redef->refTargetNs,
   11418 				    ctxt->redef->refName),
   11419 				NULL);
   11420 			    FREE_AND_NULL(str)
   11421 			    part = NULL;
   11422 			}
   11423 			ctxt->redef->reference = WXS_BASIC_CAST part;
   11424 			ctxt->redefCounter++;
   11425 		    }
   11426 		}
   11427 	    } else if (IS_SCHEMA(child, "any")) {
   11428 		part = (xmlSchemaTreeItemPtr)
   11429 		    xmlSchemaParseAny(ctxt, schema, child);
   11430 	    } else if (IS_SCHEMA(child, "choice")) {
   11431 		part = xmlSchemaParseModelGroup(ctxt, schema, child,
   11432 		    XML_SCHEMA_TYPE_CHOICE, 1);
   11433 	    } else if (IS_SCHEMA(child, "sequence")) {
   11434 		part = xmlSchemaParseModelGroup(ctxt, schema, child,
   11435 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
   11436 	    }
   11437 	    if (part != NULL) {
   11438 		if (last == NULL)
   11439 		    item->children = part;
   11440 		else
   11441 		    last->next = part;
   11442 		last = part;
   11443 	    }
   11444 	    child = child->next;
   11445 	}
   11446 	if (child != NULL) {
   11447 	    xmlSchemaPContentErr(ctxt,
   11448 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11449 		NULL, node, child, NULL,
   11450 		"(annotation?, (element | group | choice | sequence | any)*)");
   11451 	}
   11452     }
   11453     if ((max == 0) && (min == 0))
   11454 	return (NULL);
   11455     if (hasRefs) {
   11456 	/*
   11457 	* We need to resolve references.
   11458 	*/
   11459 	WXS_ADD_PENDING(ctxt, item);
   11460     }
   11461     if (withParticle)
   11462 	return ((xmlSchemaTreeItemPtr) particle);
   11463     else
   11464 	return ((xmlSchemaTreeItemPtr) item);
   11465 }
   11466 
   11467 /**
   11468  * xmlSchemaParseRestriction:
   11469  * @ctxt:  a schema validation context
   11470  * @schema:  the schema being built
   11471  * @node:  a subtree containing XML Schema informations
   11472  *
   11473  * parse a XML schema Restriction definition
   11474  * *WARNING* this interface is highly subject to change
   11475  *
   11476  * Returns the type definition or NULL in case of error
   11477  */
   11478 static xmlSchemaTypePtr
   11479 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   11480                           xmlNodePtr node, xmlSchemaTypeType parentType)
   11481 {
   11482     xmlSchemaTypePtr type;
   11483     xmlNodePtr child = NULL;
   11484     xmlAttrPtr attr;
   11485 
   11486     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   11487         return (NULL);
   11488     /* Not a component, don't create it. */
   11489     type = ctxt->ctxtType;
   11490     type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
   11491 
   11492     /*
   11493     * Check for illegal attributes.
   11494     */
   11495     attr = node->properties;
   11496     while (attr != NULL) {
   11497 	if (attr->ns == NULL) {
   11498 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   11499 		(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
   11500 		xmlSchemaPIllegalAttrErr(ctxt,
   11501 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11502 	    }
   11503 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11504 	    xmlSchemaPIllegalAttrErr(ctxt,
   11505 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11506 	}
   11507 	attr = attr->next;
   11508     }
   11509     /*
   11510     * Extract and validate attributes.
   11511     */
   11512     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   11513     /*
   11514     * Attribute
   11515     */
   11516     /*
   11517     * Extract the base type. The "base" attribute is mandatory if inside
   11518     * a complex type or if redefining.
   11519     *
   11520     * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
   11521     * among its [children]), the simple type definition which is
   11522     * the {content type} of the type definition `resolved` to by
   11523     * the `actual value` of the base [attribute]"
   11524     */
   11525     if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
   11526 	&(type->baseNs), &(type->base)) == 0)
   11527     {
   11528 	if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
   11529 	    xmlSchemaPMissingAttrErr(ctxt,
   11530 		XML_SCHEMAP_S4S_ATTR_MISSING,
   11531 		NULL, node, "base", NULL);
   11532 	} else if ((ctxt->isRedefine) &&
   11533 	    (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
   11534 	{
   11535 	    if (type->base == NULL) {
   11536 		xmlSchemaPMissingAttrErr(ctxt,
   11537 		    XML_SCHEMAP_S4S_ATTR_MISSING,
   11538 		    NULL, node, "base", NULL);
   11539 	    } else if ((! xmlStrEqual(type->base, type->name)) ||
   11540 		(! xmlStrEqual(type->baseNs, type->targetNamespace)))
   11541 	    {
   11542 		xmlChar *str1 = NULL, *str2 = NULL;
   11543 		/*
   11544 		* REDEFINE: SPEC src-redefine (5)
   11545 		* "Within the [children], each <simpleType> must have a
   11546 		* <restriction> among its [children] ... the `actual value` of
   11547 		* whose base [attribute] must be the same as the `actual value`
   11548 		* of its own name attribute plus target namespace;"
   11549 		*/
   11550 		xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   11551 		    NULL, node, "This is a redefinition, but the QName "
   11552 		    "value '%s' of the 'base' attribute does not match the "
   11553 		    "type's designation '%s'",
   11554 		    xmlSchemaFormatQName(&str1, type->baseNs, type->base),
   11555 		    xmlSchemaFormatQName(&str2, type->targetNamespace,
   11556 			type->name), NULL);
   11557 		FREE_AND_NULL(str1);
   11558 		FREE_AND_NULL(str2);
   11559 		/* Avoid confusion and erase the values. */
   11560 		type->base = NULL;
   11561 		type->baseNs = NULL;
   11562 	    }
   11563 	}
   11564     }
   11565     /*
   11566     * And now for the children...
   11567     */
   11568     child = node->children;
   11569     if (IS_SCHEMA(child, "annotation")) {
   11570 	/*
   11571 	* Add the annotation to the simple type ancestor.
   11572 	*/
   11573 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   11574 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   11575         child = child->next;
   11576     }
   11577     if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
   11578 	/*
   11579 	* Corresponds to <simpleType><restriction><simpleType>.
   11580 	*/
   11581 	if (IS_SCHEMA(child, "simpleType")) {
   11582 	    if (type->base != NULL) {
   11583 		/*
   11584 		* src-restriction-base-or-simpleType
   11585 		* Either the base [attribute] or the simpleType [child] of the
   11586 		* <restriction> element must be present, but not both.
   11587 		*/
   11588 		xmlSchemaPContentErr(ctxt,
   11589 		    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
   11590 		    NULL, node, child,
   11591 		    "The attribute 'base' and the <simpleType> child are "
   11592 		    "mutually exclusive", NULL);
   11593 	    } else {
   11594 		type->baseType = (xmlSchemaTypePtr)
   11595 		    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   11596 	    }
   11597 	    child = child->next;
   11598 	} else if (type->base == NULL) {
   11599 	    xmlSchemaPContentErr(ctxt,
   11600 		XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
   11601 		NULL, node, child,
   11602 		"Either the attribute 'base' or a <simpleType> child "
   11603 		"must be present", NULL);
   11604 	}
   11605     } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
   11606 	/*
   11607 	* Corresponds to <complexType><complexContent><restriction>...
   11608 	* followed by:
   11609 	*
   11610 	* Model groups <all>, <choice> and <sequence>.
   11611 	*/
   11612 	if (IS_SCHEMA(child, "all")) {
   11613 	    type->subtypes = (xmlSchemaTypePtr)
   11614 		xmlSchemaParseModelGroup(ctxt, schema, child,
   11615 		    XML_SCHEMA_TYPE_ALL, 1);
   11616 	    child = child->next;
   11617 	} else if (IS_SCHEMA(child, "choice")) {
   11618 	    type->subtypes = (xmlSchemaTypePtr)
   11619 		xmlSchemaParseModelGroup(ctxt,
   11620 		    schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
   11621 	    child = child->next;
   11622 	} else if (IS_SCHEMA(child, "sequence")) {
   11623 	    type->subtypes = (xmlSchemaTypePtr)
   11624 		xmlSchemaParseModelGroup(ctxt, schema, child,
   11625 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
   11626 	    child = child->next;
   11627 	/*
   11628 	* Model group reference <group>.
   11629 	*/
   11630 	} else if (IS_SCHEMA(child, "group")) {
   11631 	    type->subtypes = (xmlSchemaTypePtr)
   11632 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
   11633 	    /*
   11634 	    * Note that the reference will be resolved in
   11635 	    * xmlSchemaResolveTypeReferences();
   11636 	    */
   11637 	    child = child->next;
   11638 	}
   11639     } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
   11640 	/*
   11641 	* Corresponds to <complexType><simpleContent><restriction>...
   11642 	*
   11643 	* "1.1 the simple type definition corresponding to the <simpleType>
   11644 	* among the [children] of <restriction> if there is one;"
   11645 	*/
   11646 	if (IS_SCHEMA(child, "simpleType")) {
   11647 	    /*
   11648 	    * We will store the to-be-restricted simple type in
   11649 	    * type->contentTypeDef *temporarily*.
   11650 	    */
   11651 	    type->contentTypeDef = (xmlSchemaTypePtr)
   11652 		xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   11653 	    if ( type->contentTypeDef == NULL)
   11654 		return (NULL);
   11655 	    child = child->next;
   11656 	}
   11657     }
   11658 
   11659     if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
   11660 	(parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
   11661 	xmlSchemaFacetPtr facet, lastfacet = NULL;
   11662 	/*
   11663 	* Corresponds to <complexType><simpleContent><restriction>...
   11664 	* <simpleType><restriction>...
   11665 	*/
   11666 
   11667 	/*
   11668 	* Add the facets to the simple type ancestor.
   11669 	*/
   11670 	/*
   11671 	* TODO: Datatypes: 4.1.3 Constraints on XML Representation of
   11672 	* Simple Type Definition Schema Representation Constraint:
   11673 	* *Single Facet Value*
   11674 	*/
   11675 	while ((IS_SCHEMA(child, "minInclusive")) ||
   11676 	    (IS_SCHEMA(child, "minExclusive")) ||
   11677 	    (IS_SCHEMA(child, "maxInclusive")) ||
   11678 	    (IS_SCHEMA(child, "maxExclusive")) ||
   11679 	    (IS_SCHEMA(child, "totalDigits")) ||
   11680 	    (IS_SCHEMA(child, "fractionDigits")) ||
   11681 	    (IS_SCHEMA(child, "pattern")) ||
   11682 	    (IS_SCHEMA(child, "enumeration")) ||
   11683 	    (IS_SCHEMA(child, "whiteSpace")) ||
   11684 	    (IS_SCHEMA(child, "length")) ||
   11685 	    (IS_SCHEMA(child, "maxLength")) ||
   11686 	    (IS_SCHEMA(child, "minLength"))) {
   11687 	    facet = xmlSchemaParseFacet(ctxt, schema, child);
   11688 	    if (facet != NULL) {
   11689 		if (lastfacet == NULL)
   11690 		    type->facets = facet;
   11691 		else
   11692 		    lastfacet->next = facet;
   11693 		lastfacet = facet;
   11694 		lastfacet->next = NULL;
   11695 	    }
   11696 	    child = child->next;
   11697 	}
   11698 	/*
   11699 	* Create links for derivation and validation.
   11700 	*/
   11701 	if (type->facets != NULL) {
   11702 	    xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
   11703 
   11704 	    facet = type->facets;
   11705 	    do {
   11706 		facetLink = (xmlSchemaFacetLinkPtr)
   11707 		    xmlMalloc(sizeof(xmlSchemaFacetLink));
   11708 		if (facetLink == NULL) {
   11709 		    xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
   11710 		    xmlFree(facetLink);
   11711 		    return (NULL);
   11712 		}
   11713 		facetLink->facet = facet;
   11714 		facetLink->next = NULL;
   11715 		if (lastFacetLink == NULL)
   11716 		    type->facetSet = facetLink;
   11717 		else
   11718 		    lastFacetLink->next = facetLink;
   11719 		lastFacetLink = facetLink;
   11720 		facet = facet->next;
   11721 	    } while (facet != NULL);
   11722 	}
   11723     }
   11724     if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
   11725 	/*
   11726 	* Attribute uses/declarations.
   11727 	*/
   11728 	if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
   11729 	    (xmlSchemaItemListPtr *) &(type->attrUses),
   11730 	    XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
   11731 	    return(NULL);
   11732 	/*
   11733 	* Attribute wildcard.
   11734 	*/
   11735 	if (IS_SCHEMA(child, "anyAttribute")) {
   11736 	    type->attributeWildcard =
   11737 		xmlSchemaParseAnyAttribute(ctxt, schema, child);
   11738 	    child = child->next;
   11739 	}
   11740     }
   11741     if (child != NULL) {
   11742 	if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
   11743 	    xmlSchemaPContentErr(ctxt,
   11744 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11745 		NULL, node, child, NULL,
   11746 		"annotation?, (group | all | choice | sequence)?, "
   11747 		"((attribute | attributeGroup)*, anyAttribute?))");
   11748 	} else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
   11749 	     xmlSchemaPContentErr(ctxt,
   11750 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11751 		NULL, node, child, NULL,
   11752 		"(annotation?, (simpleType?, (minExclusive | minInclusive | "
   11753 		"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
   11754 		"length | minLength | maxLength | enumeration | whiteSpace | "
   11755 		"pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
   11756 	} else {
   11757 	    /* Simple type */
   11758 	    xmlSchemaPContentErr(ctxt,
   11759 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11760 		NULL, node, child, NULL,
   11761 		"(annotation?, (simpleType?, (minExclusive | minInclusive | "
   11762 		"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
   11763 		"length | minLength | maxLength | enumeration | whiteSpace | "
   11764 		"pattern)*))");
   11765 	}
   11766     }
   11767     return (NULL);
   11768 }
   11769 
   11770 /**
   11771  * xmlSchemaParseExtension:
   11772  * @ctxt:  a schema validation context
   11773  * @schema:  the schema being built
   11774  * @node:  a subtree containing XML Schema informations
   11775  *
   11776  * Parses an <extension>, which is found inside a
   11777  * <simpleContent> or <complexContent>.
   11778  * *WARNING* this interface is highly subject to change.
   11779  *
   11780  * TODO: Returns the type definition or NULL in case of error
   11781  */
   11782 static xmlSchemaTypePtr
   11783 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   11784                         xmlNodePtr node, xmlSchemaTypeType parentType)
   11785 {
   11786     xmlSchemaTypePtr type;
   11787     xmlNodePtr child = NULL;
   11788     xmlAttrPtr attr;
   11789 
   11790     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   11791         return (NULL);
   11792     /* Not a component, don't create it. */
   11793     type = ctxt->ctxtType;
   11794     type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
   11795 
   11796     /*
   11797     * Check for illegal attributes.
   11798     */
   11799     attr = node->properties;
   11800     while (attr != NULL) {
   11801 	if (attr->ns == NULL) {
   11802 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   11803 		(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
   11804 		xmlSchemaPIllegalAttrErr(ctxt,
   11805 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11806 	    }
   11807 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11808 	    xmlSchemaPIllegalAttrErr(ctxt,
   11809 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11810 	}
   11811 	attr = attr->next;
   11812     }
   11813 
   11814     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   11815 
   11816     /*
   11817     * Attribute "base" - mandatory.
   11818     */
   11819     if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
   11820 	"base", &(type->baseNs), &(type->base)) == 0) &&
   11821 	(type->base == NULL)) {
   11822 	xmlSchemaPMissingAttrErr(ctxt,
   11823 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   11824 	    NULL, node, "base", NULL);
   11825     }
   11826     /*
   11827     * And now for the children...
   11828     */
   11829     child = node->children;
   11830     if (IS_SCHEMA(child, "annotation")) {
   11831 	/*
   11832 	* Add the annotation to the type ancestor.
   11833 	*/
   11834 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   11835 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   11836         child = child->next;
   11837     }
   11838     if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
   11839 	/*
   11840 	* Corresponds to <complexType><complexContent><extension>... and:
   11841 	*
   11842 	* Model groups <all>, <choice>, <sequence> and <group>.
   11843 	*/
   11844 	if (IS_SCHEMA(child, "all")) {
   11845 	    type->subtypes = (xmlSchemaTypePtr)
   11846 		xmlSchemaParseModelGroup(ctxt, schema,
   11847 		    child, XML_SCHEMA_TYPE_ALL, 1);
   11848 	    child = child->next;
   11849 	} else if (IS_SCHEMA(child, "choice")) {
   11850 	    type->subtypes = (xmlSchemaTypePtr)
   11851 		xmlSchemaParseModelGroup(ctxt, schema,
   11852 		    child, XML_SCHEMA_TYPE_CHOICE, 1);
   11853 	    child = child->next;
   11854 	} else if (IS_SCHEMA(child, "sequence")) {
   11855 	    type->subtypes = (xmlSchemaTypePtr)
   11856 		xmlSchemaParseModelGroup(ctxt, schema,
   11857 		child, XML_SCHEMA_TYPE_SEQUENCE, 1);
   11858 	    child = child->next;
   11859 	} else if (IS_SCHEMA(child, "group")) {
   11860 	    type->subtypes = (xmlSchemaTypePtr)
   11861 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
   11862 	    /*
   11863 	    * Note that the reference will be resolved in
   11864 	    * xmlSchemaResolveTypeReferences();
   11865 	    */
   11866 	    child = child->next;
   11867 	}
   11868     }
   11869     if (child != NULL) {
   11870 	/*
   11871 	* Attribute uses/declarations.
   11872 	*/
   11873 	if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
   11874 	    (xmlSchemaItemListPtr *) &(type->attrUses),
   11875 	    XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
   11876 	    return(NULL);
   11877 	/*
   11878 	* Attribute wildcard.
   11879 	*/
   11880 	if (IS_SCHEMA(child, "anyAttribute")) {
   11881 	    ctxt->ctxtType->attributeWildcard =
   11882 		xmlSchemaParseAnyAttribute(ctxt, schema, child);
   11883 	    child = child->next;
   11884 	}
   11885     }
   11886     if (child != NULL) {
   11887 	if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
   11888 	    /* Complex content extension. */
   11889 	    xmlSchemaPContentErr(ctxt,
   11890 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11891 		NULL, node, child, NULL,
   11892 		"(annotation?, ((group | all | choice | sequence)?, "
   11893 		"((attribute | attributeGroup)*, anyAttribute?)))");
   11894 	} else {
   11895 	    /* Simple content extension. */
   11896 	    xmlSchemaPContentErr(ctxt,
   11897 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11898 		NULL, node, child, NULL,
   11899 		"(annotation?, ((attribute | attributeGroup)*, "
   11900 		"anyAttribute?))");
   11901 	}
   11902     }
   11903     return (NULL);
   11904 }
   11905 
   11906 /**
   11907  * xmlSchemaParseSimpleContent:
   11908  * @ctxt:  a schema validation context
   11909  * @schema:  the schema being built
   11910  * @node:  a subtree containing XML Schema informations
   11911  *
   11912  * parse a XML schema SimpleContent definition
   11913  * *WARNING* this interface is highly subject to change
   11914  *
   11915  * Returns the type definition or NULL in case of error
   11916  */
   11917 static int
   11918 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
   11919                             xmlSchemaPtr schema, xmlNodePtr node,
   11920 			    int *hasRestrictionOrExtension)
   11921 {
   11922     xmlSchemaTypePtr type;
   11923     xmlNodePtr child = NULL;
   11924     xmlAttrPtr attr;
   11925 
   11926     if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
   11927 	(hasRestrictionOrExtension == NULL))
   11928         return (-1);
   11929     *hasRestrictionOrExtension = 0;
   11930     /* Not a component, don't create it. */
   11931     type = ctxt->ctxtType;
   11932     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   11933     /*
   11934     * Check for illegal attributes.
   11935     */
   11936     attr = node->properties;
   11937     while (attr != NULL) {
   11938 	if (attr->ns == NULL) {
   11939 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
   11940 		xmlSchemaPIllegalAttrErr(ctxt,
   11941 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11942 	    }
   11943 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11944 	    xmlSchemaPIllegalAttrErr(ctxt,
   11945 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11946 	}
   11947 	attr = attr->next;
   11948     }
   11949 
   11950     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   11951 
   11952     /*
   11953     * And now for the children...
   11954     */
   11955     child = node->children;
   11956     if (IS_SCHEMA(child, "annotation")) {
   11957 	/*
   11958 	* Add the annotation to the complex type ancestor.
   11959 	*/
   11960 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   11961 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   11962         child = child->next;
   11963     }
   11964     if (child == NULL) {
   11965 	xmlSchemaPContentErr(ctxt,
   11966 	    XML_SCHEMAP_S4S_ELEM_MISSING,
   11967 	    NULL, node, NULL, NULL,
   11968 	    "(annotation?, (restriction | extension))");
   11969     }
   11970     if (child == NULL) {
   11971 	xmlSchemaPContentErr(ctxt,
   11972 	    XML_SCHEMAP_S4S_ELEM_MISSING,
   11973 	    NULL, node, NULL, NULL,
   11974 	    "(annotation?, (restriction | extension))");
   11975     }
   11976     if (IS_SCHEMA(child, "restriction")) {
   11977         xmlSchemaParseRestriction(ctxt, schema, child,
   11978 	    XML_SCHEMA_TYPE_SIMPLE_CONTENT);
   11979 	(*hasRestrictionOrExtension) = 1;
   11980         child = child->next;
   11981     } else if (IS_SCHEMA(child, "extension")) {
   11982         xmlSchemaParseExtension(ctxt, schema, child,
   11983 	    XML_SCHEMA_TYPE_SIMPLE_CONTENT);
   11984 	(*hasRestrictionOrExtension) = 1;
   11985         child = child->next;
   11986     }
   11987     if (child != NULL) {
   11988 	xmlSchemaPContentErr(ctxt,
   11989 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11990 	    NULL, node, child, NULL,
   11991 	    "(annotation?, (restriction | extension))");
   11992     }
   11993     return (0);
   11994 }
   11995 
   11996 /**
   11997  * xmlSchemaParseComplexContent:
   11998  * @ctxt:  a schema validation context
   11999  * @schema:  the schema being built
   12000  * @node:  a subtree containing XML Schema informations
   12001  *
   12002  * parse a XML schema ComplexContent definition
   12003  * *WARNING* this interface is highly subject to change
   12004  *
   12005  * Returns the type definition or NULL in case of error
   12006  */
   12007 static int
   12008 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
   12009                              xmlSchemaPtr schema, xmlNodePtr node,
   12010 			     int *hasRestrictionOrExtension)
   12011 {
   12012     xmlSchemaTypePtr type;
   12013     xmlNodePtr child = NULL;
   12014     xmlAttrPtr attr;
   12015 
   12016     if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
   12017 	(hasRestrictionOrExtension == NULL))
   12018         return (-1);
   12019     *hasRestrictionOrExtension = 0;
   12020     /* Not a component, don't create it. */
   12021     type = ctxt->ctxtType;
   12022     /*
   12023     * Check for illegal attributes.
   12024     */
   12025     attr = node->properties;
   12026     while (attr != NULL) {
   12027 	if (attr->ns == NULL) {
   12028 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   12029 		(!xmlStrEqual(attr->name, BAD_CAST "mixed")))
   12030 	    {
   12031 		xmlSchemaPIllegalAttrErr(ctxt,
   12032 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12033 	    }
   12034 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   12035 	    xmlSchemaPIllegalAttrErr(ctxt,
   12036 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12037 	}
   12038 	attr = attr->next;
   12039     }
   12040 
   12041     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   12042 
   12043     /*
   12044     * Set the 'mixed' on the complex type ancestor.
   12045     */
   12046     if (xmlGetBooleanProp(ctxt, node, "mixed", 0))  {
   12047 	if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
   12048 	    type->flags |= XML_SCHEMAS_TYPE_MIXED;
   12049     }
   12050     child = node->children;
   12051     if (IS_SCHEMA(child, "annotation")) {
   12052 	/*
   12053 	* Add the annotation to the complex type ancestor.
   12054 	*/
   12055 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   12056 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   12057         child = child->next;
   12058     }
   12059     if (child == NULL) {
   12060 	xmlSchemaPContentErr(ctxt,
   12061 	    XML_SCHEMAP_S4S_ELEM_MISSING,
   12062 	    NULL, node, NULL,
   12063 	    NULL, "(annotation?, (restriction | extension))");
   12064     }
   12065     if (child == NULL) {
   12066 	xmlSchemaPContentErr(ctxt,
   12067 	    XML_SCHEMAP_S4S_ELEM_MISSING,
   12068 	    NULL, node, NULL,
   12069 	    NULL, "(annotation?, (restriction | extension))");
   12070     }
   12071     if (IS_SCHEMA(child, "restriction")) {
   12072         xmlSchemaParseRestriction(ctxt, schema, child,
   12073 	    XML_SCHEMA_TYPE_COMPLEX_CONTENT);
   12074 	(*hasRestrictionOrExtension) = 1;
   12075         child = child->next;
   12076     } else if (IS_SCHEMA(child, "extension")) {
   12077         xmlSchemaParseExtension(ctxt, schema, child,
   12078 	    XML_SCHEMA_TYPE_COMPLEX_CONTENT);
   12079 	(*hasRestrictionOrExtension) = 1;
   12080         child = child->next;
   12081     }
   12082     if (child != NULL) {
   12083 	xmlSchemaPContentErr(ctxt,
   12084 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   12085 	    NULL, node, child,
   12086 	    NULL, "(annotation?, (restriction | extension))");
   12087     }
   12088     return (0);
   12089 }
   12090 
   12091 /**
   12092  * xmlSchemaParseComplexType:
   12093  * @ctxt:  a schema validation context
   12094  * @schema:  the schema being built
   12095  * @node:  a subtree containing XML Schema informations
   12096  *
   12097  * parse a XML schema Complex Type definition
   12098  * *WARNING* this interface is highly subject to change
   12099  *
   12100  * Returns the type definition or NULL in case of error
   12101  */
   12102 static xmlSchemaTypePtr
   12103 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   12104                           xmlNodePtr node, int topLevel)
   12105 {
   12106     xmlSchemaTypePtr type, ctxtType;
   12107     xmlNodePtr child = NULL;
   12108     const xmlChar *name = NULL;
   12109     xmlAttrPtr attr;
   12110     const xmlChar *attrValue;
   12111 #ifdef ENABLE_NAMED_LOCALS
   12112     char buf[40];
   12113 #endif
   12114     int final = 0, block = 0, hasRestrictionOrExtension = 0;
   12115 
   12116 
   12117     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   12118         return (NULL);
   12119 
   12120     ctxtType = ctxt->ctxtType;
   12121 
   12122     if (topLevel) {
   12123 	attr = xmlSchemaGetPropNode(node, "name");
   12124 	if (attr == NULL) {
   12125 	    xmlSchemaPMissingAttrErr(ctxt,
   12126 		XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
   12127 	    return (NULL);
   12128 	} else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
   12129 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   12130 	    return (NULL);
   12131 	}
   12132     }
   12133 
   12134     if (topLevel == 0) {
   12135 	/*
   12136 	* Parse as local complex type definition.
   12137 	*/
   12138 #ifdef ENABLE_NAMED_LOCALS
   12139         snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
   12140 	type = xmlSchemaAddType(ctxt, schema,
   12141 	    XML_SCHEMA_TYPE_COMPLEX,
   12142 	    xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
   12143 	    ctxt->targetNamespace, node, 0);
   12144 #else
   12145 	type = xmlSchemaAddType(ctxt, schema,
   12146 	    XML_SCHEMA_TYPE_COMPLEX,
   12147 	    NULL, ctxt->targetNamespace, node, 0);
   12148 #endif
   12149 	if (type == NULL)
   12150 	    return (NULL);
   12151 	name = type->name;
   12152 	type->node = node;
   12153 	type->type = XML_SCHEMA_TYPE_COMPLEX;
   12154 	/*
   12155 	* TODO: We need the target namespace.
   12156 	*/
   12157     } else {
   12158 	/*
   12159 	* Parse as global complex type definition.
   12160 	*/
   12161 	type = xmlSchemaAddType(ctxt, schema,
   12162 	    XML_SCHEMA_TYPE_COMPLEX,
   12163 	    name, ctxt->targetNamespace, node, 1);
   12164 	if (type == NULL)
   12165 	    return (NULL);
   12166 	type->node = node;
   12167 	type->type = XML_SCHEMA_TYPE_COMPLEX;
   12168 	type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
   12169     }
   12170     type->targetNamespace = ctxt->targetNamespace;
   12171     /*
   12172     * Handle attributes.
   12173     */
   12174     attr = node->properties;
   12175     while (attr != NULL) {
   12176 	if (attr->ns == NULL) {
   12177 	    if (xmlStrEqual(attr->name, BAD_CAST "id")) {
   12178 		/*
   12179 		* Attribute "id".
   12180 		*/
   12181 		xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   12182 	    } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
   12183 		/*
   12184 		* Attribute "mixed".
   12185 		*/
   12186 		if (xmlSchemaPGetBoolNodeValue(ctxt,
   12187 			NULL, (xmlNodePtr) attr))
   12188 		    type->flags |= XML_SCHEMAS_TYPE_MIXED;
   12189 	    } else if (topLevel) {
   12190 		/*
   12191 		* Attributes of global complex type definitions.
   12192 		*/
   12193 		if (xmlStrEqual(attr->name, BAD_CAST "name")) {
   12194 		    /* Pass. */
   12195 		} else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
   12196 		    /*
   12197 		    * Attribute "abstract".
   12198 		    */
   12199 		    if (xmlSchemaPGetBoolNodeValue(ctxt,
   12200 			    NULL, (xmlNodePtr) attr))
   12201 			type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
   12202 		} else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
   12203 		    /*
   12204 		    * Attribute "final".
   12205 		    */
   12206 		    attrValue = xmlSchemaGetNodeContent(ctxt,
   12207 			(xmlNodePtr) attr);
   12208 		    if (xmlSchemaPValAttrBlockFinal(attrValue,
   12209 			&(type->flags),
   12210 			-1,
   12211 			XML_SCHEMAS_TYPE_FINAL_EXTENSION,
   12212 			XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
   12213 			-1, -1, -1) != 0)
   12214 		    {
   12215 			xmlSchemaPSimpleTypeErr(ctxt,
   12216 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   12217 			    NULL, (xmlNodePtr) attr, NULL,
   12218 			    "(#all | List of (extension | restriction))",
   12219 			    attrValue, NULL, NULL, NULL);
   12220 		    } else
   12221 			final = 1;
   12222 		} else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
   12223 		    /*
   12224 		    * Attribute "block".
   12225 		    */
   12226 		    attrValue = xmlSchemaGetNodeContent(ctxt,
   12227 			(xmlNodePtr) attr);
   12228 		    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
   12229 			-1,
   12230 			XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
   12231 			XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
   12232 			-1, -1, -1) != 0) {
   12233 			xmlSchemaPSimpleTypeErr(ctxt,
   12234 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   12235 			    NULL, (xmlNodePtr) attr, NULL,
   12236 			    "(#all | List of (extension | restriction)) ",
   12237 			    attrValue, NULL, NULL, NULL);
   12238 		    } else
   12239 			block = 1;
   12240 		} else {
   12241 			xmlSchemaPIllegalAttrErr(ctxt,
   12242 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12243 		}
   12244 	    } else {
   12245 		xmlSchemaPIllegalAttrErr(ctxt,
   12246 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12247 	    }
   12248 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   12249 	    xmlSchemaPIllegalAttrErr(ctxt,
   12250 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12251 	}
   12252 	attr = attr->next;
   12253     }
   12254     if (! block) {
   12255 	/*
   12256 	* Apply default "block" values.
   12257 	*/
   12258 	if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
   12259 	    type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
   12260 	if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
   12261 	    type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
   12262     }
   12263     if (! final) {
   12264 	/*
   12265 	* Apply default "block" values.
   12266 	*/
   12267 	if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   12268 	    type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
   12269 	if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
   12270 	    type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
   12271     }
   12272     /*
   12273     * And now for the children...
   12274     */
   12275     child = node->children;
   12276     if (IS_SCHEMA(child, "annotation")) {
   12277         type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   12278         child = child->next;
   12279     }
   12280     ctxt->ctxtType = type;
   12281     if (IS_SCHEMA(child, "simpleContent")) {
   12282 	/*
   12283 	* <complexType><simpleContent>...
   12284 	* 3.4.3 : 2.2
   12285 	* Specifying mixed='true' when the <simpleContent>
   12286 	* alternative is chosen has no effect
   12287 	*/
   12288 	if (type->flags & XML_SCHEMAS_TYPE_MIXED)
   12289 	    type->flags ^= XML_SCHEMAS_TYPE_MIXED;
   12290         xmlSchemaParseSimpleContent(ctxt, schema, child,
   12291 	    &hasRestrictionOrExtension);
   12292         child = child->next;
   12293     } else if (IS_SCHEMA(child, "complexContent")) {
   12294 	/*
   12295 	* <complexType><complexContent>...
   12296 	*/
   12297 	type->contentType = XML_SCHEMA_CONTENT_EMPTY;
   12298         xmlSchemaParseComplexContent(ctxt, schema, child,
   12299 	    &hasRestrictionOrExtension);
   12300         child = child->next;
   12301     } else {
   12302 	/*
   12303 	* E.g <complexType><sequence>... or <complexType><attribute>... etc.
   12304 	*
   12305 	* SPEC
   12306 	* "...the third alternative (neither <simpleContent> nor
   12307 	* <complexContent>) is chosen. This case is understood as shorthand
   12308 	* for complex content restricting the `ur-type definition`, and the
   12309 	* details of the mappings should be modified as necessary.
   12310 	*/
   12311 	type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
   12312 	type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
   12313 	/*
   12314 	* Parse model groups.
   12315 	*/
   12316         if (IS_SCHEMA(child, "all")) {
   12317             type->subtypes = (xmlSchemaTypePtr)
   12318 		xmlSchemaParseModelGroup(ctxt, schema, child,
   12319 		    XML_SCHEMA_TYPE_ALL, 1);
   12320             child = child->next;
   12321         } else if (IS_SCHEMA(child, "choice")) {
   12322             type->subtypes = (xmlSchemaTypePtr)
   12323 		xmlSchemaParseModelGroup(ctxt, schema, child,
   12324 		    XML_SCHEMA_TYPE_CHOICE, 1);
   12325             child = child->next;
   12326         } else if (IS_SCHEMA(child, "sequence")) {
   12327             type->subtypes = (xmlSchemaTypePtr)
   12328 		xmlSchemaParseModelGroup(ctxt, schema, child,
   12329 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
   12330             child = child->next;
   12331         } else if (IS_SCHEMA(child, "group")) {
   12332             type->subtypes = (xmlSchemaTypePtr)
   12333 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
   12334 	    /*
   12335 	    * Note that the reference will be resolved in
   12336 	    * xmlSchemaResolveTypeReferences();
   12337 	    */
   12338             child = child->next;
   12339         }
   12340 	/*
   12341 	* Parse attribute decls/refs.
   12342 	*/
   12343         if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
   12344 	    (xmlSchemaItemListPtr *) &(type->attrUses),
   12345 	    XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
   12346 	    return(NULL);
   12347 	/*
   12348 	* Parse attribute wildcard.
   12349 	*/
   12350 	if (IS_SCHEMA(child, "anyAttribute")) {
   12351 	    type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
   12352 	    child = child->next;
   12353 	}
   12354     }
   12355     if (child != NULL) {
   12356 	xmlSchemaPContentErr(ctxt,
   12357 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   12358 	    NULL, node, child,
   12359 	    NULL, "(annotation?, (simpleContent | complexContent | "
   12360 	    "((group | all | choice | sequence)?, ((attribute | "
   12361 	    "attributeGroup)*, anyAttribute?))))");
   12362     }
   12363     /*
   12364     * REDEFINE: SPEC src-redefine (5)
   12365     */
   12366     if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
   12367 	xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   12368 	    NULL, node, "This is a redefinition, thus the "
   12369 	    "<complexType> must have a <restriction> or <extension> "
   12370 	    "grand-child", NULL);
   12371     }
   12372     ctxt->ctxtType = ctxtType;
   12373     return (type);
   12374 }
   12375 
   12376 /************************************************************************
   12377  *									*
   12378  *			Validating using Schemas			*
   12379  *									*
   12380  ************************************************************************/
   12381 
   12382 /************************************************************************
   12383  *									*
   12384  *			Reading/Writing Schemas				*
   12385  *									*
   12386  ************************************************************************/
   12387 
   12388 #if 0 /* Will be enabled if it is clear what options are needed. */
   12389 /**
   12390  * xmlSchemaParserCtxtSetOptions:
   12391  * @ctxt:	a schema parser context
   12392  * @options: a combination of xmlSchemaParserOption
   12393  *
   12394  * Sets the options to be used during the parse.
   12395  *
   12396  * Returns 0 in case of success, -1 in case of an
   12397  * API error.
   12398  */
   12399 static int
   12400 xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
   12401 			      int options)
   12402 
   12403 {
   12404     int i;
   12405 
   12406     if (ctxt == NULL)
   12407 	return (-1);
   12408     /*
   12409     * WARNING: Change the start value if adding to the
   12410     * xmlSchemaParseOption.
   12411     */
   12412     for (i = 1; i < (int) sizeof(int) * 8; i++) {
   12413         if (options & 1<<i) {
   12414 	    return (-1);
   12415         }
   12416     }
   12417     ctxt->options = options;
   12418     return (0);
   12419 }
   12420 
   12421 /**
   12422  * xmlSchemaValidCtxtGetOptions:
   12423  * @ctxt: a schema parser context
   12424  *
   12425  * Returns the option combination of the parser context.
   12426  */
   12427 static int
   12428 xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
   12429 
   12430 {
   12431     if (ctxt == NULL)
   12432 	return (-1);
   12433     else
   12434 	return (ctxt->options);
   12435 }
   12436 #endif
   12437 
   12438 /**
   12439  * xmlSchemaNewParserCtxt:
   12440  * @URL:  the location of the schema
   12441  *
   12442  * Create an XML Schemas parse context for that file/resource expected
   12443  * to contain an XML Schemas file.
   12444  *
   12445  * Returns the parser context or NULL in case of error
   12446  */
   12447 xmlSchemaParserCtxtPtr
   12448 xmlSchemaNewParserCtxt(const char *URL)
   12449 {
   12450     xmlSchemaParserCtxtPtr ret;
   12451 
   12452     if (URL == NULL)
   12453         return (NULL);
   12454 
   12455     ret = xmlSchemaParserCtxtCreate();
   12456     if (ret == NULL)
   12457 	return(NULL);
   12458     ret->dict = xmlDictCreate();
   12459     ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
   12460     return (ret);
   12461 }
   12462 
   12463 /**
   12464  * xmlSchemaNewMemParserCtxt:
   12465  * @buffer:  a pointer to a char array containing the schemas
   12466  * @size:  the size of the array
   12467  *
   12468  * Create an XML Schemas parse context for that memory buffer expected
   12469  * to contain an XML Schemas file.
   12470  *
   12471  * Returns the parser context or NULL in case of error
   12472  */
   12473 xmlSchemaParserCtxtPtr
   12474 xmlSchemaNewMemParserCtxt(const char *buffer, int size)
   12475 {
   12476     xmlSchemaParserCtxtPtr ret;
   12477 
   12478     if ((buffer == NULL) || (size <= 0))
   12479         return (NULL);
   12480     ret = xmlSchemaParserCtxtCreate();
   12481     if (ret == NULL)
   12482 	return(NULL);
   12483     ret->buffer = buffer;
   12484     ret->size = size;
   12485     ret->dict = xmlDictCreate();
   12486     return (ret);
   12487 }
   12488 
   12489 /**
   12490  * xmlSchemaNewDocParserCtxt:
   12491  * @doc:  a preparsed document tree
   12492  *
   12493  * Create an XML Schemas parse context for that document.
   12494  * NB. The document may be modified during the parsing process.
   12495  *
   12496  * Returns the parser context or NULL in case of error
   12497  */
   12498 xmlSchemaParserCtxtPtr
   12499 xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
   12500 {
   12501     xmlSchemaParserCtxtPtr ret;
   12502 
   12503     if (doc == NULL)
   12504       return (NULL);
   12505     ret = xmlSchemaParserCtxtCreate();
   12506     if (ret == NULL)
   12507 	return(NULL);
   12508     ret->doc = doc;
   12509     ret->dict = xmlDictCreate();
   12510     /* The application has responsibility for the document */
   12511     ret->preserve = 1;
   12512 
   12513     return (ret);
   12514 }
   12515 
   12516 /**
   12517  * xmlSchemaFreeParserCtxt:
   12518  * @ctxt:  the schema parser context
   12519  *
   12520  * Free the resources associated to the schema parser context
   12521  */
   12522 void
   12523 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
   12524 {
   12525     if (ctxt == NULL)
   12526         return;
   12527     if (ctxt->doc != NULL && !ctxt->preserve)
   12528         xmlFreeDoc(ctxt->doc);
   12529     if (ctxt->vctxt != NULL) {
   12530 	xmlSchemaFreeValidCtxt(ctxt->vctxt);
   12531     }
   12532     if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
   12533 	xmlSchemaConstructionCtxtFree(ctxt->constructor);
   12534 	ctxt->constructor = NULL;
   12535 	ctxt->ownsConstructor = 0;
   12536     }
   12537     if (ctxt->attrProhibs != NULL)
   12538 	xmlSchemaItemListFree(ctxt->attrProhibs);
   12539     xmlDictFree(ctxt->dict);
   12540     xmlFree(ctxt);
   12541 }
   12542 
   12543 /************************************************************************
   12544  *									*
   12545  *			Building the content models			*
   12546  *									*
   12547  ************************************************************************/
   12548 
   12549 /**
   12550  * xmlSchemaBuildContentModelForSubstGroup:
   12551  *
   12552  * Returns 1 if nillable, 0 otherwise
   12553  */
   12554 static int
   12555 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
   12556 	xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
   12557 {
   12558     xmlAutomataStatePtr start, tmp;
   12559     xmlSchemaElementPtr elemDecl, member;
   12560     xmlSchemaSubstGroupPtr substGroup;
   12561     int i;
   12562     int ret = 0;
   12563 
   12564     elemDecl = (xmlSchemaElementPtr) particle->children;
   12565     /*
   12566     * Wrap the substitution group with a CHOICE.
   12567     */
   12568     start = pctxt->state;
   12569     if (end == NULL)
   12570 	end = xmlAutomataNewState(pctxt->am);
   12571     substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
   12572     if (substGroup == NULL) {
   12573 	xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
   12574 	    XML_SCHEMAP_INTERNAL,
   12575 	    "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
   12576 	    "declaration is marked having a subst. group but none "
   12577 	    "available.\n", elemDecl->name, NULL);
   12578 	return(0);
   12579     }
   12580     if (counter >= 0) {
   12581 	/*
   12582 	* NOTE that we put the declaration in, even if it's abstract.
   12583 	* However, an error will be raised during *validation* if an element
   12584 	* information item shall be validated against an abstract element
   12585 	* declaration.
   12586 	*/
   12587 	tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
   12588         xmlAutomataNewTransition2(pctxt->am, tmp, end,
   12589 	            elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12590 	/*
   12591 	* Add subst. group members.
   12592 	*/
   12593 	for (i = 0; i < substGroup->members->nbItems; i++) {
   12594 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
   12595             xmlAutomataNewTransition2(pctxt->am, tmp, end,
   12596 		               member->name, member->targetNamespace, member);
   12597 	}
   12598     } else if (particle->maxOccurs == 1) {
   12599 	/*
   12600 	* NOTE that we put the declaration in, even if it's abstract,
   12601 	*/
   12602 	xmlAutomataNewEpsilon(pctxt->am,
   12603 	    xmlAutomataNewTransition2(pctxt->am,
   12604 	    start, NULL,
   12605 	    elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
   12606 	/*
   12607 	* Add subst. group members.
   12608 	*/
   12609 	for (i = 0; i < substGroup->members->nbItems; i++) {
   12610 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
   12611 	    /*
   12612 	    * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
   12613 	    *  was incorrectly used instead of xmlAutomataNewTransition2()
   12614 	    *  (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
   12615 	    *  section in xmlSchemaBuildAContentModel() ).
   12616 	    * TODO: Check if xmlAutomataNewOnceTrans2() was instead
   12617 	    *  intended for the above "counter" section originally. I.e.,
   12618 	    *  check xs:all with subst-groups.
   12619 	    *
   12620 	    * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
   12621 	    *	               member->name, member->targetNamespace,
   12622 	    *		       1, 1, member);
   12623 	    */
   12624 	    tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
   12625 		member->name, member->targetNamespace, member);
   12626 	    xmlAutomataNewEpsilon(pctxt->am, tmp, end);
   12627 	}
   12628     } else {
   12629 	xmlAutomataStatePtr hop;
   12630 	int maxOccurs = particle->maxOccurs == UNBOUNDED ?
   12631 	    UNBOUNDED : particle->maxOccurs - 1;
   12632 	int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
   12633 
   12634 	counter =
   12635 	    xmlAutomataNewCounter(pctxt->am, minOccurs,
   12636 	    maxOccurs);
   12637 	hop = xmlAutomataNewState(pctxt->am);
   12638 
   12639 	xmlAutomataNewEpsilon(pctxt->am,
   12640 	    xmlAutomataNewTransition2(pctxt->am,
   12641 	    start, NULL,
   12642 	    elemDecl->name, elemDecl->targetNamespace, elemDecl),
   12643 	    hop);
   12644 	/*
   12645 	 * Add subst. group members.
   12646 	 */
   12647 	for (i = 0; i < substGroup->members->nbItems; i++) {
   12648 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
   12649 	    xmlAutomataNewEpsilon(pctxt->am,
   12650 		xmlAutomataNewTransition2(pctxt->am,
   12651 		start, NULL,
   12652 		member->name, member->targetNamespace, member),
   12653 		hop);
   12654 	}
   12655 	xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
   12656 	xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
   12657     }
   12658     if (particle->minOccurs == 0) {
   12659 	xmlAutomataNewEpsilon(pctxt->am, start, end);
   12660         ret = 1;
   12661     }
   12662     pctxt->state = end;
   12663     return(ret);
   12664 }
   12665 
   12666 /**
   12667  * xmlSchemaBuildContentModelForElement:
   12668  *
   12669  * Returns 1 if nillable, 0 otherwise
   12670  */
   12671 static int
   12672 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
   12673 				     xmlSchemaParticlePtr particle)
   12674 {
   12675     int ret = 0;
   12676 
   12677     if (((xmlSchemaElementPtr) particle->children)->flags &
   12678 	XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
   12679 	/*
   12680 	* Substitution groups.
   12681 	*/
   12682 	ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
   12683     } else {
   12684 	xmlSchemaElementPtr elemDecl;
   12685 	xmlAutomataStatePtr start;
   12686 
   12687 	elemDecl = (xmlSchemaElementPtr) particle->children;
   12688 
   12689 	if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
   12690 	    return(0);
   12691 	if (particle->maxOccurs == 1) {
   12692 	    start = ctxt->state;
   12693 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
   12694 		    elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12695 	} else if ((particle->maxOccurs >= UNBOUNDED) &&
   12696 	           (particle->minOccurs < 2)) {
   12697 	    /* Special case. */
   12698 	    start = ctxt->state;
   12699 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
   12700 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12701 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
   12702 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12703 	} else {
   12704 	    int counter;
   12705 	    int maxOccurs = particle->maxOccurs == UNBOUNDED ?
   12706 			    UNBOUNDED : particle->maxOccurs - 1;
   12707 	    int minOccurs = particle->minOccurs < 1 ?
   12708 			    0 : particle->minOccurs - 1;
   12709 
   12710 	    start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
   12711 	    counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
   12712 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
   12713 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12714 	    xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
   12715 	    ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
   12716 		NULL, counter);
   12717 	}
   12718 	if (particle->minOccurs == 0) {
   12719 	    xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
   12720             ret = 1;
   12721         }
   12722     }
   12723     return(ret);
   12724 }
   12725 
   12726 /**
   12727  * xmlSchemaBuildAContentModel:
   12728  * @ctxt:  the schema parser context
   12729  * @particle:  the particle component
   12730  * @name:  the complex type's name whose content is being built
   12731  *
   12732  * Create the automaton for the {content type} of a complex type.
   12733  *
   12734  * Returns 1 if the content is nillable, 0 otherwise
   12735  */
   12736 static int
   12737 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
   12738 			    xmlSchemaParticlePtr particle)
   12739 {
   12740     int ret = 0, tmp2;
   12741 
   12742     if (particle == NULL) {
   12743 	PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
   12744 	return(1);
   12745     }
   12746     if (particle->children == NULL) {
   12747 	/*
   12748 	* Just return in this case. A missing "term" of the particle
   12749 	* might arise due to an invalid "term" component.
   12750 	*/
   12751 	return(1);
   12752     }
   12753 
   12754     switch (particle->children->type) {
   12755 	case XML_SCHEMA_TYPE_ANY: {
   12756 	    xmlAutomataStatePtr start, end;
   12757 	    xmlSchemaWildcardPtr wild;
   12758 	    xmlSchemaWildcardNsPtr ns;
   12759 
   12760 	    wild = (xmlSchemaWildcardPtr) particle->children;
   12761 
   12762 	    start = pctxt->state;
   12763 	    end = xmlAutomataNewState(pctxt->am);
   12764 
   12765 	    if (particle->maxOccurs == 1) {
   12766 		if (wild->any == 1) {
   12767 		    /*
   12768 		    * We need to add both transitions:
   12769 		    *
   12770 		    * 1. the {"*", "*"} for elements in a namespace.
   12771 		    */
   12772 		    pctxt->state =
   12773 			xmlAutomataNewTransition2(pctxt->am,
   12774 			start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
   12775 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
   12776 		    /*
   12777 		    * 2. the {"*"} for elements in no namespace.
   12778 		    */
   12779 		    pctxt->state =
   12780 			xmlAutomataNewTransition2(pctxt->am,
   12781 			start, NULL, BAD_CAST "*", NULL, wild);
   12782 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
   12783 
   12784 		} else if (wild->nsSet != NULL) {
   12785 		    ns = wild->nsSet;
   12786 		    do {
   12787 			pctxt->state = start;
   12788 			pctxt->state = xmlAutomataNewTransition2(pctxt->am,
   12789 			    pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
   12790 			xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
   12791 			ns = ns->next;
   12792 		    } while (ns != NULL);
   12793 
   12794 		} else if (wild->negNsSet != NULL) {
   12795 		    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
   12796 			start, end, BAD_CAST "*", wild->negNsSet->value,
   12797 			wild);
   12798 		}
   12799 	    } else {
   12800 		int counter;
   12801 		xmlAutomataStatePtr hop;
   12802 		int maxOccurs =
   12803 		    particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
   12804                                            particle->maxOccurs - 1;
   12805 		int minOccurs =
   12806 		    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
   12807 
   12808 		counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
   12809 		hop = xmlAutomataNewState(pctxt->am);
   12810 		if (wild->any == 1) {
   12811 		    pctxt->state =
   12812 			xmlAutomataNewTransition2(pctxt->am,
   12813 			start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
   12814 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
   12815 		    pctxt->state =
   12816 			xmlAutomataNewTransition2(pctxt->am,
   12817 			start, NULL, BAD_CAST "*", NULL, wild);
   12818 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
   12819 		} else if (wild->nsSet != NULL) {
   12820 		    ns = wild->nsSet;
   12821 		    do {
   12822 			pctxt->state =
   12823 			    xmlAutomataNewTransition2(pctxt->am,
   12824 				start, NULL, BAD_CAST "*", ns->value, wild);
   12825 			xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
   12826 			ns = ns->next;
   12827 		    } while (ns != NULL);
   12828 
   12829 		} else if (wild->negNsSet != NULL) {
   12830 		    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
   12831 			start, hop, BAD_CAST "*", wild->negNsSet->value,
   12832 			wild);
   12833 		}
   12834 		xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
   12835 		xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
   12836 	    }
   12837 	    if (particle->minOccurs == 0) {
   12838 		xmlAutomataNewEpsilon(pctxt->am, start, end);
   12839                 ret = 1;
   12840 	    }
   12841 	    pctxt->state = end;
   12842             break;
   12843 	}
   12844         case XML_SCHEMA_TYPE_ELEMENT:
   12845 	    ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
   12846 	    break;
   12847         case XML_SCHEMA_TYPE_SEQUENCE:{
   12848             xmlSchemaTreeItemPtr sub;
   12849 
   12850             ret = 1;
   12851             /*
   12852              * If max and min occurances are default (1) then
   12853              * simply iterate over the particles of the <sequence>.
   12854              */
   12855             if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
   12856                 sub = particle->children->children;
   12857 
   12858                 while (sub != NULL) {
   12859                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12860                                         (xmlSchemaParticlePtr) sub);
   12861                     if (tmp2 != 1) ret = 0;
   12862                     sub = sub->next;
   12863                 }
   12864             } else {
   12865                 xmlAutomataStatePtr oldstate = pctxt->state;
   12866 
   12867                 if (particle->maxOccurs >= UNBOUNDED) {
   12868                     if (particle->minOccurs > 1) {
   12869                         xmlAutomataStatePtr tmp;
   12870                         int counter;
   12871 
   12872                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12873                             oldstate, NULL);
   12874                         oldstate = pctxt->state;
   12875 
   12876                         counter = xmlAutomataNewCounter(pctxt->am,
   12877                             particle->minOccurs - 1, UNBOUNDED);
   12878 
   12879                         sub = particle->children->children;
   12880                         while (sub != NULL) {
   12881                             tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12882                                             (xmlSchemaParticlePtr) sub);
   12883                             if (tmp2 != 1) ret = 0;
   12884                             sub = sub->next;
   12885                         }
   12886                         tmp = pctxt->state;
   12887                         xmlAutomataNewCountedTrans(pctxt->am, tmp,
   12888                                                    oldstate, counter);
   12889                         pctxt->state =
   12890                             xmlAutomataNewCounterTrans(pctxt->am, tmp,
   12891                                                        NULL, counter);
   12892                         if (ret == 1)
   12893                             xmlAutomataNewEpsilon(pctxt->am,
   12894                                                 oldstate, pctxt->state);
   12895 
   12896                     } else {
   12897                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12898                             oldstate, NULL);
   12899                         oldstate = pctxt->state;
   12900 
   12901                         sub = particle->children->children;
   12902                         while (sub != NULL) {
   12903                             tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12904                                         (xmlSchemaParticlePtr) sub);
   12905                             if (tmp2 != 1) ret = 0;
   12906                             sub = sub->next;
   12907                         }
   12908                         xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
   12909                                               oldstate);
   12910                         /*
   12911                          * epsilon needed to block previous trans from
   12912                          * being allowed to enter back from another
   12913                          * construct
   12914                          */
   12915                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12916                                             pctxt->state, NULL);
   12917                         if (particle->minOccurs == 0) {
   12918                             xmlAutomataNewEpsilon(pctxt->am,
   12919                                 oldstate, pctxt->state);
   12920                             ret = 1;
   12921                         }
   12922                     }
   12923                 } else if ((particle->maxOccurs > 1)
   12924                            || (particle->minOccurs > 1)) {
   12925                     xmlAutomataStatePtr tmp;
   12926                     int counter;
   12927 
   12928                     pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12929                         oldstate, NULL);
   12930                     oldstate = pctxt->state;
   12931 
   12932                     counter = xmlAutomataNewCounter(pctxt->am,
   12933                         particle->minOccurs - 1,
   12934                         particle->maxOccurs - 1);
   12935 
   12936                     sub = particle->children->children;
   12937                     while (sub != NULL) {
   12938                         tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12939                                         (xmlSchemaParticlePtr) sub);
   12940                         if (tmp2 != 1) ret = 0;
   12941                         sub = sub->next;
   12942                     }
   12943                     tmp = pctxt->state;
   12944                     xmlAutomataNewCountedTrans(pctxt->am,
   12945                         tmp, oldstate, counter);
   12946                     pctxt->state =
   12947                         xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
   12948                                                    counter);
   12949                     if ((particle->minOccurs == 0) || (ret == 1)) {
   12950                         xmlAutomataNewEpsilon(pctxt->am,
   12951                                             oldstate, pctxt->state);
   12952                         ret = 1;
   12953                     }
   12954                 } else {
   12955                     sub = particle->children->children;
   12956                     while (sub != NULL) {
   12957                         tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12958                                         (xmlSchemaParticlePtr) sub);
   12959                         if (tmp2 != 1) ret = 0;
   12960                         sub = sub->next;
   12961                     }
   12962 
   12963 		    /*
   12964 		     * epsilon needed to block previous trans from
   12965 		     * being allowed to enter back from another
   12966 		     * construct
   12967 		     */
   12968 		    pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12969 					pctxt->state, NULL);
   12970 
   12971                     if (particle->minOccurs == 0) {
   12972                         xmlAutomataNewEpsilon(pctxt->am, oldstate,
   12973                                               pctxt->state);
   12974                         ret = 1;
   12975                     }
   12976                 }
   12977             }
   12978             break;
   12979         }
   12980         case XML_SCHEMA_TYPE_CHOICE:{
   12981             xmlSchemaTreeItemPtr sub;
   12982             xmlAutomataStatePtr start, end;
   12983 
   12984             ret = 0;
   12985             start = pctxt->state;
   12986             end = xmlAutomataNewState(pctxt->am);
   12987 
   12988             /*
   12989              * iterate over the subtypes and remerge the end with an
   12990              * epsilon transition
   12991              */
   12992             if (particle->maxOccurs == 1) {
   12993                 sub = particle->children->children;
   12994                 while (sub != NULL) {
   12995                     pctxt->state = start;
   12996                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12997                                         (xmlSchemaParticlePtr) sub);
   12998                     if (tmp2 == 1) ret = 1;
   12999                     xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
   13000                     sub = sub->next;
   13001                 }
   13002             } else {
   13003                 int counter;
   13004                 xmlAutomataStatePtr hop, base;
   13005                 int maxOccurs = particle->maxOccurs == UNBOUNDED ?
   13006                     UNBOUNDED : particle->maxOccurs - 1;
   13007                 int minOccurs =
   13008                     particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
   13009 
   13010                 /*
   13011                  * use a counter to keep track of the number of transtions
   13012                  * which went through the choice.
   13013                  */
   13014                 counter =
   13015                     xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
   13016                 hop = xmlAutomataNewState(pctxt->am);
   13017                 base = xmlAutomataNewState(pctxt->am);
   13018 
   13019                 sub = particle->children->children;
   13020                 while (sub != NULL) {
   13021                     pctxt->state = base;
   13022                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
   13023                                         (xmlSchemaParticlePtr) sub);
   13024                     if (tmp2 == 1) ret = 1;
   13025                     xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
   13026                     sub = sub->next;
   13027                 }
   13028                 xmlAutomataNewEpsilon(pctxt->am, start, base);
   13029                 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
   13030                 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
   13031                 if (ret == 1)
   13032                     xmlAutomataNewEpsilon(pctxt->am, base, end);
   13033             }
   13034             if (particle->minOccurs == 0) {
   13035                 xmlAutomataNewEpsilon(pctxt->am, start, end);
   13036                 ret = 1;
   13037             }
   13038             pctxt->state = end;
   13039             break;
   13040         }
   13041         case XML_SCHEMA_TYPE_ALL:{
   13042             xmlAutomataStatePtr start, tmp;
   13043             xmlSchemaParticlePtr sub;
   13044             xmlSchemaElementPtr elemDecl;
   13045 
   13046             ret = 1;
   13047 
   13048             sub = (xmlSchemaParticlePtr) particle->children->children;
   13049             if (sub == NULL)
   13050                 break;
   13051 
   13052             ret = 0;
   13053 
   13054             start = pctxt->state;
   13055             tmp = xmlAutomataNewState(pctxt->am);
   13056             xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
   13057             pctxt->state = tmp;
   13058             while (sub != NULL) {
   13059                 pctxt->state = tmp;
   13060 
   13061                 elemDecl = (xmlSchemaElementPtr) sub->children;
   13062                 if (elemDecl == NULL) {
   13063                     PERROR_INT("xmlSchemaBuildAContentModel",
   13064                         "<element> particle has no term");
   13065                     return(ret);
   13066                 };
   13067                 /*
   13068                 * NOTE: The {max occurs} of all the particles in the
   13069                 * {particles} of the group must be 0 or 1; this is
   13070                 * already ensured during the parse of the content of
   13071                 * <all>.
   13072                 */
   13073                 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
   13074                     int counter;
   13075 
   13076                     /*
   13077                      * This is an abstract group, we need to share
   13078                      * the same counter for all the element transitions
   13079                      * derived from the group
   13080                      */
   13081                     counter = xmlAutomataNewCounter(pctxt->am,
   13082                                        sub->minOccurs, sub->maxOccurs);
   13083                     xmlSchemaBuildContentModelForSubstGroup(pctxt,
   13084                                        sub, counter, pctxt->state);
   13085                 } else {
   13086                     if ((sub->minOccurs == 1) &&
   13087                         (sub->maxOccurs == 1)) {
   13088                         xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
   13089                                                 pctxt->state,
   13090                                                 elemDecl->name,
   13091                                                 elemDecl->targetNamespace,
   13092                                                 1, 1, elemDecl);
   13093                     } else if ((sub->minOccurs == 0) &&
   13094                         (sub->maxOccurs == 1)) {
   13095 
   13096                         xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
   13097                                                  pctxt->state,
   13098                                                  elemDecl->name,
   13099                                                  elemDecl->targetNamespace,
   13100                                                  0,
   13101                                                  1,
   13102                                                  elemDecl);
   13103                     }
   13104                 }
   13105                 sub = (xmlSchemaParticlePtr) sub->next;
   13106             }
   13107             pctxt->state =
   13108                 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
   13109             if (particle->minOccurs == 0) {
   13110                 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
   13111                 ret = 1;
   13112             }
   13113             break;
   13114         }
   13115 	case XML_SCHEMA_TYPE_GROUP:
   13116 	    /*
   13117 	    * If we hit a model group definition, then this means that
   13118 	    * it was empty, thus was not substituted for the containing
   13119 	    * model group. Just do nothing in this case.
   13120 	    * TODO: But the group should be substituted and not occur at
   13121 	    * all in the content model at this point. Fix this.
   13122 	    */
   13123             ret = 1;
   13124 	    break;
   13125         default:
   13126 	    xmlSchemaInternalErr2(ACTXT_CAST pctxt,
   13127 		"xmlSchemaBuildAContentModel",
   13128 		"found unexpected term of type '%s' in content model",
   13129 		WXS_ITEM_TYPE_NAME(particle->children), NULL);
   13130             return(ret);
   13131     }
   13132     return(ret);
   13133 }
   13134 
   13135 /**
   13136  * xmlSchemaBuildContentModel:
   13137  * @ctxt:  the schema parser context
   13138  * @type:  the complex type definition
   13139  * @name:  the element name
   13140  *
   13141  * Builds the content model of the complex type.
   13142  */
   13143 static void
   13144 xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
   13145 			   xmlSchemaParserCtxtPtr ctxt)
   13146 {
   13147     if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
   13148 	(type->contModel != NULL) ||
   13149 	((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
   13150 	(type->contentType != XML_SCHEMA_CONTENT_MIXED)))
   13151 	return;
   13152 
   13153 #ifdef DEBUG_CONTENT
   13154     xmlGenericError(xmlGenericErrorContext,
   13155                     "Building content model for %s\n", name);
   13156 #endif
   13157     ctxt->am = NULL;
   13158     ctxt->am = xmlNewAutomata();
   13159     if (ctxt->am == NULL) {
   13160         xmlGenericError(xmlGenericErrorContext,
   13161 	    "Cannot create automata for complex type %s\n", type->name);
   13162         return;
   13163     }
   13164     ctxt->state = xmlAutomataGetInitState(ctxt->am);
   13165     /*
   13166     * Build the automaton.
   13167     */
   13168     xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
   13169     xmlAutomataSetFinalState(ctxt->am, ctxt->state);
   13170     type->contModel = xmlAutomataCompile(ctxt->am);
   13171     if (type->contModel == NULL) {
   13172         xmlSchemaPCustomErr(ctxt,
   13173 	    XML_SCHEMAP_INTERNAL,
   13174 	    WXS_BASIC_CAST type, type->node,
   13175 	    "Failed to compile the content model", NULL);
   13176     } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
   13177         xmlSchemaPCustomErr(ctxt,
   13178 	    XML_SCHEMAP_NOT_DETERMINISTIC,
   13179 	    /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
   13180 	    WXS_BASIC_CAST type, type->node,
   13181 	    "The content model is not determinist", NULL);
   13182     } else {
   13183 #ifdef DEBUG_CONTENT_REGEXP
   13184         xmlGenericError(xmlGenericErrorContext,
   13185                         "Content model of %s:\n", type->name);
   13186         xmlRegexpPrint(stderr, type->contModel);
   13187 #endif
   13188     }
   13189     ctxt->state = NULL;
   13190     xmlFreeAutomata(ctxt->am);
   13191     ctxt->am = NULL;
   13192 }
   13193 
   13194 /**
   13195  * xmlSchemaResolveElementReferences:
   13196  * @elem:  the schema element context
   13197  * @ctxt:  the schema parser context
   13198  *
   13199  * Resolves the references of an element declaration
   13200  * or particle, which has an element declaration as it's
   13201  * term.
   13202  */
   13203 static void
   13204 xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
   13205 				  xmlSchemaParserCtxtPtr ctxt)
   13206 {
   13207     if ((ctxt == NULL) || (elemDecl == NULL) ||
   13208 	((elemDecl != NULL) &&
   13209 	(elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
   13210         return;
   13211     elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
   13212 
   13213     if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
   13214 	xmlSchemaTypePtr type;
   13215 
   13216 	/* (type definition) ... otherwise the type definition `resolved`
   13217 	* to by the `actual value` of the type [attribute] ...
   13218 	*/
   13219 	type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
   13220 	    elemDecl->namedTypeNs);
   13221 	if (type == NULL) {
   13222 	    xmlSchemaPResCompAttrErr(ctxt,
   13223 		XML_SCHEMAP_SRC_RESOLVE,
   13224 		WXS_BASIC_CAST elemDecl, elemDecl->node,
   13225 		"type", elemDecl->namedType, elemDecl->namedTypeNs,
   13226 		XML_SCHEMA_TYPE_BASIC, "type definition");
   13227 	} else
   13228 	    elemDecl->subtypes = type;
   13229     }
   13230     if (elemDecl->substGroup != NULL) {
   13231 	xmlSchemaElementPtr substHead;
   13232 
   13233 	/*
   13234 	* FIXME TODO: Do we need a new field in _xmlSchemaElement for
   13235 	* substitutionGroup?
   13236 	*/
   13237 	substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
   13238 	    elemDecl->substGroupNs);
   13239 	if (substHead == NULL) {
   13240 	    xmlSchemaPResCompAttrErr(ctxt,
   13241 		XML_SCHEMAP_SRC_RESOLVE,
   13242 		WXS_BASIC_CAST elemDecl, NULL,
   13243 		"substitutionGroup", elemDecl->substGroup,
   13244 		elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
   13245 	} else {
   13246 	    xmlSchemaResolveElementReferences(substHead, ctxt);
   13247 	    /*
   13248 	    * Set the "substitution group affiliation".
   13249 	    * NOTE that now we use the "refDecl" field for this.
   13250 	    */
   13251 	    WXS_SUBST_HEAD(elemDecl) = substHead;
   13252 	    /*
   13253 	    * The type definitions is set to:
   13254 	    * SPEC "...the {type definition} of the element
   13255 	    * declaration `resolved` to by the `actual value`
   13256 	    * of the substitutionGroup [attribute], if present"
   13257 	    */
   13258 	    if (elemDecl->subtypes == NULL)
   13259 		elemDecl->subtypes = substHead->subtypes;
   13260 	}
   13261     }
   13262     /*
   13263     * SPEC "The definition of anyType serves as the default type definition
   13264     * for element declarations whose XML representation does not specify one."
   13265     */
   13266     if ((elemDecl->subtypes == NULL) &&
   13267 	(elemDecl->namedType == NULL) &&
   13268 	(elemDecl->substGroup == NULL))
   13269 	elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
   13270 }
   13271 
   13272 /**
   13273  * xmlSchemaResolveUnionMemberTypes:
   13274  * @ctxt:  the schema parser context
   13275  * @type:  the schema simple type definition
   13276  *
   13277  * Checks and builds the "member type definitions" property of the union
   13278  * simple type. This handles part (1), part (2) is done in
   13279  * xmlSchemaFinishMemberTypeDefinitionsProperty()
   13280  *
   13281  * Returns -1 in case of an internal error, 0 otherwise.
   13282  */
   13283 static int
   13284 xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
   13285 				 xmlSchemaTypePtr type)
   13286 {
   13287 
   13288     xmlSchemaTypeLinkPtr link, lastLink, newLink;
   13289     xmlSchemaTypePtr memberType;
   13290 
   13291     /*
   13292     * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
   13293     * define the explicit members as the type definitions `resolved`
   13294     * to by the items in the `actual value` of the memberTypes [attribute],
   13295     * if any, followed by the type definitions corresponding to the
   13296     * <simpleType>s among the [children] of <union>, if any."
   13297     */
   13298     /*
   13299     * Resolve references.
   13300     */
   13301     link = type->memberTypes;
   13302     lastLink = NULL;
   13303     while (link != NULL) {
   13304 	const xmlChar *name, *nsName;
   13305 
   13306 	name = ((xmlSchemaQNameRefPtr) link->type)->name;
   13307 	nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
   13308 
   13309 	memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
   13310 	if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
   13311 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
   13312 		WXS_BASIC_CAST type, type->node, "memberTypes",
   13313 		name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
   13314 	    /*
   13315 	    * Remove the member type link.
   13316 	    */
   13317 	    if (lastLink == NULL)
   13318 		type->memberTypes = link->next;
   13319 	    else
   13320 		lastLink->next = link->next;
   13321 	    newLink = link;
   13322 	    link = link->next;
   13323 	    xmlFree(newLink);
   13324 	} else {
   13325 	    link->type = memberType;
   13326 	    lastLink = link;
   13327 	    link = link->next;
   13328 	}
   13329     }
   13330     /*
   13331     * Add local simple types,
   13332     */
   13333     memberType = type->subtypes;
   13334     while (memberType != NULL) {
   13335 	link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
   13336 	if (link == NULL) {
   13337 	    xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
   13338 	    return (-1);
   13339 	}
   13340 	link->type = memberType;
   13341 	link->next = NULL;
   13342 	if (lastLink == NULL)
   13343 	    type->memberTypes = link;
   13344 	else
   13345 	    lastLink->next = link;
   13346 	lastLink = link;
   13347 	memberType = memberType->next;
   13348     }
   13349     return (0);
   13350 }
   13351 
   13352 /**
   13353  * xmlSchemaIsDerivedFromBuiltInType:
   13354  * @ctxt:  the schema parser context
   13355  * @type:  the type definition
   13356  * @valType: the value type
   13357  *
   13358  *
   13359  * Returns 1 if the type has the given value type, or
   13360  * is derived from such a type.
   13361  */
   13362 static int
   13363 xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
   13364 {
   13365     if (type == NULL)
   13366 	return (0);
   13367     if (WXS_IS_COMPLEX(type))
   13368 	return (0);
   13369     if (type->type == XML_SCHEMA_TYPE_BASIC) {
   13370 	if (type->builtInType == valType)
   13371 	    return(1);
   13372 	if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
   13373 	    (type->builtInType == XML_SCHEMAS_ANYTYPE))
   13374 	    return (0);
   13375 	return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
   13376     }
   13377     return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
   13378 }
   13379 
   13380 #if 0
   13381 /**
   13382  * xmlSchemaIsDerivedFromBuiltInType:
   13383  * @ctxt:  the schema parser context
   13384  * @type:  the type definition
   13385  * @valType: the value type
   13386  *
   13387  *
   13388  * Returns 1 if the type has the given value type, or
   13389  * is derived from such a type.
   13390  */
   13391 static int
   13392 xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
   13393 {
   13394     if (type == NULL)
   13395 	return (0);
   13396     if (WXS_IS_COMPLEX(type))
   13397 	return (0);
   13398     if (type->type == XML_SCHEMA_TYPE_BASIC) {
   13399 	if (type->builtInType == valType)
   13400 	    return(1);
   13401 	return (0);
   13402     } else
   13403 	return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
   13404 
   13405     return (0);
   13406 }
   13407 
   13408 static xmlSchemaTypePtr
   13409 xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
   13410 {
   13411     if (type == NULL)
   13412 	return (NULL);
   13413     if (WXS_IS_COMPLEX(type))
   13414 	return (NULL);
   13415     if (type->type == XML_SCHEMA_TYPE_BASIC)
   13416 	return(type);
   13417     return(xmlSchemaQueryBuiltInType(type->subtypes));
   13418 }
   13419 #endif
   13420 
   13421 /**
   13422  * xmlSchemaGetPrimitiveType:
   13423  * @type:  the simpleType definition
   13424  *
   13425  * Returns the primitive type of the given type or
   13426  * NULL in case of error.
   13427  */
   13428 static xmlSchemaTypePtr
   13429 xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
   13430 {
   13431 
   13432     while (type != NULL) {
   13433 	/*
   13434 	* Note that anySimpleType is actually not a primitive type
   13435 	* but we need that here.
   13436 	*/
   13437 	if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
   13438 	   (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
   13439 	    return (type);
   13440 	type = type->baseType;
   13441     }
   13442 
   13443     return (NULL);
   13444 }
   13445 
   13446 #if 0
   13447 /**
   13448  * xmlSchemaGetBuiltInTypeAncestor:
   13449  * @type:  the simpleType definition
   13450  *
   13451  * Returns the primitive type of the given type or
   13452  * NULL in case of error.
   13453  */
   13454 static xmlSchemaTypePtr
   13455 xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
   13456 {
   13457     if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
   13458 	return (0);
   13459     while (type != NULL) {
   13460 	if (type->type == XML_SCHEMA_TYPE_BASIC)
   13461 	    return (type);
   13462 	type = type->baseType;
   13463     }
   13464 
   13465     return (NULL);
   13466 }
   13467 #endif
   13468 
   13469 /**
   13470  * xmlSchemaCloneWildcardNsConstraints:
   13471  * @ctxt:  the schema parser context
   13472  * @dest:  the destination wildcard
   13473  * @source: the source wildcard
   13474  *
   13475  * Clones the namespace constraints of source
   13476  * and assignes them to dest.
   13477  * Returns -1 on internal error, 0 otherwise.
   13478  */
   13479 static int
   13480 xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
   13481 				    xmlSchemaWildcardPtr dest,
   13482 				    xmlSchemaWildcardPtr source)
   13483 {
   13484     xmlSchemaWildcardNsPtr cur, tmp, last;
   13485 
   13486     if ((source == NULL) || (dest == NULL))
   13487 	return(-1);
   13488     dest->any = source->any;
   13489     cur = source->nsSet;
   13490     last = NULL;
   13491     while (cur != NULL) {
   13492 	tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
   13493 	if (tmp == NULL)
   13494 	    return(-1);
   13495 	tmp->value = cur->value;
   13496 	if (last == NULL)
   13497 	    dest->nsSet = tmp;
   13498 	else
   13499 	    last->next = tmp;
   13500 	last = tmp;
   13501 	cur = cur->next;
   13502     }
   13503     if (dest->negNsSet != NULL)
   13504 	xmlSchemaFreeWildcardNsSet(dest->negNsSet);
   13505     if (source->negNsSet != NULL) {
   13506 	dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   13507 	if (dest->negNsSet == NULL)
   13508 	    return(-1);
   13509 	dest->negNsSet->value = source->negNsSet->value;
   13510     } else
   13511 	dest->negNsSet = NULL;
   13512     return(0);
   13513 }
   13514 
   13515 /**
   13516  * xmlSchemaUnionWildcards:
   13517  * @ctxt:  the schema parser context
   13518  * @completeWild:  the first wildcard
   13519  * @curWild: the second wildcard
   13520  *
   13521  * Unions the namespace constraints of the given wildcards.
   13522  * @completeWild will hold the resulting union.
   13523  * Returns a positive error code on failure, -1 in case of an
   13524  * internal error, 0 otherwise.
   13525  */
   13526 static int
   13527 xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
   13528 			    xmlSchemaWildcardPtr completeWild,
   13529 			    xmlSchemaWildcardPtr curWild)
   13530 {
   13531     xmlSchemaWildcardNsPtr cur, curB, tmp;
   13532 
   13533     /*
   13534     * 1 If O1 and O2 are the same value, then that value must be the
   13535     * value.
   13536     */
   13537     if ((completeWild->any == curWild->any) &&
   13538 	((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
   13539 	((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
   13540 
   13541 	if ((completeWild->negNsSet == NULL) ||
   13542 	    (completeWild->negNsSet->value == curWild->negNsSet->value)) {
   13543 
   13544 	    if (completeWild->nsSet != NULL) {
   13545 		int found = 0;
   13546 
   13547 		/*
   13548 		* Check equality of sets.
   13549 		*/
   13550 		cur = completeWild->nsSet;
   13551 		while (cur != NULL) {
   13552 		    found = 0;
   13553 		    curB = curWild->nsSet;
   13554 		    while (curB != NULL) {
   13555 			if (cur->value == curB->value) {
   13556 			    found = 1;
   13557 			    break;
   13558 			}
   13559 			curB = curB->next;
   13560 		    }
   13561 		    if (!found)
   13562 			break;
   13563 		    cur = cur->next;
   13564 		}
   13565 		if (found)
   13566 		    return(0);
   13567 	    } else
   13568 		return(0);
   13569 	}
   13570     }
   13571     /*
   13572     * 2 If either O1 or O2 is any, then any must be the value
   13573     */
   13574     if (completeWild->any != curWild->any) {
   13575 	if (completeWild->any == 0) {
   13576 	    completeWild->any = 1;
   13577 	    if (completeWild->nsSet != NULL) {
   13578 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13579 		completeWild->nsSet = NULL;
   13580 	    }
   13581 	    if (completeWild->negNsSet != NULL) {
   13582 		xmlFree(completeWild->negNsSet);
   13583 		completeWild->negNsSet = NULL;
   13584 	    }
   13585 	}
   13586 	return (0);
   13587     }
   13588     /*
   13589     * 3 If both O1 and O2 are sets of (namespace names or `absent`),
   13590     * then the union of those sets must be the value.
   13591     */
   13592     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
   13593 	int found;
   13594 	xmlSchemaWildcardNsPtr start;
   13595 
   13596 	cur = curWild->nsSet;
   13597 	start = completeWild->nsSet;
   13598 	while (cur != NULL) {
   13599 	    found = 0;
   13600 	    curB = start;
   13601 	    while (curB != NULL) {
   13602 		if (cur->value == curB->value) {
   13603 		    found = 1;
   13604 		    break;
   13605 		}
   13606 		curB = curB->next;
   13607 	    }
   13608 	    if (!found) {
   13609 		tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
   13610 		if (tmp == NULL)
   13611 		    return (-1);
   13612 		tmp->value = cur->value;
   13613 		tmp->next = completeWild->nsSet;
   13614 		completeWild->nsSet = tmp;
   13615 	    }
   13616 	    cur = cur->next;
   13617 	}
   13618 
   13619 	return(0);
   13620     }
   13621     /*
   13622     * 4 If the two are negations of different values (namespace names
   13623     * or `absent`), then a pair of not and `absent` must be the value.
   13624     */
   13625     if ((completeWild->negNsSet != NULL) &&
   13626 	(curWild->negNsSet != NULL) &&
   13627 	(completeWild->negNsSet->value != curWild->negNsSet->value)) {
   13628 	completeWild->negNsSet->value = NULL;
   13629 
   13630 	return(0);
   13631     }
   13632     /*
   13633      * 5.
   13634      */
   13635     if (((completeWild->negNsSet != NULL) &&
   13636 	(completeWild->negNsSet->value != NULL) &&
   13637 	(curWild->nsSet != NULL)) ||
   13638 	((curWild->negNsSet != NULL) &&
   13639 	(curWild->negNsSet->value != NULL) &&
   13640 	(completeWild->nsSet != NULL))) {
   13641 
   13642 	int nsFound, absentFound = 0;
   13643 
   13644 	if (completeWild->nsSet != NULL) {
   13645 	    cur = completeWild->nsSet;
   13646 	    curB = curWild->negNsSet;
   13647 	} else {
   13648 	    cur = curWild->nsSet;
   13649 	    curB = completeWild->negNsSet;
   13650 	}
   13651 	nsFound = 0;
   13652 	while (cur != NULL) {
   13653 	    if (cur->value == NULL)
   13654 		absentFound = 1;
   13655 	    else if (cur->value == curB->value)
   13656 		nsFound = 1;
   13657 	    if (nsFound && absentFound)
   13658 		break;
   13659 	    cur = cur->next;
   13660 	}
   13661 
   13662 	if (nsFound && absentFound) {
   13663 	    /*
   13664 	    * 5.1 If the set S includes both the negated namespace
   13665 	    * name and `absent`, then any must be the value.
   13666 	    */
   13667 	    completeWild->any = 1;
   13668 	    if (completeWild->nsSet != NULL) {
   13669 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13670 		completeWild->nsSet = NULL;
   13671 	    }
   13672 	    if (completeWild->negNsSet != NULL) {
   13673 		xmlFree(completeWild->negNsSet);
   13674 		completeWild->negNsSet = NULL;
   13675 	    }
   13676 	} else if (nsFound && (!absentFound)) {
   13677 	    /*
   13678 	    * 5.2 If the set S includes the negated namespace name
   13679 	    * but not `absent`, then a pair of not and `absent` must
   13680 	    * be the value.
   13681 	    */
   13682 	    if (completeWild->nsSet != NULL) {
   13683 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13684 		completeWild->nsSet = NULL;
   13685 	    }
   13686 	    if (completeWild->negNsSet == NULL) {
   13687 		completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   13688 		if (completeWild->negNsSet == NULL)
   13689 		    return (-1);
   13690 	    }
   13691 	    completeWild->negNsSet->value = NULL;
   13692 	} else if ((!nsFound) && absentFound) {
   13693 	    /*
   13694 	    * 5.3 If the set S includes `absent` but not the negated
   13695 	    * namespace name, then the union is not expressible.
   13696 	    */
   13697 	    xmlSchemaPErr(ctxt, completeWild->node,
   13698 		XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
   13699 		"The union of the wilcard is not expressible.\n",
   13700 		NULL, NULL);
   13701 	    return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
   13702 	} else if ((!nsFound) && (!absentFound)) {
   13703 	    /*
   13704 	    * 5.4 If the set S does not include either the negated namespace
   13705 	    * name or `absent`, then whichever of O1 or O2 is a pair of not
   13706 	    * and a namespace name must be the value.
   13707 	    */
   13708 	    if (completeWild->negNsSet == NULL) {
   13709 		if (completeWild->nsSet != NULL) {
   13710 		    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13711 		    completeWild->nsSet = NULL;
   13712 		}
   13713 		completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   13714 		if (completeWild->negNsSet == NULL)
   13715 		    return (-1);
   13716 		completeWild->negNsSet->value = curWild->negNsSet->value;
   13717 	    }
   13718 	}
   13719 	return (0);
   13720     }
   13721     /*
   13722      * 6.
   13723      */
   13724     if (((completeWild->negNsSet != NULL) &&
   13725 	(completeWild->negNsSet->value == NULL) &&
   13726 	(curWild->nsSet != NULL)) ||
   13727 	((curWild->negNsSet != NULL) &&
   13728 	(curWild->negNsSet->value == NULL) &&
   13729 	(completeWild->nsSet != NULL))) {
   13730 
   13731 	if (completeWild->nsSet != NULL) {
   13732 	    cur = completeWild->nsSet;
   13733 	} else {
   13734 	    cur = curWild->nsSet;
   13735 	}
   13736 	while (cur != NULL) {
   13737 	    if (cur->value == NULL) {
   13738 		/*
   13739 		* 6.1 If the set S includes `absent`, then any must be the
   13740 		* value.
   13741 		*/
   13742 		completeWild->any = 1;
   13743 		if (completeWild->nsSet != NULL) {
   13744 		    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13745 		    completeWild->nsSet = NULL;
   13746 		}
   13747 		if (completeWild->negNsSet != NULL) {
   13748 		    xmlFree(completeWild->negNsSet);
   13749 		    completeWild->negNsSet = NULL;
   13750 		}
   13751 		return (0);
   13752 	    }
   13753 	    cur = cur->next;
   13754 	}
   13755 	if (completeWild->negNsSet == NULL) {
   13756 	    /*
   13757 	    * 6.2 If the set S does not include `absent`, then a pair of not
   13758 	    * and `absent` must be the value.
   13759 	    */
   13760 	    if (completeWild->nsSet != NULL) {
   13761 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13762 		completeWild->nsSet = NULL;
   13763 	    }
   13764 	    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   13765 	    if (completeWild->negNsSet == NULL)
   13766 		return (-1);
   13767 	    completeWild->negNsSet->value = NULL;
   13768 	}
   13769 	return (0);
   13770     }
   13771     return (0);
   13772 
   13773 }
   13774 
   13775 /**
   13776  * xmlSchemaIntersectWildcards:
   13777  * @ctxt:  the schema parser context
   13778  * @completeWild:  the first wildcard
   13779  * @curWild: the second wildcard
   13780  *
   13781  * Intersects the namespace constraints of the given wildcards.
   13782  * @completeWild will hold the resulting intersection.
   13783  * Returns a positive error code on failure, -1 in case of an
   13784  * internal error, 0 otherwise.
   13785  */
   13786 static int
   13787 xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
   13788 			    xmlSchemaWildcardPtr completeWild,
   13789 			    xmlSchemaWildcardPtr curWild)
   13790 {
   13791     xmlSchemaWildcardNsPtr cur, curB, prev,  tmp;
   13792 
   13793     /*
   13794     * 1 If O1 and O2 are the same value, then that value must be the
   13795     * value.
   13796     */
   13797     if ((completeWild->any == curWild->any) &&
   13798 	((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
   13799 	((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
   13800 
   13801 	if ((completeWild->negNsSet == NULL) ||
   13802 	    (completeWild->negNsSet->value == curWild->negNsSet->value)) {
   13803 
   13804 	    if (completeWild->nsSet != NULL) {
   13805 		int found = 0;
   13806 
   13807 		/*
   13808 		* Check equality of sets.
   13809 		*/
   13810 		cur = completeWild->nsSet;
   13811 		while (cur != NULL) {
   13812 		    found = 0;
   13813 		    curB = curWild->nsSet;
   13814 		    while (curB != NULL) {
   13815 			if (cur->value == curB->value) {
   13816 			    found = 1;
   13817 			    break;
   13818 			}
   13819 			curB = curB->next;
   13820 		    }
   13821 		    if (!found)
   13822 			break;
   13823 		    cur = cur->next;
   13824 		}
   13825 		if (found)
   13826 		    return(0);
   13827 	    } else
   13828 		return(0);
   13829 	}
   13830     }
   13831     /*
   13832     * 2 If either O1 or O2 is any, then the other must be the value.
   13833     */
   13834     if ((completeWild->any != curWild->any) && (completeWild->any)) {
   13835 	if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
   13836 	    return(-1);
   13837 	return(0);
   13838     }
   13839     /*
   13840     * 3 If either O1 or O2 is a pair of not and a value (a namespace
   13841     * name or `absent`) and the other is a set of (namespace names or
   13842     * `absent`), then that set, minus the negated value if it was in
   13843     * the set, minus `absent` if it was in the set, must be the value.
   13844     */
   13845     if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
   13846 	((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
   13847 	const xmlChar *neg;
   13848 
   13849 	if (completeWild->nsSet == NULL) {
   13850 	    neg = completeWild->negNsSet->value;
   13851 	    if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
   13852 		return(-1);
   13853 	} else
   13854 	    neg = curWild->negNsSet->value;
   13855 	/*
   13856 	* Remove absent and negated.
   13857 	*/
   13858 	prev = NULL;
   13859 	cur = completeWild->nsSet;
   13860 	while (cur != NULL) {
   13861 	    if (cur->value == NULL) {
   13862 		if (prev == NULL)
   13863 		    completeWild->nsSet = cur->next;
   13864 		else
   13865 		    prev->next = cur->next;
   13866 		xmlFree(cur);
   13867 		break;
   13868 	    }
   13869 	    prev = cur;
   13870 	    cur = cur->next;
   13871 	}
   13872 	if (neg != NULL) {
   13873 	    prev = NULL;
   13874 	    cur = completeWild->nsSet;
   13875 	    while (cur != NULL) {
   13876 		if (cur->value == neg) {
   13877 		    if (prev == NULL)
   13878 			completeWild->nsSet = cur->next;
   13879 		    else
   13880 			prev->next = cur->next;
   13881 		    xmlFree(cur);
   13882 		    break;
   13883 		}
   13884 		prev = cur;
   13885 		cur = cur->next;
   13886 	    }
   13887 	}
   13888 
   13889 	return(0);
   13890     }
   13891     /*
   13892     * 4 If both O1 and O2 are sets of (namespace names or `absent`),
   13893     * then the intersection of those sets must be the value.
   13894     */
   13895     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
   13896 	int found;
   13897 
   13898 	cur = completeWild->nsSet;
   13899 	prev = NULL;
   13900 	while (cur != NULL) {
   13901 	    found = 0;
   13902 	    curB = curWild->nsSet;
   13903 	    while (curB != NULL) {
   13904 		if (cur->value == curB->value) {
   13905 		    found = 1;
   13906 		    break;
   13907 		}
   13908 		curB = curB->next;
   13909 	    }
   13910 	    if (!found) {
   13911 		if (prev == NULL)
   13912 		    completeWild->nsSet = cur->next;
   13913 		else
   13914 		    prev->next = cur->next;
   13915 		tmp = cur->next;
   13916 		xmlFree(cur);
   13917 		cur = tmp;
   13918 		continue;
   13919 	    }
   13920 	    prev = cur;
   13921 	    cur = cur->next;
   13922 	}
   13923 
   13924 	return(0);
   13925     }
   13926     /* 5 If the two are negations of different namespace names,
   13927     * then the intersection is not expressible
   13928     */
   13929     if ((completeWild->negNsSet != NULL) &&
   13930 	(curWild->negNsSet != NULL) &&
   13931 	(completeWild->negNsSet->value != curWild->negNsSet->value) &&
   13932 	(completeWild->negNsSet->value != NULL) &&
   13933 	(curWild->negNsSet->value != NULL)) {
   13934 
   13935 	xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
   13936 	    "The intersection of the wilcard is not expressible.\n",
   13937 	    NULL, NULL);
   13938 	return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
   13939     }
   13940     /*
   13941     * 6 If the one is a negation of a namespace name and the other
   13942     * is a negation of `absent`, then the one which is the negation
   13943     * of a namespace name must be the value.
   13944     */
   13945     if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
   13946 	(completeWild->negNsSet->value != curWild->negNsSet->value) &&
   13947 	(completeWild->negNsSet->value == NULL)) {
   13948 	completeWild->negNsSet->value =  curWild->negNsSet->value;
   13949     }
   13950     return(0);
   13951 }
   13952 
   13953 /**
   13954  * xmlSchemaIsWildcardNsConstraintSubset:
   13955  * @ctxt:  the schema parser context
   13956  * @sub:  the first wildcard
   13957  * @super: the second wildcard
   13958  *
   13959  * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
   13960  *
   13961  * Returns 0 if the namespace constraint of @sub is an intensional
   13962  * subset of @super, 1 otherwise.
   13963  */
   13964 static int
   13965 xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
   13966 			  xmlSchemaWildcardPtr super)
   13967 {
   13968     /*
   13969     * 1 super must be any.
   13970     */
   13971     if (super->any)
   13972 	return (0);
   13973     /*
   13974     * 2.1 sub must be a pair of not and a namespace name or `absent`.
   13975     * 2.2 super must be a pair of not and the same value.
   13976     */
   13977     if ((sub->negNsSet != NULL) &&
   13978 	(super->negNsSet != NULL) &&
   13979 	(sub->negNsSet->value == super->negNsSet->value))
   13980 	return (0);
   13981     /*
   13982     * 3.1 sub must be a set whose members are either namespace names or `absent`.
   13983     */
   13984     if (sub->nsSet != NULL) {
   13985 	/*
   13986 	* 3.2.1 super must be the same set or a superset thereof.
   13987 	*/
   13988 	if (super->nsSet != NULL) {
   13989 	    xmlSchemaWildcardNsPtr cur, curB;
   13990 	    int found = 0;
   13991 
   13992 	    cur = sub->nsSet;
   13993 	    while (cur != NULL) {
   13994 		found = 0;
   13995 		curB = super->nsSet;
   13996 		while (curB != NULL) {
   13997 		    if (cur->value == curB->value) {
   13998 			found = 1;
   13999 			break;
   14000 		    }
   14001 		    curB = curB->next;
   14002 		}
   14003 		if (!found)
   14004 		    return (1);
   14005 		cur = cur->next;
   14006 	    }
   14007 	    if (found)
   14008 		return (0);
   14009 	} else if (super->negNsSet != NULL) {
   14010 	    xmlSchemaWildcardNsPtr cur;
   14011 	    /*
   14012 	    * 3.2.2 super must be a pair of not and a namespace name or
   14013 	    * `absent` and that value must not be in sub's set.
   14014 	    */
   14015 	    cur = sub->nsSet;
   14016 	    while (cur != NULL) {
   14017 		if (cur->value == super->negNsSet->value)
   14018 		    return (1);
   14019 		cur = cur->next;
   14020 	    }
   14021 	    return (0);
   14022 	}
   14023     }
   14024     return (1);
   14025 }
   14026 
   14027 static int
   14028 xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
   14029 				     int *fixed,
   14030 				     const xmlChar **value,
   14031 				     xmlSchemaValPtr *val)
   14032 {
   14033     *fixed = 0;
   14034     *value = NULL;
   14035     if (val != 0)
   14036 	*val = NULL;
   14037 
   14038     if (attruse->defValue != NULL) {
   14039 	*value = attruse->defValue;
   14040 	if (val != NULL)
   14041 	    *val = attruse->defVal;
   14042 	if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
   14043 	    *fixed = 1;
   14044 	return(1);
   14045     } else if ((attruse->attrDecl != NULL) &&
   14046 	(attruse->attrDecl->defValue != NULL)) {
   14047 	*value = attruse->attrDecl->defValue;
   14048 	if (val != NULL)
   14049 	    *val = attruse->attrDecl->defVal;
   14050 	if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
   14051 	    *fixed = 1;
   14052 	return(1);
   14053     }
   14054     return(0);
   14055 }
   14056 /**
   14057  * xmlSchemaCheckCVCWildcardNamespace:
   14058  * @wild:  the wildcard
   14059  * @ns:  the namespace
   14060  *
   14061  * Validation Rule: Wildcard allows Namespace Name
   14062  * (cvc-wildcard-namespace)
   14063  *
   14064  * Returns 0 if the given namespace matches the wildcard,
   14065  * 1 otherwise and -1 on API errors.
   14066  */
   14067 static int
   14068 xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
   14069 				   const xmlChar* ns)
   14070 {
   14071     if (wild == NULL)
   14072 	return(-1);
   14073 
   14074     if (wild->any)
   14075 	return(0);
   14076     else if (wild->nsSet != NULL) {
   14077 	xmlSchemaWildcardNsPtr cur;
   14078 
   14079 	cur = wild->nsSet;
   14080 	while (cur != NULL) {
   14081 	    if (xmlStrEqual(cur->value, ns))
   14082 		return(0);
   14083 	    cur = cur->next;
   14084 	}
   14085     } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
   14086 	(!xmlStrEqual(wild->negNsSet->value, ns)))
   14087 	return(0);
   14088 
   14089     return(1);
   14090 }
   14091 
   14092 #define XML_SCHEMA_ACTION_DERIVE 0
   14093 #define XML_SCHEMA_ACTION_REDEFINE 1
   14094 
   14095 #define WXS_ACTION_STR(a) \
   14096 ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
   14097 
   14098 /*
   14099 * Schema Component Constraint:
   14100 *   Derivation Valid (Restriction, Complex)
   14101 *   derivation-ok-restriction (2) - (4)
   14102 *
   14103 * ATTENTION:
   14104 * In XML Schema 1.1 this will be:
   14105 * Validation Rule:
   14106 *     Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
   14107 *
   14108 */
   14109 static int
   14110 xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
   14111 				       int action,
   14112 				       xmlSchemaBasicItemPtr item,
   14113 				       xmlSchemaBasicItemPtr baseItem,
   14114 				       xmlSchemaItemListPtr uses,
   14115 				       xmlSchemaItemListPtr baseUses,
   14116 				       xmlSchemaWildcardPtr wild,
   14117 				       xmlSchemaWildcardPtr baseWild)
   14118 {
   14119     xmlSchemaAttributeUsePtr cur = NULL, bcur;
   14120     int i, j, found; /* err = 0; */
   14121     const xmlChar *bEffValue;
   14122     int effFixed;
   14123 
   14124     if (uses != NULL) {
   14125 	for (i = 0; i < uses->nbItems; i++) {
   14126 	    cur = uses->items[i];
   14127 	    found = 0;
   14128 	    if (baseUses == NULL)
   14129 		goto not_found;
   14130 	    for (j = 0; j < baseUses->nbItems; j++) {
   14131 		bcur = baseUses->items[j];
   14132 		if ((WXS_ATTRUSE_DECL_NAME(cur) ==
   14133 			WXS_ATTRUSE_DECL_NAME(bcur)) &&
   14134 		    (WXS_ATTRUSE_DECL_TNS(cur) ==
   14135 			WXS_ATTRUSE_DECL_TNS(bcur)))
   14136 		{
   14137 		    /*
   14138 		    * (2.1) "If there is an attribute use in the {attribute
   14139 		    * uses} of the {base type definition} (call this B) whose
   14140 		    * {attribute declaration} has the same {name} and {target
   14141 		    * namespace}, then  all of the following must be true:"
   14142 		    */
   14143 		    found = 1;
   14144 
   14145 		    if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
   14146 			(bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
   14147 		    {
   14148 			xmlChar *str = NULL;
   14149 			/*
   14150 			* (2.1.1) "one of the following must be true:"
   14151 			* (2.1.1.1) "B's {required} is false."
   14152 			* (2.1.1.2) "R's {required} is true."
   14153 			*/
   14154 			xmlSchemaPAttrUseErr4(pctxt,
   14155 			    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
   14156 			    WXS_ITEM_NODE(item), item, cur,
   14157 			    "The 'optional' attribute use is inconsistent "
   14158 			    "with the corresponding 'required' attribute use of "
   14159 			    "the %s %s",
   14160 			    WXS_ACTION_STR(action),
   14161 			    xmlSchemaGetComponentDesignation(&str, baseItem),
   14162 			    NULL, NULL);
   14163 			FREE_AND_NULL(str);
   14164 			/* err = pctxt->err; */
   14165 		    } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
   14166 			WXS_ATTRUSE_TYPEDEF(cur),
   14167 			WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
   14168 		    {
   14169 			xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
   14170 
   14171 			/*
   14172 			* SPEC (2.1.2) "R's {attribute declaration}'s
   14173 			* {type definition} must be validly derived from
   14174 			* B's {type definition} given the empty set as
   14175 			* defined in Type Derivation OK (Simple) ($3.14.6)."
   14176 			*/
   14177 			xmlSchemaPAttrUseErr4(pctxt,
   14178 			    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
   14179 			    WXS_ITEM_NODE(item), item, cur,
   14180 			    "The attribute declaration's %s "
   14181 			    "is not validly derived from "
   14182 			    "the corresponding %s of the "
   14183 			    "attribute declaration in the %s %s",
   14184 			    xmlSchemaGetComponentDesignation(&strA,
   14185 				WXS_ATTRUSE_TYPEDEF(cur)),
   14186 			    xmlSchemaGetComponentDesignation(&strB,
   14187 				WXS_ATTRUSE_TYPEDEF(bcur)),
   14188 			    WXS_ACTION_STR(action),
   14189 			    xmlSchemaGetComponentDesignation(&strC, baseItem));
   14190 			    /* xmlSchemaGetComponentDesignation(&str, baseItem), */
   14191 			FREE_AND_NULL(strA);
   14192 			FREE_AND_NULL(strB);
   14193 			FREE_AND_NULL(strC);
   14194 			/* err = pctxt->err; */
   14195 		    } else {
   14196 			/*
   14197 			* 2.1.3 [Definition:]  Let the effective value
   14198 			* constraint of an attribute use be its {value
   14199 			* constraint}, if present, otherwise its {attribute
   14200 			* declaration}'s {value constraint} .
   14201 			*/
   14202 			xmlSchemaGetEffectiveValueConstraint(bcur,
   14203 			    &effFixed, &bEffValue, NULL);
   14204 			/*
   14205 			* 2.1.3 ... one of the following must be true
   14206 			*
   14207 			* 2.1.3.1 B's `effective value constraint` is
   14208 			* `absent` or default.
   14209 			*/
   14210 			if ((bEffValue != NULL) &&
   14211 			    (effFixed == 1)) {
   14212 			    const xmlChar *rEffValue = NULL;
   14213 
   14214 			    xmlSchemaGetEffectiveValueConstraint(bcur,
   14215 				&effFixed, &rEffValue, NULL);
   14216 			    /*
   14217 			    * 2.1.3.2 R's `effective value constraint` is
   14218 			    * fixed with the same string as B's.
   14219 			    * MAYBE TODO: Compare the computed values.
   14220 			    *       Hmm, it says "same string" so
   14221 			    *       string-equality might really be sufficient.
   14222 			    */
   14223 			    if ((effFixed == 0) ||
   14224 				(! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
   14225 			    {
   14226 				xmlChar *str = NULL;
   14227 
   14228 				xmlSchemaPAttrUseErr4(pctxt,
   14229 				    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
   14230 				    WXS_ITEM_NODE(item), item, cur,
   14231 				    "The effective value constraint of the "
   14232 				    "attribute use is inconsistent with "
   14233 				    "its correspondent in the %s %s",
   14234 				    WXS_ACTION_STR(action),
   14235 				    xmlSchemaGetComponentDesignation(&str,
   14236 					baseItem),
   14237 				    NULL, NULL);
   14238 				FREE_AND_NULL(str);
   14239 				/* err = pctxt->err; */
   14240 			    }
   14241 			}
   14242 		    }
   14243 		    break;
   14244 		}
   14245 	    }
   14246 not_found:
   14247 	    if (!found) {
   14248 		/*
   14249 		* (2.2) "otherwise the {base type definition} must have an
   14250 		* {attribute wildcard} and the {target namespace} of the
   14251 		* R's {attribute declaration} must be `valid` with respect
   14252 		* to that wildcard, as defined in Wildcard allows Namespace
   14253 		* Name ($3.10.4)."
   14254 		*/
   14255 		if ((baseWild == NULL) ||
   14256 		    (xmlSchemaCheckCVCWildcardNamespace(baseWild,
   14257 		    (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
   14258 		{
   14259 		    xmlChar *str = NULL;
   14260 
   14261 		    xmlSchemaPAttrUseErr4(pctxt,
   14262 			XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
   14263 			WXS_ITEM_NODE(item), item, cur,
   14264 			"Neither a matching attribute use, "
   14265 			"nor a matching wildcard exists in the %s %s",
   14266 			WXS_ACTION_STR(action),
   14267 			xmlSchemaGetComponentDesignation(&str, baseItem),
   14268 			NULL, NULL);
   14269 		    FREE_AND_NULL(str);
   14270 		    /* err = pctxt->err; */
   14271 		}
   14272 	    }
   14273 	}
   14274     }
   14275     /*
   14276     * SPEC derivation-ok-restriction (3):
   14277     * (3) "For each attribute use in the {attribute uses} of the {base type
   14278     * definition} whose {required} is true, there must be an attribute
   14279     * use with an {attribute declaration} with the same {name} and
   14280     * {target namespace} as its {attribute declaration} in the {attribute
   14281     * uses} of the complex type definition itself whose {required} is true.
   14282     */
   14283     if (baseUses != NULL) {
   14284 	for (j = 0; j < baseUses->nbItems; j++) {
   14285 	    bcur = baseUses->items[j];
   14286 	    if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
   14287 		continue;
   14288 	    found = 0;
   14289 	    if (uses != NULL) {
   14290 		for (i = 0; i < uses->nbItems; i++) {
   14291 		    cur = uses->items[i];
   14292 		    if ((WXS_ATTRUSE_DECL_NAME(cur) ==
   14293 			WXS_ATTRUSE_DECL_NAME(bcur)) &&
   14294 			(WXS_ATTRUSE_DECL_TNS(cur) ==
   14295 			WXS_ATTRUSE_DECL_TNS(bcur))) {
   14296 			found = 1;
   14297 			break;
   14298 		    }
   14299 		}
   14300 	    }
   14301 	    if (!found) {
   14302 		xmlChar *strA = NULL, *strB = NULL;
   14303 
   14304 		xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   14305 		    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
   14306 		    NULL, item,
   14307 		    "A matching attribute use for the "
   14308 		    "'required' %s of the %s %s is missing",
   14309 		    xmlSchemaGetComponentDesignation(&strA, bcur),
   14310 		    WXS_ACTION_STR(action),
   14311 		    xmlSchemaGetComponentDesignation(&strB, baseItem),
   14312 		    NULL);
   14313 		FREE_AND_NULL(strA);
   14314 		FREE_AND_NULL(strB);
   14315 	    }
   14316 	}
   14317     }
   14318     /*
   14319     * derivation-ok-restriction (4)
   14320     */
   14321     if (wild != NULL) {
   14322 	/*
   14323 	* (4) "If there is an {attribute wildcard}, all of the
   14324 	* following must be true:"
   14325 	*/
   14326 	if (baseWild == NULL) {
   14327 	    xmlChar *str = NULL;
   14328 
   14329 	    /*
   14330 	    * (4.1) "The {base type definition} must also have one."
   14331 	    */
   14332 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   14333 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
   14334 		NULL, item,
   14335 		"The %s has an attribute wildcard, "
   14336 		"but the %s %s '%s' does not have one",
   14337 		WXS_ITEM_TYPE_NAME(item),
   14338 		WXS_ACTION_STR(action),
   14339 		WXS_ITEM_TYPE_NAME(baseItem),
   14340 		xmlSchemaGetComponentQName(&str, baseItem));
   14341 	    FREE_AND_NULL(str);
   14342 	    return(pctxt->err);
   14343 	} else if ((baseWild->any == 0) &&
   14344 		xmlSchemaCheckCOSNSSubset(wild, baseWild))
   14345 	{
   14346 	    xmlChar *str = NULL;
   14347 	    /*
   14348 	    * (4.2) "The complex type definition's {attribute wildcard}'s
   14349 	    * {namespace constraint} must be a subset of the {base type
   14350 	    * definition}'s {attribute wildcard}'s {namespace constraint},
   14351 	    * as defined by Wildcard Subset ($3.10.6)."
   14352 	    */
   14353 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   14354 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
   14355 		NULL, item,
   14356 		"The attribute wildcard is not a valid "
   14357 		"subset of the wildcard in the %s %s '%s'",
   14358 		WXS_ACTION_STR(action),
   14359 		WXS_ITEM_TYPE_NAME(baseItem),
   14360 		xmlSchemaGetComponentQName(&str, baseItem),
   14361 		NULL);
   14362 	    FREE_AND_NULL(str);
   14363 	    return(pctxt->err);
   14364 	}
   14365 	/* 4.3 Unless the {base type definition} is the `ur-type
   14366 	* definition`, the complex type definition's {attribute
   14367 	* wildcard}'s {process contents} must be identical to or
   14368 	* stronger than the {base type definition}'s {attribute
   14369 	* wildcard}'s {process contents}, where strict is stronger
   14370 	* than lax is stronger than skip.
   14371 	*/
   14372 	if ((! WXS_IS_ANYTYPE(baseItem)) &&
   14373 	    (wild->processContents < baseWild->processContents)) {
   14374 	    xmlChar *str = NULL;
   14375 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   14376 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
   14377 		NULL, baseItem,
   14378 		"The {process contents} of the attribute wildcard is "
   14379 		"weaker than the one in the %s %s '%s'",
   14380 		WXS_ACTION_STR(action),
   14381 		WXS_ITEM_TYPE_NAME(baseItem),
   14382 		xmlSchemaGetComponentQName(&str, baseItem),
   14383 		NULL);
   14384 	    FREE_AND_NULL(str)
   14385 		return(pctxt->err);
   14386 	}
   14387     }
   14388     return(0);
   14389 }
   14390 
   14391 
   14392 static int
   14393 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
   14394 				  xmlSchemaBasicItemPtr item,
   14395 				  xmlSchemaWildcardPtr *completeWild,
   14396 				  xmlSchemaItemListPtr list,
   14397 				  xmlSchemaItemListPtr prohibs);
   14398 /**
   14399  * xmlSchemaFixupTypeAttributeUses:
   14400  * @ctxt:  the schema parser context
   14401  * @type:  the complex type definition
   14402  *
   14403  *
   14404  * Builds the wildcard and the attribute uses on the given complex type.
   14405  * Returns -1 if an internal error occurs, 0 otherwise.
   14406  *
   14407  * ATTENTION TODO: Experimantally this uses pointer comparisons for
   14408  * strings, so recheck this if we start to hardcode some schemata, since
   14409  * they might not be in the same dict.
   14410  * NOTE: It is allowed to "extend" the xs:anyType type.
   14411  */
   14412 static int
   14413 xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
   14414 				  xmlSchemaTypePtr type)
   14415 {
   14416     xmlSchemaTypePtr baseType = NULL;
   14417     xmlSchemaAttributeUsePtr use;
   14418     xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
   14419 
   14420     if (type->baseType == NULL) {
   14421 	PERROR_INT("xmlSchemaFixupTypeAttributeUses",
   14422 	    "no base type");
   14423         return (-1);
   14424     }
   14425     baseType = type->baseType;
   14426     if (WXS_IS_TYPE_NOT_FIXED(baseType))
   14427 	if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
   14428 	    return(-1);
   14429 
   14430     uses = type->attrUses;
   14431     baseUses = baseType->attrUses;
   14432     /*
   14433     * Expand attribute group references. And build the 'complete'
   14434     * wildcard, i.e. intersect multiple wildcards.
   14435     * Move attribute prohibitions into a separate list.
   14436     */
   14437     if (uses != NULL) {
   14438 	if (WXS_IS_RESTRICTION(type)) {
   14439 	    /*
   14440 	    * This one will transfer all attr. prohibitions
   14441 	    * into pctxt->attrProhibs.
   14442 	    */
   14443 	    if (xmlSchemaExpandAttributeGroupRefs(pctxt,
   14444 		WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
   14445 		pctxt->attrProhibs) == -1)
   14446 	    {
   14447 		PERROR_INT("xmlSchemaFixupTypeAttributeUses",
   14448 		"failed to expand attributes");
   14449 	    }
   14450 	    if (pctxt->attrProhibs->nbItems != 0)
   14451 		prohibs = pctxt->attrProhibs;
   14452 	} else {
   14453 	    if (xmlSchemaExpandAttributeGroupRefs(pctxt,
   14454 		WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
   14455 		NULL) == -1)
   14456 	    {
   14457 		PERROR_INT("xmlSchemaFixupTypeAttributeUses",
   14458 		"failed to expand attributes");
   14459 	    }
   14460 	}
   14461     }
   14462     /*
   14463     * Inherit the attribute uses of the base type.
   14464     */
   14465     if (baseUses != NULL) {
   14466 	int i, j;
   14467 	xmlSchemaAttributeUseProhibPtr pro;
   14468 
   14469 	if (WXS_IS_RESTRICTION(type)) {
   14470 	    int usesCount;
   14471 	    xmlSchemaAttributeUsePtr tmp;
   14472 
   14473 	    if (uses != NULL)
   14474 		usesCount = uses->nbItems;
   14475 	    else
   14476 		usesCount = 0;
   14477 
   14478 	    /* Restriction. */
   14479 	    for (i = 0; i < baseUses->nbItems; i++) {
   14480 		use = baseUses->items[i];
   14481 		if (prohibs) {
   14482 		    /*
   14483 		    * Filter out prohibited uses.
   14484 		    */
   14485 		    for (j = 0; j < prohibs->nbItems; j++) {
   14486 			pro = prohibs->items[j];
   14487 			if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
   14488 			    (WXS_ATTRUSE_DECL_TNS(use) ==
   14489 				pro->targetNamespace))
   14490 			{
   14491 			    goto inherit_next;
   14492 			}
   14493 		    }
   14494 		}
   14495 		if (usesCount) {
   14496 		    /*
   14497 		    * Filter out existing uses.
   14498 		    */
   14499 		    for (j = 0; j < usesCount; j++) {
   14500 			tmp = uses->items[j];
   14501 			if ((WXS_ATTRUSE_DECL_NAME(use) ==
   14502 				WXS_ATTRUSE_DECL_NAME(tmp)) &&
   14503 			    (WXS_ATTRUSE_DECL_TNS(use) ==
   14504 				WXS_ATTRUSE_DECL_TNS(tmp)))
   14505 			{
   14506 			    goto inherit_next;
   14507 			}
   14508 		    }
   14509 		}
   14510 		if (uses == NULL) {
   14511 		    type->attrUses = xmlSchemaItemListCreate();
   14512 		    if (type->attrUses == NULL)
   14513 			goto exit_failure;
   14514 		    uses = type->attrUses;
   14515 		}
   14516 		xmlSchemaItemListAddSize(uses, 2, use);
   14517 inherit_next: {}
   14518 	    }
   14519 	} else {
   14520 	    /* Extension. */
   14521 	    for (i = 0; i < baseUses->nbItems; i++) {
   14522 		use = baseUses->items[i];
   14523 		if (uses == NULL) {
   14524 		    type->attrUses = xmlSchemaItemListCreate();
   14525 		    if (type->attrUses == NULL)
   14526 			goto exit_failure;
   14527 		    uses = type->attrUses;
   14528 		}
   14529 		xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
   14530 	    }
   14531 	}
   14532     }
   14533     /*
   14534     * Shrink attr. uses.
   14535     */
   14536     if (uses) {
   14537 	if (uses->nbItems == 0) {
   14538 	    xmlSchemaItemListFree(uses);
   14539 	    type->attrUses = NULL;
   14540 	}
   14541 	/*
   14542 	* TODO: We could shrink the size of the array
   14543 	* to fit the actual number of items.
   14544 	*/
   14545     }
   14546     /*
   14547     * Compute the complete wildcard.
   14548     */
   14549     if (WXS_IS_EXTENSION(type)) {
   14550 	if (baseType->attributeWildcard != NULL) {
   14551 	    /*
   14552 	    * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
   14553 	    * the appropriate case among the following:"
   14554 	    */
   14555 	    if (type->attributeWildcard != NULL) {
   14556 		/*
   14557 		* Union the complete wildcard with the base wildcard.
   14558 		* SPEC {attribute wildcard}
   14559 		* (3.2.2.1.2) "otherwise a wildcard whose {process contents}
   14560 		* and {annotation} are those of the `complete wildcard`,
   14561 		* and whose {namespace constraint} is the intensional union
   14562 		* of the {namespace constraint} of the `complete wildcard`
   14563 		* and of the `base wildcard`, as defined in Attribute
   14564 		* Wildcard Union ($3.10.6)."
   14565 		*/
   14566 		if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
   14567 		    baseType->attributeWildcard) == -1)
   14568 		    goto exit_failure;
   14569 	    } else {
   14570 		/*
   14571 		* (3.2.2.1.1) "If the `complete wildcard` is `absent`,
   14572 		* then the `base wildcard`."
   14573 		*/
   14574 		type->attributeWildcard = baseType->attributeWildcard;
   14575 	    }
   14576 	} else {
   14577 	    /*
   14578 	    * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
   14579 	    * `complete wildcard`"
   14580 	    * NOOP
   14581 	    */
   14582 	}
   14583     } else {
   14584 	/*
   14585 	* SPEC {attribute wildcard}
   14586 	* (3.1) "If the <restriction> alternative is chosen, then the
   14587 	* `complete wildcard`;"
   14588 	* NOOP
   14589 	*/
   14590     }
   14591 
   14592     return (0);
   14593 
   14594 exit_failure:
   14595     return(-1);
   14596 }
   14597 
   14598 /**
   14599  * xmlSchemaTypeFinalContains:
   14600  * @schema:  the schema
   14601  * @type:  the type definition
   14602  * @final: the final
   14603  *
   14604  * Evaluates if a type definition contains the given "final".
   14605  * This does take "finalDefault" into account as well.
   14606  *
   14607  * Returns 1 if the type does containt the given "final",
   14608  * 0 otherwise.
   14609  */
   14610 static int
   14611 xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
   14612 {
   14613     if (type == NULL)
   14614 	return (0);
   14615     if (type->flags & final)
   14616 	return (1);
   14617     else
   14618 	return (0);
   14619 }
   14620 
   14621 /**
   14622  * xmlSchemaGetUnionSimpleTypeMemberTypes:
   14623  * @type:  the Union Simple Type
   14624  *
   14625  * Returns a list of member types of @type if existing,
   14626  * returns NULL otherwise.
   14627  */
   14628 static xmlSchemaTypeLinkPtr
   14629 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
   14630 {
   14631     while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
   14632 	if (type->memberTypes != NULL)
   14633 	    return (type->memberTypes);
   14634 	else
   14635 	    type = type->baseType;
   14636     }
   14637     return (NULL);
   14638 }
   14639 
   14640 /**
   14641  * xmlSchemaGetParticleTotalRangeMin:
   14642  * @particle: the particle
   14643  *
   14644  * Schema Component Constraint: Effective Total Range
   14645  * (all and sequence) + (choice)
   14646  *
   14647  * Returns the minimun Effective Total Range.
   14648  */
   14649 static int
   14650 xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
   14651 {
   14652     if ((particle->children == NULL) ||
   14653 	(particle->minOccurs == 0))
   14654 	return (0);
   14655     if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
   14656 	int min = -1, cur;
   14657 	xmlSchemaParticlePtr part =
   14658 	    (xmlSchemaParticlePtr) particle->children->children;
   14659 
   14660 	if (part == NULL)
   14661 	    return (0);
   14662 	while (part != NULL) {
   14663 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
   14664 		(part->children->type == XML_SCHEMA_TYPE_ANY))
   14665 		cur = part->minOccurs;
   14666 	    else
   14667 		cur = xmlSchemaGetParticleTotalRangeMin(part);
   14668 	    if (cur == 0)
   14669 		return (0);
   14670 	    if ((min > cur) || (min == -1))
   14671 		min = cur;
   14672 	    part = (xmlSchemaParticlePtr) part->next;
   14673 	}
   14674 	return (particle->minOccurs * min);
   14675     } else {
   14676 	/* <all> and <sequence> */
   14677 	int sum = 0;
   14678 	xmlSchemaParticlePtr part =
   14679 	    (xmlSchemaParticlePtr) particle->children->children;
   14680 
   14681 	if (part == NULL)
   14682 	    return (0);
   14683 	do {
   14684 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
   14685 		(part->children->type == XML_SCHEMA_TYPE_ANY))
   14686 		sum += part->minOccurs;
   14687 	    else
   14688 		sum += xmlSchemaGetParticleTotalRangeMin(part);
   14689 	    part = (xmlSchemaParticlePtr) part->next;
   14690 	} while (part != NULL);
   14691 	return (particle->minOccurs * sum);
   14692     }
   14693 }
   14694 
   14695 #if 0
   14696 /**
   14697  * xmlSchemaGetParticleTotalRangeMax:
   14698  * @particle: the particle
   14699  *
   14700  * Schema Component Constraint: Effective Total Range
   14701  * (all and sequence) + (choice)
   14702  *
   14703  * Returns the maximum Effective Total Range.
   14704  */
   14705 static int
   14706 xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
   14707 {
   14708     if ((particle->children == NULL) ||
   14709 	(particle->children->children == NULL))
   14710 	return (0);
   14711     if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
   14712 	int max = -1, cur;
   14713 	xmlSchemaParticlePtr part =
   14714 	    (xmlSchemaParticlePtr) particle->children->children;
   14715 
   14716 	for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
   14717 	    if (part->children == NULL)
   14718 		continue;
   14719 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
   14720 		(part->children->type == XML_SCHEMA_TYPE_ANY))
   14721 		cur = part->maxOccurs;
   14722 	    else
   14723 		cur = xmlSchemaGetParticleTotalRangeMax(part);
   14724 	    if (cur == UNBOUNDED)
   14725 		return (UNBOUNDED);
   14726 	    if ((max < cur) || (max == -1))
   14727 		max = cur;
   14728 	}
   14729 	/* TODO: Handle overflows? */
   14730 	return (particle->maxOccurs * max);
   14731     } else {
   14732 	/* <all> and <sequence> */
   14733 	int sum = 0, cur;
   14734 	xmlSchemaParticlePtr part =
   14735 	    (xmlSchemaParticlePtr) particle->children->children;
   14736 
   14737 	for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
   14738 	    if (part->children == NULL)
   14739 		continue;
   14740 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
   14741 		(part->children->type == XML_SCHEMA_TYPE_ANY))
   14742 		cur = part->maxOccurs;
   14743 	    else
   14744 		cur = xmlSchemaGetParticleTotalRangeMax(part);
   14745 	    if (cur == UNBOUNDED)
   14746 		return (UNBOUNDED);
   14747 	    if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
   14748 		return (UNBOUNDED);
   14749 	    sum += cur;
   14750 	}
   14751 	/* TODO: Handle overflows? */
   14752 	return (particle->maxOccurs * sum);
   14753     }
   14754 }
   14755 #endif
   14756 
   14757 /**
   14758  * xmlSchemaIsParticleEmptiable:
   14759  * @particle: the particle
   14760  *
   14761  * Schema Component Constraint: Particle Emptiable
   14762  * Checks whether the given particle is emptiable.
   14763  *
   14764  * Returns 1 if emptiable, 0 otherwise.
   14765  */
   14766 static int
   14767 xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
   14768 {
   14769     /*
   14770     * SPEC (1) "Its {min occurs} is 0."
   14771     */
   14772     if ((particle == NULL) || (particle->minOccurs == 0) ||
   14773 	(particle->children == NULL))
   14774 	return (1);
   14775     /*
   14776     * SPEC (2) "Its {term} is a group and the minimum part of the
   14777     * effective total range of that group, [...] is 0."
   14778     */
   14779     if (WXS_IS_MODEL_GROUP(particle->children)) {
   14780 	if (xmlSchemaGetParticleTotalRangeMin(particle) == 0)
   14781 	    return (1);
   14782     }
   14783     return (0);
   14784 }
   14785 
   14786 /**
   14787  * xmlSchemaCheckCOSSTDerivedOK:
   14788  * @actxt: a context
   14789  * @type:  the derived simple type definition
   14790  * @baseType:  the base type definition
   14791  * @subset: the subset of ('restriction', ect.)
   14792  *
   14793  * Schema Component Constraint:
   14794  * Type Derivation OK (Simple) (cos-st-derived-OK)
   14795  *
   14796  * Checks wheter @type can be validly
   14797  * derived from @baseType.
   14798  *
   14799  * Returns 0 on success, an positive error code otherwise.
   14800  */
   14801 static int
   14802 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
   14803 			     xmlSchemaTypePtr type,
   14804 			     xmlSchemaTypePtr baseType,
   14805 			     int subset)
   14806 {
   14807     /*
   14808     * 1 They are the same type definition.
   14809     * TODO: The identy check might have to be more complex than this.
   14810     */
   14811     if (type == baseType)
   14812 	return (0);
   14813     /*
   14814     * 2.1 restriction is not in the subset, or in the {final}
   14815     * of its own {base type definition};
   14816     *
   14817     * NOTE that this will be used also via "xsi:type".
   14818     *
   14819     * TODO: Revise this, it looks strange. How can the "type"
   14820     * not be fixed or *in* fixing?
   14821     */
   14822     if (WXS_IS_TYPE_NOT_FIXED(type))
   14823 	if (xmlSchemaTypeFixup(type, actxt) == -1)
   14824 	    return(-1);
   14825     if (WXS_IS_TYPE_NOT_FIXED(baseType))
   14826 	if (xmlSchemaTypeFixup(baseType, actxt) == -1)
   14827 	    return(-1);
   14828     if ((subset & SUBSET_RESTRICTION) ||
   14829 	(xmlSchemaTypeFinalContains(type->baseType,
   14830 	    XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
   14831 	return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
   14832     }
   14833     /* 2.2 */
   14834     if (type->baseType == baseType) {
   14835 	/*
   14836 	* 2.2.1 D's `base type definition` is B.
   14837 	*/
   14838 	return (0);
   14839     }
   14840     /*
   14841     * 2.2.2 D's `base type definition` is not the `ur-type definition`
   14842     * and is validly derived from B given the subset, as defined by this
   14843     * constraint.
   14844     */
   14845     if ((! WXS_IS_ANYTYPE(type->baseType)) &&
   14846 	(xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
   14847 	    baseType, subset) == 0)) {
   14848 	return (0);
   14849     }
   14850     /*
   14851     * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
   14852     * definition`.
   14853     */
   14854     if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
   14855 	(WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
   14856 	return (0);
   14857     }
   14858     /*
   14859     * 2.2.4 B's {variety} is union and D is validly derived from a type
   14860     * definition in B's {member type definitions} given the subset, as
   14861     * defined by this constraint.
   14862     *
   14863     * NOTE: This seems not to involve built-in types, since there is no
   14864     * built-in Union Simple Type.
   14865     */
   14866     if (WXS_IS_UNION(baseType)) {
   14867 	xmlSchemaTypeLinkPtr cur;
   14868 
   14869 	cur = baseType->memberTypes;
   14870 	while (cur != NULL) {
   14871 	    if (WXS_IS_TYPE_NOT_FIXED(cur->type))
   14872 		if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
   14873 		    return(-1);
   14874 	    if (xmlSchemaCheckCOSSTDerivedOK(actxt,
   14875 		    type, cur->type, subset) == 0)
   14876 	    {
   14877 		/*
   14878 		* It just has to be validly derived from at least one
   14879 		* member-type.
   14880 		*/
   14881 		return (0);
   14882 	    }
   14883 	    cur = cur->next;
   14884 	}
   14885     }
   14886     return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
   14887 }
   14888 
   14889 /**
   14890  * xmlSchemaCheckTypeDefCircularInternal:
   14891  * @pctxt:  the schema parser context
   14892  * @ctxtType:  the type definition
   14893  * @ancestor: an ancestor of @ctxtType
   14894  *
   14895  * Checks st-props-correct (2) + ct-props-correct (3).
   14896  * Circular type definitions are not allowed.
   14897  *
   14898  * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
   14899  * circular, 0 otherwise.
   14900  */
   14901 static int
   14902 xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
   14903 			   xmlSchemaTypePtr ctxtType,
   14904 			   xmlSchemaTypePtr ancestor)
   14905 {
   14906     int ret;
   14907 
   14908     if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
   14909 	return (0);
   14910 
   14911     if (ctxtType == ancestor) {
   14912 	xmlSchemaPCustomErr(pctxt,
   14913 	    XML_SCHEMAP_ST_PROPS_CORRECT_2,
   14914 	    WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
   14915 	    "The definition is circular", NULL);
   14916 	return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
   14917     }
   14918     if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
   14919 	/*
   14920 	* Avoid inifinite recursion on circular types not yet checked.
   14921 	*/
   14922 	return (0);
   14923     }
   14924     ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
   14925     ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
   14926 	ancestor->baseType);
   14927     ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
   14928     return (ret);
   14929 }
   14930 
   14931 /**
   14932  * xmlSchemaCheckTypeDefCircular:
   14933  * @item:  the complex/simple type definition
   14934  * @ctxt:  the parser context
   14935  * @name:  the name
   14936  *
   14937  * Checks for circular type definitions.
   14938  */
   14939 static void
   14940 xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
   14941 			      xmlSchemaParserCtxtPtr ctxt)
   14942 {
   14943     if ((item == NULL) ||
   14944 	(item->type == XML_SCHEMA_TYPE_BASIC) ||
   14945 	(item->baseType == NULL))
   14946 	return;
   14947     xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
   14948 	item->baseType);
   14949 }
   14950 
   14951 /*
   14952 * Simple Type Definition Representation OK (src-simple-type) 4
   14953 *
   14954 * "4 Circular union type definition is disallowed. That is, if the
   14955 * <union> alternative is chosen, there must not be any entries in the
   14956 * memberTypes [attribute] at any depth which resolve to the component
   14957 * corresponding to the <simpleType>."
   14958 *
   14959 * Note that this should work on the *representation* of a component,
   14960 * thus assumes any union types in the member types not being yet
   14961 * substituted. At this stage we need the variety of the types
   14962 * to be already computed.
   14963 */
   14964 static int
   14965 xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
   14966 					xmlSchemaTypePtr ctxType,
   14967 					xmlSchemaTypeLinkPtr members)
   14968 {
   14969     xmlSchemaTypeLinkPtr member;
   14970     xmlSchemaTypePtr memberType;
   14971 
   14972     member = members;
   14973     while (member != NULL) {
   14974 	memberType = member->type;
   14975 	while ((memberType != NULL) &&
   14976 	    (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
   14977 	    if (memberType == ctxType) {
   14978 		xmlSchemaPCustomErr(pctxt,
   14979 		    XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
   14980 		    WXS_BASIC_CAST ctxType, NULL,
   14981 		    "The union type definition is circular", NULL);
   14982 		return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
   14983 	    }
   14984 	    if ((WXS_IS_UNION(memberType)) &&
   14985 		((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
   14986 	    {
   14987 		int res;
   14988 		memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
   14989 		res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
   14990 		    ctxType,
   14991 		    xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
   14992 		memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
   14993 		if (res != 0)
   14994 		    return(res);
   14995 	    }
   14996 	    memberType = memberType->baseType;
   14997 	}
   14998 	member = member->next;
   14999     }
   15000     return(0);
   15001 }
   15002 
   15003 static int
   15004 xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
   15005 				   xmlSchemaTypePtr type)
   15006 {
   15007     if (! WXS_IS_UNION(type))
   15008 	return(0);
   15009     return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
   15010 	type->memberTypes));
   15011 }
   15012 
   15013 /**
   15014  * xmlSchemaResolveTypeReferences:
   15015  * @item:  the complex/simple type definition
   15016  * @ctxt:  the parser context
   15017  * @name:  the name
   15018  *
   15019  * Resolvese type definition references
   15020  */
   15021 static void
   15022 xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
   15023 			 xmlSchemaParserCtxtPtr ctxt)
   15024 {
   15025     if (typeDef == NULL)
   15026 	return;
   15027 
   15028     /*
   15029     * Resolve the base type.
   15030     */
   15031     if (typeDef->baseType == NULL) {
   15032 	typeDef->baseType = xmlSchemaGetType(ctxt->schema,
   15033 	    typeDef->base, typeDef->baseNs);
   15034 	if (typeDef->baseType == NULL) {
   15035 	    xmlSchemaPResCompAttrErr(ctxt,
   15036 		XML_SCHEMAP_SRC_RESOLVE,
   15037 		WXS_BASIC_CAST typeDef, typeDef->node,
   15038 		"base", typeDef->base, typeDef->baseNs,
   15039 		XML_SCHEMA_TYPE_SIMPLE, NULL);
   15040 	    return;
   15041 	}
   15042     }
   15043     if (WXS_IS_SIMPLE(typeDef)) {
   15044 	if (WXS_IS_UNION(typeDef)) {
   15045 	    /*
   15046 	    * Resolve the memberTypes.
   15047 	    */
   15048 	    xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
   15049 	    return;
   15050 	} else if (WXS_IS_LIST(typeDef)) {
   15051 	    /*
   15052 	    * Resolve the itemType.
   15053 	    */
   15054 	    if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
   15055 
   15056 		typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
   15057 		    typeDef->base, typeDef->baseNs);
   15058 
   15059 		if ((typeDef->subtypes == NULL) ||
   15060 		    (! WXS_IS_SIMPLE(typeDef->subtypes)))
   15061 		{
   15062 		    typeDef->subtypes = NULL;
   15063 		    xmlSchemaPResCompAttrErr(ctxt,
   15064 			XML_SCHEMAP_SRC_RESOLVE,
   15065 			WXS_BASIC_CAST typeDef, typeDef->node,
   15066 			"itemType", typeDef->base, typeDef->baseNs,
   15067 			XML_SCHEMA_TYPE_SIMPLE, NULL);
   15068 		}
   15069 	    }
   15070 	    return;
   15071 	}
   15072     }
   15073     /*
   15074     * The ball of letters below means, that if we have a particle
   15075     * which has a QName-helper component as its {term}, we want
   15076     * to resolve it...
   15077     */
   15078     else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
   15079 	((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
   15080 	    XML_SCHEMA_TYPE_PARTICLE) &&
   15081 	(WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
   15082 	((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
   15083 	    XML_SCHEMA_EXTRA_QNAMEREF))
   15084     {
   15085 	xmlSchemaQNameRefPtr ref =
   15086 	    WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
   15087 	xmlSchemaModelGroupDefPtr groupDef;
   15088 
   15089 	/*
   15090 	* URGENT TODO: Test this.
   15091 	*/
   15092 	WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
   15093 	/*
   15094 	* Resolve the MG definition reference.
   15095 	*/
   15096 	groupDef =
   15097 	    WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
   15098 		ref->itemType, ref->name, ref->targetNamespace);
   15099 	if (groupDef == NULL) {
   15100 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
   15101 		NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
   15102 		"ref", ref->name, ref->targetNamespace, ref->itemType,
   15103 		NULL);
   15104 	    /* Remove the particle. */
   15105 	    WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
   15106 	} else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
   15107 	    /* Remove the particle. */
   15108 	    WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
   15109 	else {
   15110 	    /*
   15111 	    * Assign the MG definition's {model group} to the
   15112 	    * particle's {term}.
   15113 	    */
   15114 	    WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
   15115 
   15116 	    if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
   15117 		/*
   15118 		* SPEC cos-all-limited (1.2)
   15119 		* "1.2 the {term} property of a particle with
   15120 		* {max occurs}=1 which is part of a pair which constitutes
   15121 		* the {content type} of a complex type definition."
   15122 		*/
   15123 		if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
   15124 		    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   15125 			/* TODO: error code */
   15126 			XML_SCHEMAP_COS_ALL_LIMITED,
   15127 			WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
   15128 			"The particle's {max occurs} must be 1, since the "
   15129 			"reference resolves to an 'all' model group",
   15130 			NULL, NULL);
   15131 		}
   15132 	    }
   15133 	}
   15134     }
   15135 }
   15136 
   15137 
   15138 
   15139 /**
   15140  * xmlSchemaCheckSTPropsCorrect:
   15141  * @ctxt:  the schema parser context
   15142  * @type:  the simple type definition
   15143  *
   15144  * Checks st-props-correct.
   15145  *
   15146  * Returns 0 if the properties are correct,
   15147  * if not, a positive error code and -1 on internal
   15148  * errors.
   15149  */
   15150 static int
   15151 xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
   15152 			     xmlSchemaTypePtr type)
   15153 {
   15154     xmlSchemaTypePtr baseType = type->baseType;
   15155     xmlChar *str = NULL;
   15156 
   15157     /* STATE: error funcs converted. */
   15158     /*
   15159     * Schema Component Constraint: Simple Type Definition Properties Correct
   15160     *
   15161     * NOTE: This is somehow redundant, since we actually built a simple type
   15162     * to have all the needed information; this acts as an self test.
   15163     */
   15164     /* Base type: If the datatype has been `derived` by `restriction`
   15165     * then the Simple Type Definition component from which it is `derived`,
   15166     * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
   15167     */
   15168     if (baseType == NULL) {
   15169 	/*
   15170 	* TODO: Think about: "modulo the impact of Missing
   15171 	* Sub-components ($5.3)."
   15172 	*/
   15173 	xmlSchemaPCustomErr(ctxt,
   15174 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
   15175 	    WXS_BASIC_CAST type, NULL,
   15176 	    "No base type existent", NULL);
   15177 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
   15178 
   15179     }
   15180     if (! WXS_IS_SIMPLE(baseType)) {
   15181 	xmlSchemaPCustomErr(ctxt,
   15182 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
   15183 	    WXS_BASIC_CAST type, NULL,
   15184 	    "The base type '%s' is not a simple type",
   15185 	    xmlSchemaGetComponentQName(&str, baseType));
   15186 	FREE_AND_NULL(str)
   15187 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
   15188     }
   15189     if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
   15190 	(WXS_IS_RESTRICTION(type) == 0) &&
   15191 	((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
   15192          (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
   15193 	xmlSchemaPCustomErr(ctxt,
   15194 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
   15195 	    WXS_BASIC_CAST type, NULL,
   15196 	    "A type, derived by list or union, must have "
   15197 	    "the simple ur-type definition as base type, not '%s'",
   15198 	    xmlSchemaGetComponentQName(&str, baseType));
   15199 	FREE_AND_NULL(str)
   15200 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
   15201     }
   15202     /*
   15203     * Variety: One of {atomic, list, union}.
   15204     */
   15205     if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
   15206 	(! WXS_IS_LIST(type))) {
   15207 	xmlSchemaPCustomErr(ctxt,
   15208 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
   15209 	    WXS_BASIC_CAST type, NULL,
   15210 	    "The variety is absent", NULL);
   15211 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
   15212     }
   15213     /* TODO: Finish this. Hmm, is this finished? */
   15214 
   15215     /*
   15216     * 3 The {final} of the {base type definition} must not contain restriction.
   15217     */
   15218     if (xmlSchemaTypeFinalContains(baseType,
   15219 	XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
   15220 	xmlSchemaPCustomErr(ctxt,
   15221 	    XML_SCHEMAP_ST_PROPS_CORRECT_3,
   15222 	    WXS_BASIC_CAST type, NULL,
   15223 	    "The 'final' of its base type '%s' must not contain "
   15224 	    "'restriction'",
   15225 	    xmlSchemaGetComponentQName(&str, baseType));
   15226 	FREE_AND_NULL(str)
   15227 	return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
   15228     }
   15229 
   15230     /*
   15231     * 2 All simple type definitions must be derived ultimately from the `simple
   15232     * ur-type definition` (so circular definitions are disallowed). That is, it
   15233     * must be possible to reach a built-in primitive datatype or the `simple
   15234     * ur-type definition` by repeatedly following the {base type definition}.
   15235     *
   15236     * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
   15237     */
   15238     return (0);
   15239 }
   15240 
   15241 /**
   15242  * xmlSchemaCheckCOSSTRestricts:
   15243  * @ctxt:  the schema parser context
   15244  * @type:  the simple type definition
   15245  *
   15246  * Schema Component Constraint:
   15247  * Derivation Valid (Restriction, Simple) (cos-st-restricts)
   15248 
   15249  * Checks if the given @type (simpleType) is derived validly by restriction.
   15250  * STATUS:
   15251  *
   15252  * Returns -1 on internal errors, 0 if the type is validly derived,
   15253  * a positive error code otherwise.
   15254  */
   15255 static int
   15256 xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
   15257 			     xmlSchemaTypePtr type)
   15258 {
   15259     xmlChar *str = NULL;
   15260 
   15261     if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
   15262 	PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15263 	    "given type is not a user-derived simpleType");
   15264 	return (-1);
   15265     }
   15266 
   15267     if (WXS_IS_ATOMIC(type)) {
   15268 	xmlSchemaTypePtr primitive;
   15269 	/*
   15270 	* 1.1 The {base type definition} must be an atomic simple
   15271 	* type definition or a built-in primitive datatype.
   15272 	*/
   15273 	if (! WXS_IS_ATOMIC(type->baseType)) {
   15274 	    xmlSchemaPCustomErr(pctxt,
   15275 		XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
   15276 		WXS_BASIC_CAST type, NULL,
   15277 		"The base type '%s' is not an atomic simple type",
   15278 		xmlSchemaGetComponentQName(&str, type->baseType));
   15279 	    FREE_AND_NULL(str)
   15280 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
   15281 	}
   15282 	/* 1.2 The {final} of the {base type definition} must not contain
   15283 	* restriction.
   15284 	*/
   15285 	/* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
   15286 	if (xmlSchemaTypeFinalContains(type->baseType,
   15287 	    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
   15288 	    xmlSchemaPCustomErr(pctxt,
   15289 		XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
   15290 		WXS_BASIC_CAST type, NULL,
   15291 		"The final of its base type '%s' must not contain 'restriction'",
   15292 		xmlSchemaGetComponentQName(&str, type->baseType));
   15293 	    FREE_AND_NULL(str)
   15294 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
   15295 	}
   15296 
   15297 	/*
   15298 	* 1.3.1 DF must be an allowed constraining facet for the {primitive
   15299 	* type definition}, as specified in the appropriate subsection of 3.2
   15300 	* Primitive datatypes.
   15301 	*/
   15302 	if (type->facets != NULL) {
   15303 	    xmlSchemaFacetPtr facet;
   15304 	    int ok = 1;
   15305 
   15306 	    primitive = xmlSchemaGetPrimitiveType(type);
   15307 	    if (primitive == NULL) {
   15308 		PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15309 		    "failed to get primitive type");
   15310 		return (-1);
   15311 	    }
   15312 	    facet = type->facets;
   15313 	    do {
   15314 		if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
   15315 		    ok = 0;
   15316 		    xmlSchemaPIllegalFacetAtomicErr(pctxt,
   15317 			XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
   15318 			type, primitive, facet);
   15319 		}
   15320 		facet = facet->next;
   15321 	    } while (facet != NULL);
   15322 	    if (ok == 0)
   15323 		return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
   15324 	}
   15325 	/*
   15326 	* SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
   15327 	* of the {base type definition} (call this BF),then the DF's {value}
   15328 	* must be a valid restriction of BF's {value} as defined in
   15329 	* [XML Schemas: Datatypes]."
   15330 	*
   15331 	* NOTE (1.3.2) Facet derivation constraints are currently handled in
   15332 	* xmlSchemaDeriveAndValidateFacets()
   15333 	*/
   15334     } else if (WXS_IS_LIST(type)) {
   15335 	xmlSchemaTypePtr itemType = NULL;
   15336 
   15337 	itemType = type->subtypes;
   15338 	if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
   15339 	    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15340 		"failed to evaluate the item type");
   15341 	    return (-1);
   15342 	}
   15343 	if (WXS_IS_TYPE_NOT_FIXED(itemType))
   15344 	    xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
   15345 	/*
   15346 	* 2.1 The {item type definition} must have a {variety} of atomic or
   15347 	* union (in which case all the {member type definitions}
   15348 	* must be atomic).
   15349 	*/
   15350 	if ((! WXS_IS_ATOMIC(itemType)) &&
   15351 	    (! WXS_IS_UNION(itemType))) {
   15352 	    xmlSchemaPCustomErr(pctxt,
   15353 		XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
   15354 		WXS_BASIC_CAST type, NULL,
   15355 		"The item type '%s' does not have a variety of atomic or union",
   15356 		xmlSchemaGetComponentQName(&str, itemType));
   15357 	    FREE_AND_NULL(str)
   15358 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
   15359 	} else if (WXS_IS_UNION(itemType)) {
   15360 	    xmlSchemaTypeLinkPtr member;
   15361 
   15362 	    member = itemType->memberTypes;
   15363 	    while (member != NULL) {
   15364 		if (! WXS_IS_ATOMIC(member->type)) {
   15365 		    xmlSchemaPCustomErr(pctxt,
   15366 			XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
   15367 			WXS_BASIC_CAST type, NULL,
   15368 			"The item type is a union type, but the "
   15369 			"member type '%s' of this item type is not atomic",
   15370 			xmlSchemaGetComponentQName(&str, member->type));
   15371 		    FREE_AND_NULL(str)
   15372 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
   15373 		}
   15374 		member = member->next;
   15375 	    }
   15376 	}
   15377 
   15378 	if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
   15379 	    xmlSchemaFacetPtr facet;
   15380 	    /*
   15381 	    * This is the case if we have: <simpleType><list ..
   15382 	    */
   15383 	    /*
   15384 	    * 2.3.1
   15385 	    * 2.3.1.1 The {final} of the {item type definition} must not
   15386 	    * contain list.
   15387 	    */
   15388 	    if (xmlSchemaTypeFinalContains(itemType,
   15389 		XML_SCHEMAS_TYPE_FINAL_LIST)) {
   15390 		xmlSchemaPCustomErr(pctxt,
   15391 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
   15392 		    WXS_BASIC_CAST type, NULL,
   15393 		    "The final of its item type '%s' must not contain 'list'",
   15394 		    xmlSchemaGetComponentQName(&str, itemType));
   15395 		FREE_AND_NULL(str)
   15396 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
   15397 	    }
   15398 	    /*
   15399 	    * 2.3.1.2 The {facets} must only contain the whiteSpace
   15400 	    * facet component.
   15401 	    * OPTIMIZE TODO: the S4S already disallows any facet
   15402 	    * to be specified.
   15403 	    */
   15404 	    if (type->facets != NULL) {
   15405 		facet = type->facets;
   15406 		do {
   15407 		    if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
   15408 			xmlSchemaPIllegalFacetListUnionErr(pctxt,
   15409 			    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
   15410 			    type, facet);
   15411 			return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
   15412 		    }
   15413 		    facet = facet->next;
   15414 		} while (facet != NULL);
   15415 	    }
   15416 	    /*
   15417 	    * MAYBE TODO: (Hmm, not really) Datatypes states:
   15418 	    * A `list` datatype can be `derived` from an `atomic` datatype
   15419 	    * whose `lexical space` allows space (such as string or anyURI)or
   15420 	    * a `union` datatype any of whose {member type definitions}'s
   15421 	    * `lexical space` allows space.
   15422 	    */
   15423 	} else {
   15424 	    /*
   15425 	    * This is the case if we have: <simpleType><restriction ...
   15426 	    * I.e. the variety of "list" is inherited.
   15427 	    */
   15428 	    /*
   15429 	    * 2.3.2
   15430 	    * 2.3.2.1 The {base type definition} must have a {variety} of list.
   15431 	    */
   15432 	    if (! WXS_IS_LIST(type->baseType)) {
   15433 		xmlSchemaPCustomErr(pctxt,
   15434 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
   15435 		    WXS_BASIC_CAST type, NULL,
   15436 		    "The base type '%s' must be a list type",
   15437 		    xmlSchemaGetComponentQName(&str, type->baseType));
   15438 		FREE_AND_NULL(str)
   15439 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
   15440 	    }
   15441 	    /*
   15442 	    * 2.3.2.2 The {final} of the {base type definition} must not
   15443 	    * contain restriction.
   15444 	    */
   15445 	    if (xmlSchemaTypeFinalContains(type->baseType,
   15446 		XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
   15447 		xmlSchemaPCustomErr(pctxt,
   15448 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
   15449 		    WXS_BASIC_CAST type, NULL,
   15450 		    "The 'final' of the base type '%s' must not contain 'restriction'",
   15451 		    xmlSchemaGetComponentQName(&str, type->baseType));
   15452 		FREE_AND_NULL(str)
   15453 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
   15454 	    }
   15455 	    /*
   15456 	    * 2.3.2.3 The {item type definition} must be validly derived
   15457 	    * from the {base type definition}'s {item type definition} given
   15458 	    * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
   15459 	    */
   15460 	    {
   15461 		xmlSchemaTypePtr baseItemType;
   15462 
   15463 		baseItemType = type->baseType->subtypes;
   15464 		if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
   15465 		    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15466 			"failed to eval the item type of a base type");
   15467 		    return (-1);
   15468 		}
   15469 		if ((itemType != baseItemType) &&
   15470 		    (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
   15471 			baseItemType, 0) != 0)) {
   15472 		    xmlChar *strBIT = NULL, *strBT = NULL;
   15473 		    xmlSchemaPCustomErrExt(pctxt,
   15474 			XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
   15475 			WXS_BASIC_CAST type, NULL,
   15476 			"The item type '%s' is not validly derived from "
   15477 			"the item type '%s' of the base type '%s'",
   15478 			xmlSchemaGetComponentQName(&str, itemType),
   15479 			xmlSchemaGetComponentQName(&strBIT, baseItemType),
   15480 			xmlSchemaGetComponentQName(&strBT, type->baseType));
   15481 
   15482 		    FREE_AND_NULL(str)
   15483 		    FREE_AND_NULL(strBIT)
   15484 		    FREE_AND_NULL(strBT)
   15485 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
   15486 		}
   15487 	    }
   15488 
   15489 	    if (type->facets != NULL) {
   15490 		xmlSchemaFacetPtr facet;
   15491 		int ok = 1;
   15492 		/*
   15493 		* 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
   15494 		* and enumeration facet components are allowed among the {facets}.
   15495 		*/
   15496 		facet = type->facets;
   15497 		do {
   15498 		    switch (facet->type) {
   15499 			case XML_SCHEMA_FACET_LENGTH:
   15500 			case XML_SCHEMA_FACET_MINLENGTH:
   15501 			case XML_SCHEMA_FACET_MAXLENGTH:
   15502 			case XML_SCHEMA_FACET_WHITESPACE:
   15503 			    /*
   15504 			    * TODO: 2.5.1.2 List datatypes
   15505 			    * The value of `whiteSpace` is fixed to the value collapse.
   15506 			    */
   15507 			case XML_SCHEMA_FACET_PATTERN:
   15508 			case XML_SCHEMA_FACET_ENUMERATION:
   15509 			    break;
   15510 			default: {
   15511 			    xmlSchemaPIllegalFacetListUnionErr(pctxt,
   15512 				XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
   15513 				type, facet);
   15514 			    /*
   15515 			    * We could return, but it's nicer to report all
   15516 			    * invalid facets.
   15517 			    */
   15518 			    ok = 0;
   15519 			}
   15520 		    }
   15521 		    facet = facet->next;
   15522 		} while (facet != NULL);
   15523 		if (ok == 0)
   15524 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
   15525 		/*
   15526 		* SPEC (2.3.2.5) (same as 1.3.2)
   15527 		*
   15528 		* NOTE (2.3.2.5) This is currently done in
   15529 		* xmlSchemaDeriveAndValidateFacets()
   15530 		*/
   15531 	    }
   15532 	}
   15533     } else if (WXS_IS_UNION(type)) {
   15534 	/*
   15535 	* 3.1 The {member type definitions} must all have {variety} of
   15536 	* atomic or list.
   15537 	*/
   15538 	xmlSchemaTypeLinkPtr member;
   15539 
   15540 	member = type->memberTypes;
   15541 	while (member != NULL) {
   15542 	    if (WXS_IS_TYPE_NOT_FIXED(member->type))
   15543 		xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
   15544 
   15545 	    if ((! WXS_IS_ATOMIC(member->type)) &&
   15546 		(! WXS_IS_LIST(member->type))) {
   15547 		xmlSchemaPCustomErr(pctxt,
   15548 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
   15549 		    WXS_BASIC_CAST type, NULL,
   15550 		    "The member type '%s' is neither an atomic, nor a list type",
   15551 		    xmlSchemaGetComponentQName(&str, member->type));
   15552 		FREE_AND_NULL(str)
   15553 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
   15554 	    }
   15555 	    member = member->next;
   15556 	}
   15557 	/*
   15558 	* 3.3.1 If the {base type definition} is the `simple ur-type
   15559 	* definition`
   15560 	*/
   15561 	if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
   15562 	    /*
   15563 	    * 3.3.1.1 All of the {member type definitions} must have a
   15564 	    * {final} which does not contain union.
   15565 	    */
   15566 	    member = type->memberTypes;
   15567 	    while (member != NULL) {
   15568 		if (xmlSchemaTypeFinalContains(member->type,
   15569 		    XML_SCHEMAS_TYPE_FINAL_UNION)) {
   15570 		    xmlSchemaPCustomErr(pctxt,
   15571 			XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
   15572 			WXS_BASIC_CAST type, NULL,
   15573 			"The 'final' of member type '%s' contains 'union'",
   15574 			xmlSchemaGetComponentQName(&str, member->type));
   15575 		    FREE_AND_NULL(str)
   15576 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
   15577 		}
   15578 		member = member->next;
   15579 	    }
   15580 	    /*
   15581 	    * 3.3.1.2 The {facets} must be empty.
   15582 	    */
   15583 	    if (type->facetSet != NULL) {
   15584 		xmlSchemaPCustomErr(pctxt,
   15585 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
   15586 		    WXS_BASIC_CAST type, NULL,
   15587 		    "No facets allowed", NULL);
   15588 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
   15589 	    }
   15590 	} else {
   15591 	    /*
   15592 	    * 3.3.2.1 The {base type definition} must have a {variety} of union.
   15593 	    * I.e. the variety of "list" is inherited.
   15594 	    */
   15595 	    if (! WXS_IS_UNION(type->baseType)) {
   15596 		xmlSchemaPCustomErr(pctxt,
   15597 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
   15598 		    WXS_BASIC_CAST type, NULL,
   15599 		    "The base type '%s' is not a union type",
   15600 		    xmlSchemaGetComponentQName(&str, type->baseType));
   15601 		FREE_AND_NULL(str)
   15602 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
   15603 	    }
   15604 	    /*
   15605 	    * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
   15606 	    */
   15607 	    if (xmlSchemaTypeFinalContains(type->baseType,
   15608 		XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
   15609 		xmlSchemaPCustomErr(pctxt,
   15610 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
   15611 		    WXS_BASIC_CAST type, NULL,
   15612 		    "The 'final' of its base type '%s' must not contain 'restriction'",
   15613 		    xmlSchemaGetComponentQName(&str, type->baseType));
   15614 		FREE_AND_NULL(str)
   15615 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
   15616 	    }
   15617 	    /*
   15618 	    * 3.3.2.3 The {member type definitions}, in order, must be validly
   15619 	    * derived from the corresponding type definitions in the {base
   15620 	    * type definition}'s {member type definitions} given the empty set,
   15621 	    * as defined in Type Derivation OK (Simple) ($3.14.6).
   15622 	    */
   15623 	    {
   15624 		xmlSchemaTypeLinkPtr baseMember;
   15625 
   15626 		/*
   15627 		* OPTIMIZE: if the type is restricting, it has no local defined
   15628 		* member types and inherits the member types of the base type;
   15629 		* thus a check for equality can be skipped.
   15630 		*/
   15631 		/*
   15632 		* Even worse: I cannot see a scenario where a restricting
   15633 		* union simple type can have other member types as the member
   15634 		* types of it's base type. This check seems not necessary with
   15635 		* respect to the derivation process in libxml2.
   15636 		* But necessary if constructing types with an API.
   15637 		*/
   15638 		if (type->memberTypes != NULL) {
   15639 		    member = type->memberTypes;
   15640 		    baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
   15641 		    if ((member == NULL) && (baseMember != NULL)) {
   15642 			PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15643 			    "different number of member types in base");
   15644 		    }
   15645 		    while (member != NULL) {
   15646 			if (baseMember == NULL) {
   15647 			    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15648 			    "different number of member types in base");
   15649 			} else if ((member->type != baseMember->type) &&
   15650 			    (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
   15651 				member->type, baseMember->type, 0) != 0)) {
   15652 			    xmlChar *strBMT = NULL, *strBT = NULL;
   15653 
   15654 			    xmlSchemaPCustomErrExt(pctxt,
   15655 				XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
   15656 				WXS_BASIC_CAST type, NULL,
   15657 				"The member type %s is not validly "
   15658 				"derived from its corresponding member "
   15659 				"type %s of the base type %s",
   15660 				xmlSchemaGetComponentQName(&str, member->type),
   15661 				xmlSchemaGetComponentQName(&strBMT, baseMember->type),
   15662 				xmlSchemaGetComponentQName(&strBT, type->baseType));
   15663 			    FREE_AND_NULL(str)
   15664 			    FREE_AND_NULL(strBMT)
   15665 			    FREE_AND_NULL(strBT)
   15666 			    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
   15667 			}
   15668 			member = member->next;
   15669                         if (baseMember != NULL)
   15670                             baseMember = baseMember->next;
   15671 		    }
   15672 		}
   15673 	    }
   15674 	    /*
   15675 	    * 3.3.2.4 Only pattern and enumeration facet components are
   15676 	    * allowed among the {facets}.
   15677 	    */
   15678 	    if (type->facets != NULL) {
   15679 		xmlSchemaFacetPtr facet;
   15680 		int ok = 1;
   15681 
   15682 		facet = type->facets;
   15683 		do {
   15684 		    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
   15685 			(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
   15686 			xmlSchemaPIllegalFacetListUnionErr(pctxt,
   15687 				XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
   15688 				type, facet);
   15689 			ok = 0;
   15690 		    }
   15691 		    facet = facet->next;
   15692 		} while (facet != NULL);
   15693 		if (ok == 0)
   15694 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
   15695 
   15696 	    }
   15697 	    /*
   15698 	    * SPEC (3.3.2.5) (same as 1.3.2)
   15699 	    *
   15700 	    * NOTE (3.3.2.5) This is currently done in
   15701 	    * xmlSchemaDeriveAndValidateFacets()
   15702 	    */
   15703 	}
   15704     }
   15705 
   15706     return (0);
   15707 }
   15708 
   15709 /**
   15710  * xmlSchemaCheckSRCSimpleType:
   15711  * @ctxt:  the schema parser context
   15712  * @type:  the simple type definition
   15713  *
   15714  * Checks crc-simple-type constraints.
   15715  *
   15716  * Returns 0 if the constraints are satisfied,
   15717  * if not a positive error code and -1 on internal
   15718  * errors.
   15719  */
   15720 #if 0
   15721 static int
   15722 xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
   15723 			    xmlSchemaTypePtr type)
   15724 {
   15725     /*
   15726     * src-simple-type.1 The corresponding simple type definition, if any,
   15727     * must satisfy the conditions set out in Constraints on Simple Type
   15728     * Definition Schema Components ($3.14.6).
   15729     */
   15730     if (WXS_IS_RESTRICTION(type)) {
   15731 	/*
   15732 	* src-simple-type.2 "If the <restriction> alternative is chosen,
   15733 	* either it must have a base [attribute] or a <simpleType> among its
   15734 	* [children], but not both."
   15735 	* NOTE: This is checked in the parse function of <restriction>.
   15736 	*/
   15737 	/*
   15738 	*
   15739 	*/
   15740     } else if (WXS_IS_LIST(type)) {
   15741 	/* src-simple-type.3 "If the <list> alternative is chosen, either it must have
   15742 	* an itemType [attribute] or a <simpleType> among its [children],
   15743 	* but not both."
   15744 	*
   15745 	* NOTE: This is checked in the parse function of <list>.
   15746 	*/
   15747     } else if (WXS_IS_UNION(type)) {
   15748 	/*
   15749 	* src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
   15750 	*/
   15751     }
   15752     return (0);
   15753 }
   15754 #endif
   15755 
   15756 static int
   15757 xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
   15758 {
   15759    if (ctxt->vctxt == NULL) {
   15760 	ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
   15761 	if (ctxt->vctxt == NULL) {
   15762 	    xmlSchemaPErr(ctxt, NULL,
   15763 		XML_SCHEMAP_INTERNAL,
   15764 		"Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
   15765 		"failed to create a temp. validation context.\n",
   15766 		NULL, NULL);
   15767 	    return (-1);
   15768 	}
   15769 	/* TODO: Pass user data. */
   15770 	xmlSchemaSetValidErrors(ctxt->vctxt,
   15771 	    ctxt->error, ctxt->warning, ctxt->errCtxt);
   15772 	xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
   15773 	    ctxt->serror, ctxt->errCtxt);
   15774     }
   15775     return (0);
   15776 }
   15777 
   15778 static int
   15779 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
   15780 			     xmlNodePtr node,
   15781 			     xmlSchemaTypePtr type,
   15782 			     const xmlChar *value,
   15783 			     xmlSchemaValPtr *retVal,
   15784 			     int fireErrors,
   15785 			     int normalize,
   15786 			     int isNormalized);
   15787 
   15788 /**
   15789  * xmlSchemaParseCheckCOSValidDefault:
   15790  * @pctxt:  the schema parser context
   15791  * @type:  the simple type definition
   15792  * @value: the default value
   15793  * @node: an optional node (the holder of the value)
   15794  *
   15795  * Schema Component Constraint: Element Default Valid (Immediate)
   15796  * (cos-valid-default)
   15797  * This will be used by the parser only. For the validator there's
   15798  * an other version.
   15799  *
   15800  * Returns 0 if the constraints are satisfied,
   15801  * if not, a positive error code and -1 on internal
   15802  * errors.
   15803  */
   15804 static int
   15805 xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
   15806 				   xmlNodePtr node,
   15807 				   xmlSchemaTypePtr type,
   15808 				   const xmlChar *value,
   15809 				   xmlSchemaValPtr *val)
   15810 {
   15811     int ret = 0;
   15812 
   15813     /*
   15814     * cos-valid-default:
   15815     * Schema Component Constraint: Element Default Valid (Immediate)
   15816     * For a string to be a valid default with respect to a type
   15817     * definition the appropriate case among the following must be true:
   15818     */
   15819     if WXS_IS_COMPLEX(type) {
   15820 	/*
   15821 	* Complex type.
   15822 	*
   15823 	* SPEC (2.1) "its {content type} must be a simple type definition
   15824 	* or mixed."
   15825 	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
   15826 	* type}'s particle must be `emptiable` as defined by
   15827 	* Particle Emptiable ($3.9.6)."
   15828 	*/
   15829 	if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
   15830 	    ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
   15831 	    /* NOTE that this covers (2.2.2) as well. */
   15832 	    xmlSchemaPCustomErr(pctxt,
   15833 		XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
   15834 		WXS_BASIC_CAST type, type->node,
   15835 		"For a string to be a valid default, the type definition "
   15836 		"must be a simple type or a complex type with mixed content "
   15837 		"and a particle emptiable", NULL);
   15838 	    return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
   15839 	}
   15840     }
   15841     /*
   15842     * 1 If the type definition is a simple type definition, then the string
   15843     * must be `valid` with respect to that definition as defined by String
   15844     * Valid ($3.14.4).
   15845     *
   15846     * AND
   15847     *
   15848     * 2.2.1 If the {content type} is a simple type definition, then the
   15849     * string must be `valid` with respect to that simple type definition
   15850     * as defined by String Valid ($3.14.4).
   15851     */
   15852     if (WXS_IS_SIMPLE(type))
   15853 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
   15854 	    type, value, val, 1, 1, 0);
   15855     else if (WXS_HAS_SIMPLE_CONTENT(type))
   15856 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
   15857 	    type->contentTypeDef, value, val, 1, 1, 0);
   15858     else
   15859 	return (ret);
   15860 
   15861     if (ret < 0) {
   15862 	PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
   15863 	    "calling xmlSchemaVCheckCVCSimpleType()");
   15864     }
   15865 
   15866     return (ret);
   15867 }
   15868 
   15869 /**
   15870  * xmlSchemaCheckCTPropsCorrect:
   15871  * @ctxt:  the schema parser context
   15872  * @type:  the complex type definition
   15873  *
   15874  *.(4.6) Constraints on Complex Type Definition Schema Components
   15875  * Schema Component Constraint:
   15876  * Complex Type Definition Properties Correct (ct-props-correct)
   15877  * STATUS: (seems) complete
   15878  *
   15879  * Returns 0 if the constraints are satisfied, a positive
   15880  * error code if not and -1 if an internal error occured.
   15881  */
   15882 static int
   15883 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
   15884 			     xmlSchemaTypePtr type)
   15885 {
   15886     /*
   15887     * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
   15888     *
   15889     * SPEC (1) "The values of the properties of a complex type definition must
   15890     * be as described in the property tableau in The Complex Type Definition
   15891     * Schema Component ($3.4.1), modulo the impact of Missing
   15892     * Sub-components ($5.3)."
   15893     */
   15894     if ((type->baseType != NULL) &&
   15895 	(WXS_IS_SIMPLE(type->baseType)) &&
   15896 	(WXS_IS_EXTENSION(type) == 0)) {
   15897 	/*
   15898 	* SPEC (2) "If the {base type definition} is a simple type definition,
   15899 	* the {derivation method} must be extension."
   15900 	*/
   15901 	xmlSchemaCustomErr(ACTXT_CAST pctxt,
   15902 	    XML_SCHEMAP_SRC_CT_1,
   15903 	    NULL, WXS_BASIC_CAST type,
   15904 	    "If the base type is a simple type, the derivation method must be "
   15905 	    "'extension'", NULL, NULL);
   15906 	return (XML_SCHEMAP_SRC_CT_1);
   15907     }
   15908     /*
   15909     * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
   15910     * definition`. That is, it must be possible to reach the `ur-type
   15911     * definition` by repeatedly following the {base type definition}."
   15912     *
   15913     * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
   15914     */
   15915     /*
   15916     * NOTE that (4) and (5) need the following:
   15917     *   - attribute uses need to be already inherited (apply attr. prohibitions)
   15918     *   - attribute group references need to be expanded already
   15919     *   - simple types need to be typefixed already
   15920     */
   15921     if (type->attrUses &&
   15922 	(((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
   15923     {
   15924 	xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
   15925 	xmlSchemaAttributeUsePtr use, tmp;
   15926 	int i, j, hasId = 0;
   15927 
   15928 	for (i = uses->nbItems -1; i >= 0; i--) {
   15929 	    use = uses->items[i];
   15930 
   15931 	    /*
   15932 	    * SPEC ct-props-correct
   15933 	    * (4) "Two distinct attribute declarations in the
   15934 	    * {attribute uses} must not have identical {name}s and
   15935 	    * {target namespace}s."
   15936 	    */
   15937 	    if (i > 0) {
   15938 		for (j = i -1; j >= 0; j--) {
   15939 		    tmp = uses->items[j];
   15940 		    if ((WXS_ATTRUSE_DECL_NAME(use) ==
   15941 			WXS_ATTRUSE_DECL_NAME(tmp)) &&
   15942 			(WXS_ATTRUSE_DECL_TNS(use) ==
   15943 			WXS_ATTRUSE_DECL_TNS(tmp)))
   15944 		    {
   15945 			xmlChar *str = NULL;
   15946 
   15947 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   15948 			    XML_SCHEMAP_AG_PROPS_CORRECT,
   15949 			    NULL, WXS_BASIC_CAST type,
   15950 			    "Duplicate %s",
   15951 			    xmlSchemaGetComponentDesignation(&str, use),
   15952 			    NULL);
   15953 			FREE_AND_NULL(str);
   15954 			/*
   15955 			* Remove the duplicate.
   15956 			*/
   15957 			if (xmlSchemaItemListRemove(uses, i) == -1)
   15958 			    goto exit_failure;
   15959 			goto next_use;
   15960 		    }
   15961 		}
   15962 	    }
   15963 	    /*
   15964 	    * SPEC ct-props-correct
   15965 	    * (5) "Two distinct attribute declarations in the
   15966 	    * {attribute uses} must not have {type definition}s which
   15967 	    * are or are derived from ID."
   15968 	    */
   15969 	    if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
   15970 		if (xmlSchemaIsDerivedFromBuiltInType(
   15971 		    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
   15972 		{
   15973 		    if (hasId) {
   15974 			xmlChar *str = NULL;
   15975 
   15976 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   15977 			    XML_SCHEMAP_AG_PROPS_CORRECT,
   15978 			    NULL, WXS_BASIC_CAST type,
   15979 			    "There must not exist more than one attribute "
   15980 			    "declaration of type 'xs:ID' "
   15981 			    "(or derived from 'xs:ID'). The %s violates this "
   15982 			    "constraint",
   15983 			    xmlSchemaGetComponentDesignation(&str, use),
   15984 			    NULL);
   15985 			FREE_AND_NULL(str);
   15986 			if (xmlSchemaItemListRemove(uses, i) == -1)
   15987 			    goto exit_failure;
   15988 		    }
   15989 
   15990 		    hasId = 1;
   15991 		}
   15992 	    }
   15993 next_use: {}
   15994 	}
   15995     }
   15996     return (0);
   15997 exit_failure:
   15998     return(-1);
   15999 }
   16000 
   16001 static int
   16002 xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
   16003 		       xmlSchemaTypePtr typeB)
   16004 {
   16005     /*
   16006     * TODO: This should implement component-identity
   16007     * in the future.
   16008     */
   16009     if ((typeA == NULL) || (typeB == NULL))
   16010 	return (0);
   16011     return (typeA == typeB);
   16012 }
   16013 
   16014 /**
   16015  * xmlSchemaCheckCOSCTDerivedOK:
   16016  * @ctxt:  the schema parser context
   16017  * @type:  the to-be derived complex type definition
   16018  * @baseType:  the base complex type definition
   16019  * @set: the given set
   16020  *
   16021  * Schema Component Constraint:
   16022  * Type Derivation OK (Complex) (cos-ct-derived-ok)
   16023  *
   16024  * STATUS: completed
   16025  *
   16026  * Returns 0 if the constraints are satisfied, or 1
   16027  * if not.
   16028  */
   16029 static int
   16030 xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
   16031 			     xmlSchemaTypePtr type,
   16032 			     xmlSchemaTypePtr baseType,
   16033 			     int set)
   16034 {
   16035     int equal = xmlSchemaAreEqualTypes(type, baseType);
   16036     /* TODO: Error codes. */
   16037     /*
   16038     * SPEC "For a complex type definition (call it D, for derived)
   16039     * to be validly derived from a type definition (call this
   16040     * B, for base) given a subset of {extension, restriction}
   16041     * all of the following must be true:"
   16042     */
   16043     if (! equal) {
   16044 	/*
   16045 	* SPEC (1) "If B and D are not the same type definition, then the
   16046 	* {derivation method} of D must not be in the subset."
   16047 	*/
   16048 	if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
   16049 	    ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
   16050 	    return (1);
   16051     } else {
   16052 	/*
   16053 	* SPEC (2.1) "B and D must be the same type definition."
   16054 	*/
   16055 	return (0);
   16056     }
   16057     /*
   16058     * SPEC (2.2) "B must be D's {base type definition}."
   16059     */
   16060     if (type->baseType == baseType)
   16061 	return (0);
   16062     /*
   16063     * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
   16064     * definition`."
   16065     */
   16066     if (WXS_IS_ANYTYPE(type->baseType))
   16067 	return (1);
   16068 
   16069     if (WXS_IS_COMPLEX(type->baseType)) {
   16070 	/*
   16071 	* SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
   16072 	* must be validly derived from B given the subset as defined by this
   16073 	* constraint."
   16074 	*/
   16075 	return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
   16076 	    baseType, set));
   16077     } else {
   16078 	/*
   16079 	* SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
   16080 	* must be validly derived from B given the subset as defined in Type
   16081 	* Derivation OK (Simple) ($3.14.6).
   16082 	*/
   16083 	return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
   16084 	    baseType, set));
   16085     }
   16086 }
   16087 
   16088 /**
   16089  * xmlSchemaCheckCOSDerivedOK:
   16090  * @type:  the derived simple type definition
   16091  * @baseType:  the base type definition
   16092  *
   16093  * Calls:
   16094  * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
   16095  *
   16096  * Checks wheter @type can be validly derived from @baseType.
   16097  *
   16098  * Returns 0 on success, an positive error code otherwise.
   16099  */
   16100 static int
   16101 xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
   16102 			   xmlSchemaTypePtr type,
   16103 			   xmlSchemaTypePtr baseType,
   16104 			   int set)
   16105 {
   16106     if (WXS_IS_SIMPLE(type))
   16107 	return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
   16108     else
   16109 	return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
   16110 }
   16111 
   16112 /**
   16113  * xmlSchemaCheckCOSCTExtends:
   16114  * @ctxt:  the schema parser context
   16115  * @type:  the complex type definition
   16116  *
   16117  * (3.4.6) Constraints on Complex Type Definition Schema Components
   16118  * Schema Component Constraint:
   16119  * Derivation Valid (Extension) (cos-ct-extends)
   16120  *
   16121  * STATUS:
   16122  *   missing:
   16123  *     (1.5)
   16124  *     (1.4.3.2.2.2) "Particle Valid (Extension)"
   16125  *
   16126  * Returns 0 if the constraints are satisfied, a positive
   16127  * error code if not and -1 if an internal error occured.
   16128  */
   16129 static int
   16130 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
   16131 			   xmlSchemaTypePtr type)
   16132 {
   16133     xmlSchemaTypePtr base = type->baseType;
   16134     /*
   16135     * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
   16136     * temporarily only.
   16137     */
   16138     /*
   16139     * SPEC (1) "If the {base type definition} is a complex type definition,
   16140     * then all of the following must be true:"
   16141     */
   16142     if (WXS_IS_COMPLEX(base)) {
   16143 	/*
   16144 	* SPEC (1.1) "The {final} of the {base type definition} must not
   16145 	* contain extension."
   16146 	*/
   16147 	if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
   16148 	    xmlSchemaPCustomErr(ctxt,
   16149 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16150 		WXS_BASIC_CAST type, NULL,
   16151 		"The 'final' of the base type definition "
   16152 		"contains 'extension'", NULL);
   16153 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16154 	}
   16155 
   16156 	/*
   16157 	* ATTENTION: The constrains (1.2) and (1.3) are not applied,
   16158 	* since they are automatically satisfied through the
   16159 	* inheriting mechanism.
   16160 	* Note that even if redefining components, the inheriting mechanism
   16161 	* is used.
   16162 	*/
   16163 #if 0
   16164 	/*
   16165 	* SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
   16166 	* uses}
   16167 	* of the complex type definition itself, that is, for every attribute
   16168 	* use in the {attribute uses} of the {base type definition}, there
   16169 	* must be an attribute use in the {attribute uses} of the complex
   16170 	* type definition itself whose {attribute declaration} has the same
   16171 	* {name}, {target namespace} and {type definition} as its attribute
   16172 	* declaration"
   16173 	*/
   16174 	if (base->attrUses != NULL) {
   16175 	    int i, j, found;
   16176 	    xmlSchemaAttributeUsePtr use, buse;
   16177 
   16178 	    for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
   16179 		buse = (WXS_LIST_CAST base->attrUses)->items[i];
   16180 		found = 0;
   16181 		if (type->attrUses != NULL) {
   16182 		    use = (WXS_LIST_CAST type->attrUses)->items[j];
   16183 		    for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
   16184 		    {
   16185 			if ((WXS_ATTRUSE_DECL_NAME(use) ==
   16186 				WXS_ATTRUSE_DECL_NAME(buse)) &&
   16187 			    (WXS_ATTRUSE_DECL_TNS(use) ==
   16188 				WXS_ATTRUSE_DECL_TNS(buse)) &&
   16189 			    (WXS_ATTRUSE_TYPEDEF(use) ==
   16190 				WXS_ATTRUSE_TYPEDEF(buse))
   16191 			{
   16192 			    found = 1;
   16193 			    break;
   16194 			}
   16195 		    }
   16196 		}
   16197 		if (! found) {
   16198 		    xmlChar *str = NULL;
   16199 
   16200 		    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   16201 			XML_SCHEMAP_COS_CT_EXTENDS_1_2,
   16202 			NULL, WXS_BASIC_CAST type,
   16203 			/*
   16204 			* TODO: The report does not indicate that also the
   16205 			* type needs to be the same.
   16206 			*/
   16207 			"This type is missing a matching correspondent "
   16208 			"for its {base type}'s %s in its {attribute uses}",
   16209 			xmlSchemaGetComponentDesignation(&str,
   16210 			    buse->children),
   16211 			NULL);
   16212 		    FREE_AND_NULL(str)
   16213 		}
   16214 	    }
   16215 	}
   16216 	/*
   16217 	* SPEC (1.3) "If it has an {attribute wildcard}, the complex type
   16218 	* definition must also have one, and the base type definition's
   16219 	* {attribute  wildcard}'s {namespace constraint} must be a subset
   16220 	* of the complex  type definition's {attribute wildcard}'s {namespace
   16221 	* constraint}, as defined by Wildcard Subset ($3.10.6)."
   16222 	*/
   16223 
   16224 	/*
   16225 	* MAYBE TODO: Enable if ever needed. But this will be needed only
   16226 	* if created the type via a schema construction API.
   16227 	*/
   16228 	if (base->attributeWildcard != NULL) {
   16229 	    if (type->attributeWilcard == NULL) {
   16230 		xmlChar *str = NULL;
   16231 
   16232 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   16233 		    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
   16234 		    NULL, type,
   16235 		    "The base %s has an attribute wildcard, "
   16236 		    "but this type is missing an attribute wildcard",
   16237 		    xmlSchemaGetComponentDesignation(&str, base));
   16238 		FREE_AND_NULL(str)
   16239 
   16240 	    } else if (xmlSchemaCheckCOSNSSubset(
   16241 		base->attributeWildcard, type->attributeWildcard))
   16242 	    {
   16243 		xmlChar *str = NULL;
   16244 
   16245 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   16246 		    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
   16247 		    NULL, type,
   16248 		    "The attribute wildcard is not a valid "
   16249 		    "superset of the one in the base %s",
   16250 		    xmlSchemaGetComponentDesignation(&str, base));
   16251 		FREE_AND_NULL(str)
   16252 	    }
   16253 	}
   16254 #endif
   16255 	/*
   16256 	* SPEC (1.4) "One of the following must be true:"
   16257 	*/
   16258 	if ((type->contentTypeDef != NULL) &&
   16259 	    (type->contentTypeDef == base->contentTypeDef)) {
   16260 	    /*
   16261 	    * SPEC (1.4.1) "The {content type} of the {base type definition}
   16262 	    * and the {content type} of the complex type definition itself
   16263 	    * must be the same simple type definition"
   16264 	    * PASS
   16265 	    */
   16266 	} else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
   16267 	    (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
   16268 	    /*
   16269 	    * SPEC (1.4.2) "The {content type} of both the {base type
   16270 	    * definition} and the complex type definition itself must
   16271 	    * be empty."
   16272 	    * PASS
   16273 	    */
   16274 	} else {
   16275 	    /*
   16276 	    * SPEC (1.4.3) "All of the following must be true:"
   16277 	    */
   16278 	    if (type->subtypes == NULL) {
   16279 		/*
   16280 		* SPEC 1.4.3.1 The {content type} of the complex type
   16281 		* definition itself must specify a particle.
   16282 		*/
   16283 		xmlSchemaPCustomErr(ctxt,
   16284 		    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16285 		    WXS_BASIC_CAST type, NULL,
   16286 		    "The content type must specify a particle", NULL);
   16287 		return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16288 	    }
   16289 	    /*
   16290 	    * SPEC (1.4.3.2) "One of the following must be true:"
   16291 	    */
   16292 	    if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   16293 		/*
   16294 		* SPEC (1.4.3.2.1) "The {content type} of the {base type
   16295 		* definition} must be empty.
   16296 		* PASS
   16297 		*/
   16298 	    } else {
   16299 		/*
   16300 		* SPEC (1.4.3.2.2) "All of the following must be true:"
   16301 		*/
   16302 		if ((type->contentType != base->contentType) ||
   16303 		    ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
   16304 		    (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
   16305 		    /*
   16306 		    * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
   16307 		    * or both must be element-only."
   16308 		    */
   16309 		    xmlSchemaPCustomErr(ctxt,
   16310 			XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16311 			WXS_BASIC_CAST type, NULL,
   16312 			"The content type of both, the type and its base "
   16313 			"type, must either 'mixed' or 'element-only'", NULL);
   16314 		    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16315 		}
   16316 		/*
   16317 		* URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
   16318 		* complex type definition must be a `valid extension`
   16319 		* of the {base type definition}'s particle, as defined
   16320 		* in Particle Valid (Extension) ($3.9.6)."
   16321 		*
   16322 		* NOTE that we won't check "Particle Valid (Extension)",
   16323 		* since it is ensured by the derivation process in
   16324 		* xmlSchemaTypeFixup(). We need to implement this when heading
   16325 		* for a construction API
   16326 		* TODO: !! This is needed to be checked if redefining a type !!
   16327 		*/
   16328 	    }
   16329 	    /*
   16330 	    * URGENT TODO (1.5)
   16331 	    */
   16332 	}
   16333     } else {
   16334 	/*
   16335 	* SPEC (2) "If the {base type definition} is a simple type definition,
   16336 	* then all of the following must be true:"
   16337 	*/
   16338 	if (type->contentTypeDef != base) {
   16339 	    /*
   16340 	    * SPEC (2.1) "The {content type} must be the same simple type
   16341 	    * definition."
   16342 	    */
   16343 	    xmlSchemaPCustomErr(ctxt,
   16344 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16345 		WXS_BASIC_CAST type, NULL,
   16346 		"The content type must be the simple base type", NULL);
   16347 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16348 	}
   16349 	if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
   16350 	    /*
   16351 	    * SPEC (2.2) "The {final} of the {base type definition} must not
   16352 	    * contain extension"
   16353 	    * NOTE that this is the same as (1.1).
   16354 	    */
   16355 	    xmlSchemaPCustomErr(ctxt,
   16356 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16357 		WXS_BASIC_CAST type, NULL,
   16358 		"The 'final' of the base type definition "
   16359 		"contains 'extension'", NULL);
   16360 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16361 	}
   16362     }
   16363     return (0);
   16364 }
   16365 
   16366 /**
   16367  * xmlSchemaCheckDerivationOKRestriction:
   16368  * @ctxt:  the schema parser context
   16369  * @type:  the complex type definition
   16370  *
   16371  * (3.4.6) Constraints on Complex Type Definition Schema Components
   16372  * Schema Component Constraint:
   16373  * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
   16374  *
   16375  * STATUS:
   16376  *   missing:
   16377  *     (5.4.2) ???
   16378  *
   16379  * ATTENTION:
   16380  * In XML Schema 1.1 this will be:
   16381  * Validation Rule: Checking complex type subsumption
   16382  *
   16383  * Returns 0 if the constraints are satisfied, a positive
   16384  * error code if not and -1 if an internal error occured.
   16385  */
   16386 static int
   16387 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
   16388 				      xmlSchemaTypePtr type)
   16389 {
   16390     xmlSchemaTypePtr base;
   16391 
   16392     /*
   16393     * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
   16394     * temporarily only.
   16395     */
   16396     base = type->baseType;
   16397     if (! WXS_IS_COMPLEX(base)) {
   16398 	xmlSchemaCustomErr(ACTXT_CAST ctxt,
   16399 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16400 	    type->node, WXS_BASIC_CAST type,
   16401 	    "The base type must be a complex type", NULL, NULL);
   16402 	return(ctxt->err);
   16403     }
   16404     if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
   16405 	/*
   16406 	* SPEC (1) "The {base type definition} must be a complex type
   16407 	* definition whose {final} does not contain restriction."
   16408 	*/
   16409 	xmlSchemaCustomErr(ACTXT_CAST ctxt,
   16410 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16411 	    type->node, WXS_BASIC_CAST type,
   16412 	    "The 'final' of the base type definition "
   16413 	    "contains 'restriction'", NULL, NULL);
   16414 	return (ctxt->err);
   16415     }
   16416     /*
   16417     * SPEC (2), (3) and (4)
   16418     * Those are handled in a separate function, since the
   16419     * same constraints are needed for redefinition of
   16420     * attribute groups as well.
   16421     */
   16422     if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
   16423 	XML_SCHEMA_ACTION_DERIVE,
   16424 	WXS_BASIC_CAST type, WXS_BASIC_CAST base,
   16425 	type->attrUses, base->attrUses,
   16426 	type->attributeWildcard,
   16427 	base->attributeWildcard) == -1)
   16428     {
   16429 	return(-1);
   16430     }
   16431     /*
   16432     * SPEC (5) "One of the following must be true:"
   16433     */
   16434     if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
   16435 	/*
   16436 	* SPEC (5.1) "The {base type definition} must be the
   16437 	* `ur-type definition`."
   16438 	* PASS
   16439 	*/
   16440     } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
   16441 	    (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
   16442 	/*
   16443 	* SPEC (5.2.1) "The {content type} of the complex type definition
   16444 	* must be a simple type definition"
   16445 	*
   16446 	* SPEC (5.2.2) "One of the following must be true:"
   16447 	*/
   16448 	if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
   16449 	    (base->contentType == XML_SCHEMA_CONTENT_BASIC))
   16450 	{
   16451 	    int err;
   16452 	    /*
   16453 	    * SPEC (5.2.2.1) "The {content type} of the {base type
   16454 	    * definition} must be a simple type definition from which
   16455 	    * the {content type} is validly derived given the empty
   16456 	    * set as defined in Type Derivation OK (Simple) ($3.14.6)."
   16457 	    *
   16458 	    * ATTENTION TODO: This seems not needed if the type implicitely
   16459 	    * derived from the base type.
   16460 	    *
   16461 	    */
   16462 	    err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
   16463 		type->contentTypeDef, base->contentTypeDef, 0);
   16464 	    if (err != 0) {
   16465 		xmlChar *strA = NULL, *strB = NULL;
   16466 
   16467 		if (err == -1)
   16468 		    return(-1);
   16469 		xmlSchemaCustomErr(ACTXT_CAST ctxt,
   16470 		    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16471 		    NULL, WXS_BASIC_CAST type,
   16472 		    "The {content type} %s is not validly derived from the "
   16473 		    "base type's {content type} %s",
   16474 		    xmlSchemaGetComponentDesignation(&strA,
   16475 			type->contentTypeDef),
   16476 		    xmlSchemaGetComponentDesignation(&strB,
   16477 			base->contentTypeDef));
   16478 		FREE_AND_NULL(strA);
   16479 		FREE_AND_NULL(strB);
   16480 		return(ctxt->err);
   16481 	    }
   16482 	} else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
   16483 	    (xmlSchemaIsParticleEmptiable(
   16484 		(xmlSchemaParticlePtr) base->subtypes))) {
   16485 	    /*
   16486 	    * SPEC (5.2.2.2) "The {base type definition} must be mixed
   16487 	    * and have a particle which is `emptiable` as defined in
   16488 	    * Particle Emptiable ($3.9.6)."
   16489 	    * PASS
   16490 	    */
   16491 	} else {
   16492 	    xmlSchemaPCustomErr(ctxt,
   16493 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16494 		WXS_BASIC_CAST type, NULL,
   16495 		"The content type of the base type must be either "
   16496 		"a simple type or 'mixed' and an emptiable particle", NULL);
   16497 	    return (ctxt->err);
   16498 	}
   16499     } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   16500 	/*
   16501 	* SPEC (5.3.1) "The {content type} of the complex type itself must
   16502 	* be empty"
   16503 	*/
   16504 	if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   16505 	    /*
   16506 	    * SPEC (5.3.2.1) "The {content type} of the {base type
   16507 	    * definition} must also be empty."
   16508 	    * PASS
   16509 	    */
   16510 	} else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
   16511 	    (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
   16512 	    xmlSchemaIsParticleEmptiable(
   16513 		(xmlSchemaParticlePtr) base->subtypes)) {
   16514 	    /*
   16515 	    * SPEC (5.3.2.2) "The {content type} of the {base type
   16516 	    * definition} must be elementOnly or mixed and have a particle
   16517 	    * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
   16518 	    * PASS
   16519 	    */
   16520 	} else {
   16521 	    xmlSchemaPCustomErr(ctxt,
   16522 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16523 		WXS_BASIC_CAST type, NULL,
   16524 		"The content type of the base type must be either "
   16525 		"empty or 'mixed' (or 'elements-only') and an emptiable "
   16526 		"particle", NULL);
   16527 	    return (ctxt->err);
   16528 	}
   16529     } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
   16530 	WXS_HAS_MIXED_CONTENT(type)) {
   16531 	/*
   16532 	* SPEC (5.4.1.1) "The {content type} of the complex type definition
   16533 	* itself must be element-only"
   16534 	*/
   16535 	if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
   16536 	    /*
   16537 	    * SPEC (5.4.1.2) "The {content type} of the complex type
   16538 	    * definition itself and of the {base type definition} must be
   16539 	    * mixed"
   16540 	    */
   16541 	    xmlSchemaPCustomErr(ctxt,
   16542 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16543 		WXS_BASIC_CAST type, NULL,
   16544 		"If the content type is 'mixed', then the content type of the "
   16545 		"base type must also be 'mixed'", NULL);
   16546 	    return (ctxt->err);
   16547 	}
   16548 	/*
   16549 	* SPEC (5.4.2) "The particle of the complex type definition itself
   16550 	* must be a `valid restriction` of the particle of the {content
   16551 	* type} of the {base type definition} as defined in Particle Valid
   16552 	* (Restriction) ($3.9.6).
   16553 	*
   16554 	* URGENT TODO: (5.4.2)
   16555 	*/
   16556     } else {
   16557 	xmlSchemaPCustomErr(ctxt,
   16558 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16559 	    WXS_BASIC_CAST type, NULL,
   16560 	    "The type is not a valid restriction of its base type", NULL);
   16561 	return (ctxt->err);
   16562     }
   16563     return (0);
   16564 }
   16565 
   16566 /**
   16567  * xmlSchemaCheckCTComponent:
   16568  * @ctxt:  the schema parser context
   16569  * @type:  the complex type definition
   16570  *
   16571  * (3.4.6) Constraints on Complex Type Definition Schema Components
   16572  *
   16573  * Returns 0 if the constraints are satisfied, a positive
   16574  * error code if not and -1 if an internal error occured.
   16575  */
   16576 static int
   16577 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
   16578 			  xmlSchemaTypePtr type)
   16579 {
   16580     int ret;
   16581     /*
   16582     * Complex Type Definition Properties Correct
   16583     */
   16584     ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
   16585     if (ret != 0)
   16586 	return (ret);
   16587     if (WXS_IS_EXTENSION(type))
   16588 	ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
   16589     else
   16590 	ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
   16591     return (ret);
   16592 }
   16593 
   16594 /**
   16595  * xmlSchemaCheckSRCCT:
   16596  * @ctxt:  the schema parser context
   16597  * @type:  the complex type definition
   16598  *
   16599  * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
   16600  * Schema Representation Constraint:
   16601  * Complex Type Definition Representation OK (src-ct)
   16602  *
   16603  * Returns 0 if the constraints are satisfied, a positive
   16604  * error code if not and -1 if an internal error occured.
   16605  */
   16606 static int
   16607 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
   16608 		    xmlSchemaTypePtr type)
   16609 {
   16610     xmlSchemaTypePtr base;
   16611     int ret = 0;
   16612 
   16613     /*
   16614     * TODO: Adjust the error codes here, as I used
   16615     * XML_SCHEMAP_SRC_CT_1 only yet.
   16616     */
   16617     base = type->baseType;
   16618     if (! WXS_HAS_SIMPLE_CONTENT(type)) {
   16619 	/*
   16620 	* 1 If the <complexContent> alternative is chosen, the type definition
   16621 	* `resolved` to by the `actual value` of the base [attribute]
   16622 	* must be a complex type definition;
   16623 	*/
   16624 	if (! WXS_IS_COMPLEX(base)) {
   16625 	    xmlChar *str = NULL;
   16626 	    xmlSchemaPCustomErr(ctxt,
   16627 		XML_SCHEMAP_SRC_CT_1,
   16628 		WXS_BASIC_CAST type, type->node,
   16629 		"If using <complexContent>, the base type is expected to be "
   16630 		"a complex type. The base type '%s' is a simple type",
   16631 		xmlSchemaFormatQName(&str, base->targetNamespace,
   16632 		base->name));
   16633 	    FREE_AND_NULL(str)
   16634 	    return (XML_SCHEMAP_SRC_CT_1);
   16635 	}
   16636     } else {
   16637 	/*
   16638 	* SPEC
   16639 	* 2 If the <simpleContent> alternative is chosen, all of the
   16640 	* following must be true:
   16641 	* 2.1 The type definition `resolved` to by the `actual value` of the
   16642 	* base [attribute] must be one of the following:
   16643 	*/
   16644 	if (WXS_IS_SIMPLE(base)) {
   16645 	    if (WXS_IS_EXTENSION(type) == 0) {
   16646 		xmlChar *str = NULL;
   16647 		/*
   16648 		* 2.1.3 only if the <extension> alternative is also
   16649 		* chosen, a simple type definition.
   16650 		*/
   16651 		/* TODO: Change error code to ..._SRC_CT_2_1_3. */
   16652 		xmlSchemaPCustomErr(ctxt,
   16653 		    XML_SCHEMAP_SRC_CT_1,
   16654 		    WXS_BASIC_CAST type, NULL,
   16655 		    "If using <simpleContent> and <restriction>, the base "
   16656 		    "type must be a complex type. The base type '%s' is "
   16657 		    "a simple type",
   16658 		    xmlSchemaFormatQName(&str, base->targetNamespace,
   16659 			base->name));
   16660 		FREE_AND_NULL(str)
   16661 		return (XML_SCHEMAP_SRC_CT_1);
   16662 	    }
   16663 	} else {
   16664 	    /* Base type is a complex type. */
   16665 	    if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
   16666 		(base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
   16667 		/*
   16668 		* 2.1.1 a complex type definition whose {content type} is a
   16669 		* simple type definition;
   16670 		* PASS
   16671 		*/
   16672 		if (base->contentTypeDef == NULL) {
   16673 		    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
   16674 			WXS_BASIC_CAST type, NULL,
   16675 			"Internal error: xmlSchemaCheckSRCCT, "
   16676 			"'%s', base type has no content type",
   16677 			type->name);
   16678 		    return (-1);
   16679 		}
   16680 	    } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
   16681 		(WXS_IS_RESTRICTION(type))) {
   16682 
   16683 		/*
   16684 		* 2.1.2 only if the <restriction> alternative is also
   16685 		* chosen, a complex type definition whose {content type}
   16686 		* is mixed and a particle emptiable.
   16687 		*/
   16688 		if (! xmlSchemaIsParticleEmptiable(
   16689 		    (xmlSchemaParticlePtr) base->subtypes)) {
   16690 		    ret = XML_SCHEMAP_SRC_CT_1;
   16691 		} else
   16692 		    /*
   16693 		    * Attention: at this point the <simpleType> child is in
   16694 		    * ->contentTypeDef (put there during parsing).
   16695 		    */
   16696 		    if (type->contentTypeDef == NULL) {
   16697 		    xmlChar *str = NULL;
   16698 		    /*
   16699 		    * 2.2 If clause 2.1.2 above is satisfied, then there
   16700 		    * must be a <simpleType> among the [children] of
   16701 		    * <restriction>.
   16702 		    */
   16703 		    /* TODO: Change error code to ..._SRC_CT_2_2. */
   16704 		    xmlSchemaPCustomErr(ctxt,
   16705 			XML_SCHEMAP_SRC_CT_1,
   16706 			WXS_BASIC_CAST type, NULL,
   16707 			"A <simpleType> is expected among the children "
   16708 			"of <restriction>, if <simpleContent> is used and "
   16709 			"the base type '%s' is a complex type",
   16710 			xmlSchemaFormatQName(&str, base->targetNamespace,
   16711 			base->name));
   16712 		    FREE_AND_NULL(str)
   16713 		    return (XML_SCHEMAP_SRC_CT_1);
   16714 		}
   16715 	    } else {
   16716 		ret = XML_SCHEMAP_SRC_CT_1;
   16717 	    }
   16718 	}
   16719 	if (ret > 0) {
   16720 	    xmlChar *str = NULL;
   16721 	    if (WXS_IS_RESTRICTION(type)) {
   16722 		xmlSchemaPCustomErr(ctxt,
   16723 		    XML_SCHEMAP_SRC_CT_1,
   16724 		    WXS_BASIC_CAST type, NULL,
   16725 		    "If <simpleContent> and <restriction> is used, the "
   16726 		    "base type must be a simple type or a complex type with "
   16727 		    "mixed content and particle emptiable. The base type "
   16728 		    "'%s' is none of those",
   16729 		    xmlSchemaFormatQName(&str, base->targetNamespace,
   16730 		    base->name));
   16731 	    } else {
   16732 		xmlSchemaPCustomErr(ctxt,
   16733 		    XML_SCHEMAP_SRC_CT_1,
   16734 		    WXS_BASIC_CAST type, NULL,
   16735 		    "If <simpleContent> and <extension> is used, the "
   16736 		    "base type must be a simple type. The base type '%s' "
   16737 		    "is a complex type",
   16738 		    xmlSchemaFormatQName(&str, base->targetNamespace,
   16739 		    base->name));
   16740 	    }
   16741 	    FREE_AND_NULL(str)
   16742 	}
   16743     }
   16744     /*
   16745     * SPEC (3) "The corresponding complex type definition component must
   16746     * satisfy the conditions set out in Constraints on Complex Type
   16747     * Definition Schema Components ($3.4.6);"
   16748     * NOTE (3) will be done in xmlSchemaTypeFixup().
   16749     */
   16750     /*
   16751     * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
   16752     * above for {attribute wildcard} is satisfied, the intensional
   16753     * intersection must be expressible, as defined in Attribute Wildcard
   16754     * Intersection ($3.10.6).
   16755     * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
   16756     */
   16757     return (ret);
   16758 }
   16759 
   16760 #ifdef ENABLE_PARTICLE_RESTRICTION
   16761 /**
   16762  * xmlSchemaCheckParticleRangeOK:
   16763  * @ctxt:  the schema parser context
   16764  * @type:  the complex type definition
   16765  *
   16766  * (3.9.6) Constraints on Particle Schema Components
   16767  * Schema Component Constraint:
   16768  * Occurrence Range OK (range-ok)
   16769  *
   16770  * STATUS: complete
   16771  *
   16772  * Returns 0 if the constraints are satisfied, a positive
   16773  * error code if not and -1 if an internal error occured.
   16774  */
   16775 static int
   16776 xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
   16777 			      int bmin, int bmax)
   16778 {
   16779     if (rmin < bmin)
   16780 	return (1);
   16781     if ((bmax != UNBOUNDED) &&
   16782 	(rmax > bmax))
   16783 	return (1);
   16784     return (0);
   16785 }
   16786 
   16787 /**
   16788  * xmlSchemaCheckRCaseNameAndTypeOK:
   16789  * @ctxt:  the schema parser context
   16790  * @r: the restricting element declaration particle
   16791  * @b: the base element declaration particle
   16792  *
   16793  * (3.9.6) Constraints on Particle Schema Components
   16794  * Schema Component Constraint:
   16795  * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
   16796  * (rcase-NameAndTypeOK)
   16797  *
   16798  * STATUS:
   16799  *   MISSING (3.2.3)
   16800  *   CLARIFY: (3.2.2)
   16801  *
   16802  * Returns 0 if the constraints are satisfied, a positive
   16803  * error code if not and -1 if an internal error occured.
   16804  */
   16805 static int
   16806 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
   16807 				 xmlSchemaParticlePtr r,
   16808 				 xmlSchemaParticlePtr b)
   16809 {
   16810     xmlSchemaElementPtr elemR, elemB;
   16811 
   16812     /* TODO: Error codes (rcase-NameAndTypeOK). */
   16813     elemR = (xmlSchemaElementPtr) r->children;
   16814     elemB = (xmlSchemaElementPtr) b->children;
   16815     /*
   16816     * SPEC (1) "The declarations' {name}s and {target namespace}s are
   16817     * the same."
   16818     */
   16819     if ((elemR != elemB) &&
   16820 	((! xmlStrEqual(elemR->name, elemB->name)) ||
   16821 	(! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
   16822 	return (1);
   16823     /*
   16824     * SPEC (2) "R's occurrence range is a valid restriction of B's
   16825     * occurrence range as defined by Occurrence Range OK ($3.9.6)."
   16826     */
   16827     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
   16828 	    b->minOccurs, b->maxOccurs) != 0)
   16829 	return (1);
   16830     /*
   16831     * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
   16832     * {scope} are global."
   16833     */
   16834     if (elemR == elemB)
   16835 	return (0);
   16836     /*
   16837     * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
   16838     */
   16839     if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
   16840 	(elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
   16841 	 return (1);
   16842     /*
   16843     * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
   16844     * or is not fixed, or R's declaration's {value constraint} is fixed
   16845     * with the same value."
   16846     */
   16847     if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
   16848 	((elemR->value == NULL) ||
   16849 	 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
   16850 	 /* TODO: Equality of the initial value or normalized or canonical? */
   16851 	 (! xmlStrEqual(elemR->value, elemB->value))))
   16852 	 return (1);
   16853     /*
   16854     * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
   16855     * definitions} is a subset of B's declaration's {identity-constraint
   16856     * definitions}, if any."
   16857     */
   16858     if (elemB->idcs != NULL) {
   16859 	/* TODO */
   16860     }
   16861     /*
   16862     * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
   16863     * superset of B's declaration's {disallowed substitutions}."
   16864     */
   16865     if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
   16866 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
   16867 	((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
   16868 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
   16869 	((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
   16870 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
   16871 	 return (1);
   16872     /*
   16873     * SPEC (3.2.5) "R's {type definition} is validly derived given
   16874     * {extension, list, union} from B's {type definition}"
   16875     *
   16876     * BADSPEC TODO: What's the point of adding "list" and "union" to the
   16877     * set, if the corresponding constraints handle "restriction" and
   16878     * "extension" only?
   16879     *
   16880     */
   16881     {
   16882 	int set = 0;
   16883 
   16884 	set |= SUBSET_EXTENSION;
   16885 	set |= SUBSET_LIST;
   16886 	set |= SUBSET_UNION;
   16887 	if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
   16888 	    elemB->subtypes, set) != 0)
   16889 	    return (1);
   16890     }
   16891     return (0);
   16892 }
   16893 
   16894 /**
   16895  * xmlSchemaCheckRCaseNSCompat:
   16896  * @ctxt:  the schema parser context
   16897  * @r: the restricting element declaration particle
   16898  * @b: the base wildcard particle
   16899  *
   16900  * (3.9.6) Constraints on Particle Schema Components
   16901  * Schema Component Constraint:
   16902  * Particle Derivation OK (Elt:Any -- NSCompat)
   16903  * (rcase-NSCompat)
   16904  *
   16905  * STATUS: complete
   16906  *
   16907  * Returns 0 if the constraints are satisfied, a positive
   16908  * error code if not and -1 if an internal error occured.
   16909  */
   16910 static int
   16911 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
   16912 			    xmlSchemaParticlePtr r,
   16913 			    xmlSchemaParticlePtr b)
   16914 {
   16915     /* TODO:Error codes (rcase-NSCompat). */
   16916     /*
   16917     * SPEC "For an element declaration particle to be a `valid restriction`
   16918     * of a wildcard particle all of the following must be true:"
   16919     *
   16920     * SPEC (1) "The element declaration's {target namespace} is `valid`
   16921     * with respect to the wildcard's {namespace constraint} as defined by
   16922     * Wildcard allows Namespace Name ($3.10.4)."
   16923     */
   16924     if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
   16925 	((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
   16926 	return (1);
   16927     /*
   16928     * SPEC (2) "R's occurrence range is a valid restriction of B's
   16929     * occurrence range as defined by Occurrence Range OK ($3.9.6)."
   16930     */
   16931     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
   16932 	    b->minOccurs, b->maxOccurs) != 0)
   16933 	return (1);
   16934 
   16935     return (0);
   16936 }
   16937 
   16938 /**
   16939  * xmlSchemaCheckRCaseRecurseAsIfGroup:
   16940  * @ctxt:  the schema parser context
   16941  * @r: the restricting element declaration particle
   16942  * @b: the base model group particle
   16943  *
   16944  * (3.9.6) Constraints on Particle Schema Components
   16945  * Schema Component Constraint:
   16946  * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
   16947  * (rcase-RecurseAsIfGroup)
   16948  *
   16949  * STATUS: TODO
   16950  *
   16951  * Returns 0 if the constraints are satisfied, a positive
   16952  * error code if not and -1 if an internal error occured.
   16953  */
   16954 static int
   16955 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
   16956 				    xmlSchemaParticlePtr r,
   16957 				    xmlSchemaParticlePtr b)
   16958 {
   16959     /* TODO: Error codes (rcase-RecurseAsIfGroup). */
   16960     TODO
   16961     return (0);
   16962 }
   16963 
   16964 /**
   16965  * xmlSchemaCheckRCaseNSSubset:
   16966  * @ctxt:  the schema parser context
   16967  * @r: the restricting wildcard particle
   16968  * @b: the base wildcard particle
   16969  *
   16970  * (3.9.6) Constraints on Particle Schema Components
   16971  * Schema Component Constraint:
   16972  * Particle Derivation OK (Any:Any -- NSSubset)
   16973  * (rcase-NSSubset)
   16974  *
   16975  * STATUS: complete
   16976  *
   16977  * Returns 0 if the constraints are satisfied, a positive
   16978  * error code if not and -1 if an internal error occured.
   16979  */
   16980 static int
   16981 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
   16982 				    xmlSchemaParticlePtr r,
   16983 				    xmlSchemaParticlePtr b,
   16984 				    int isAnyTypeBase)
   16985 {
   16986     /* TODO: Error codes (rcase-NSSubset). */
   16987     /*
   16988     * SPEC (1) "R's occurrence range is a valid restriction of B's
   16989     * occurrence range as defined by Occurrence Range OK ($3.9.6)."
   16990     */
   16991     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
   16992 	    b->minOccurs, b->maxOccurs))
   16993 	return (1);
   16994     /*
   16995     * SPEC (2) "R's {namespace constraint} must be an intensional subset
   16996     * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
   16997     */
   16998     if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
   16999 	(xmlSchemaWildcardPtr) b->children))
   17000 	return (1);
   17001     /*
   17002     * SPEC (3) "Unless B is the content model wildcard of the `ur-type
   17003     * definition`, R's {process contents} must be identical to or stronger
   17004     * than B's {process contents}, where strict is stronger than lax is
   17005     * stronger than skip."
   17006     */
   17007     if (! isAnyTypeBase) {
   17008 	if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
   17009 	    ((xmlSchemaWildcardPtr) b->children)->processContents)
   17010 	    return (1);
   17011     }
   17012 
   17013     return (0);
   17014 }
   17015 
   17016 /**
   17017  * xmlSchemaCheckCOSParticleRestrict:
   17018  * @ctxt:  the schema parser context
   17019  * @type:  the complex type definition
   17020  *
   17021  * (3.9.6) Constraints on Particle Schema Components
   17022  * Schema Component Constraint:
   17023  * Particle Valid (Restriction) (cos-particle-restrict)
   17024  *
   17025  * STATUS: TODO
   17026  *
   17027  * Returns 0 if the constraints are satisfied, a positive
   17028  * error code if not and -1 if an internal error occured.
   17029  */
   17030 static int
   17031 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
   17032 				  xmlSchemaParticlePtr r,
   17033 				  xmlSchemaParticlePtr b)
   17034 {
   17035     int ret = 0;
   17036 
   17037     /*part = WXS_TYPE_PARTICLE(type);
   17038     basePart = WXS_TYPE_PARTICLE(base);
   17039     */
   17040 
   17041     TODO
   17042 
   17043     /*
   17044     * SPEC (1) "They are the same particle."
   17045     */
   17046     if (r == b)
   17047 	return (0);
   17048 
   17049 
   17050     return (0);
   17051 }
   17052 
   17053 #if 0
   17054 /**
   17055  * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
   17056  * @ctxt:  the schema parser context
   17057  * @r: the model group particle
   17058  * @b: the base wildcard particle
   17059  *
   17060  * (3.9.6) Constraints on Particle Schema Components
   17061  * Schema Component Constraint:
   17062  * Particle Derivation OK (All/Choice/Sequence:Any --
   17063  *                         NSRecurseCheckCardinality)
   17064  * (rcase-NSRecurseCheckCardinality)
   17065  *
   17066  * STATUS: TODO: subst-groups
   17067  *
   17068  * Returns 0 if the constraints are satisfied, a positive
   17069  * error code if not and -1 if an internal error occured.
   17070  */
   17071 static int
   17072 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
   17073 					     xmlSchemaParticlePtr r,
   17074 					     xmlSchemaParticlePtr b)
   17075 {
   17076     xmlSchemaParticlePtr part;
   17077     /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
   17078     if ((r->children == NULL) || (r->children->children == NULL))
   17079 	return (-1);
   17080     /*
   17081     * SPEC "For a group particle to be a `valid restriction` of a
   17082     * wildcard particle..."
   17083     *
   17084     * SPEC (1) "Every member of the {particles} of the group is a `valid
   17085     * restriction` of the wildcard as defined by
   17086     * Particle Valid (Restriction) ($3.9.6)."
   17087     */
   17088     part = (xmlSchemaParticlePtr) r->children->children;
   17089     do {
   17090 	if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
   17091 	    return (1);
   17092 	part = (xmlSchemaParticlePtr) part->next;
   17093     } while (part != NULL);
   17094     /*
   17095     * SPEC (2) "The effective total range of the group [...] is a
   17096     * valid restriction of B's occurrence range as defined by
   17097     * Occurrence Range OK ($3.9.6)."
   17098     */
   17099     if (xmlSchemaCheckParticleRangeOK(
   17100 	    xmlSchemaGetParticleTotalRangeMin(r),
   17101 	    xmlSchemaGetParticleTotalRangeMax(r),
   17102 	    b->minOccurs, b->maxOccurs) != 0)
   17103 	return (1);
   17104     return (0);
   17105 }
   17106 #endif
   17107 
   17108 /**
   17109  * xmlSchemaCheckRCaseRecurse:
   17110  * @ctxt:  the schema parser context
   17111  * @r: the <all> or <sequence> model group particle
   17112  * @b: the base <all> or <sequence> model group particle
   17113  *
   17114  * (3.9.6) Constraints on Particle Schema Components
   17115  * Schema Component Constraint:
   17116  * Particle Derivation OK (All:All,Sequence:Sequence --
   17117                            Recurse)
   17118  * (rcase-Recurse)
   17119  *
   17120  * STATUS:  ?
   17121  * TODO: subst-groups
   17122  *
   17123  * Returns 0 if the constraints are satisfied, a positive
   17124  * error code if not and -1 if an internal error occured.
   17125  */
   17126 static int
   17127 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
   17128 			   xmlSchemaParticlePtr r,
   17129 			   xmlSchemaParticlePtr b)
   17130 {
   17131     /* xmlSchemaParticlePtr part; */
   17132     /* TODO: Error codes (rcase-Recurse). */
   17133     if ((r->children == NULL) || (b->children == NULL) ||
   17134 	(r->children->type != b->children->type))
   17135 	return (-1);
   17136     /*
   17137     * SPEC "For an all or sequence group particle to be a `valid
   17138     * restriction` of another group particle with the same {compositor}..."
   17139     *
   17140     * SPEC (1) "R's occurrence range is a valid restriction of B's
   17141     * occurrence range as defined by Occurrence Range OK ($3.9.6)."
   17142     */
   17143     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
   17144 	    b->minOccurs, b->maxOccurs))
   17145 	return (1);
   17146 
   17147 
   17148     return (0);
   17149 }
   17150 
   17151 #endif
   17152 
   17153 #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
   17154     xmlSchemaPCustomErrExt(pctxt,      \
   17155 	XML_SCHEMAP_INVALID_FACET_VALUE, \
   17156 	WXS_BASIC_CAST fac1, fac1->node, \
   17157 	"It is an error for both '%s' and '%s' to be specified on the "\
   17158 	"same type definition", \
   17159 	BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
   17160 	BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
   17161 
   17162 #define FACET_RESTR_ERR(fac1, msg) \
   17163     xmlSchemaPCustomErr(pctxt,      \
   17164 	XML_SCHEMAP_INVALID_FACET_VALUE, \
   17165 	WXS_BASIC_CAST fac1, fac1->node, \
   17166 	msg, NULL);
   17167 
   17168 #define FACET_RESTR_FIXED_ERR(fac) \
   17169     xmlSchemaPCustomErr(pctxt, \
   17170 	XML_SCHEMAP_INVALID_FACET_VALUE, \
   17171 	WXS_BASIC_CAST fac, fac->node, \
   17172 	"The base type's facet is 'fixed', thus the value must not " \
   17173 	"differ", NULL);
   17174 
   17175 static void
   17176 xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
   17177 			xmlSchemaFacetPtr facet1,
   17178 			xmlSchemaFacetPtr facet2,
   17179 			int lessGreater,
   17180 			int orEqual,
   17181 			int ofBase)
   17182 {
   17183     xmlChar *msg = NULL;
   17184 
   17185     msg = xmlStrdup(BAD_CAST "'");
   17186     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
   17187     msg = xmlStrcat(msg, BAD_CAST "' has to be");
   17188     if (lessGreater == 0)
   17189 	msg = xmlStrcat(msg, BAD_CAST " equal to");
   17190     if (lessGreater == 1)
   17191 	msg = xmlStrcat(msg, BAD_CAST " greater than");
   17192     else
   17193 	msg = xmlStrcat(msg, BAD_CAST " less than");
   17194 
   17195     if (orEqual)
   17196 	msg = xmlStrcat(msg, BAD_CAST " or equal to");
   17197     msg = xmlStrcat(msg, BAD_CAST " '");
   17198     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
   17199     if (ofBase)
   17200 	msg = xmlStrcat(msg, BAD_CAST "' of the base type");
   17201     else
   17202 	msg = xmlStrcat(msg, BAD_CAST "'");
   17203 
   17204     xmlSchemaPCustomErr(pctxt,
   17205 	XML_SCHEMAP_INVALID_FACET_VALUE,
   17206 	WXS_BASIC_CAST facet1, NULL,
   17207 	(const char *) msg, NULL);
   17208 
   17209     if (msg != NULL)
   17210 	xmlFree(msg);
   17211 }
   17212 
   17213 /*
   17214 * xmlSchemaDeriveAndValidateFacets:
   17215 *
   17216 * Schema Component Constraint: Simple Type Restriction (Facets)
   17217 * (st-restrict-facets)
   17218 */
   17219 static int
   17220 xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
   17221 				 xmlSchemaTypePtr type)
   17222 {
   17223     xmlSchemaTypePtr base = type->baseType;
   17224     xmlSchemaFacetLinkPtr link, cur, last = NULL;
   17225     xmlSchemaFacetPtr facet, bfacet,
   17226 	flength = NULL, ftotdig = NULL, ffracdig = NULL,
   17227 	fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
   17228 	fmininc = NULL, fmaxinc = NULL,
   17229 	fminexc = NULL, fmaxexc = NULL,
   17230 	bflength = NULL, bftotdig = NULL, bffracdig = NULL,
   17231 	bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
   17232 	bfmininc = NULL, bfmaxinc = NULL,
   17233 	bfminexc = NULL, bfmaxexc = NULL;
   17234     int res; /* err = 0, fixedErr; */
   17235 
   17236     /*
   17237     * SPEC st-restrict-facets 1:
   17238     * "The {variety} of R is the same as that of B."
   17239     */
   17240     /*
   17241     * SPEC st-restrict-facets 2:
   17242     * "If {variety} is atomic, the {primitive type definition}
   17243     * of R is the same as that of B."
   17244     *
   17245     * NOTE: we leave 1 & 2 out for now, since this will be
   17246     * satisfied by the derivation process.
   17247     * CONSTRUCTION TODO: Maybe needed if using a construction API.
   17248     */
   17249     /*
   17250     * SPEC st-restrict-facets 3:
   17251     * "The {facets} of R are the union of S and the {facets}
   17252     * of B, eliminating duplicates. To eliminate duplicates,
   17253     * when a facet of the same kind occurs in both S and the
   17254     * {facets} of B, the one in the {facets} of B is not
   17255     * included, with the exception of enumeration and pattern
   17256     * facets, for which multiple occurrences with distinct values
   17257     * are allowed."
   17258     */
   17259 
   17260     if ((type->facetSet == NULL) && (base->facetSet == NULL))
   17261 	return (0);
   17262 
   17263     last = type->facetSet;
   17264     if (last != NULL)
   17265 	while (last->next != NULL)
   17266 	    last = last->next;
   17267 
   17268     for (cur = type->facetSet; cur != NULL; cur = cur->next) {
   17269 	facet = cur->facet;
   17270 	switch (facet->type) {
   17271 	    case XML_SCHEMA_FACET_LENGTH:
   17272 		flength = facet; break;
   17273 	    case XML_SCHEMA_FACET_MINLENGTH:
   17274 		fminlen = facet; break;
   17275 	    case XML_SCHEMA_FACET_MININCLUSIVE:
   17276 		fmininc = facet; break;
   17277 	    case XML_SCHEMA_FACET_MINEXCLUSIVE:
   17278 		fminexc = facet; break;
   17279 	    case XML_SCHEMA_FACET_MAXLENGTH:
   17280 		fmaxlen = facet; break;
   17281 	    case XML_SCHEMA_FACET_MAXINCLUSIVE:
   17282 		fmaxinc = facet; break;
   17283 	    case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   17284 		fmaxexc = facet; break;
   17285 	    case XML_SCHEMA_FACET_TOTALDIGITS:
   17286 		ftotdig = facet; break;
   17287 	    case XML_SCHEMA_FACET_FRACTIONDIGITS:
   17288 		ffracdig = facet; break;
   17289 	    default:
   17290 		break;
   17291 	}
   17292     }
   17293     for (cur = base->facetSet; cur != NULL; cur = cur->next) {
   17294 	facet = cur->facet;
   17295 	switch (facet->type) {
   17296 	    case XML_SCHEMA_FACET_LENGTH:
   17297 		bflength = facet; break;
   17298 	    case XML_SCHEMA_FACET_MINLENGTH:
   17299 		bfminlen = facet; break;
   17300 	    case XML_SCHEMA_FACET_MININCLUSIVE:
   17301 		bfmininc = facet; break;
   17302 	    case XML_SCHEMA_FACET_MINEXCLUSIVE:
   17303 		bfminexc = facet; break;
   17304 	    case XML_SCHEMA_FACET_MAXLENGTH:
   17305 		bfmaxlen = facet; break;
   17306 	    case XML_SCHEMA_FACET_MAXINCLUSIVE:
   17307 		bfmaxinc = facet; break;
   17308 	    case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   17309 		bfmaxexc = facet; break;
   17310 	    case XML_SCHEMA_FACET_TOTALDIGITS:
   17311 		bftotdig = facet; break;
   17312 	    case XML_SCHEMA_FACET_FRACTIONDIGITS:
   17313 		bffracdig = facet; break;
   17314 	    default:
   17315 		break;
   17316 	}
   17317     }
   17318     /*
   17319     * length and minLength or maxLength (2.2) + (3.2)
   17320     */
   17321     if (flength && (fminlen || fmaxlen)) {
   17322 	FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
   17323 	    "either of 'minLength' or 'maxLength' to be specified on "
   17324 	    "the same type definition")
   17325     }
   17326     /*
   17327     * Mutual exclusions in the same derivation step.
   17328     */
   17329     if ((fmaxinc) && (fmaxexc)) {
   17330 	/*
   17331 	* SCC "maxInclusive and maxExclusive"
   17332 	*/
   17333 	FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
   17334     }
   17335     if ((fmininc) && (fminexc)) {
   17336 	/*
   17337 	* SCC "minInclusive and minExclusive"
   17338 	*/
   17339 	FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
   17340     }
   17341 
   17342     if (flength && bflength) {
   17343 	/*
   17344 	* SCC "length valid restriction"
   17345 	* The values have to be equal.
   17346 	*/
   17347 	res = xmlSchemaCompareValues(flength->val, bflength->val);
   17348 	if (res == -2)
   17349 	    goto internal_error;
   17350 	if (res != 0)
   17351 	    xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
   17352 	if ((res != 0) && (bflength->fixed)) {
   17353 	    FACET_RESTR_FIXED_ERR(flength)
   17354 	}
   17355 
   17356     }
   17357     if (fminlen && bfminlen) {
   17358 	/*
   17359 	* SCC "minLength valid restriction"
   17360 	* minLength >= BASE minLength
   17361 	*/
   17362 	res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
   17363 	if (res == -2)
   17364 	    goto internal_error;
   17365 	if (res == -1)
   17366 	    xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
   17367 	if ((res != 0) && (bfminlen->fixed)) {
   17368 	    FACET_RESTR_FIXED_ERR(fminlen)
   17369 	}
   17370     }
   17371     if (fmaxlen && bfmaxlen) {
   17372 	/*
   17373 	* SCC "maxLength valid restriction"
   17374 	* maxLength <= BASE minLength
   17375 	*/
   17376 	res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
   17377 	if (res == -2)
   17378 	    goto internal_error;
   17379 	if (res == 1)
   17380 	    xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
   17381 	if ((res != 0) && (bfmaxlen->fixed)) {
   17382 	    FACET_RESTR_FIXED_ERR(fmaxlen)
   17383 	}
   17384     }
   17385     /*
   17386     * SCC "length and minLength or maxLength"
   17387     */
   17388     if (! flength)
   17389 	flength = bflength;
   17390     if (flength) {
   17391 	if (! fminlen)
   17392 	    fminlen = bfminlen;
   17393 	if (fminlen) {
   17394 	    /* (1.1) length >= minLength */
   17395 	    res = xmlSchemaCompareValues(flength->val, fminlen->val);
   17396 	    if (res == -2)
   17397 		goto internal_error;
   17398 	    if (res == -1)
   17399 		xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
   17400 	}
   17401 	if (! fmaxlen)
   17402 	    fmaxlen = bfmaxlen;
   17403 	if (fmaxlen) {
   17404 	    /* (2.1) length <= maxLength */
   17405 	    res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
   17406 	    if (res == -2)
   17407 		goto internal_error;
   17408 	    if (res == 1)
   17409 		xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
   17410 	}
   17411     }
   17412     if (fmaxinc) {
   17413 	/*
   17414 	* "maxInclusive"
   17415 	*/
   17416 	if (fmininc) {
   17417 	    /* SCC "maxInclusive >= minInclusive" */
   17418 	    res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
   17419 	    if (res == -2)
   17420 		goto internal_error;
   17421 	    if (res == -1) {
   17422 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
   17423 	    }
   17424 	}
   17425 	/*
   17426 	* SCC "maxInclusive valid restriction"
   17427 	*/
   17428 	if (bfmaxinc) {
   17429 	    /* maxInclusive <= BASE maxInclusive */
   17430 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
   17431 	    if (res == -2)
   17432 		goto internal_error;
   17433 	    if (res == 1)
   17434 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
   17435 	    if ((res != 0) && (bfmaxinc->fixed)) {
   17436 		FACET_RESTR_FIXED_ERR(fmaxinc)
   17437 	    }
   17438 	}
   17439 	if (bfmaxexc) {
   17440 	    /* maxInclusive < BASE maxExclusive */
   17441 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
   17442 	    if (res == -2)
   17443 		goto internal_error;
   17444 	    if (res != -1) {
   17445 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
   17446 	    }
   17447 	}
   17448 	if (bfmininc) {
   17449 	    /* maxInclusive >= BASE minInclusive */
   17450 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
   17451 	    if (res == -2)
   17452 		goto internal_error;
   17453 	    if (res == -1) {
   17454 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
   17455 	    }
   17456 	}
   17457 	if (bfminexc) {
   17458 	    /* maxInclusive > BASE minExclusive */
   17459 	    res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
   17460 	    if (res == -2)
   17461 		goto internal_error;
   17462 	    if (res != 1) {
   17463 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
   17464 	    }
   17465 	}
   17466     }
   17467     if (fmaxexc) {
   17468 	/*
   17469 	* "maxExclusive >= minExclusive"
   17470 	*/
   17471 	if (fminexc) {
   17472 	    res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
   17473 	    if (res == -2)
   17474 		goto internal_error;
   17475 	    if (res == -1) {
   17476 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
   17477 	    }
   17478 	}
   17479 	/*
   17480 	* "maxExclusive valid restriction"
   17481 	*/
   17482 	if (bfmaxexc) {
   17483 	    /* maxExclusive <= BASE maxExclusive */
   17484 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
   17485 	    if (res == -2)
   17486 		goto internal_error;
   17487 	    if (res == 1) {
   17488 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
   17489 	    }
   17490 	    if ((res != 0) && (bfmaxexc->fixed)) {
   17491 		FACET_RESTR_FIXED_ERR(fmaxexc)
   17492 	    }
   17493 	}
   17494 	if (bfmaxinc) {
   17495 	    /* maxExclusive <= BASE maxInclusive */
   17496 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
   17497 	    if (res == -2)
   17498 		goto internal_error;
   17499 	    if (res == 1) {
   17500 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
   17501 	    }
   17502 	}
   17503 	if (bfmininc) {
   17504 	    /* maxExclusive > BASE minInclusive */
   17505 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
   17506 	    if (res == -2)
   17507 		goto internal_error;
   17508 	    if (res != 1) {
   17509 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
   17510 	    }
   17511 	}
   17512 	if (bfminexc) {
   17513 	    /* maxExclusive > BASE minExclusive */
   17514 	    res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
   17515 	    if (res == -2)
   17516 		goto internal_error;
   17517 	    if (res != 1) {
   17518 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
   17519 	    }
   17520 	}
   17521     }
   17522     if (fminexc) {
   17523 	/*
   17524 	* "minExclusive < maxInclusive"
   17525 	*/
   17526 	if (fmaxinc) {
   17527 	    res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
   17528 	    if (res == -2)
   17529 		goto internal_error;
   17530 	    if (res != -1) {
   17531 		xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
   17532 	    }
   17533 	}
   17534 	/*
   17535 	* "minExclusive valid restriction"
   17536 	*/
   17537 	if (bfminexc) {
   17538 	    /* minExclusive >= BASE minExclusive */
   17539 	    res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
   17540 	    if (res == -2)
   17541 		goto internal_error;
   17542 	    if (res == -1) {
   17543 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
   17544 	    }
   17545 	    if ((res != 0) && (bfminexc->fixed)) {
   17546 		FACET_RESTR_FIXED_ERR(fminexc)
   17547 	    }
   17548 	}
   17549 	if (bfmaxinc) {
   17550 	    /* minExclusive <= BASE maxInclusive */
   17551 	    res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
   17552 	    if (res == -2)
   17553 		goto internal_error;
   17554 	    if (res == 1) {
   17555 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
   17556 	    }
   17557 	}
   17558 	if (bfmininc) {
   17559 	    /* minExclusive >= BASE minInclusive */
   17560 	    res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
   17561 	    if (res == -2)
   17562 		goto internal_error;
   17563 	    if (res == -1) {
   17564 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
   17565 	    }
   17566 	}
   17567 	if (bfmaxexc) {
   17568 	    /* minExclusive < BASE maxExclusive */
   17569 	    res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
   17570 	    if (res == -2)
   17571 		goto internal_error;
   17572 	    if (res != -1) {
   17573 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
   17574 	    }
   17575 	}
   17576     }
   17577     if (fmininc) {
   17578 	/*
   17579 	* "minInclusive < maxExclusive"
   17580 	*/
   17581 	if (fmaxexc) {
   17582 	    res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
   17583 	    if (res == -2)
   17584 		goto internal_error;
   17585 	    if (res != -1) {
   17586 		xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
   17587 	    }
   17588 	}
   17589 	/*
   17590 	* "minExclusive valid restriction"
   17591 	*/
   17592 	if (bfmininc) {
   17593 	    /* minInclusive >= BASE minInclusive */
   17594 	    res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
   17595 	    if (res == -2)
   17596 		goto internal_error;
   17597 	    if (res == -1) {
   17598 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
   17599 	    }
   17600 	    if ((res != 0) && (bfmininc->fixed)) {
   17601 		FACET_RESTR_FIXED_ERR(fmininc)
   17602 	    }
   17603 	}
   17604 	if (bfmaxinc) {
   17605 	    /* minInclusive <= BASE maxInclusive */
   17606 	    res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
   17607 	    if (res == -2)
   17608 		goto internal_error;
   17609 	    if (res == 1) {
   17610 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
   17611 	    }
   17612 	}
   17613 	if (bfminexc) {
   17614 	    /* minInclusive > BASE minExclusive */
   17615 	    res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
   17616 	    if (res == -2)
   17617 		goto internal_error;
   17618 	    if (res != 1)
   17619 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
   17620 	}
   17621 	if (bfmaxexc) {
   17622 	    /* minInclusive < BASE maxExclusive */
   17623 	    res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
   17624 	    if (res == -2)
   17625 		goto internal_error;
   17626 	    if (res != -1)
   17627 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
   17628 	}
   17629     }
   17630     if (ftotdig && bftotdig) {
   17631 	/*
   17632 	* SCC " totalDigits valid restriction"
   17633 	* totalDigits <= BASE totalDigits
   17634 	*/
   17635 	res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
   17636 	if (res == -2)
   17637 	    goto internal_error;
   17638 	if (res == 1)
   17639 	    xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
   17640 	    -1, 1, 1);
   17641 	if ((res != 0) && (bftotdig->fixed)) {
   17642 	    FACET_RESTR_FIXED_ERR(ftotdig)
   17643 	}
   17644     }
   17645     if (ffracdig && bffracdig) {
   17646 	/*
   17647 	* SCC  "fractionDigits valid restriction"
   17648 	* fractionDigits <= BASE fractionDigits
   17649 	*/
   17650 	res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
   17651 	if (res == -2)
   17652 	    goto internal_error;
   17653 	if (res == 1)
   17654 	    xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
   17655 	    -1, 1, 1);
   17656 	if ((res != 0) && (bffracdig->fixed)) {
   17657 	    FACET_RESTR_FIXED_ERR(ffracdig)
   17658 	}
   17659     }
   17660     /*
   17661     * SCC "fractionDigits less than or equal to totalDigits"
   17662     */
   17663     if (! ftotdig)
   17664 	ftotdig = bftotdig;
   17665     if (! ffracdig)
   17666 	ffracdig = bffracdig;
   17667     if (ftotdig && ffracdig) {
   17668 	res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
   17669 	if (res == -2)
   17670 	    goto internal_error;
   17671 	if (res == 1)
   17672 	    xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
   17673 		-1, 1, 0);
   17674     }
   17675     /*
   17676     * *Enumerations* won' be added here, since only the first set
   17677     * of enumerations in the ancestor-or-self axis is used
   17678     * for validation, plus we need to use the base type of those
   17679     * enumerations for whitespace.
   17680     *
   17681     * *Patterns*: won't be add here, since they are ORed at
   17682     * type level and ANDed at ancestor level. This will
   17683     * happed during validation by walking the base axis
   17684     * of the type.
   17685     */
   17686     for (cur = base->facetSet; cur != NULL; cur = cur->next) {
   17687 	bfacet = cur->facet;
   17688 	/*
   17689 	* Special handling of enumerations and patterns.
   17690 	* TODO: hmm, they should not appear in the set, so remove this.
   17691 	*/
   17692 	if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
   17693 	    (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
   17694 	    continue;
   17695 	/*
   17696 	* Search for a duplicate facet in the current type.
   17697 	*/
   17698 	link = type->facetSet;
   17699 	/* err = 0; */
   17700 	/* fixedErr = 0; */
   17701 	while (link != NULL) {
   17702 	    facet = link->facet;
   17703 	    if (facet->type == bfacet->type) {
   17704 		switch (facet->type) {
   17705 		    case XML_SCHEMA_FACET_WHITESPACE:
   17706 			/*
   17707 			* The whitespace must be stronger.
   17708 			*/
   17709 			if (facet->whitespace < bfacet->whitespace) {
   17710 			    FACET_RESTR_ERR(facet,
   17711 				"The 'whitespace' value has to be equal to "
   17712 				"or stronger than the 'whitespace' value of "
   17713 				"the base type")
   17714 			}
   17715 			if ((bfacet->fixed) &&
   17716 			    (facet->whitespace != bfacet->whitespace)) {
   17717 			    FACET_RESTR_FIXED_ERR(facet)
   17718 			}
   17719 			break;
   17720 		    default:
   17721 			break;
   17722 		}
   17723 		/* Duplicate found. */
   17724 		break;
   17725 	    }
   17726 	    link = link->next;
   17727 	}
   17728 	/*
   17729 	* If no duplicate was found: add the base types's facet
   17730 	* to the set.
   17731 	*/
   17732 	if (link == NULL) {
   17733 	    link = (xmlSchemaFacetLinkPtr)
   17734 		xmlMalloc(sizeof(xmlSchemaFacetLink));
   17735 	    if (link == NULL) {
   17736 		xmlSchemaPErrMemory(pctxt,
   17737 		    "deriving facets, creating a facet link", NULL);
   17738 		return (-1);
   17739 	    }
   17740 	    link->facet = cur->facet;
   17741 	    link->next = NULL;
   17742 	    if (last == NULL)
   17743 		type->facetSet = link;
   17744 	    else
   17745 		last->next = link;
   17746 	    last = link;
   17747 	}
   17748 
   17749     }
   17750 
   17751     return (0);
   17752 internal_error:
   17753     PERROR_INT("xmlSchemaDeriveAndValidateFacets",
   17754 	"an error occured");
   17755     return (-1);
   17756 }
   17757 
   17758 static int
   17759 xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
   17760 					     xmlSchemaTypePtr type)
   17761 {
   17762     xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
   17763     /*
   17764     * The actual value is then formed by replacing any union type
   17765     * definition in the `explicit members` with the members of their
   17766     * {member type definitions}, in order.
   17767     *
   17768     * TODO: There's a bug entry at
   17769     * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
   17770     * which indicates that we'll keep the union types the future.
   17771     */
   17772     link = type->memberTypes;
   17773     while (link != NULL) {
   17774 
   17775 	if (WXS_IS_TYPE_NOT_FIXED(link->type))
   17776 	    xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
   17777 
   17778 	if (WXS_IS_UNION(link->type)) {
   17779 	    subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
   17780 	    if (subLink != NULL) {
   17781 		link->type = subLink->type;
   17782 		if (subLink->next != NULL) {
   17783 		    lastLink = link->next;
   17784 		    subLink = subLink->next;
   17785 		    prevLink = link;
   17786 		    while (subLink != NULL) {
   17787 			newLink = (xmlSchemaTypeLinkPtr)
   17788 			    xmlMalloc(sizeof(xmlSchemaTypeLink));
   17789 			if (newLink == NULL) {
   17790 			    xmlSchemaPErrMemory(pctxt, "allocating a type link",
   17791 				NULL);
   17792 			    return (-1);
   17793 			}
   17794 			newLink->type = subLink->type;
   17795 			prevLink->next = newLink;
   17796 			prevLink = newLink;
   17797 			newLink->next = lastLink;
   17798 
   17799 			subLink = subLink->next;
   17800 		    }
   17801 		}
   17802 	    }
   17803 	}
   17804 	link = link->next;
   17805     }
   17806     return (0);
   17807 }
   17808 
   17809 static void
   17810 xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
   17811 {
   17812     int has = 0, needVal = 0, normVal = 0;
   17813 
   17814     has	= (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
   17815     if (has) {
   17816 	needVal = (type->baseType->flags &
   17817 	    XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
   17818 	normVal = (type->baseType->flags &
   17819 	    XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
   17820     }
   17821     if (type->facets != NULL) {
   17822 	xmlSchemaFacetPtr fac;
   17823 
   17824 	for (fac = type->facets; fac != NULL; fac = fac->next) {
   17825 	    switch (fac->type) {
   17826 		case XML_SCHEMA_FACET_WHITESPACE:
   17827 		    break;
   17828 		case XML_SCHEMA_FACET_PATTERN:
   17829 		    normVal = 1;
   17830 		    has = 1;
   17831 		    break;
   17832 		case XML_SCHEMA_FACET_ENUMERATION:
   17833 		    needVal = 1;
   17834 		    normVal = 1;
   17835 		    has = 1;
   17836 		    break;
   17837 		default:
   17838 		    has = 1;
   17839 		    break;
   17840 	    }
   17841 	}
   17842     }
   17843     if (normVal)
   17844 	type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
   17845     if (needVal)
   17846 	type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
   17847     if (has)
   17848 	type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
   17849 
   17850     if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
   17851 	xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
   17852 	/*
   17853 	* OPTIMIZE VAL TODO: Some facets need a computed value.
   17854 	*/
   17855 	if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
   17856 	    (prim->builtInType != XML_SCHEMAS_STRING)) {
   17857 	    type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
   17858 	}
   17859     }
   17860 }
   17861 
   17862 static int
   17863 xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
   17864 {
   17865 
   17866 
   17867     /*
   17868     * Evaluate the whitespace-facet value.
   17869     */
   17870     if (WXS_IS_LIST(type)) {
   17871 	type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
   17872 	return (0);
   17873     } else if (WXS_IS_UNION(type))
   17874 	return (0);
   17875 
   17876     if (type->facetSet != NULL) {
   17877 	xmlSchemaFacetLinkPtr lin;
   17878 
   17879 	for (lin = type->facetSet; lin != NULL; lin = lin->next) {
   17880 	    if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
   17881 		switch (lin->facet->whitespace) {
   17882 		case XML_SCHEMAS_FACET_PRESERVE:
   17883 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
   17884 		    break;
   17885 		case XML_SCHEMAS_FACET_REPLACE:
   17886 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
   17887 		    break;
   17888 		case XML_SCHEMAS_FACET_COLLAPSE:
   17889 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
   17890 		    break;
   17891 		default:
   17892 		    return (-1);
   17893 		}
   17894 		return (0);
   17895 	    }
   17896 	}
   17897     }
   17898     /*
   17899     * For all `atomic` datatypes other than string (and types `derived`
   17900     * by `restriction` from it) the value of whiteSpace is fixed to
   17901     * collapse
   17902     */
   17903     {
   17904 	xmlSchemaTypePtr anc;
   17905 
   17906 	for (anc = type->baseType; anc != NULL &&
   17907 		anc->builtInType != XML_SCHEMAS_ANYTYPE;
   17908 		anc = anc->baseType) {
   17909 
   17910 	    if (anc->type == XML_SCHEMA_TYPE_BASIC) {
   17911 		if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
   17912 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
   17913 
   17914 		} else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
   17915 		    (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
   17916 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
   17917 
   17918 		} else
   17919 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
   17920 		break;
   17921 	    }
   17922 	}
   17923     }
   17924     return (0);
   17925 }
   17926 
   17927 static int
   17928 xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
   17929 			  xmlSchemaTypePtr type)
   17930 {
   17931     if (type->type != XML_SCHEMA_TYPE_SIMPLE)
   17932 	return(0);
   17933     if (! WXS_IS_TYPE_NOT_FIXED_1(type))
   17934 	return(0);
   17935     type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
   17936 
   17937     if (WXS_IS_LIST(type)) {
   17938 	/*
   17939 	* Corresponds to <simpleType><list>...
   17940 	*/
   17941 	if (type->subtypes == NULL) {
   17942 	    /*
   17943 	    * This one is really needed, so get out.
   17944 	    */
   17945 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
   17946 		"list type has no item-type assigned");
   17947 	    return(-1);
   17948 	}
   17949     } else if (WXS_IS_UNION(type)) {
   17950 	/*
   17951 	* Corresponds to <simpleType><union>...
   17952 	*/
   17953 	if (type->memberTypes == NULL) {
   17954 	    /*
   17955 	    * This one is really needed, so get out.
   17956 	    */
   17957 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
   17958 		"union type has no member-types assigned");
   17959 	    return(-1);
   17960 	}
   17961     } else {
   17962 	/*
   17963 	* Corresponds to <simpleType><restriction>...
   17964 	*/
   17965 	if (type->baseType == NULL) {
   17966 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
   17967 		"type has no base-type assigned");
   17968 	    return(-1);
   17969 	}
   17970 	if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
   17971 	    if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
   17972 		return(-1);
   17973 	/*
   17974 	* Variety
   17975 	* If the <restriction> alternative is chosen, then the
   17976 	* {variety} of the {base type definition}.
   17977 	*/
   17978 	if (WXS_IS_ATOMIC(type->baseType))
   17979 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
   17980 	else if (WXS_IS_LIST(type->baseType)) {
   17981 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
   17982 	    /*
   17983 	    * Inherit the itemType.
   17984 	    */
   17985 	    type->subtypes = type->baseType->subtypes;
   17986 	} else if (WXS_IS_UNION(type->baseType)) {
   17987 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
   17988 	    /*
   17989 	    * NOTE that we won't assign the memberTypes of the base,
   17990 	    * since this will make trouble when freeing them; we will
   17991 	    * use a lookup function to access them instead.
   17992 	    */
   17993 	}
   17994     }
   17995     return(0);
   17996 }
   17997 
   17998 #ifdef DEBUG_TYPE
   17999 static void
   18000 xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
   18001 		       xmlSchemaTypePtr type)
   18002 {
   18003     if (type->node != NULL) {
   18004         xmlGenericError(xmlGenericErrorContext,
   18005                         "Type of %s : %s:%d :", name,
   18006                         type->node->doc->URL,
   18007                         xmlGetLineNo(type->node));
   18008     } else {
   18009         xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
   18010     }
   18011     if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
   18012 	switch (type->contentType) {
   18013 	    case XML_SCHEMA_CONTENT_SIMPLE:
   18014 		xmlGenericError(xmlGenericErrorContext, "simple\n");
   18015 		break;
   18016 	    case XML_SCHEMA_CONTENT_ELEMENTS:
   18017 		xmlGenericError(xmlGenericErrorContext, "elements\n");
   18018 		break;
   18019 	    case XML_SCHEMA_CONTENT_UNKNOWN:
   18020 		xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
   18021 		break;
   18022 	    case XML_SCHEMA_CONTENT_EMPTY:
   18023 		xmlGenericError(xmlGenericErrorContext, "empty\n");
   18024 		break;
   18025 	    case XML_SCHEMA_CONTENT_MIXED:
   18026 		if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
   18027 		    type->subtypes))
   18028 		    xmlGenericError(xmlGenericErrorContext,
   18029 			"mixed as emptiable particle\n");
   18030 		else
   18031 		    xmlGenericError(xmlGenericErrorContext, "mixed\n");
   18032 		break;
   18033 		/* Removed, since not used. */
   18034 		/*
   18035 		case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
   18036 		xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
   18037 		break;
   18038 		*/
   18039 	    case XML_SCHEMA_CONTENT_BASIC:
   18040 		xmlGenericError(xmlGenericErrorContext, "basic\n");
   18041 		break;
   18042 	    default:
   18043 		xmlGenericError(xmlGenericErrorContext,
   18044 		    "not registered !!!\n");
   18045 		break;
   18046 	}
   18047     }
   18048 }
   18049 #endif
   18050 
   18051 /*
   18052 * 3.14.6 Constraints on Simple Type Definition Schema Components
   18053 */
   18054 static int
   18055 xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
   18056 				 xmlSchemaTypePtr type)
   18057 {
   18058     int res, olderrs = pctxt->nberrors;
   18059 
   18060     if (type->type != XML_SCHEMA_TYPE_SIMPLE)
   18061 	return(-1);
   18062 
   18063     if (! WXS_IS_TYPE_NOT_FIXED(type))
   18064 	return(0);
   18065 
   18066     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
   18067     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   18068 
   18069     if (type->baseType == NULL) {
   18070 	PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
   18071 	    "missing baseType");
   18072 	goto exit_failure;
   18073     }
   18074     if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
   18075 	xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
   18076     /*
   18077     * If a member type of a union is a union itself, we need to substitute
   18078     * that member type for its member types.
   18079     * NOTE that this might change in WXS 1.1; i.e. we will keep the union
   18080     * types in WXS 1.1.
   18081     */
   18082     if ((type->memberTypes != NULL) &&
   18083 	(xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
   18084 	return(-1);
   18085     /*
   18086     * SPEC src-simple-type 1
   18087     * "The corresponding simple type definition, if any, must satisfy
   18088     * the conditions set out in Constraints on Simple Type Definition
   18089     * Schema Components ($3.14.6)."
   18090     */
   18091     /*
   18092     * Schema Component Constraint: Simple Type Definition Properties Correct
   18093     * (st-props-correct)
   18094     */
   18095     res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
   18096     HFAILURE HERROR
   18097     /*
   18098     * Schema Component Constraint: Derivation Valid (Restriction, Simple)
   18099     * (cos-st-restricts)
   18100     */
   18101     res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
   18102     HFAILURE HERROR
   18103     /*
   18104     * TODO: Removed the error report, since it got annoying to get an
   18105     * extra error report, if anything failed until now.
   18106     * Enable this if needed.
   18107     *
   18108     * xmlSchemaPErr(ctxt, type->node,
   18109     *    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   18110     *    "Simple type '%s' does not satisfy the constraints "
   18111     *    "on simple type definitions.\n",
   18112     *    type->name, NULL);
   18113     */
   18114     /*
   18115     * Schema Component Constraint: Simple Type Restriction (Facets)
   18116     * (st-restrict-facets)
   18117     */
   18118     res = xmlSchemaCheckFacetValues(type, pctxt);
   18119     HFAILURE HERROR
   18120     if ((type->facetSet != NULL) ||
   18121 	(type->baseType->facetSet != NULL)) {
   18122 	res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
   18123 	HFAILURE HERROR
   18124     }
   18125     /*
   18126     * Whitespace value.
   18127     */
   18128     res = xmlSchemaTypeFixupWhitespace(type);
   18129     HFAILURE HERROR
   18130     xmlSchemaTypeFixupOptimFacets(type);
   18131 
   18132 exit_error:
   18133 #ifdef DEBUG_TYPE
   18134     xmlSchemaDebugFixedType(pctxt, type);
   18135 #endif
   18136     if (olderrs != pctxt->nberrors)
   18137 	return(pctxt->err);
   18138     return(0);
   18139 
   18140 exit_failure:
   18141 #ifdef DEBUG_TYPE
   18142     xmlSchemaDebugFixedType(pctxt, type);
   18143 #endif
   18144     return(-1);
   18145 }
   18146 
   18147 static int
   18148 xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
   18149 			  xmlSchemaTypePtr type)
   18150 {
   18151     int res = 0, olderrs = pctxt->nberrors;
   18152     xmlSchemaTypePtr baseType = type->baseType;
   18153 
   18154     if (! WXS_IS_TYPE_NOT_FIXED(type))
   18155 	return(0);
   18156     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
   18157     if (baseType == NULL) {
   18158 	PERROR_INT("xmlSchemaFixupComplexType",
   18159 	    "missing baseType");
   18160 	goto exit_failure;
   18161     }
   18162     /*
   18163     * Fixup the base type.
   18164     */
   18165     if (WXS_IS_TYPE_NOT_FIXED(baseType))
   18166 	xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
   18167     if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
   18168 	/*
   18169 	* Skip fixup if the base type is invalid.
   18170 	* TODO: Generate a warning!
   18171 	*/
   18172 	return(0);
   18173     }
   18174     /*
   18175     * This basically checks if the base type can be derived.
   18176     */
   18177     res = xmlSchemaCheckSRCCT(pctxt, type);
   18178     HFAILURE HERROR
   18179     /*
   18180     * Fixup the content type.
   18181     */
   18182     if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
   18183 	/*
   18184 	* Corresponds to <complexType><simpleContent>...
   18185 	*/
   18186 	if ((WXS_IS_COMPLEX(baseType)) &&
   18187 	    (baseType->contentTypeDef != NULL) &&
   18188 	    (WXS_IS_RESTRICTION(type))) {
   18189 	    xmlSchemaTypePtr contentBase, content;
   18190 #ifdef ENABLE_NAMED_LOCALS
   18191 	    char buf[30];
   18192 	    const xmlChar *tmpname;
   18193 #endif
   18194 	    /*
   18195 	    * SPEC (1) If <restriction> + base type is <complexType>,
   18196 	    * "whose own {content type} is a simple type..."
   18197 	    */
   18198 	    if (type->contentTypeDef != NULL) {
   18199 		/*
   18200 		* SPEC (1.1) "the simple type definition corresponding to the
   18201 		* <simpleType> among the [children] of <restriction> if there
   18202 		* is one;"
   18203 		* Note that this "<simpleType> among the [children]" was put
   18204 		* into ->contentTypeDef during parsing.
   18205 		*/
   18206 		contentBase = type->contentTypeDef;
   18207 		type->contentTypeDef = NULL;
   18208 	    } else {
   18209 		/*
   18210 		* (1.2) "...otherwise (<restriction> has no <simpleType>
   18211 		* among its [children]), the simple type definition which
   18212 		* is the {content type} of the ... base type."
   18213 		*/
   18214 		contentBase = baseType->contentTypeDef;
   18215 	    }
   18216 	    /*
   18217 	    * SPEC
   18218 	    * "... a simple type definition which restricts the simple
   18219 	    * type definition identified in clause 1.1 or clause 1.2
   18220 	    * with a set of facet components"
   18221 	    *
   18222 	    * Create the anonymous simple type, which will be the content
   18223 	    * type of the complex type.
   18224 	    */
   18225 #ifdef ENABLE_NAMED_LOCALS
   18226 	    snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
   18227 	    tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
   18228 	    content = xmlSchemaAddType(pctxt, pctxt->schema,
   18229 		XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
   18230 		type->node, 0);
   18231 #else
   18232 	    content = xmlSchemaAddType(pctxt, pctxt->schema,
   18233 		XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
   18234 		type->node, 0);
   18235 #endif
   18236 	    if (content == NULL)
   18237 		goto exit_failure;
   18238 	    /*
   18239 	    * We will use the same node as for the <complexType>
   18240 	    * to have it somehow anchored in the schema doc.
   18241 	    */
   18242 	    content->type = XML_SCHEMA_TYPE_SIMPLE;
   18243 	    content->baseType = contentBase;
   18244 	    /*
   18245 	    * Move the facets, previously anchored on the
   18246 	    * complexType during parsing.
   18247 	    */
   18248 	    content->facets = type->facets;
   18249 	    type->facets = NULL;
   18250 	    content->facetSet = type->facetSet;
   18251 	    type->facetSet = NULL;
   18252 
   18253 	    type->contentTypeDef = content;
   18254 	    if (WXS_IS_TYPE_NOT_FIXED(contentBase))
   18255 		xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
   18256 	    /*
   18257 	    * Fixup the newly created type. We don't need to check
   18258 	    * for circularity here.
   18259 	    */
   18260 	    res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
   18261 	    HFAILURE HERROR
   18262 	    res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
   18263 	    HFAILURE HERROR
   18264 
   18265 	} else if ((WXS_IS_COMPLEX(baseType)) &&
   18266 	    (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
   18267 	    (WXS_IS_RESTRICTION(type))) {
   18268 	    /*
   18269 	    * SPEC (2) If <restriction> + base is a mixed <complexType> with
   18270 	    * an emptiable particle, then a simple type definition which
   18271 	    * restricts the <restriction>'s <simpleType> child.
   18272 	    */
   18273 	    if ((type->contentTypeDef == NULL) ||
   18274 		(type->contentTypeDef->baseType == NULL)) {
   18275 		/*
   18276 		* TODO: Check if this ever happens.
   18277 		*/
   18278 		xmlSchemaPCustomErr(pctxt,
   18279 		    XML_SCHEMAP_INTERNAL,
   18280 		    WXS_BASIC_CAST type, NULL,
   18281 		    "Internal error: xmlSchemaTypeFixup, "
   18282 		    "complex type '%s': the <simpleContent><restriction> "
   18283 		    "is missing a <simpleType> child, but was not catched "
   18284 		    "by xmlSchemaCheckSRCCT()", type->name);
   18285 		goto exit_failure;
   18286 	    }
   18287 	} else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
   18288 	    /*
   18289 	    * SPEC (3) If <extension> + base is <complexType> with
   18290 	    * <simpleType> content, "...then the {content type} of that
   18291 	    * complex type definition"
   18292 	    */
   18293 	    if (baseType->contentTypeDef == NULL) {
   18294 		/*
   18295 		* TODO: Check if this ever happens. xmlSchemaCheckSRCCT
   18296 		* should have catched this already.
   18297 		*/
   18298 		xmlSchemaPCustomErr(pctxt,
   18299 		    XML_SCHEMAP_INTERNAL,
   18300 		    WXS_BASIC_CAST type, NULL,
   18301 		    "Internal error: xmlSchemaTypeFixup, "
   18302 		    "complex type '%s': the <extension>ed base type is "
   18303 		    "a complex type with no simple content type",
   18304 		    type->name);
   18305 		goto exit_failure;
   18306 	    }
   18307 	    type->contentTypeDef = baseType->contentTypeDef;
   18308 	} else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
   18309 	    /*
   18310 	    * SPEC (4) <extension> + base is <simpleType>
   18311 	    * "... then that simple type definition"
   18312 	    */
   18313 	    type->contentTypeDef = baseType;
   18314 	} else {
   18315 	    /*
   18316 	    * TODO: Check if this ever happens.
   18317 	    */
   18318 	    xmlSchemaPCustomErr(pctxt,
   18319 		XML_SCHEMAP_INTERNAL,
   18320 		WXS_BASIC_CAST type, NULL,
   18321 		"Internal error: xmlSchemaTypeFixup, "
   18322 		"complex type '%s' with <simpleContent>: unhandled "
   18323 		"derivation case", type->name);
   18324 	    goto exit_failure;
   18325 	}
   18326     } else {
   18327 	int dummySequence = 0;
   18328 	xmlSchemaParticlePtr particle =
   18329 	    (xmlSchemaParticlePtr) type->subtypes;
   18330 	/*
   18331 	* Corresponds to <complexType><complexContent>...
   18332 	*
   18333 	* NOTE that the effective mixed was already set during parsing of
   18334 	* <complexType> and <complexContent>; its flag value is
   18335 	* XML_SCHEMAS_TYPE_MIXED.
   18336 	*
   18337 	* Compute the "effective content":
   18338 	* (2.1.1) + (2.1.2) + (2.1.3)
   18339 	*/
   18340 	if ((particle == NULL) ||
   18341 	    ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
   18342 	    ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
   18343 	    (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
   18344 	    ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
   18345 	    (particle->minOccurs == 0))) &&
   18346 	    ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
   18347 	    if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
   18348 		/*
   18349 		* SPEC (2.1.4) "If the `effective mixed` is true, then
   18350 		* a particle whose properties are as follows:..."
   18351 		*
   18352 		* Empty sequence model group with
   18353 		* minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
   18354 		* NOTE that we sill assign it the <complexType> node to
   18355 		* somehow anchor it in the doc.
   18356 		*/
   18357 		if ((particle == NULL) ||
   18358 		    (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
   18359 		    /*
   18360 		    * Create the particle.
   18361 		    */
   18362 		    particle = xmlSchemaAddParticle(pctxt,
   18363 			type->node, 1, 1);
   18364 		    if (particle == NULL)
   18365 			goto exit_failure;
   18366 		    /*
   18367 		    * Create the model group.
   18368 		    */ /* URGENT TODO: avoid adding to pending items. */
   18369 		    particle->children = (xmlSchemaTreeItemPtr)
   18370 			xmlSchemaAddModelGroup(pctxt, pctxt->schema,
   18371 			XML_SCHEMA_TYPE_SEQUENCE, type->node);
   18372 		    if (particle->children == NULL)
   18373 			goto exit_failure;
   18374 
   18375 		    type->subtypes = (xmlSchemaTypePtr) particle;
   18376 		}
   18377 		dummySequence = 1;
   18378 		type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
   18379 	    } else {
   18380 		/*
   18381 		* SPEC (2.1.5) "otherwise empty"
   18382 		*/
   18383 		type->contentType = XML_SCHEMA_CONTENT_EMPTY;
   18384 	    }
   18385 	} else {
   18386 	    /*
   18387 	    * SPEC (2.2) "otherwise the particle corresponding to the
   18388 	    * <all>, <choice>, <group> or <sequence> among the
   18389 	    * [children]."
   18390 	    */
   18391 	    type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
   18392 	}
   18393 	/*
   18394 	* Compute the "content type".
   18395 	*/
   18396 	if (WXS_IS_RESTRICTION(type)) {
   18397 	    /*
   18398 	    * SPEC (3.1) "If <restriction>..."
   18399 	    * (3.1.1) + (3.1.2) */
   18400 	    if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
   18401 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
   18402 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
   18403 	    }
   18404 	} else {
   18405 	    /*
   18406 	    * SPEC (3.2) "If <extension>..."
   18407 	    */
   18408 	    if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   18409 		/*
   18410 		* SPEC (3.2.1)
   18411 		* "If the `effective content` is empty, then the
   18412 		*  {content type} of the [...] base ..."
   18413 		*/
   18414 		type->contentType = baseType->contentType;
   18415 		type->subtypes = baseType->subtypes;
   18416 		/*
   18417 		* Fixes bug #347316:
   18418 		* This is the case when the base type has a simple
   18419 		* type definition as content.
   18420 		*/
   18421 		type->contentTypeDef = baseType->contentTypeDef;
   18422 		/*
   18423 		* NOTE that the effective mixed is ignored here.
   18424 		*/
   18425 	    } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   18426 		/*
   18427 		* SPEC (3.2.2)
   18428 		*/
   18429 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
   18430 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
   18431 	    } else {
   18432 		/*
   18433 		* SPEC (3.2.3)
   18434 		*/
   18435 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
   18436 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
   18437 		    /*
   18438 		    * "A model group whose {compositor} is sequence and whose
   18439 		    * {particles} are..."
   18440 		    */
   18441 		if ((WXS_TYPE_PARTICLE(type) != NULL) &&
   18442 		    (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
   18443 		    ((WXS_TYPE_PARTICLE_TERM(type))->type ==
   18444 			XML_SCHEMA_TYPE_ALL))
   18445 		{
   18446 		    /*
   18447 		    * SPEC cos-all-limited (1)
   18448 		    */
   18449 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18450 			/* TODO: error code */
   18451 			XML_SCHEMAP_COS_ALL_LIMITED,
   18452 			WXS_ITEM_NODE(type), NULL,
   18453 			"The type has an 'all' model group in its "
   18454 			"{content type} and thus cannot be derived from "
   18455 			"a non-empty type, since this would produce a "
   18456 			"'sequence' model group containing the 'all' "
   18457 			"model group; 'all' model groups are not "
   18458 			"allowed to appear inside other model groups",
   18459 			NULL, NULL);
   18460 
   18461 		} else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
   18462 		    (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
   18463 		    ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
   18464 			XML_SCHEMA_TYPE_ALL))
   18465 		{
   18466 		    /*
   18467 		    * SPEC cos-all-limited (1)
   18468 		    */
   18469 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18470 			/* TODO: error code */
   18471 			XML_SCHEMAP_COS_ALL_LIMITED,
   18472 			WXS_ITEM_NODE(type), NULL,
   18473 			"A type cannot be derived by extension from a type "
   18474 			"which has an 'all' model group in its "
   18475 			"{content type}, since this would produce a "
   18476 			"'sequence' model group containing the 'all' "
   18477 			"model group; 'all' model groups are not "
   18478 			"allowed to appear inside other model groups",
   18479 			NULL, NULL);
   18480 
   18481 		} else if (! dummySequence) {
   18482 		    xmlSchemaTreeItemPtr effectiveContent =
   18483 			(xmlSchemaTreeItemPtr) type->subtypes;
   18484 		    /*
   18485 		    * Create the particle.
   18486 		    */
   18487 		    particle = xmlSchemaAddParticle(pctxt,
   18488 			type->node, 1, 1);
   18489 		    if (particle == NULL)
   18490 			goto exit_failure;
   18491 		    /*
   18492 		    * Create the "sequence" model group.
   18493 		    */
   18494 		    particle->children = (xmlSchemaTreeItemPtr)
   18495 			xmlSchemaAddModelGroup(pctxt, pctxt->schema,
   18496 			XML_SCHEMA_TYPE_SEQUENCE, type->node);
   18497 		    if (particle->children == NULL)
   18498 			goto exit_failure;
   18499 		    WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
   18500 		    /*
   18501 		    * SPEC "the particle of the {content type} of
   18502 		    * the ... base ..."
   18503 		    * Create a duplicate of the base type's particle
   18504 		    * and assign its "term" to it.
   18505 		    */
   18506 		    particle->children->children =
   18507 			(xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
   18508 			type->node,
   18509 			((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
   18510 			((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
   18511 		    if (particle->children->children == NULL)
   18512 			goto exit_failure;
   18513 		    particle = (xmlSchemaParticlePtr)
   18514 			particle->children->children;
   18515 		    particle->children =
   18516 			((xmlSchemaParticlePtr) baseType->subtypes)->children;
   18517 		    /*
   18518 		    * SPEC "followed by the `effective content`."
   18519 		    */
   18520 		    particle->next = effectiveContent;
   18521 		    /*
   18522 		    * This all will result in:
   18523 		    * new-particle
   18524 		    *   --> new-sequence(
   18525 		    *         new-particle
   18526 		    *           --> base-model,
   18527 		    *         this-particle
   18528 		    *	        --> this-model
   18529 		    *	    )
   18530 		    */
   18531 		} else {
   18532 		    /*
   18533 		    * This is the case when there is already an empty
   18534 		    * <sequence> with minOccurs==maxOccurs==1.
   18535 		    * Just add the base types's content type.
   18536 		    * NOTE that, although we miss to add an intermediate
   18537 		    * <sequence>, this should produce no difference to
   18538 		    * neither the regex compilation of the content model,
   18539 		    * nor to the complex type contraints.
   18540 		    */
   18541 		    particle->children->children =
   18542 			(xmlSchemaTreeItemPtr) baseType->subtypes;
   18543 		}
   18544 	    }
   18545 	}
   18546     }
   18547     /*
   18548     * Now fixup attribute uses:
   18549     *   - expand attr. group references
   18550     *     - intersect attribute wildcards
   18551     *   - inherit attribute uses of the base type
   18552     *   - inherit or union attr. wildcards if extending
   18553     *   - apply attr. use prohibitions if restricting
   18554     */
   18555     res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
   18556     HFAILURE HERROR
   18557     /*
   18558     * Apply the complex type component constraints; this will not
   18559     * check attributes, since this is done in
   18560     * xmlSchemaFixupTypeAttributeUses().
   18561     */
   18562     res = xmlSchemaCheckCTComponent(pctxt, type);
   18563     HFAILURE HERROR
   18564 
   18565 #ifdef DEBUG_TYPE
   18566     xmlSchemaDebugFixedType(pctxt, type);
   18567 #endif
   18568     if (olderrs != pctxt->nberrors)
   18569 	return(pctxt->err);
   18570     else
   18571 	return(0);
   18572 
   18573 exit_error:
   18574     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
   18575 #ifdef DEBUG_TYPE
   18576     xmlSchemaDebugFixedType(pctxt, type);
   18577 #endif
   18578     return(pctxt->err);
   18579 
   18580 exit_failure:
   18581     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
   18582 #ifdef DEBUG_TYPE
   18583     xmlSchemaDebugFixedType(pctxt, type);
   18584 #endif
   18585     return(-1);
   18586 }
   18587 
   18588 
   18589 /**
   18590  * xmlSchemaTypeFixup:
   18591  * @typeDecl:  the schema type definition
   18592  * @ctxt:  the schema parser context
   18593  *
   18594  * Fixes the content model of the type.
   18595  * URGENT TODO: We need an int result!
   18596  */
   18597 static int
   18598 xmlSchemaTypeFixup(xmlSchemaTypePtr type,
   18599                    xmlSchemaAbstractCtxtPtr actxt)
   18600 {
   18601     if (type == NULL)
   18602         return(0);
   18603     if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
   18604 	AERROR_INT("xmlSchemaTypeFixup",
   18605 	    "this function needs a parser context");
   18606 	return(-1);
   18607     }
   18608     if (! WXS_IS_TYPE_NOT_FIXED(type))
   18609 	return(0);
   18610     if (type->type == XML_SCHEMA_TYPE_COMPLEX)
   18611 	return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
   18612     else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
   18613 	return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
   18614     return(0);
   18615 }
   18616 
   18617 /**
   18618  * xmlSchemaCheckFacet:
   18619  * @facet:  the facet
   18620  * @typeDecl:  the schema type definition
   18621  * @pctxt:  the schema parser context or NULL
   18622  * @name: the optional name of the type
   18623  *
   18624  * Checks and computes the values of facets.
   18625  *
   18626  * Returns 0 if valid, a positive error code if not valid and
   18627  *         -1 in case of an internal or API error.
   18628  */
   18629 int
   18630 xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
   18631                     xmlSchemaTypePtr typeDecl,
   18632                     xmlSchemaParserCtxtPtr pctxt,
   18633 		    const xmlChar * name ATTRIBUTE_UNUSED)
   18634 {
   18635     int ret = 0, ctxtGiven;
   18636 
   18637     if ((facet == NULL) || (typeDecl == NULL))
   18638         return(-1);
   18639     /*
   18640     * TODO: will the parser context be given if used from
   18641     * the relaxNG module?
   18642     */
   18643     if (pctxt == NULL)
   18644 	ctxtGiven = 0;
   18645     else
   18646 	ctxtGiven = 1;
   18647 
   18648     switch (facet->type) {
   18649         case XML_SCHEMA_FACET_MININCLUSIVE:
   18650         case XML_SCHEMA_FACET_MINEXCLUSIVE:
   18651         case XML_SCHEMA_FACET_MAXINCLUSIVE:
   18652         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   18653 	case XML_SCHEMA_FACET_ENUMERATION: {
   18654                 /*
   18655                  * Okay we need to validate the value
   18656                  * at that point.
   18657                  */
   18658 		xmlSchemaTypePtr base;
   18659 
   18660 		/* 4.3.5.5 Constraints on enumeration Schema Components
   18661 		* Schema Component Constraint: enumeration valid restriction
   18662 		* It is an `error` if any member of {value} is not in the
   18663 		* `value space` of {base type definition}.
   18664 		*
   18665 		* minInclusive, maxInclusive, minExclusive, maxExclusive:
   18666 		* The value `must` be in the
   18667 		* `value space` of the `base type`.
   18668 		*/
   18669 		/*
   18670 		* This function is intended to deliver a compiled value
   18671 		* on the facet. In this implementation of XML Schemata the
   18672 		* type holding a facet, won't be a built-in type.
   18673 		* Thus to ensure that other API
   18674 		* calls (relaxng) do work, if the given type is a built-in
   18675 		* type, we will assume that the given built-in type *is
   18676 		* already* the base type.
   18677 		*/
   18678 		if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
   18679 		    base = typeDecl->baseType;
   18680 		    if (base == NULL) {
   18681 			PERROR_INT("xmlSchemaCheckFacet",
   18682 			    "a type user derived type has no base type");
   18683 			return (-1);
   18684 		    }
   18685 		} else
   18686 		    base = typeDecl;
   18687 
   18688 		if (! ctxtGiven) {
   18689 		    /*
   18690 		    * A context is needed if called from RelaxNG.
   18691 		    */
   18692 		    pctxt = xmlSchemaNewParserCtxt("*");
   18693 		    if (pctxt == NULL)
   18694 			return (-1);
   18695 		}
   18696 		/*
   18697 		* NOTE: This call does not check the content nodes,
   18698 		* since they are not available:
   18699 		* facet->node is just the node holding the facet
   18700 		* definition, *not* the attribute holding the *value*
   18701 		* of the facet.
   18702 		*/
   18703 		ret = xmlSchemaVCheckCVCSimpleType(
   18704 		    ACTXT_CAST pctxt, facet->node, base,
   18705 		    facet->value, &(facet->val), 1, 1, 0);
   18706                 if (ret != 0) {
   18707 		    if (ret < 0) {
   18708 			/* No error message for RelaxNG. */
   18709 			if (ctxtGiven) {
   18710 			    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18711 				XML_SCHEMAP_INTERNAL, facet->node, NULL,
   18712 				"Internal error: xmlSchemaCheckFacet, "
   18713 				"failed to validate the value '%s' of the "
   18714 				"facet '%s' against the base type",
   18715 				facet->value, xmlSchemaFacetTypeToString(facet->type));
   18716 			}
   18717 			goto internal_error;
   18718 		    }
   18719 		    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
   18720 		    /* No error message for RelaxNG. */
   18721 		    if (ctxtGiven) {
   18722 			xmlChar *str = NULL;
   18723 
   18724 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18725 			    ret, facet->node, WXS_BASIC_CAST facet,
   18726 			    "The value '%s' of the facet does not validate "
   18727 			    "against the base type '%s'",
   18728 			    facet->value,
   18729 			    xmlSchemaFormatQName(&str,
   18730 				base->targetNamespace, base->name));
   18731 			FREE_AND_NULL(str);
   18732 		    }
   18733 		    goto exit;
   18734                 } else if (facet->val == NULL) {
   18735 		    if (ctxtGiven) {
   18736 			PERROR_INT("xmlSchemaCheckFacet",
   18737 			    "value was not computed");
   18738 		    }
   18739 		    TODO
   18740 		}
   18741                 break;
   18742             }
   18743         case XML_SCHEMA_FACET_PATTERN:
   18744             facet->regexp = xmlRegexpCompile(facet->value);
   18745             if (facet->regexp == NULL) {
   18746 		ret = XML_SCHEMAP_REGEXP_INVALID;
   18747 		/* No error message for RelaxNG. */
   18748 		if (ctxtGiven) {
   18749 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18750 			ret, facet->node, WXS_BASIC_CAST typeDecl,
   18751 			"The value '%s' of the facet 'pattern' is not a "
   18752 			"valid regular expression",
   18753 			facet->value, NULL);
   18754 		}
   18755             }
   18756             break;
   18757         case XML_SCHEMA_FACET_TOTALDIGITS:
   18758         case XML_SCHEMA_FACET_FRACTIONDIGITS:
   18759         case XML_SCHEMA_FACET_LENGTH:
   18760         case XML_SCHEMA_FACET_MAXLENGTH:
   18761         case XML_SCHEMA_FACET_MINLENGTH:
   18762 
   18763 	    if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
   18764 		ret = xmlSchemaValidatePredefinedType(
   18765 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
   18766 		    facet->value, &(facet->val));
   18767 	    } else {
   18768 		ret = xmlSchemaValidatePredefinedType(
   18769 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
   18770 		    facet->value, &(facet->val));
   18771 	    }
   18772 	    if (ret != 0) {
   18773 		if (ret < 0) {
   18774 		    /* No error message for RelaxNG. */
   18775 		    if (ctxtGiven) {
   18776 			PERROR_INT("xmlSchemaCheckFacet",
   18777 			    "validating facet value");
   18778 		    }
   18779 		    goto internal_error;
   18780 		}
   18781 		ret = XML_SCHEMAP_INVALID_FACET_VALUE;
   18782 		/* No error message for RelaxNG. */
   18783 		if (ctxtGiven) {
   18784 		    /* error code */
   18785 		    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   18786 			ret, facet->node, WXS_BASIC_CAST typeDecl,
   18787 			"The value '%s' of the facet '%s' is not a valid '%s'",
   18788 			facet->value,
   18789 			xmlSchemaFacetTypeToString(facet->type),
   18790 			(facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
   18791 			    BAD_CAST "nonNegativeInteger" :
   18792 			    BAD_CAST "positiveInteger",
   18793 			NULL);
   18794 		}
   18795 	    }
   18796 	    break;
   18797 
   18798         case XML_SCHEMA_FACET_WHITESPACE:{
   18799                 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
   18800                     facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
   18801                 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
   18802                     facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
   18803                 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
   18804                     facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
   18805                 } else {
   18806 		    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
   18807                     /* No error message for RelaxNG. */
   18808 		    if (ctxtGiven) {
   18809 			/* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
   18810 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18811 			    ret, facet->node, WXS_BASIC_CAST typeDecl,
   18812 			    "The value '%s' of the facet 'whitespace' is not "
   18813 			    "valid", facet->value, NULL);
   18814                     }
   18815                 }
   18816             }
   18817         default:
   18818             break;
   18819     }
   18820 exit:
   18821     if ((! ctxtGiven) && (pctxt != NULL))
   18822 	xmlSchemaFreeParserCtxt(pctxt);
   18823     return (ret);
   18824 internal_error:
   18825     if ((! ctxtGiven) && (pctxt != NULL))
   18826 	xmlSchemaFreeParserCtxt(pctxt);
   18827     return (-1);
   18828 }
   18829 
   18830 /**
   18831  * xmlSchemaCheckFacetValues:
   18832  * @typeDecl:  the schema type definition
   18833  * @ctxt:  the schema parser context
   18834  *
   18835  * Checks the default values types, especially for facets
   18836  */
   18837 static int
   18838 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
   18839 			  xmlSchemaParserCtxtPtr pctxt)
   18840 {
   18841     int res, olderrs = pctxt->nberrors;
   18842     const xmlChar *name = typeDecl->name;
   18843     /*
   18844     * NOTE: It is intended to use the facets list, instead
   18845     * of facetSet.
   18846     */
   18847     if (typeDecl->facets != NULL) {
   18848 	xmlSchemaFacetPtr facet = typeDecl->facets;
   18849 
   18850 	/*
   18851 	* Temporarily assign the "schema" to the validation context
   18852 	* of the parser context. This is needed for NOTATION validation.
   18853 	*/
   18854 	if (pctxt->vctxt == NULL) {
   18855 	    if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
   18856 		return(-1);
   18857 	}
   18858 	pctxt->vctxt->schema = pctxt->schema;
   18859 	while (facet != NULL) {
   18860 	    res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
   18861 	    HFAILURE
   18862 	    facet = facet->next;
   18863 	}
   18864 	pctxt->vctxt->schema = NULL;
   18865     }
   18866     if (olderrs != pctxt->nberrors)
   18867 	return(pctxt->err);
   18868     return(0);
   18869 exit_failure:
   18870     return(-1);
   18871 }
   18872 
   18873 /**
   18874  * xmlSchemaGetCircModelGrDefRef:
   18875  * @ctxtMGroup: the searched model group
   18876  * @selfMGroup: the second searched model group
   18877  * @particle: the first particle
   18878  *
   18879  * This one is intended to be used by
   18880  * xmlSchemaCheckGroupDefCircular only.
   18881  *
   18882  * Returns the particle with the circular model group definition reference,
   18883  * otherwise NULL.
   18884  */
   18885 static xmlSchemaTreeItemPtr
   18886 xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
   18887 			      xmlSchemaTreeItemPtr particle)
   18888 {
   18889     xmlSchemaTreeItemPtr circ = NULL;
   18890     xmlSchemaTreeItemPtr term;
   18891     xmlSchemaModelGroupDefPtr gdef;
   18892 
   18893     for (; particle != NULL; particle = particle->next) {
   18894 	term = particle->children;
   18895 	if (term == NULL)
   18896 	    continue;
   18897 	switch (term->type) {
   18898 	    case XML_SCHEMA_TYPE_GROUP:
   18899 		gdef = (xmlSchemaModelGroupDefPtr) term;
   18900 		if (gdef == groupDef)
   18901 		    return (particle);
   18902 		/*
   18903 		* Mark this model group definition to avoid infinite
   18904 		* recursion on circular references not yet examined.
   18905 		*/
   18906 		if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
   18907 		    continue;
   18908 		if (gdef->children != NULL) {
   18909 		    gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
   18910 		    circ = xmlSchemaGetCircModelGrDefRef(groupDef,
   18911 			gdef->children->children);
   18912 		    gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
   18913 		    if (circ != NULL)
   18914 			return (circ);
   18915 		}
   18916 		break;
   18917 	    case XML_SCHEMA_TYPE_SEQUENCE:
   18918 	    case XML_SCHEMA_TYPE_CHOICE:
   18919 	    case XML_SCHEMA_TYPE_ALL:
   18920 		circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
   18921 		if (circ != NULL)
   18922 		    return (circ);
   18923 		break;
   18924 	    default:
   18925 		break;
   18926 	}
   18927     }
   18928     return (NULL);
   18929 }
   18930 
   18931 /**
   18932  * xmlSchemaCheckGroupDefCircular:
   18933  * @item:  the model group definition
   18934  * @ctxt:  the parser context
   18935  * @name:  the name
   18936  *
   18937  * Checks for circular references to model group definitions.
   18938  */
   18939 static void
   18940 xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
   18941 			       xmlSchemaParserCtxtPtr ctxt)
   18942 {
   18943     /*
   18944     * Schema Component Constraint: Model Group Correct
   18945     * 2 Circular groups are disallowed. That is, within the {particles}
   18946     * of a group there must not be at any depth a particle whose {term}
   18947     * is the group itself.
   18948     */
   18949     if ((item == NULL) ||
   18950 	(item->type != XML_SCHEMA_TYPE_GROUP) ||
   18951 	(item->children == NULL))
   18952 	return;
   18953     {
   18954 	xmlSchemaTreeItemPtr circ;
   18955 
   18956 	circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
   18957 	if (circ != NULL) {
   18958 	    xmlChar *str = NULL;
   18959 	    /*
   18960 	    * TODO: The error report is not adequate: this constraint
   18961 	    * is defined for model groups but not definitions, but since
   18962 	    * there cannot be any circular model groups without a model group
   18963 	    * definition (if not using a construction API), we check those
   18964 	    * defintions only.
   18965 	    */
   18966 	    xmlSchemaPCustomErr(ctxt,
   18967 		XML_SCHEMAP_MG_PROPS_CORRECT_2,
   18968 		NULL, WXS_ITEM_NODE(circ),
   18969 		"Circular reference to the model group definition '%s' "
   18970 		"defined", xmlSchemaFormatQName(&str,
   18971 		    item->targetNamespace, item->name));
   18972 	    FREE_AND_NULL(str)
   18973 	    /*
   18974 	    * NOTE: We will cut the reference to avoid further
   18975 	    * confusion of the processor. This is a fatal error.
   18976 	    */
   18977 	    circ->children = NULL;
   18978 	}
   18979     }
   18980 }
   18981 
   18982 /**
   18983  * xmlSchemaModelGroupToModelGroupDefFixup:
   18984  * @ctxt:  the parser context
   18985  * @mg:  the model group
   18986  *
   18987  * Assigns the model group of model group definitions to the "term"
   18988  * of the referencing particle.
   18989  * In xmlSchemaResolveModelGroupParticleReferences the model group
   18990  * definitions were assigned to the "term", since needed for the
   18991  * circularity check.
   18992  *
   18993  * Schema Component Constraint:
   18994  *     All Group Limited (cos-all-limited) (1.2)
   18995  */
   18996 static void
   18997 xmlSchemaModelGroupToModelGroupDefFixup(
   18998     xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
   18999     xmlSchemaModelGroupPtr mg)
   19000 {
   19001     xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
   19002 
   19003     while (particle != NULL) {
   19004 	if ((WXS_PARTICLE_TERM(particle) == NULL) ||
   19005 	    ((WXS_PARTICLE_TERM(particle))->type !=
   19006 		XML_SCHEMA_TYPE_GROUP))
   19007 	{
   19008 	    particle = WXS_PTC_CAST particle->next;
   19009 	    continue;
   19010 	}
   19011 	if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
   19012 	    /*
   19013 	    * TODO: Remove the particle.
   19014 	    */
   19015 	    WXS_PARTICLE_TERM(particle) = NULL;
   19016 	    particle = WXS_PTC_CAST particle->next;
   19017 	    continue;
   19018 	}
   19019 	/*
   19020 	* Assign the model group to the {term} of the particle.
   19021 	*/
   19022 	WXS_PARTICLE_TERM(particle) =
   19023 	    WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
   19024 
   19025 	particle = WXS_PTC_CAST particle->next;
   19026     }
   19027 }
   19028 
   19029 /**
   19030  * xmlSchemaCheckAttrGroupCircularRecur:
   19031  * @ctxtGr: the searched attribute group
   19032  * @attr: the current attribute list to be processed
   19033  *
   19034  * This one is intended to be used by
   19035  * xmlSchemaCheckAttrGroupCircular only.
   19036  *
   19037  * Returns the circular attribute grou reference, otherwise NULL.
   19038  */
   19039 static xmlSchemaQNameRefPtr
   19040 xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
   19041 				     xmlSchemaItemListPtr list)
   19042 {
   19043     xmlSchemaAttributeGroupPtr gr;
   19044     xmlSchemaQNameRefPtr ref, circ;
   19045     int i;
   19046     /*
   19047     * We will search for an attribute group reference which
   19048     * references the context attribute group.
   19049     */
   19050     for (i = 0; i < list->nbItems; i++) {
   19051 	ref = list->items[i];
   19052 	if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
   19053 	    (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
   19054 	    (ref->item != NULL))
   19055 	{
   19056 	    gr = WXS_ATTR_GROUP_CAST ref->item;
   19057 	    if (gr == ctxtGr)
   19058 		return(ref);
   19059 	    if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
   19060 		continue;
   19061 	    /*
   19062 	    * Mark as visited to avoid infinite recursion on
   19063 	    * circular references not yet examined.
   19064 	    */
   19065 	    if ((gr->attrUses) &&
   19066 		(gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
   19067 	    {
   19068 		gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
   19069 		circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
   19070 		    (xmlSchemaItemListPtr) gr->attrUses);
   19071 		gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
   19072 		if (circ != NULL)
   19073 		    return (circ);
   19074 	    }
   19075 
   19076 	}
   19077     }
   19078     return (NULL);
   19079 }
   19080 
   19081 /**
   19082  * xmlSchemaCheckAttrGroupCircular:
   19083  * attrGr:  the attribute group definition
   19084  * @ctxt:  the parser context
   19085  * @name:  the name
   19086  *
   19087  * Checks for circular references of attribute groups.
   19088  */
   19089 static int
   19090 xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
   19091 				xmlSchemaParserCtxtPtr ctxt)
   19092 {
   19093     /*
   19094     * Schema Representation Constraint:
   19095     * Attribute Group Definition Representation OK
   19096     * 3 Circular group reference is disallowed outside <redefine>.
   19097     * That is, unless this element information item's parent is
   19098     * <redefine>, then among the [children], if any, there must
   19099     * not be an <attributeGroup> with ref [attribute] which resolves
   19100     * to the component corresponding to this <attributeGroup>. Indirect
   19101     * circularity is also ruled out. That is, when QName resolution
   19102     * (Schema Document) ($3.15.3) is applied to a `QName` arising from
   19103     * any <attributeGroup>s with a ref [attribute] among the [children],
   19104     * it must not be the case that a `QName` is encountered at any depth
   19105     * which resolves to the component corresponding to this <attributeGroup>.
   19106     */
   19107     if (attrGr->attrUses == NULL)
   19108 	return(0);
   19109     else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
   19110 	return(0);
   19111     else {
   19112 	xmlSchemaQNameRefPtr circ;
   19113 
   19114 	circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
   19115 	    (xmlSchemaItemListPtr) attrGr->attrUses);
   19116 	if (circ != NULL) {
   19117 	    xmlChar *str = NULL;
   19118 	    /*
   19119 	    * TODO: Report the referenced attr group as QName.
   19120 	    */
   19121 	    xmlSchemaPCustomErr(ctxt,
   19122 		XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
   19123 		NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
   19124 		"Circular reference to the attribute group '%s' "
   19125 		"defined", xmlSchemaGetComponentQName(&str, attrGr));
   19126 	    FREE_AND_NULL(str);
   19127 	    /*
   19128 	    * NOTE: We will cut the reference to avoid further
   19129 	    * confusion of the processor.
   19130 	    * BADSPEC TODO: The spec should define how to process in this case.
   19131 	    */
   19132 	    circ->item = NULL;
   19133 	    return(ctxt->err);
   19134 	}
   19135     }
   19136     return(0);
   19137 }
   19138 
   19139 static int
   19140 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
   19141 				  xmlSchemaAttributeGroupPtr attrGr);
   19142 
   19143 /**
   19144  * xmlSchemaExpandAttributeGroupRefs:
   19145  * @pctxt: the parser context
   19146  * @node: the node of the component holding the attribute uses
   19147  * @completeWild: the intersected wildcard to be returned
   19148  * @list: the attribute uses
   19149  *
   19150  * Substitutes contained attribute group references
   19151  * for their attribute uses. Wilcards are intersected.
   19152  * Attribute use prohibitions are removed from the list
   19153  * and returned via the @prohibs list.
   19154  * Pointlessness of attr. prohibs, if a matching attr. decl
   19155  * is existent a well, are checked.
   19156  */
   19157 static int
   19158 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
   19159 				  xmlSchemaBasicItemPtr item,
   19160 				  xmlSchemaWildcardPtr *completeWild,
   19161 				  xmlSchemaItemListPtr list,
   19162 				  xmlSchemaItemListPtr prohibs)
   19163 {
   19164     xmlSchemaAttributeGroupPtr gr;
   19165     xmlSchemaAttributeUsePtr use;
   19166     xmlSchemaItemListPtr sublist;
   19167     int i, j;
   19168     int created = (*completeWild == NULL) ? 0 : 1;
   19169 
   19170     if (prohibs)
   19171 	prohibs->nbItems = 0;
   19172 
   19173     for (i = 0; i < list->nbItems; i++) {
   19174 	use = list->items[i];
   19175 
   19176 	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
   19177 	    if (prohibs == NULL) {
   19178 		PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
   19179 		    "unexpected attr prohibition found");
   19180 		return(-1);
   19181 	    }
   19182 	    /*
   19183 	    * Remove from attribute uses.
   19184 	    */
   19185 	    if (xmlSchemaItemListRemove(list, i) == -1)
   19186 		return(-1);
   19187 	    i--;
   19188 	    /*
   19189 	    * Note that duplicate prohibitions were already
   19190 	    * handled at parsing time.
   19191 	    */
   19192 	    /*
   19193 	    * Add to list of prohibitions.
   19194 	    */
   19195 	    xmlSchemaItemListAddSize(prohibs, 2, use);
   19196 	    continue;
   19197 	}
   19198 	if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
   19199 	    ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
   19200 	{
   19201 	    if ((WXS_QNAME_CAST use)->item == NULL)
   19202 		return(-1);
   19203 	    gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
   19204 	    /*
   19205 	    * Expand the referenced attr. group.
   19206 	    * TODO: remove this, this is done in a previous step, so
   19207 	    * already done here.
   19208 	    */
   19209 	    if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
   19210 		if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
   19211 		    return(-1);
   19212 	    }
   19213 	    /*
   19214 	    * Build the 'complete' wildcard; i.e. intersect multiple
   19215 	    * wildcards.
   19216 	    */
   19217 	    if (gr->attributeWildcard != NULL) {
   19218 		if (*completeWild == NULL) {
   19219 		    *completeWild = gr->attributeWildcard;
   19220 		} else {
   19221 		    if (! created) {
   19222 			xmlSchemaWildcardPtr tmpWild;
   19223 
   19224 			 /*
   19225 			* Copy the first encountered wildcard as context,
   19226 			* except for the annotation.
   19227 			*
   19228 			* Although the complete wildcard might not correspond
   19229 			* to any node in the schema, we will anchor it on
   19230 			* the node of the owner component.
   19231 			*/
   19232 			tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
   19233 			    XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
   19234 			    WXS_ITEM_NODE(item));
   19235 			if (tmpWild == NULL)
   19236 			    return(-1);
   19237 			if (xmlSchemaCloneWildcardNsConstraints(pctxt,
   19238 			    tmpWild, *completeWild) == -1)
   19239 			    return (-1);
   19240 			tmpWild->processContents = (*completeWild)->processContents;
   19241 			*completeWild = tmpWild;
   19242 			created = 1;
   19243 		    }
   19244 
   19245 		    if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
   19246 			gr->attributeWildcard) == -1)
   19247 			return(-1);
   19248 		}
   19249 	    }
   19250 	    /*
   19251 	    * Just remove the reference if the referenced group does not
   19252 	    * contain any attribute uses.
   19253 	    */
   19254 	    sublist = ((xmlSchemaItemListPtr) gr->attrUses);
   19255 	    if ((sublist == NULL) || sublist->nbItems == 0) {
   19256 		if (xmlSchemaItemListRemove(list, i) == -1)
   19257 		    return(-1);
   19258 		i--;
   19259 		continue;
   19260 	    }
   19261 	    /*
   19262 	    * Add the attribute uses.
   19263 	    */
   19264 	    list->items[i] = sublist->items[0];
   19265 	    if (sublist->nbItems != 1) {
   19266 		for (j = 1; j < sublist->nbItems; j++) {
   19267 		    i++;
   19268 		    if (xmlSchemaItemListInsert(list,
   19269 			    sublist->items[j], i) == -1)
   19270 			return(-1);
   19271 		}
   19272 	    }
   19273 	}
   19274 
   19275     }
   19276     /*
   19277     * Handle pointless prohibitions of declared attributes.
   19278     */
   19279     if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
   19280 	xmlSchemaAttributeUseProhibPtr prohib;
   19281 
   19282 	for (i = prohibs->nbItems -1; i >= 0; i--) {
   19283 	    prohib = prohibs->items[i];
   19284 	    for (j = 0; j < list->nbItems; j++) {
   19285 		use = list->items[j];
   19286 
   19287 		if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
   19288 		    (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
   19289 		{
   19290 		    xmlChar *str = NULL;
   19291 
   19292 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   19293 			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   19294 			prohib->node, NULL,
   19295 			"Skipping pointless attribute use prohibition "
   19296 			"'%s', since a corresponding attribute use "
   19297 			"exists already in the type definition",
   19298 			xmlSchemaFormatQName(&str,
   19299 			    prohib->targetNamespace, prohib->name),
   19300 			NULL, NULL);
   19301 		    FREE_AND_NULL(str);
   19302 		    /*
   19303 		    * Remove the prohibition.
   19304 		    */
   19305 		    if (xmlSchemaItemListRemove(prohibs, i) == -1)
   19306 			return(-1);
   19307 		    break;
   19308 		}
   19309 	    }
   19310 	}
   19311     }
   19312     return(0);
   19313 }
   19314 
   19315 /**
   19316  * xmlSchemaAttributeGroupExpandRefs:
   19317  * @pctxt:  the parser context
   19318  * @attrGr:  the attribute group definition
   19319  *
   19320  * Computation of:
   19321  * {attribute uses} property
   19322  * {attribute wildcard} property
   19323  *
   19324  * Substitutes contained attribute group references
   19325  * for their attribute uses. Wilcards are intersected.
   19326  */
   19327 static int
   19328 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
   19329 				  xmlSchemaAttributeGroupPtr attrGr)
   19330 {
   19331     if ((attrGr->attrUses == NULL) ||
   19332 	(attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
   19333 	return(0);
   19334 
   19335     attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
   19336     if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
   19337 	&(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
   19338 	return(-1);
   19339     return(0);
   19340 }
   19341 
   19342 /**
   19343  * xmlSchemaAttributeGroupExpandRefs:
   19344  * @pctxt:  the parser context
   19345  * @attrGr:  the attribute group definition
   19346  *
   19347  * Substitutes contained attribute group references
   19348  * for their attribute uses. Wilcards are intersected.
   19349  *
   19350  * Schema Component Constraint:
   19351  *    Attribute Group Definition Properties Correct (ag-props-correct)
   19352  */
   19353 static int
   19354 xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
   19355 				  xmlSchemaAttributeGroupPtr attrGr)
   19356 {
   19357     /*
   19358     * SPEC ag-props-correct
   19359     * (1) "The values of the properties of an attribute group definition
   19360     * must be as described in the property tableau in The Attribute
   19361     * Group Definition Schema Component ($3.6.1), modulo the impact of
   19362     * Missing Sub-components ($5.3);"
   19363     */
   19364 
   19365     if ((attrGr->attrUses != NULL) &&
   19366 	(WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
   19367     {
   19368 	xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
   19369 	xmlSchemaAttributeUsePtr use, tmp;
   19370 	int i, j, hasId = 0;
   19371 
   19372 	for (i = uses->nbItems -1; i >= 0; i--) {
   19373 	    use = uses->items[i];
   19374 	    /*
   19375 	    * SPEC ag-props-correct
   19376 	    * (2) "Two distinct members of the {attribute uses} must not have
   19377 	    * {attribute declaration}s both of whose {name}s match and whose
   19378 	    * {target namespace}s are identical."
   19379 	    */
   19380 	    if (i > 0) {
   19381 		for (j = i -1; j >= 0; j--) {
   19382 		    tmp = uses->items[j];
   19383 		    if ((WXS_ATTRUSE_DECL_NAME(use) ==
   19384 			WXS_ATTRUSE_DECL_NAME(tmp)) &&
   19385 			(WXS_ATTRUSE_DECL_TNS(use) ==
   19386 			WXS_ATTRUSE_DECL_TNS(tmp)))
   19387 		    {
   19388 			xmlChar *str = NULL;
   19389 
   19390 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19391 			    XML_SCHEMAP_AG_PROPS_CORRECT,
   19392 			    attrGr->node, WXS_BASIC_CAST attrGr,
   19393 			    "Duplicate %s",
   19394 			    xmlSchemaGetComponentDesignation(&str, use),
   19395 			    NULL);
   19396 			FREE_AND_NULL(str);
   19397 			/*
   19398 			* Remove the duplicate.
   19399 			*/
   19400 			if (xmlSchemaItemListRemove(uses, i) == -1)
   19401 			    return(-1);
   19402 			goto next_use;
   19403 		    }
   19404 		}
   19405 	    }
   19406 	    /*
   19407 	    * SPEC ag-props-correct
   19408 	    * (3) "Two distinct members of the {attribute uses} must not have
   19409 	    * {attribute declaration}s both of whose {type definition}s are or
   19410 	    * are derived from ID."
   19411 	    * TODO: Does 'derived' include member-types of unions?
   19412 	    */
   19413 	    if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
   19414 		if (xmlSchemaIsDerivedFromBuiltInType(
   19415 		    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
   19416 		{
   19417 		    if (hasId) {
   19418 			xmlChar *str = NULL;
   19419 
   19420 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19421 			    XML_SCHEMAP_AG_PROPS_CORRECT,
   19422 			    attrGr->node, WXS_BASIC_CAST attrGr,
   19423 			    "There must not exist more than one attribute "
   19424 			    "declaration of type 'xs:ID' "
   19425 			    "(or derived from 'xs:ID'). The %s violates this "
   19426 			    "constraint",
   19427 			    xmlSchemaGetComponentDesignation(&str, use),
   19428 			    NULL);
   19429 			FREE_AND_NULL(str);
   19430 			if (xmlSchemaItemListRemove(uses, i) == -1)
   19431 			    return(-1);
   19432 		    }
   19433 		    hasId = 1;
   19434 		}
   19435 	    }
   19436 next_use: {}
   19437 	}
   19438     }
   19439     return(0);
   19440 }
   19441 
   19442 /**
   19443  * xmlSchemaResolveAttrGroupReferences:
   19444  * @attrgrpDecl:  the schema attribute definition
   19445  * @ctxt:  the schema parser context
   19446  * @name:  the attribute name
   19447  *
   19448  * Resolves references to attribute group definitions.
   19449  */
   19450 static int
   19451 xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
   19452 				    xmlSchemaParserCtxtPtr ctxt)
   19453 {
   19454     xmlSchemaAttributeGroupPtr group;
   19455 
   19456     if (ref->item != NULL)
   19457         return(0);
   19458     group = xmlSchemaGetAttributeGroup(ctxt->schema,
   19459 	ref->name,
   19460 	ref->targetNamespace);
   19461     if (group == NULL) {
   19462 	xmlSchemaPResCompAttrErr(ctxt,
   19463 	    XML_SCHEMAP_SRC_RESOLVE,
   19464 	    NULL, ref->node,
   19465 	    "ref", ref->name, ref->targetNamespace,
   19466 	    ref->itemType, NULL);
   19467 	return(ctxt->err);
   19468     }
   19469     ref->item = WXS_BASIC_CAST group;
   19470     return(0);
   19471 }
   19472 
   19473 /**
   19474  * xmlSchemaCheckAttrPropsCorrect:
   19475  * @item:  an schema attribute declaration/use
   19476  * @ctxt:  a schema parser context
   19477  * @name:  the name of the attribute
   19478  *
   19479  *
   19480  * Schema Component Constraint:
   19481  *    Attribute Declaration Properties Correct (a-props-correct)
   19482  *
   19483  * Validates the value constraints of an attribute declaration/use.
   19484  * NOTE that this needs the simle type definitions to be already
   19485  *   builded and checked.
   19486  */
   19487 static int
   19488 xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
   19489 			       xmlSchemaAttributePtr attr)
   19490 {
   19491 
   19492     /*
   19493     * SPEC a-props-correct (1)
   19494     * "The values of the properties of an attribute declaration must
   19495     * be as described in the property tableau in The Attribute
   19496     * Declaration Schema Component ($3.2.1), modulo the impact of
   19497     * Missing Sub-components ($5.3)."
   19498     */
   19499 
   19500     if (WXS_ATTR_TYPEDEF(attr) == NULL)
   19501 	return(0);
   19502 
   19503     if (attr->defValue != NULL) {
   19504 	int ret;
   19505 
   19506 	/*
   19507 	* SPEC a-props-correct (3)
   19508 	* "If the {type definition} is or is derived from ID then there
   19509 	* must not be a {value constraint}."
   19510 	*/
   19511 	if (xmlSchemaIsDerivedFromBuiltInType(
   19512 	    WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
   19513 	{
   19514 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19515 		XML_SCHEMAP_A_PROPS_CORRECT_3,
   19516 		NULL, WXS_BASIC_CAST attr,
   19517 		"Value constraints are not allowed if the type definition "
   19518 		"is or is derived from xs:ID",
   19519 		NULL, NULL);
   19520 	    return(pctxt->err);
   19521 	}
   19522 	/*
   19523 	* SPEC a-props-correct (2)
   19524 	* "if there is a {value constraint}, the canonical lexical
   19525 	* representation of its value must be `valid` with respect
   19526 	* to the {type definition} as defined in String Valid ($3.14.4)."
   19527 	* TODO: Don't care about the *canonical* stuff here, this requirement
   19528 	* will be removed in WXS 1.1 anyway.
   19529 	*/
   19530 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
   19531 	    attr->node, WXS_ATTR_TYPEDEF(attr),
   19532 	    attr->defValue, &(attr->defVal),
   19533 	    1, 1, 0);
   19534 	if (ret != 0) {
   19535 	    if (ret < 0) {
   19536 		PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
   19537 		    "calling xmlSchemaVCheckCVCSimpleType()");
   19538 		return(-1);
   19539 	    }
   19540 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19541 		XML_SCHEMAP_A_PROPS_CORRECT_2,
   19542 		NULL, WXS_BASIC_CAST attr,
   19543 		"The value of the value constraint is not valid",
   19544 		NULL, NULL);
   19545 	    return(pctxt->err);
   19546 	}
   19547     }
   19548 
   19549     return(0);
   19550 }
   19551 
   19552 static xmlSchemaElementPtr
   19553 xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
   19554 				 xmlSchemaElementPtr ancestor)
   19555 {
   19556     xmlSchemaElementPtr ret;
   19557 
   19558     if (WXS_SUBST_HEAD(ancestor) == NULL)
   19559 	return (NULL);
   19560     if (WXS_SUBST_HEAD(ancestor) == elemDecl)
   19561 	return (ancestor);
   19562 
   19563     if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
   19564 	return (NULL);
   19565     WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
   19566     ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
   19567 	WXS_SUBST_HEAD(ancestor));
   19568     WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
   19569 
   19570     return (ret);
   19571 }
   19572 
   19573 /**
   19574  * xmlSchemaCheckElemPropsCorrect:
   19575  * @ctxt:  a schema parser context
   19576  * @decl: the element declaration
   19577  * @name:  the name of the attribute
   19578  *
   19579  * Schema Component Constraint:
   19580  * Element Declaration Properties Correct (e-props-correct)
   19581  *
   19582  * STATUS:
   19583  *   missing: (6)
   19584  */
   19585 static int
   19586 xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
   19587 			       xmlSchemaElementPtr elemDecl)
   19588 {
   19589     int ret = 0;
   19590     xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
   19591     /*
   19592     * SPEC (1) "The values of the properties of an element declaration
   19593     * must be as described in the property tableau in The Element
   19594     * Declaration Schema Component ($3.3.1), modulo the impact of Missing
   19595     * Sub-components ($5.3)."
   19596     */
   19597     if (WXS_SUBST_HEAD(elemDecl) != NULL) {
   19598 	xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
   19599 
   19600 	xmlSchemaCheckElementDeclComponent(head, pctxt);
   19601 	/*
   19602 	* SPEC (3) "If there is a non-`absent` {substitution group
   19603 	* affiliation}, then {scope} must be global."
   19604 	*/
   19605 	if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
   19606 	    xmlSchemaPCustomErr(pctxt,
   19607 		XML_SCHEMAP_E_PROPS_CORRECT_3,
   19608 		WXS_BASIC_CAST elemDecl, NULL,
   19609 		"Only global element declarations can have a "
   19610 		"substitution group affiliation", NULL);
   19611 	    ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
   19612 	}
   19613 	/*
   19614 	* TODO: SPEC (6) "Circular substitution groups are disallowed.
   19615 	* That is, it must not be possible to return to an element declaration
   19616 	* by repeatedly following the {substitution group affiliation}
   19617 	* property."
   19618 	*/
   19619 	if (head == elemDecl)
   19620 	    circ = head;
   19621 	else if (WXS_SUBST_HEAD(head) != NULL)
   19622 	    circ = xmlSchemaCheckSubstGroupCircular(head, head);
   19623 	else
   19624 	    circ = NULL;
   19625 	if (circ != NULL) {
   19626 	    xmlChar *strA = NULL, *strB = NULL;
   19627 
   19628 	    xmlSchemaPCustomErrExt(pctxt,
   19629 		XML_SCHEMAP_E_PROPS_CORRECT_6,
   19630 		WXS_BASIC_CAST circ, NULL,
   19631 		"The element declaration '%s' defines a circular "
   19632 		"substitution group to element declaration '%s'",
   19633 		xmlSchemaGetComponentQName(&strA, circ),
   19634 		xmlSchemaGetComponentQName(&strB, head),
   19635 		NULL);
   19636 	    FREE_AND_NULL(strA)
   19637 	    FREE_AND_NULL(strB)
   19638 	    ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
   19639 	}
   19640 	/*
   19641 	* SPEC (4) "If there is a {substitution group affiliation},
   19642 	* the {type definition}
   19643 	* of the element declaration must be validly derived from the {type
   19644 	* definition} of the {substitution group affiliation}, given the value
   19645 	* of the {substitution group exclusions} of the {substitution group
   19646 	* affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
   19647 	* (if the {type definition} is complex) or as defined in
   19648 	* Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
   19649 	* simple)."
   19650 	*
   19651 	* NOTE: {substitution group exclusions} means the values of the
   19652 	* attribute "final".
   19653 	*/
   19654 
   19655 	if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
   19656 	    int set = 0;
   19657 
   19658 	    if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
   19659 		set |= SUBSET_EXTENSION;
   19660 	    if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
   19661 		set |= SUBSET_RESTRICTION;
   19662 
   19663 	    if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
   19664 		WXS_ELEM_TYPEDEF(head), set) != 0) {
   19665 		xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
   19666 
   19667 		ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
   19668 		xmlSchemaPCustomErrExt(pctxt,
   19669 		    XML_SCHEMAP_E_PROPS_CORRECT_4,
   19670 		    WXS_BASIC_CAST elemDecl, NULL,
   19671 		    "The type definition '%s' was "
   19672 		    "either rejected by the substitution group "
   19673 		    "affiliation '%s', or not validly derived from its type "
   19674 		    "definition '%s'",
   19675 		    xmlSchemaGetComponentQName(&strA, typeDef),
   19676 		    xmlSchemaGetComponentQName(&strB, head),
   19677 		    xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
   19678 		FREE_AND_NULL(strA)
   19679 		FREE_AND_NULL(strB)
   19680 		FREE_AND_NULL(strC)
   19681 	    }
   19682 	}
   19683     }
   19684     /*
   19685     * SPEC (5) "If the {type definition} or {type definition}'s
   19686     * {content type}
   19687     * is or is derived from ID then there must not be a {value constraint}.
   19688     * Note: The use of ID as a type definition for elements goes beyond
   19689     * XML 1.0, and should be avoided if backwards compatibility is desired"
   19690     */
   19691     if ((elemDecl->value != NULL) &&
   19692 	((WXS_IS_SIMPLE(typeDef) &&
   19693 	  xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
   19694 	 (WXS_IS_COMPLEX(typeDef) &&
   19695 	  WXS_HAS_SIMPLE_CONTENT(typeDef) &&
   19696 	  xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
   19697 	    XML_SCHEMAS_ID)))) {
   19698 
   19699 	ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
   19700 	xmlSchemaPCustomErr(pctxt,
   19701 	    XML_SCHEMAP_E_PROPS_CORRECT_5,
   19702 	    WXS_BASIC_CAST elemDecl, NULL,
   19703 	    "The type definition (or type definition's content type) is or "
   19704 	    "is derived from ID; value constraints are not allowed in "
   19705 	    "conjunction with such a type definition", NULL);
   19706     } else if (elemDecl->value != NULL) {
   19707 	int vcret;
   19708 	xmlNodePtr node = NULL;
   19709 
   19710 	/*
   19711 	* SPEC (2) "If there is a {value constraint}, the canonical lexical
   19712 	* representation of its value must be `valid` with respect to the
   19713 	* {type definition} as defined in Element Default Valid (Immediate)
   19714 	* ($3.3.6)."
   19715 	*/
   19716 	if (typeDef == NULL) {
   19717 	    xmlSchemaPErr(pctxt, elemDecl->node,
   19718 		XML_SCHEMAP_INTERNAL,
   19719 		"Internal error: xmlSchemaCheckElemPropsCorrect, "
   19720 		"type is missing... skipping validation of "
   19721 		"the value constraint", NULL, NULL);
   19722 	    return (-1);
   19723 	}
   19724 	if (elemDecl->node != NULL) {
   19725 	    if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
   19726 		node = (xmlNodePtr) xmlHasProp(elemDecl->node,
   19727 		    BAD_CAST "fixed");
   19728 	    else
   19729 		node = (xmlNodePtr) xmlHasProp(elemDecl->node,
   19730 		    BAD_CAST "default");
   19731 	}
   19732 	vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
   19733 	    typeDef, elemDecl->value, &(elemDecl->defVal));
   19734 	if (vcret != 0) {
   19735 	    if (vcret < 0) {
   19736 		PERROR_INT("xmlSchemaElemCheckValConstr",
   19737 		    "failed to validate the value constraint of an "
   19738 		    "element declaration");
   19739 		return (-1);
   19740 	    }
   19741 	    return (vcret);
   19742 	}
   19743     }
   19744 
   19745     return (ret);
   19746 }
   19747 
   19748 /**
   19749  * xmlSchemaCheckElemSubstGroup:
   19750  * @ctxt:  a schema parser context
   19751  * @decl: the element declaration
   19752  * @name:  the name of the attribute
   19753  *
   19754  * Schema Component Constraint:
   19755  * Substitution Group (cos-equiv-class)
   19756  *
   19757  * In Libxml2 the subst. groups will be precomputed, in terms of that
   19758  * a list will be built for each subst. group head, holding all direct
   19759  * referents to this head.
   19760  * NOTE that this function needs:
   19761  *   1. circular subst. groups to be checked beforehand
   19762  *   2. the declaration's type to be derived from the head's type
   19763  *
   19764  * STATUS:
   19765  *
   19766  */
   19767 static void
   19768 xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
   19769 			     xmlSchemaElementPtr elemDecl)
   19770 {
   19771     if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
   19772 	/* SPEC (1) "Its {abstract} is false." */
   19773 	(elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
   19774 	return;
   19775     {
   19776 	xmlSchemaElementPtr head;
   19777 	xmlSchemaTypePtr headType, type;
   19778 	int set, methSet;
   19779 	/*
   19780 	* SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
   19781 	* {disallowed substitutions} as the blocking constraint, as defined in
   19782 	* Substitution Group OK (Transitive) ($3.3.6)."
   19783 	*/
   19784 	for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
   19785 	    head = WXS_SUBST_HEAD(head)) {
   19786 	    set = 0;
   19787 	    methSet = 0;
   19788 	    /*
   19789 	    * The blocking constraints.
   19790 	    */
   19791 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
   19792 		continue;
   19793 	    headType = head->subtypes;
   19794 	    type = elemDecl->subtypes;
   19795 	    if (headType == type)
   19796 		goto add_member;
   19797 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
   19798 		set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
   19799 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
   19800 		set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
   19801 	    /*
   19802 	    * SPEC: Substitution Group OK (Transitive) (2.3)
   19803 	    * "The set of all {derivation method}s involved in the
   19804 	    * derivation of D's {type definition} from C's {type definition}
   19805 	    * does not intersect with the union of the blocking constraint,
   19806 	    * C's {prohibited substitutions} (if C is complex, otherwise the
   19807 	    * empty set) and the {prohibited substitutions} (respectively the
   19808 	    * empty set) of any intermediate {type definition}s in the
   19809 	    * derivation of D's {type definition} from C's {type definition}."
   19810 	    */
   19811 	    /*
   19812 	    * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
   19813 	    * subst.head axis, the methSet does not need to be computed for
   19814 	    * the full depth over and over.
   19815 	    */
   19816 	    /*
   19817 	    * The set of all {derivation method}s involved in the derivation
   19818 	    */
   19819 	    while ((type != NULL) && (type != headType)) {
   19820 		if ((WXS_IS_EXTENSION(type)) &&
   19821 		    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
   19822 		    methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
   19823 
   19824 		if (WXS_IS_RESTRICTION(type) &&
   19825 		    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
   19826 		    methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
   19827 
   19828 		type = type->baseType;
   19829 	    }
   19830 	    /*
   19831 	    * The {prohibited substitutions} of all intermediate types +
   19832 	    * the head's type.
   19833 	    */
   19834 	    type = elemDecl->subtypes->baseType;
   19835 	    while (type != NULL) {
   19836 		if (WXS_IS_COMPLEX(type)) {
   19837 		    if ((type->flags &
   19838 			    XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
   19839 			((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
   19840 		    set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
   19841 		    if ((type->flags &
   19842 			    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
   19843 			((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
   19844 		    set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
   19845 		} else
   19846 		    break;
   19847 		if (type == headType)
   19848 		    break;
   19849 		type = type->baseType;
   19850 	    }
   19851 	    if ((set != 0) &&
   19852 		(((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
   19853 		(methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
   19854 		((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
   19855 		(methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
   19856 		continue;
   19857 	    }
   19858 add_member:
   19859 	    xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
   19860 	    if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
   19861 		head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
   19862 	}
   19863     }
   19864 }
   19865 
   19866 #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
   19867 /**
   19868  * xmlSchemaCheckElementDeclComponent
   19869  * @pctxt: the schema parser context
   19870  * @ctxtComponent: the context component (an element declaration)
   19871  * @ctxtParticle: the first particle of the context component
   19872  * @searchParticle: the element declaration particle to be analysed
   19873  *
   19874  * Schema Component Constraint: Element Declarations Consistent
   19875  */
   19876 static int
   19877 xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
   19878 				    xmlSchemaBasicItemPtr ctxtComponent,
   19879 				    xmlSchemaParticlePtr ctxtParticle,
   19880 				    xmlSchemaParticlePtr searchParticle,
   19881 				    xmlSchemaParticlePtr curParticle,
   19882 				    int search)
   19883 {
   19884     return(0);
   19885 
   19886     int ret = 0;
   19887     xmlSchemaParticlePtr cur = curParticle;
   19888     if (curParticle == NULL) {
   19889 	return(0);
   19890     }
   19891     if (WXS_PARTICLE_TERM(curParticle) == NULL) {
   19892 	/*
   19893 	* Just return in this case. A missing "term" of the particle
   19894 	* might arise due to an invalid "term" component.
   19895 	*/
   19896 	return(0);
   19897     }
   19898     while (cur != NULL) {
   19899 	switch (WXS_PARTICLE_TERM(cur)->type) {
   19900 	    case XML_SCHEMA_TYPE_ANY:
   19901 		break;
   19902 	    case XML_SCHEMA_TYPE_ELEMENT:
   19903 		if (search == 0) {
   19904 		    ret = xmlSchemaCheckElementDeclConsistent(pctxt,
   19905 			ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
   19906 		    if (ret != 0)
   19907 			return(ret);
   19908 		} else {
   19909 		    xmlSchemaElementPtr elem =
   19910 			WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
   19911 		    /*
   19912 		    * SPEC Element Declarations Consistent:
   19913 		    * "If the {particles} contains, either directly,
   19914 		    * indirectly (that is, within the {particles} of a
   19915 		    * contained model group, recursively) or `implicitly`
   19916 		    * two or more element declaration particles with
   19917 		    * the same {name} and {target namespace}, then
   19918 		    * all their type definitions must be the same
   19919 		    * top-level definition [...]"
   19920 		    */
   19921 		    if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
   19922 			    WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
   19923 			xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
   19924 			    WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
   19925 		    {
   19926 			xmlChar *strA = NULL, *strB = NULL;
   19927 
   19928 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19929 			    /* TODO: error code */
   19930 			    XML_SCHEMAP_COS_NONAMBIG,
   19931 			    WXS_ITEM_NODE(cur), NULL,
   19932 			    "In the content model of %s, there are multiple "
   19933 			    "element declarations for '%s' with different "
   19934 			    "type definitions",
   19935 			    xmlSchemaGetComponentDesignation(&strA,
   19936 				ctxtComponent),
   19937 			    xmlSchemaFormatQName(&strB,
   19938 				WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
   19939 				WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
   19940 			FREE_AND_NULL(strA);
   19941 			FREE_AND_NULL(strB);
   19942 			return(XML_SCHEMAP_COS_NONAMBIG);
   19943 		    }
   19944 		}
   19945 		break;
   19946 	    case XML_SCHEMA_TYPE_SEQUENCE: {
   19947 		break;
   19948 		}
   19949 	    case XML_SCHEMA_TYPE_CHOICE:{
   19950 		/*
   19951 		xmlSchemaTreeItemPtr sub;
   19952 
   19953 		sub = WXS_PARTICLE_TERM(particle)->children;  (xmlSchemaParticlePtr)
   19954 		while (sub != NULL) {
   19955 		    ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
   19956 			ctxtParticle, ctxtElem);
   19957 		    if (ret != 0)
   19958 			return(ret);
   19959 		    sub = sub->next;
   19960 		}
   19961 		*/
   19962 		break;
   19963 		}
   19964 	    case XML_SCHEMA_TYPE_ALL:
   19965 		break;
   19966 	    case XML_SCHEMA_TYPE_GROUP:
   19967 		break;
   19968 	    default:
   19969 		xmlSchemaInternalErr2(ACTXT_CAST pctxt,
   19970 		    "xmlSchemaCheckElementDeclConsistent",
   19971 		    "found unexpected term of type '%s' in content model",
   19972 		    WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
   19973 		return(-1);
   19974 	}
   19975 	cur = (xmlSchemaParticlePtr) cur->next;
   19976     }
   19977 
   19978 exit:
   19979     return(ret);
   19980 }
   19981 #endif
   19982 
   19983 /**
   19984  * xmlSchemaCheckElementDeclComponent
   19985  * @item:  an schema element declaration/particle
   19986  * @ctxt:  a schema parser context
   19987  * @name:  the name of the attribute
   19988  *
   19989  * Validates the value constraints of an element declaration.
   19990  * Adds substitution group members.
   19991  */
   19992 static void
   19993 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
   19994 				   xmlSchemaParserCtxtPtr ctxt)
   19995 {
   19996     if (elemDecl == NULL)
   19997 	return;
   19998     if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
   19999 	return;
   20000     elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
   20001     if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
   20002 	/*
   20003 	* Adds substitution group members.
   20004 	*/
   20005 	xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
   20006     }
   20007 }
   20008 
   20009 /**
   20010  * xmlSchemaResolveModelGroupParticleReferences:
   20011  * @particle:  a particle component
   20012  * @ctxt:  a parser context
   20013  *
   20014  * Resolves references of a model group's {particles} to
   20015  * model group definitions and to element declarations.
   20016  */
   20017 static void
   20018 xmlSchemaResolveModelGroupParticleReferences(
   20019     xmlSchemaParserCtxtPtr ctxt,
   20020     xmlSchemaModelGroupPtr mg)
   20021 {
   20022     xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
   20023     xmlSchemaQNameRefPtr ref;
   20024     xmlSchemaBasicItemPtr refItem;
   20025 
   20026     /*
   20027     * URGENT TODO: Test this.
   20028     */
   20029     while (particle != NULL) {
   20030 	if ((WXS_PARTICLE_TERM(particle) == NULL) ||
   20031 	    ((WXS_PARTICLE_TERM(particle))->type !=
   20032 		XML_SCHEMA_EXTRA_QNAMEREF))
   20033 	{
   20034 	    goto next_particle;
   20035 	}
   20036 	ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
   20037 	/*
   20038 	* Resolve the reference.
   20039 	* NULL the {term} by default.
   20040 	*/
   20041 	particle->children = NULL;
   20042 
   20043 	refItem = xmlSchemaGetNamedComponent(ctxt->schema,
   20044 	    ref->itemType, ref->name, ref->targetNamespace);
   20045 	if (refItem == NULL) {
   20046 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
   20047 		NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
   20048 		ref->targetNamespace, ref->itemType, NULL);
   20049 	    /* TODO: remove the particle. */
   20050 	    goto next_particle;
   20051 	}
   20052 	if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
   20053 	    if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
   20054 		/* TODO: remove the particle. */
   20055 		goto next_particle;
   20056 	    /*
   20057 	    * NOTE that we will assign the model group definition
   20058 	    * itself to the "term" of the particle. This will ease
   20059 	    * the check for circular model group definitions. After
   20060 	    * that the "term" will be assigned the model group of the
   20061 	    * model group definition.
   20062 	    */
   20063 	    if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
   20064 		    XML_SCHEMA_TYPE_ALL) {
   20065 		/*
   20066 		* SPEC cos-all-limited (1)
   20067 		* SPEC cos-all-limited (1.2)
   20068 		* "It appears only as the value of one or both of the
   20069 		* following properties:"
   20070 		* (1.1) "the {model group} property of a model group
   20071 		*        definition."
   20072 		* (1.2) "the {term} property of a particle [... of] the "
   20073 		* {content type} of a complex type definition."
   20074 		*/
   20075 		xmlSchemaCustomErr(ACTXT_CAST ctxt,
   20076 		    /* TODO: error code */
   20077 		    XML_SCHEMAP_COS_ALL_LIMITED,
   20078 		    WXS_ITEM_NODE(particle), NULL,
   20079 		    "A model group definition is referenced, but "
   20080 		    "it contains an 'all' model group, which "
   20081 		    "cannot be contained by model groups",
   20082 		    NULL, NULL);
   20083 		/* TODO: remove the particle. */
   20084 		goto next_particle;
   20085 	    }
   20086 	    particle->children = (xmlSchemaTreeItemPtr) refItem;
   20087 	} else {
   20088 	    /*
   20089 	    * TODO: Are referenced element declarations the only
   20090 	    * other components we expect here?
   20091 	    */
   20092 	    particle->children = (xmlSchemaTreeItemPtr) refItem;
   20093 	}
   20094 next_particle:
   20095 	particle = WXS_PTC_CAST particle->next;
   20096     }
   20097 }
   20098 
   20099 static int
   20100 xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
   20101 		       xmlSchemaValPtr y)
   20102 {
   20103     xmlSchemaTypePtr tx, ty, ptx, pty;
   20104     int ret;
   20105 
   20106     while (x != NULL) {
   20107 	/* Same types. */
   20108 	tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
   20109 	ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
   20110 	ptx = xmlSchemaGetPrimitiveType(tx);
   20111 	pty = xmlSchemaGetPrimitiveType(ty);
   20112 	/*
   20113 	* (1) if a datatype T' is `derived` by `restriction` from an
   20114 	* atomic datatype T then the `value space` of T' is a subset of
   20115 	* the `value space` of T. */
   20116 	/*
   20117 	* (2) if datatypes T' and T'' are `derived` by `restriction`
   20118 	* from a common atomic ancestor T then the `value space`s of T'
   20119 	* and T'' may overlap.
   20120 	*/
   20121 	if (ptx != pty)
   20122 	    return(0);
   20123 	/*
   20124 	* We assume computed values to be normalized, so do a fast
   20125 	* string comparison for string based types.
   20126 	*/
   20127 	if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
   20128 	    WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
   20129 	    if (! xmlStrEqual(
   20130 		xmlSchemaValueGetAsString(x),
   20131 		xmlSchemaValueGetAsString(y)))
   20132 		return (0);
   20133 	} else {
   20134 	    ret = xmlSchemaCompareValuesWhtsp(
   20135 		x, XML_SCHEMA_WHITESPACE_PRESERVE,
   20136 		y, XML_SCHEMA_WHITESPACE_PRESERVE);
   20137 	    if (ret == -2)
   20138 		return(-1);
   20139 	    if (ret != 0)
   20140 		return(0);
   20141 	}
   20142 	/*
   20143 	* Lists.
   20144 	*/
   20145 	x = xmlSchemaValueGetNext(x);
   20146 	if (x != NULL) {
   20147 	    y = xmlSchemaValueGetNext(y);
   20148 	    if (y == NULL)
   20149 		return (0);
   20150 	} else if (xmlSchemaValueGetNext(y) != NULL)
   20151 	    return (0);
   20152 	else
   20153 	    return (1);
   20154     }
   20155     return (0);
   20156 }
   20157 
   20158 /**
   20159  * xmlSchemaResolveAttrUseReferences:
   20160  * @item:  an attribute use
   20161  * @ctxt:  a parser context
   20162  *
   20163  * Resolves the referenced attribute declaration.
   20164  */
   20165 static int
   20166 xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
   20167 				  xmlSchemaParserCtxtPtr ctxt)
   20168 {
   20169     if ((ctxt == NULL) || (ause == NULL))
   20170 	return(-1);
   20171     if ((ause->attrDecl == NULL) ||
   20172 	(ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
   20173 	return(0);
   20174 
   20175     {
   20176 	xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
   20177 
   20178 	/*
   20179 	* TODO: Evaluate, what errors could occur if the declaration is not
   20180 	* found.
   20181 	*/
   20182 	ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
   20183 	    ref->name, ref->targetNamespace);
   20184         if (ause->attrDecl == NULL) {
   20185 	    xmlSchemaPResCompAttrErr(ctxt,
   20186 		XML_SCHEMAP_SRC_RESOLVE,
   20187 		WXS_BASIC_CAST ause, ause->node,
   20188 		"ref", ref->name, ref->targetNamespace,
   20189 		XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
   20190             return(ctxt->err);;
   20191         }
   20192     }
   20193     return(0);
   20194 }
   20195 
   20196 /**
   20197  * xmlSchemaCheckAttrUsePropsCorrect:
   20198  * @ctxt:  a parser context
   20199  * @use:  an attribute use
   20200  *
   20201  * Schema Component Constraint:
   20202  * Attribute Use Correct (au-props-correct)
   20203  *
   20204  */
   20205 static int
   20206 xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
   20207 			     xmlSchemaAttributeUsePtr use)
   20208 {
   20209     if ((ctxt == NULL) || (use == NULL))
   20210 	return(-1);
   20211     if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
   20212 	((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
   20213 	return(0);
   20214 
   20215     /*
   20216     * SPEC au-props-correct (1)
   20217     * "The values of the properties of an attribute use must be as
   20218     * described in the property tableau in The Attribute Use Schema
   20219     * Component ($3.5.1), modulo the impact of Missing
   20220     * Sub-components ($5.3)."
   20221     */
   20222 
   20223     if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
   20224 	((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
   20225         ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
   20226     {
   20227 	xmlSchemaPCustomErr(ctxt,
   20228 	    XML_SCHEMAP_AU_PROPS_CORRECT_2,
   20229 	    WXS_BASIC_CAST use, NULL,
   20230 	    "The attribute declaration has a 'fixed' value constraint "
   20231 	    ", thus the attribute use must also have a 'fixed' value "
   20232 	    "constraint",
   20233 	    NULL);
   20234 	return(ctxt->err);
   20235     }
   20236     /*
   20237     * Compute and check the value constraint's value.
   20238     */
   20239     if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
   20240 	int ret;
   20241 	/*
   20242 	* TODO: The spec seems to be missing a check of the
   20243 	* value constraint of the attribute use. We will do it here.
   20244 	*/
   20245 	/*
   20246 	* SPEC a-props-correct (3)
   20247 	*/
   20248 	if (xmlSchemaIsDerivedFromBuiltInType(
   20249 	    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
   20250 	{
   20251 	    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   20252 		XML_SCHEMAP_AU_PROPS_CORRECT,
   20253 		NULL, WXS_BASIC_CAST use,
   20254 		"Value constraints are not allowed if the type definition "
   20255 		"is or is derived from xs:ID",
   20256 		NULL, NULL);
   20257 	    return(ctxt->err);
   20258 	}
   20259 
   20260 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
   20261 	    use->node, WXS_ATTRUSE_TYPEDEF(use),
   20262 	    use->defValue, &(use->defVal),
   20263 	    1, 1, 0);
   20264 	if (ret != 0) {
   20265 	    if (ret < 0) {
   20266 		PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
   20267 		    "calling xmlSchemaVCheckCVCSimpleType()");
   20268 		return(-1);
   20269 	    }
   20270 	    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   20271 		XML_SCHEMAP_AU_PROPS_CORRECT,
   20272 		NULL, WXS_BASIC_CAST use,
   20273 		"The value of the value constraint is not valid",
   20274 		NULL, NULL);
   20275 	    return(ctxt->err);
   20276 	}
   20277     }
   20278     /*
   20279     * SPEC au-props-correct (2)
   20280     * "If the {attribute declaration} has a fixed
   20281     * {value constraint}, then if the attribute use itself has a
   20282     * {value constraint}, it must also be fixed and its value must match
   20283     * that of the {attribute declaration}'s {value constraint}."
   20284     */
   20285     if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
   20286 	(((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
   20287     {
   20288 	if (! xmlSchemaAreValuesEqual(use->defVal,
   20289 		(WXS_ATTRUSE_DECL(use))->defVal))
   20290 	{
   20291 	    xmlSchemaPCustomErr(ctxt,
   20292 		XML_SCHEMAP_AU_PROPS_CORRECT_2,
   20293 		WXS_BASIC_CAST use, NULL,
   20294 		"The 'fixed' value constraint of the attribute use "
   20295 		"must match the attribute declaration's value "
   20296 		"constraint '%s'",
   20297 		(WXS_ATTRUSE_DECL(use))->defValue);
   20298 	}
   20299 	return(ctxt->err);
   20300     }
   20301     return(0);
   20302 }
   20303 
   20304 
   20305 
   20306 
   20307 /**
   20308  * xmlSchemaResolveAttrTypeReferences:
   20309  * @item:  an attribute declaration
   20310  * @ctxt:  a parser context
   20311  *
   20312  * Resolves the referenced type definition component.
   20313  */
   20314 static int
   20315 xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
   20316 				   xmlSchemaParserCtxtPtr ctxt)
   20317 {
   20318     /*
   20319     * The simple type definition corresponding to the <simpleType> element
   20320     * information item in the [children], if present, otherwise the simple
   20321     * type definition `resolved` to by the `actual value` of the type
   20322     * [attribute], if present, otherwise the `simple ur-type definition`.
   20323     */
   20324     if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
   20325 	return(0);
   20326     item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
   20327     if (item->subtypes != NULL)
   20328         return(0);
   20329     if (item->typeName != NULL) {
   20330         xmlSchemaTypePtr type;
   20331 
   20332 	type = xmlSchemaGetType(ctxt->schema, item->typeName,
   20333 	    item->typeNs);
   20334 	if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
   20335 	    xmlSchemaPResCompAttrErr(ctxt,
   20336 		XML_SCHEMAP_SRC_RESOLVE,
   20337 		WXS_BASIC_CAST item, item->node,
   20338 		"type", item->typeName, item->typeNs,
   20339 		XML_SCHEMA_TYPE_SIMPLE, NULL);
   20340 	    return(ctxt->err);
   20341 	} else
   20342 	    item->subtypes = type;
   20343 
   20344     } else {
   20345 	/*
   20346 	* The type defaults to the xs:anySimpleType.
   20347 	*/
   20348 	item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
   20349     }
   20350     return(0);
   20351 }
   20352 
   20353 /**
   20354  * xmlSchemaResolveIDCKeyReferences:
   20355  * @idc:  the identity-constraint definition
   20356  * @ctxt:  the schema parser context
   20357  * @name:  the attribute name
   20358  *
   20359  * Resolve keyRef references to key/unique IDCs.
   20360  * Schema Component Constraint:
   20361  *   Identity-constraint Definition Properties Correct (c-props-correct)
   20362  */
   20363 static int
   20364 xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
   20365 			  xmlSchemaParserCtxtPtr pctxt)
   20366 {
   20367     if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
   20368         return(0);
   20369     if (idc->ref->name != NULL) {
   20370 	idc->ref->item = (xmlSchemaBasicItemPtr)
   20371 	    xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
   20372 		idc->ref->targetNamespace);
   20373         if (idc->ref->item == NULL) {
   20374 	    /*
   20375 	    * TODO: It is actually not an error to fail to resolve
   20376 	    * at this stage. BUT we need to be that strict!
   20377 	    */
   20378 	    xmlSchemaPResCompAttrErr(pctxt,
   20379 		XML_SCHEMAP_SRC_RESOLVE,
   20380 		WXS_BASIC_CAST idc, idc->node,
   20381 		"refer", idc->ref->name,
   20382 		idc->ref->targetNamespace,
   20383 		XML_SCHEMA_TYPE_IDC_KEY, NULL);
   20384             return(pctxt->err);
   20385 	} else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
   20386 	    /*
   20387 	    * SPEC c-props-correct (1)
   20388 	    */
   20389 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20390 		XML_SCHEMAP_C_PROPS_CORRECT,
   20391 		NULL, WXS_BASIC_CAST idc,
   20392 		"The keyref references a keyref",
   20393 		NULL, NULL);
   20394 	    idc->ref->item = NULL;
   20395 	    return(pctxt->err);
   20396 	} else {
   20397 	    if (idc->nbFields !=
   20398 		((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
   20399 		xmlChar *str = NULL;
   20400 		xmlSchemaIDCPtr refer;
   20401 
   20402 		refer = (xmlSchemaIDCPtr) idc->ref->item;
   20403 		/*
   20404 		* SPEC c-props-correct(2)
   20405 		* "If the {identity-constraint category} is keyref,
   20406 		* the cardinality of the {fields} must equal that of
   20407 		* the {fields} of the {referenced key}.
   20408 		*/
   20409 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20410 		    XML_SCHEMAP_C_PROPS_CORRECT,
   20411 		    NULL, WXS_BASIC_CAST idc,
   20412 		    "The cardinality of the keyref differs from the "
   20413 		    "cardinality of the referenced key/unique '%s'",
   20414 		    xmlSchemaFormatQName(&str, refer->targetNamespace,
   20415 			refer->name),
   20416 		    NULL);
   20417 		FREE_AND_NULL(str)
   20418 		return(pctxt->err);
   20419 	    }
   20420 	}
   20421     }
   20422     return(0);
   20423 }
   20424 
   20425 static int
   20426 xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
   20427 				       xmlSchemaParserCtxtPtr pctxt)
   20428 {
   20429     if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
   20430 	prohib->targetNamespace) == NULL) {
   20431 
   20432 	xmlSchemaPResCompAttrErr(pctxt,
   20433 	    XML_SCHEMAP_SRC_RESOLVE,
   20434 	    NULL, prohib->node,
   20435 	    "ref", prohib->name, prohib->targetNamespace,
   20436 	    XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
   20437 	return(XML_SCHEMAP_SRC_RESOLVE);
   20438     }
   20439     return(0);
   20440 }
   20441 
   20442 #define WXS_REDEFINED_TYPE(c) \
   20443 (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
   20444 
   20445 #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
   20446 (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
   20447 
   20448 #define WXS_REDEFINED_ATTR_GROUP(c) \
   20449 (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
   20450 
   20451 static int
   20452 xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
   20453 {
   20454     int err = 0;
   20455     xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
   20456     xmlSchemaBasicItemPtr prev, item;
   20457     int wasRedefined;
   20458 
   20459     if (redef == NULL)
   20460 	return(0);
   20461 
   20462     do {
   20463 	item = redef->item;
   20464 	/*
   20465 	* First try to locate the redefined component in the
   20466 	* schema graph starting with the redefined schema.
   20467 	* NOTE: According to this schema bug entry:
   20468 	*   http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
   20469 	*   it's not clear if the referenced component needs to originate
   20470 	*   from the <redefine>d schema _document_ or the schema; the latter
   20471 	*   would include all imported and included sub-schemas of the
   20472 	*   <redefine>d schema. Currenlty we latter approach is used.
   20473 	*   SUPPLEMENT: It seems that the WG moves towards the latter
   20474 	*   approach, so we are doing it right.
   20475 	*
   20476 	*/
   20477 	prev = xmlSchemaFindRedefCompInGraph(
   20478 	    redef->targetBucket, item->type,
   20479 	    redef->refName, redef->refTargetNs);
   20480 	if (prev == NULL) {
   20481 	    xmlChar *str = NULL;
   20482 	    xmlNodePtr node;
   20483 
   20484 	    /*
   20485 	    * SPEC src-redefine:
   20486 	    * (6.2.1) "The `actual value` of its own name attribute plus
   20487 	    * target namespace must successfully `resolve` to a model
   20488 	    * group definition in I."
   20489 	    * (7.2.1) "The `actual value` of its own name attribute plus
   20490 	    * target namespace must successfully `resolve` to an attribute
   20491 	    * group definition in I."
   20492 
   20493 	    *
   20494 	    * Note that, if we are redefining with the use of references
   20495 	    * to components, the spec assumes the src-resolve to be used;
   20496 	    * but this won't assure that we search only *inside* the
   20497 	    * redefined schema.
   20498 	    */
   20499 	    if (redef->reference)
   20500 		node = WXS_ITEM_NODE(redef->reference);
   20501 	    else
   20502 		node = WXS_ITEM_NODE(item);
   20503 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20504 		/*
   20505 		* TODO: error code.
   20506 		* Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
   20507 		* reference kind.
   20508 		*/
   20509 		XML_SCHEMAP_SRC_REDEFINE, node, NULL,
   20510 		"The %s '%s' to be redefined could not be found in "
   20511 		"the redefined schema",
   20512 		WXS_ITEM_TYPE_NAME(item),
   20513 		xmlSchemaFormatQName(&str, redef->refTargetNs,
   20514 		    redef->refName));
   20515 	    FREE_AND_NULL(str);
   20516 	    err = pctxt->err;
   20517 	    redef = redef->next;
   20518 	    continue;
   20519 	}
   20520 	/*
   20521 	* TODO: Obtaining and setting the redefinition state is really
   20522 	* clumsy.
   20523 	*/
   20524 	wasRedefined = 0;
   20525 	switch (item->type) {
   20526 	    case XML_SCHEMA_TYPE_COMPLEX:
   20527 	    case XML_SCHEMA_TYPE_SIMPLE:
   20528 		if ((WXS_TYPE_CAST prev)->flags &
   20529 		    XML_SCHEMAS_TYPE_REDEFINED)
   20530 		{
   20531 		    wasRedefined = 1;
   20532 		    break;
   20533 		}
   20534 		/* Mark it as redefined. */
   20535 		(WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
   20536 		/*
   20537 		* Assign the redefined type to the
   20538 		* base type of the redefining type.
   20539 		* TODO: How
   20540 		*/
   20541 		((xmlSchemaTypePtr) item)->baseType =
   20542 		    (xmlSchemaTypePtr) prev;
   20543 		break;
   20544 	    case XML_SCHEMA_TYPE_GROUP:
   20545 		if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
   20546 		    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
   20547 		{
   20548 		    wasRedefined = 1;
   20549 		    break;
   20550 		}
   20551 		/* Mark it as redefined. */
   20552 		(WXS_MODEL_GROUPDEF_CAST prev)->flags |=
   20553 		    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
   20554 		if (redef->reference != NULL) {
   20555 		    /*
   20556 		    * Overwrite the QName-reference with the
   20557 		    * referenced model group def.
   20558 		    */
   20559 		    (WXS_PTC_CAST redef->reference)->children =
   20560 			WXS_TREE_CAST prev;
   20561 		}
   20562 		redef->target = prev;
   20563 		break;
   20564 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   20565 		if ((WXS_ATTR_GROUP_CAST prev)->flags &
   20566 		    XML_SCHEMAS_ATTRGROUP_REDEFINED)
   20567 		{
   20568 		    wasRedefined = 1;
   20569 		    break;
   20570 		}
   20571 		(WXS_ATTR_GROUP_CAST prev)->flags |=
   20572 		    XML_SCHEMAS_ATTRGROUP_REDEFINED;
   20573 		if (redef->reference != NULL) {
   20574 		    /*
   20575 		    * Assign the redefined attribute group to the
   20576 		    * QName-reference component.
   20577 		    * This is the easy case, since we will just
   20578 		    * expand the redefined group.
   20579 		    */
   20580 		    (WXS_QNAME_CAST redef->reference)->item = prev;
   20581 		    redef->target = NULL;
   20582 		} else {
   20583 		    /*
   20584 		    * This is the complicated case: we need
   20585 		    * to apply src-redefine (7.2.2) at a later
   20586 		    * stage, i.e. when attribute group references
   20587 		    * have beed expanded and simple types have
   20588 		    * beed fixed.
   20589 		    */
   20590 		    redef->target = prev;
   20591 		}
   20592 		break;
   20593 	    default:
   20594 		PERROR_INT("xmlSchemaResolveRedefReferences",
   20595 		    "Unexpected redefined component type");
   20596 		return(-1);
   20597 	}
   20598 	if (wasRedefined) {
   20599 	    xmlChar *str = NULL;
   20600 	    xmlNodePtr node;
   20601 
   20602 	    if (redef->reference)
   20603 		node = WXS_ITEM_NODE(redef->reference);
   20604 	    else
   20605 		node = WXS_ITEM_NODE(redef->item);
   20606 
   20607 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20608 		/* TODO: error code. */
   20609 		XML_SCHEMAP_SRC_REDEFINE,
   20610 		node, NULL,
   20611 		"The referenced %s was already redefined. Multiple "
   20612 		"redefinition of the same component is not supported",
   20613 		xmlSchemaGetComponentDesignation(&str, prev),
   20614 		NULL);
   20615 	    FREE_AND_NULL(str)
   20616 	    err = pctxt->err;
   20617 	    redef = redef->next;
   20618 	    continue;
   20619 	}
   20620 	redef = redef->next;
   20621     } while (redef != NULL);
   20622 
   20623     return(err);
   20624 }
   20625 
   20626 static int
   20627 xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
   20628 {
   20629     int err = 0;
   20630     xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
   20631     xmlSchemaBasicItemPtr item;
   20632 
   20633     if (redef == NULL)
   20634 	return(0);
   20635 
   20636     do {
   20637 	if (redef->target == NULL) {
   20638 	    redef = redef->next;
   20639 	    continue;
   20640 	}
   20641 	item = redef->item;
   20642 
   20643 	switch (item->type) {
   20644 	    case XML_SCHEMA_TYPE_SIMPLE:
   20645 	    case XML_SCHEMA_TYPE_COMPLEX:
   20646 		/*
   20647 		* Since the spec wants the {name} of the redefined
   20648 		* type to be 'absent', we'll NULL it.
   20649 		*/
   20650 		(WXS_TYPE_CAST redef->target)->name = NULL;
   20651 
   20652 		/*
   20653 		* TODO: Seems like there's nothing more to do. The normal
   20654 		* inheritance mechanism is used. But not 100% sure.
   20655 		*/
   20656 		break;
   20657 	    case XML_SCHEMA_TYPE_GROUP:
   20658 		/*
   20659 		* URGENT TODO:
   20660 		* SPEC src-redefine:
   20661 		* (6.2.2) "The {model group} of the model group definition
   20662 		* which corresponds to it per XML Representation of Model
   20663 		* Group Definition Schema Components ($3.7.2) must be a
   20664 		* `valid restriction` of the {model group} of that model
   20665 		* group definition in I, as defined in Particle Valid
   20666 		* (Restriction) ($3.9.6)."
   20667 		*/
   20668 		break;
   20669 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   20670 		/*
   20671 		* SPEC src-redefine:
   20672 		* (7.2.2) "The {attribute uses} and {attribute wildcard} of
   20673 		* the attribute group definition which corresponds to it
   20674 		* per XML Representation of Attribute Group Definition Schema
   20675 		* Components ($3.6.2) must be `valid restrictions` of the
   20676 		* {attribute uses} and {attribute wildcard} of that attribute
   20677 		* group definition in I, as defined in clause 2, clause 3 and
   20678 		* clause 4 of Derivation Valid (Restriction, Complex)
   20679 		* ($3.4.6) (where references to the base type definition are
   20680 		* understood as references to the attribute group definition
   20681 		* in I)."
   20682 		*/
   20683 		err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
   20684 		    XML_SCHEMA_ACTION_REDEFINE,
   20685 		    item, redef->target,
   20686 		    (WXS_ATTR_GROUP_CAST item)->attrUses,
   20687 		    (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
   20688 		    (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
   20689 		    (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
   20690 		if (err == -1)
   20691 		    return(-1);
   20692 		break;
   20693 	    default:
   20694 		break;
   20695 	}
   20696 	redef = redef->next;
   20697     } while (redef != NULL);
   20698     return(0);
   20699 }
   20700 
   20701 
   20702 static int
   20703 xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
   20704 		       xmlSchemaBucketPtr bucket)
   20705 {
   20706     xmlSchemaBasicItemPtr item;
   20707     int err;
   20708     xmlHashTablePtr *table;
   20709     const xmlChar *name;
   20710     int i;
   20711 
   20712 #define WXS_GET_GLOBAL_HASH(c, slot) { \
   20713     if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
   20714 	table = &(WXS_IMPBUCKET((c))->schema->slot); \
   20715     else \
   20716 	table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
   20717 
   20718     /*
   20719     * Add global components to the schema's hash tables.
   20720     * This is the place where duplicate components will be
   20721     * detected.
   20722     * TODO: I think normally we should support imports of the
   20723     *   same namespace from multiple locations. We don't do currently,
   20724     *   but if we do then according to:
   20725     *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
   20726     *   we would need, if imported directly, to import redefined
   20727     *   components as well to be able to catch clashing components.
   20728     *   (I hope I'll still know what this means after some months :-()
   20729     */
   20730     if (bucket == NULL)
   20731 	return(-1);
   20732     if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
   20733 	return(0);
   20734     bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
   20735 
   20736     for (i = 0; i < bucket->globals->nbItems; i++) {
   20737 	item = bucket->globals->items[i];
   20738 	table = NULL;
   20739 	switch (item->type) {
   20740 	    case XML_SCHEMA_TYPE_COMPLEX:
   20741 	    case XML_SCHEMA_TYPE_SIMPLE:
   20742 		if (WXS_REDEFINED_TYPE(item))
   20743 		    continue;
   20744 		name = (WXS_TYPE_CAST item)->name;
   20745 		WXS_GET_GLOBAL_HASH(bucket, typeDecl)
   20746 		break;
   20747 	    case XML_SCHEMA_TYPE_ELEMENT:
   20748 		name = (WXS_ELEM_CAST item)->name;
   20749 		WXS_GET_GLOBAL_HASH(bucket, elemDecl)
   20750 		break;
   20751 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
   20752 		name = (WXS_ATTR_CAST item)->name;
   20753 		WXS_GET_GLOBAL_HASH(bucket, attrDecl)
   20754 		break;
   20755 	    case XML_SCHEMA_TYPE_GROUP:
   20756 		if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
   20757 		    continue;
   20758 		name = (WXS_MODEL_GROUPDEF_CAST item)->name;
   20759 		WXS_GET_GLOBAL_HASH(bucket, groupDecl)
   20760 		break;
   20761 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   20762 		if (WXS_REDEFINED_ATTR_GROUP(item))
   20763 		    continue;
   20764 		name = (WXS_ATTR_GROUP_CAST item)->name;
   20765 		WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
   20766 		break;
   20767 	    case XML_SCHEMA_TYPE_IDC_KEY:
   20768 	    case XML_SCHEMA_TYPE_IDC_UNIQUE:
   20769 	    case XML_SCHEMA_TYPE_IDC_KEYREF:
   20770 		name = (WXS_IDC_CAST item)->name;
   20771 		WXS_GET_GLOBAL_HASH(bucket, idcDef)
   20772 		break;
   20773 	    case XML_SCHEMA_TYPE_NOTATION:
   20774 		name = ((xmlSchemaNotationPtr) item)->name;
   20775 		WXS_GET_GLOBAL_HASH(bucket, notaDecl)
   20776 		break;
   20777 	    default:
   20778 		PERROR_INT("xmlSchemaAddComponents",
   20779 		    "Unexpected global component type");
   20780 		continue;
   20781 	}
   20782 	if (*table == NULL) {
   20783 	    *table = xmlHashCreateDict(10, pctxt->dict);
   20784 	    if (*table == NULL) {
   20785 		PERROR_INT("xmlSchemaAddComponents",
   20786 		    "failed to create a component hash table");
   20787 		return(-1);
   20788 	    }
   20789 	}
   20790 	err = xmlHashAddEntry(*table, name, item);
   20791 	if (err != 0) {
   20792 	    xmlChar *str = NULL;
   20793 
   20794 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20795 		XML_SCHEMAP_REDEFINED_TYPE,
   20796 		WXS_ITEM_NODE(item),
   20797 		WXS_BASIC_CAST item,
   20798 		"A global %s '%s' does already exist",
   20799 		WXS_ITEM_TYPE_NAME(item),
   20800 		xmlSchemaGetComponentQName(&str, item));
   20801 	    FREE_AND_NULL(str);
   20802 	}
   20803     }
   20804     /*
   20805     * Process imported/included schemas.
   20806     */
   20807     if (bucket->relations != NULL) {
   20808 	xmlSchemaSchemaRelationPtr rel = bucket->relations;
   20809 	do {
   20810 	    if ((rel->bucket != NULL) &&
   20811 		((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
   20812 		if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
   20813 		    return(-1);
   20814 	    }
   20815 	    rel = rel->next;
   20816 	} while (rel != NULL);
   20817     }
   20818     return(0);
   20819 }
   20820 
   20821 static int
   20822 xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
   20823 			 xmlSchemaBucketPtr rootBucket)
   20824 {
   20825     xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
   20826     xmlSchemaTreeItemPtr item, *items;
   20827     int nbItems, i, ret = 0;
   20828     xmlSchemaBucketPtr oldbucket = con->bucket;
   20829     xmlSchemaElementPtr elemDecl;
   20830 
   20831 #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
   20832 
   20833     if ((con->pending == NULL) ||
   20834 	(con->pending->nbItems == 0))
   20835 	return(0);
   20836 
   20837     /*
   20838     * Since xmlSchemaFixupComplexType() will create new particles
   20839     * (local components), and those particle components need a bucket
   20840     * on the constructor, we'll assure here that the constructor has
   20841     * a bucket.
   20842     * TODO: Think about storing locals _only_ on the main bucket.
   20843     */
   20844     if (con->bucket == NULL)
   20845 	con->bucket = rootBucket;
   20846 
   20847     /* TODO:
   20848     * SPEC (src-redefine):
   20849     * (6.2) "If it has no such self-reference, then all of the
   20850     * following must be true:"
   20851 
   20852     * (6.2.2) The {model group} of the model group definition which
   20853     * corresponds to it per XML Representation of Model Group
   20854     * Definition Schema Components ($3.7.2) must be a `valid
   20855     * restriction` of the {model group} of that model group definition
   20856     * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
   20857     */
   20858     xmlSchemaCheckSRCRedefineFirst(pctxt);
   20859 
   20860     /*
   20861     * Add global components to the schemata's hash tables.
   20862     */
   20863     xmlSchemaAddComponents(pctxt, rootBucket);
   20864 
   20865     pctxt->ctxtType = NULL;
   20866     items = (xmlSchemaTreeItemPtr *) con->pending->items;
   20867     nbItems = con->pending->nbItems;
   20868     /*
   20869     * Now that we have parsed *all* the schema document(s) and converted
   20870     * them to schema components, we can resolve references, apply component
   20871     * constraints, create the FSA from the content model, etc.
   20872     */
   20873     /*
   20874     * Resolve references of..
   20875     *
   20876     * 1. element declarations:
   20877     *   - the type definition
   20878     *   - the substitution group affiliation
   20879     * 2. simple/complex types:
   20880     *   - the base type definition
   20881     *   - the memberTypes of union types
   20882     *   - the itemType of list types
   20883     * 3. attributes declarations and attribute uses:
   20884     *   - the type definition
   20885     *   - if an attribute use, then the attribute declaration
   20886     * 4. attribute group references:
   20887     *   - the attribute group definition
   20888     * 5. particles:
   20889     *   - the term of the particle (e.g. a model group)
   20890     * 6. IDC key-references:
   20891     *   - the referenced IDC 'key' or 'unique' definition
   20892     * 7. Attribute prohibitions which had a "ref" attribute.
   20893     */
   20894     for (i = 0; i < nbItems; i++) {
   20895 	item = items[i];
   20896 	switch (item->type) {
   20897 	    case XML_SCHEMA_TYPE_ELEMENT:
   20898 		xmlSchemaResolveElementReferences(
   20899 		    (xmlSchemaElementPtr) item, pctxt);
   20900 		FIXHFAILURE;
   20901 		break;
   20902 	    case XML_SCHEMA_TYPE_COMPLEX:
   20903 	    case XML_SCHEMA_TYPE_SIMPLE:
   20904 		xmlSchemaResolveTypeReferences(
   20905 		    (xmlSchemaTypePtr) item, pctxt);
   20906 		FIXHFAILURE;
   20907 		break;
   20908 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
   20909 		xmlSchemaResolveAttrTypeReferences(
   20910 		    (xmlSchemaAttributePtr) item, pctxt);
   20911 		FIXHFAILURE;
   20912 		break;
   20913 	    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   20914 		xmlSchemaResolveAttrUseReferences(
   20915 		    (xmlSchemaAttributeUsePtr) item, pctxt);
   20916 		FIXHFAILURE;
   20917 		break;
   20918 	    case XML_SCHEMA_EXTRA_QNAMEREF:
   20919 		if ((WXS_QNAME_CAST item)->itemType ==
   20920 		    XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
   20921 		{
   20922 		    xmlSchemaResolveAttrGroupReferences(
   20923 			WXS_QNAME_CAST item, pctxt);
   20924 		}
   20925 		FIXHFAILURE;
   20926 		break;
   20927 	    case XML_SCHEMA_TYPE_SEQUENCE:
   20928 	    case XML_SCHEMA_TYPE_CHOICE:
   20929 	    case XML_SCHEMA_TYPE_ALL:
   20930 		xmlSchemaResolveModelGroupParticleReferences(pctxt,
   20931 		    WXS_MODEL_GROUP_CAST item);
   20932 		FIXHFAILURE;
   20933 		break;
   20934 	    case XML_SCHEMA_TYPE_IDC_KEY:
   20935 	    case XML_SCHEMA_TYPE_IDC_UNIQUE:
   20936 	    case XML_SCHEMA_TYPE_IDC_KEYREF:
   20937 		xmlSchemaResolveIDCKeyReferences(
   20938 		    (xmlSchemaIDCPtr) item, pctxt);
   20939 		FIXHFAILURE;
   20940 		break;
   20941 	    case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
   20942 		/*
   20943 		* Handle attribue prohibition which had a
   20944 		* "ref" attribute.
   20945 		*/
   20946 		xmlSchemaResolveAttrUseProhibReferences(
   20947 		    WXS_ATTR_PROHIB_CAST item, pctxt);
   20948 		FIXHFAILURE;
   20949 		break;
   20950 	    default:
   20951 		break;
   20952 	}
   20953     }
   20954     if (pctxt->nberrors != 0)
   20955 	goto exit_error;
   20956 
   20957     /*
   20958     * Now that all references are resolved we
   20959     * can check for circularity of...
   20960     * 1. the base axis of type definitions
   20961     * 2. nested model group definitions
   20962     * 3. nested attribute group definitions
   20963     * TODO: check for circual substitution groups.
   20964     */
   20965     for (i = 0; i < nbItems; i++) {
   20966 	item = items[i];
   20967 	/*
   20968 	* Let's better stop on the first error here.
   20969 	*/
   20970 	switch (item->type) {
   20971 	    case XML_SCHEMA_TYPE_COMPLEX:
   20972 	    case XML_SCHEMA_TYPE_SIMPLE:
   20973 		xmlSchemaCheckTypeDefCircular(
   20974 		    (xmlSchemaTypePtr) item, pctxt);
   20975 		FIXHFAILURE;
   20976 		if (pctxt->nberrors != 0)
   20977 		    goto exit_error;
   20978 		break;
   20979 	    case XML_SCHEMA_TYPE_GROUP:
   20980 		xmlSchemaCheckGroupDefCircular(
   20981 		    (xmlSchemaModelGroupDefPtr) item, pctxt);
   20982 		FIXHFAILURE;
   20983 		if (pctxt->nberrors != 0)
   20984 		    goto exit_error;
   20985 		break;
   20986 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   20987 		xmlSchemaCheckAttrGroupCircular(
   20988 		    (xmlSchemaAttributeGroupPtr) item, pctxt);
   20989 		FIXHFAILURE;
   20990 		if (pctxt->nberrors != 0)
   20991 		    goto exit_error;
   20992 		break;
   20993 	    default:
   20994 		break;
   20995 	}
   20996     }
   20997     if (pctxt->nberrors != 0)
   20998 	goto exit_error;
   20999     /*
   21000     * Model group definition references:
   21001     * Such a reference is reflected by a particle at the component
   21002     * level. Until now the 'term' of such particles pointed
   21003     * to the model group definition; this was done, in order to
   21004     * ease circularity checks. Now we need to set the 'term' of
   21005     * such particles to the model group of the model group definition.
   21006     */
   21007     for (i = 0; i < nbItems; i++) {
   21008 	item = items[i];
   21009 	switch (item->type) {
   21010 	    case XML_SCHEMA_TYPE_SEQUENCE:
   21011 	    case XML_SCHEMA_TYPE_CHOICE:
   21012 		xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
   21013 		    WXS_MODEL_GROUP_CAST item);
   21014 		break;
   21015 	    default:
   21016 		break;
   21017 	}
   21018     }
   21019     if (pctxt->nberrors != 0)
   21020 	goto exit_error;
   21021     /*
   21022     * Expand attribute group references of attribute group definitions.
   21023     */
   21024     for (i = 0; i < nbItems; i++) {
   21025 	item = items[i];
   21026 	switch (item->type) {
   21027             case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   21028 		if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
   21029 		    WXS_ATTR_GROUP_HAS_REFS(item))
   21030 		{
   21031 		    xmlSchemaAttributeGroupExpandRefs(pctxt,
   21032 			WXS_ATTR_GROUP_CAST item);
   21033 		    FIXHFAILURE;
   21034 		}
   21035 		break;
   21036 	    default:
   21037 		break;
   21038 	}
   21039     }
   21040     if (pctxt->nberrors != 0)
   21041 	goto exit_error;
   21042     /*
   21043     * First compute the variety of simple types. This is needed as
   21044     * a seperate step, since otherwise we won't be able to detect
   21045     * circular union types in all cases.
   21046     */
   21047     for (i = 0; i < nbItems; i++) {
   21048 	item = items[i];
   21049 	switch (item->type) {
   21050             case XML_SCHEMA_TYPE_SIMPLE:
   21051 		if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
   21052 		    xmlSchemaFixupSimpleTypeStageOne(pctxt,
   21053 			(xmlSchemaTypePtr) item);
   21054 		    FIXHFAILURE;
   21055 		}
   21056 		break;
   21057 	    default:
   21058 		break;
   21059 	}
   21060     }
   21061     if (pctxt->nberrors != 0)
   21062 	goto exit_error;
   21063     /*
   21064     * Detect circular union types. Note that this needs the variety to
   21065     * be already computed.
   21066     */
   21067     for (i = 0; i < nbItems; i++) {
   21068 	item = items[i];
   21069 	switch (item->type) {
   21070             case XML_SCHEMA_TYPE_SIMPLE:
   21071 		if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
   21072 		    xmlSchemaCheckUnionTypeDefCircular(pctxt,
   21073 			(xmlSchemaTypePtr) item);
   21074 		    FIXHFAILURE;
   21075 		}
   21076 		break;
   21077 	    default:
   21078 		break;
   21079 	}
   21080     }
   21081     if (pctxt->nberrors != 0)
   21082 	goto exit_error;
   21083 
   21084     /*
   21085     * Do the complete type fixup for simple types.
   21086     */
   21087     for (i = 0; i < nbItems; i++) {
   21088 	item = items[i];
   21089 	switch (item->type) {
   21090             case XML_SCHEMA_TYPE_SIMPLE:
   21091 		if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
   21092 		    xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
   21093 		    FIXHFAILURE;
   21094 		}
   21095 		break;
   21096 	    default:
   21097 		break;
   21098 	}
   21099     }
   21100     if (pctxt->nberrors != 0)
   21101 	goto exit_error;
   21102     /*
   21103     * At this point we need build and check all simple types.
   21104     */
   21105     /*
   21106     * Apply contraints for attribute declarations.
   21107     */
   21108     for (i = 0; i < nbItems; i++) {
   21109 	item = items[i];
   21110 	switch (item->type) {
   21111 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
   21112 		xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
   21113 		FIXHFAILURE;
   21114 		break;
   21115 	    default:
   21116 		break;
   21117 	}
   21118     }
   21119     if (pctxt->nberrors != 0)
   21120 	goto exit_error;
   21121     /*
   21122     * Apply constraints for attribute uses.
   21123     */
   21124     for (i = 0; i < nbItems; i++) {
   21125 	item = items[i];
   21126 	switch (item->type) {
   21127 	    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   21128 		if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
   21129 		    xmlSchemaCheckAttrUsePropsCorrect(pctxt,
   21130 			WXS_ATTR_USE_CAST item);
   21131 		    FIXHFAILURE;
   21132 		}
   21133 		break;
   21134 	    default:
   21135 		break;
   21136 	}
   21137     }
   21138     if (pctxt->nberrors != 0)
   21139 	goto exit_error;
   21140 
   21141     /*
   21142     * Apply constraints for attribute group definitions.
   21143     */
   21144     for (i = 0; i < nbItems; i++) {
   21145 	item = items[i];
   21146 	switch (item->type) {
   21147 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   21148 	    if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
   21149 		( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
   21150 	    {
   21151 		xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
   21152 		FIXHFAILURE;
   21153 	    }
   21154 	    break;
   21155 	default:
   21156 	    break;
   21157 	}
   21158     }
   21159     if (pctxt->nberrors != 0)
   21160 	goto exit_error;
   21161 
   21162     /*
   21163     * Apply constraints for redefinitions.
   21164     */
   21165     if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
   21166 	xmlSchemaCheckSRCRedefineSecond(pctxt);
   21167     if (pctxt->nberrors != 0)
   21168 	goto exit_error;
   21169 
   21170     /*
   21171     * Complex types are builded and checked.
   21172     */
   21173     for (i = 0; i < nbItems; i++) {
   21174 	item = con->pending->items[i];
   21175 	switch (item->type) {
   21176 	    case XML_SCHEMA_TYPE_COMPLEX:
   21177 		if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
   21178 		    xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
   21179 		    FIXHFAILURE;
   21180 		}
   21181 		break;
   21182 	    default:
   21183 		break;
   21184 	}
   21185     }
   21186     if (pctxt->nberrors != 0)
   21187 	goto exit_error;
   21188 
   21189     /*
   21190     * The list could have changed, since xmlSchemaFixupComplexType()
   21191     * will create particles and model groups in some cases.
   21192     */
   21193     items = (xmlSchemaTreeItemPtr *) con->pending->items;
   21194     nbItems = con->pending->nbItems;
   21195 
   21196     /*
   21197     * Apply some constraints for element declarations.
   21198     */
   21199     for (i = 0; i < nbItems; i++) {
   21200 	item = items[i];
   21201 	switch (item->type) {
   21202 	    case XML_SCHEMA_TYPE_ELEMENT:
   21203 		elemDecl = (xmlSchemaElementPtr) item;
   21204 
   21205 		if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
   21206 		{
   21207 		    xmlSchemaCheckElementDeclComponent(
   21208 			(xmlSchemaElementPtr) elemDecl, pctxt);
   21209 		    FIXHFAILURE;
   21210 		}
   21211 
   21212 #ifdef WXS_ELEM_DECL_CONS_ENABLED
   21213 		/*
   21214 		* Schema Component Constraint: Element Declarations Consistent
   21215 		* Apply this constraint to local types of element declarations.
   21216 		*/
   21217 		if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
   21218 		    (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
   21219 		    (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
   21220 		{
   21221 		    xmlSchemaCheckElementDeclConsistent(pctxt,
   21222 			WXS_BASIC_CAST elemDecl,
   21223 			WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
   21224 			NULL, NULL, 0);
   21225 		}
   21226 #endif
   21227 		break;
   21228 	    default:
   21229 		break;
   21230 	}
   21231     }
   21232     if (pctxt->nberrors != 0)
   21233 	goto exit_error;
   21234 
   21235     /*
   21236     * Finally we can build the automaton from the content model of
   21237     * complex types.
   21238     */
   21239 
   21240     for (i = 0; i < nbItems; i++) {
   21241 	item = items[i];
   21242 	switch (item->type) {
   21243 	    case XML_SCHEMA_TYPE_COMPLEX:
   21244 		xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
   21245 		/* FIXHFAILURE; */
   21246 		break;
   21247 	    default:
   21248 		break;
   21249 	}
   21250     }
   21251     if (pctxt->nberrors != 0)
   21252 	goto exit_error;
   21253     /*
   21254     * URGENT TODO: cos-element-consistent
   21255     */
   21256     goto exit;
   21257 
   21258 exit_error:
   21259     ret = pctxt->err;
   21260     goto exit;
   21261 
   21262 exit_failure:
   21263     ret = -1;
   21264 
   21265 exit:
   21266     /*
   21267     * Reset the constructor. This is needed for XSI acquisition, since
   21268     * those items will be processed over and over again for every XSI
   21269     * if not cleared here.
   21270     */
   21271     con->bucket = oldbucket;
   21272     con->pending->nbItems = 0;
   21273     if (con->substGroups != NULL) {
   21274 	xmlHashFree(con->substGroups,
   21275 	    (xmlHashDeallocator) xmlSchemaSubstGroupFree);
   21276 	con->substGroups = NULL;
   21277     }
   21278     if (con->redefs != NULL) {
   21279 	xmlSchemaRedefListFree(con->redefs);
   21280 	con->redefs = NULL;
   21281     }
   21282     return(ret);
   21283 }
   21284 /**
   21285  * xmlSchemaParse:
   21286  * @ctxt:  a schema validation context
   21287  *
   21288  * parse a schema definition resource and build an internal
   21289  * XML Shema struture which can be used to validate instances.
   21290  *
   21291  * Returns the internal XML Schema structure built from the resource or
   21292  *         NULL in case of error
   21293  */
   21294 xmlSchemaPtr
   21295 xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
   21296 {
   21297     xmlSchemaPtr mainSchema = NULL;
   21298     xmlSchemaBucketPtr bucket = NULL;
   21299     int res;
   21300 
   21301     /*
   21302     * This one is used if the schema to be parsed was specified via
   21303     * the API; i.e. not automatically by the validated instance document.
   21304     */
   21305 
   21306     xmlSchemaInitTypes();
   21307 
   21308     if (ctxt == NULL)
   21309         return (NULL);
   21310 
   21311     /* TODO: Init the context. Is this all we need?*/
   21312     ctxt->nberrors = 0;
   21313     ctxt->err = 0;
   21314     ctxt->counter = 0;
   21315 
   21316     /* Create the *main* schema. */
   21317     mainSchema = xmlSchemaNewSchema(ctxt);
   21318     if (mainSchema == NULL)
   21319 	goto exit_failure;
   21320     /*
   21321     * Create the schema constructor.
   21322     */
   21323     if (ctxt->constructor == NULL) {
   21324 	ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
   21325 	if (ctxt->constructor == NULL)
   21326 	    return(NULL);
   21327 	/* Take ownership of the constructor to be able to free it. */
   21328 	ctxt->ownsConstructor = 1;
   21329     }
   21330     ctxt->constructor->mainSchema = mainSchema;
   21331     /*
   21332     * Locate and add the schema document.
   21333     */
   21334     res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
   21335 	ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
   21336 	NULL, NULL, &bucket);
   21337     if (res == -1)
   21338 	goto exit_failure;
   21339     if (res != 0)
   21340 	goto exit;
   21341 
   21342     if (bucket == NULL) {
   21343 	/* TODO: Error code, actually we failed to *locate* the schema. */
   21344 	if (ctxt->URL)
   21345 	    xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
   21346 		NULL, NULL,
   21347 		"Failed to locate the main schema resource at '%s'",
   21348 		ctxt->URL, NULL);
   21349 	else
   21350 	    xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
   21351 		NULL, NULL,
   21352 		"Failed to locate the main schema resource",
   21353 		    NULL, NULL);
   21354 	goto exit;
   21355     }
   21356     /* Then do the parsing for good. */
   21357     if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
   21358 	goto exit_failure;
   21359     if (ctxt->nberrors != 0)
   21360 	goto exit;
   21361 
   21362     mainSchema->doc = bucket->doc;
   21363     mainSchema->preserve = ctxt->preserve;
   21364 
   21365     ctxt->schema = mainSchema;
   21366 
   21367     if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
   21368 	goto exit_failure;
   21369 
   21370     /*
   21371     * TODO: This is not nice, since we cannot distinguish from the
   21372     * result if there was an internal error or not.
   21373     */
   21374 exit:
   21375     if (ctxt->nberrors != 0) {
   21376 	if (mainSchema) {
   21377 	    xmlSchemaFree(mainSchema);
   21378 	    mainSchema = NULL;
   21379 	}
   21380 	if (ctxt->constructor) {
   21381 	    xmlSchemaConstructionCtxtFree(ctxt->constructor);
   21382 	    ctxt->constructor = NULL;
   21383 	    ctxt->ownsConstructor = 0;
   21384 	}
   21385     }
   21386     ctxt->schema = NULL;
   21387     return(mainSchema);
   21388 exit_failure:
   21389     /*
   21390     * Quite verbose, but should catch internal errors, which were
   21391     * not communitated.
   21392     */
   21393     if (mainSchema) {
   21394         xmlSchemaFree(mainSchema);
   21395 	mainSchema = NULL;
   21396     }
   21397     if (ctxt->constructor) {
   21398 	xmlSchemaConstructionCtxtFree(ctxt->constructor);
   21399 	ctxt->constructor = NULL;
   21400 	ctxt->ownsConstructor = 0;
   21401     }
   21402     PERROR_INT2("xmlSchemaParse",
   21403 	"An internal error occured");
   21404     ctxt->schema = NULL;
   21405     return(NULL);
   21406 }
   21407 
   21408 /**
   21409  * xmlSchemaSetParserErrors:
   21410  * @ctxt:  a schema validation context
   21411  * @err:  the error callback
   21412  * @warn:  the warning callback
   21413  * @ctx:  contextual data for the callbacks
   21414  *
   21415  * Set the callback functions used to handle errors for a validation context
   21416  */
   21417 void
   21418 xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
   21419                          xmlSchemaValidityErrorFunc err,
   21420                          xmlSchemaValidityWarningFunc warn, void *ctx)
   21421 {
   21422     if (ctxt == NULL)
   21423         return;
   21424     ctxt->error = err;
   21425     ctxt->warning = warn;
   21426     ctxt->errCtxt = ctx;
   21427     if (ctxt->vctxt != NULL)
   21428 	xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
   21429 }
   21430 
   21431 /**
   21432  * xmlSchemaSetParserStructuredErrors:
   21433  * @ctxt:  a schema parser context
   21434  * @serror:  the structured error function
   21435  * @ctx: the functions context
   21436  *
   21437  * Set the structured error callback
   21438  */
   21439 void
   21440 xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
   21441 				   xmlStructuredErrorFunc serror,
   21442 				   void *ctx)
   21443 {
   21444     if (ctxt == NULL)
   21445 	return;
   21446     ctxt->serror = serror;
   21447     ctxt->errCtxt = ctx;
   21448     if (ctxt->vctxt != NULL)
   21449 	xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
   21450 }
   21451 
   21452 /**
   21453  * xmlSchemaGetParserErrors:
   21454  * @ctxt:  a XMl-Schema parser context
   21455  * @err: the error callback result
   21456  * @warn: the warning callback result
   21457  * @ctx: contextual data for the callbacks result
   21458  *
   21459  * Get the callback information used to handle errors for a parser context
   21460  *
   21461  * Returns -1 in case of failure, 0 otherwise
   21462  */
   21463 int
   21464 xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
   21465 			 xmlSchemaValidityErrorFunc * err,
   21466 			 xmlSchemaValidityWarningFunc * warn, void **ctx)
   21467 {
   21468 	if (ctxt == NULL)
   21469 		return(-1);
   21470 	if (err != NULL)
   21471 		*err = ctxt->error;
   21472 	if (warn != NULL)
   21473 		*warn = ctxt->warning;
   21474 	if (ctx != NULL)
   21475 		*ctx = ctxt->errCtxt;
   21476 	return(0);
   21477 }
   21478 
   21479 /**
   21480  * xmlSchemaFacetTypeToString:
   21481  * @type:  the facet type
   21482  *
   21483  * Convert the xmlSchemaTypeType to a char string.
   21484  *
   21485  * Returns the char string representation of the facet type if the
   21486  *     type is a facet and an "Internal Error" string otherwise.
   21487  */
   21488 static const xmlChar *
   21489 xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
   21490 {
   21491     switch (type) {
   21492         case XML_SCHEMA_FACET_PATTERN:
   21493             return (BAD_CAST "pattern");
   21494         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   21495             return (BAD_CAST "maxExclusive");
   21496         case XML_SCHEMA_FACET_MAXINCLUSIVE:
   21497             return (BAD_CAST "maxInclusive");
   21498         case XML_SCHEMA_FACET_MINEXCLUSIVE:
   21499             return (BAD_CAST "minExclusive");
   21500         case XML_SCHEMA_FACET_MININCLUSIVE:
   21501             return (BAD_CAST "minInclusive");
   21502         case XML_SCHEMA_FACET_WHITESPACE:
   21503             return (BAD_CAST "whiteSpace");
   21504         case XML_SCHEMA_FACET_ENUMERATION:
   21505             return (BAD_CAST "enumeration");
   21506         case XML_SCHEMA_FACET_LENGTH:
   21507             return (BAD_CAST "length");
   21508         case XML_SCHEMA_FACET_MAXLENGTH:
   21509             return (BAD_CAST "maxLength");
   21510         case XML_SCHEMA_FACET_MINLENGTH:
   21511             return (BAD_CAST "minLength");
   21512         case XML_SCHEMA_FACET_TOTALDIGITS:
   21513             return (BAD_CAST "totalDigits");
   21514         case XML_SCHEMA_FACET_FRACTIONDIGITS:
   21515             return (BAD_CAST "fractionDigits");
   21516         default:
   21517             break;
   21518     }
   21519     return (BAD_CAST "Internal Error");
   21520 }
   21521 
   21522 static xmlSchemaWhitespaceValueType
   21523 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
   21524 {
   21525     /*
   21526     * The normalization type can be changed only for types which are derived
   21527     * from xsd:string.
   21528     */
   21529     if (type->type == XML_SCHEMA_TYPE_BASIC) {
   21530 	/*
   21531 	* Note that we assume a whitespace of preserve for anySimpleType.
   21532 	*/
   21533 	if ((type->builtInType == XML_SCHEMAS_STRING) ||
   21534 	    (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
   21535 	    return(XML_SCHEMA_WHITESPACE_PRESERVE);
   21536 	else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
   21537 	    return(XML_SCHEMA_WHITESPACE_REPLACE);
   21538 	else {
   21539 	    /*
   21540 	    * For all `atomic` datatypes other than string (and types `derived`
   21541 	    * by `restriction` from it) the value of whiteSpace is fixed to
   21542 	    * collapse
   21543 	    * Note that this includes built-in list datatypes.
   21544 	    */
   21545 	    return(XML_SCHEMA_WHITESPACE_COLLAPSE);
   21546 	}
   21547     } else if (WXS_IS_LIST(type)) {
   21548 	/*
   21549 	* For list types the facet "whiteSpace" is fixed to "collapse".
   21550 	*/
   21551 	return (XML_SCHEMA_WHITESPACE_COLLAPSE);
   21552     } else if (WXS_IS_UNION(type)) {
   21553 	return (XML_SCHEMA_WHITESPACE_UNKNOWN);
   21554     } else if (WXS_IS_ATOMIC(type)) {
   21555 	if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
   21556 	    return (XML_SCHEMA_WHITESPACE_PRESERVE);
   21557 	else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
   21558 	    return (XML_SCHEMA_WHITESPACE_REPLACE);
   21559 	else
   21560 	    return (XML_SCHEMA_WHITESPACE_COLLAPSE);
   21561     }
   21562     return (-1);
   21563 }
   21564 
   21565 /************************************************************************
   21566  *									*
   21567  *			Simple type validation				*
   21568  *									*
   21569  ************************************************************************/
   21570 
   21571 
   21572 /************************************************************************
   21573  *									*
   21574  *			DOM Validation code				*
   21575  *									*
   21576  ************************************************************************/
   21577 
   21578 /**
   21579  * xmlSchemaAssembleByLocation:
   21580  * @pctxt:  a schema parser context
   21581  * @vctxt:  a schema validation context
   21582  * @schema: the existing schema
   21583  * @node: the node that fired the assembling
   21584  * @nsName: the namespace name of the new schema
   21585  * @location: the location of the schema
   21586  *
   21587  * Expands an existing schema by an additional schema.
   21588  *
   21589  * Returns 0 if the new schema is correct, a positive error code
   21590  * number otherwise and -1 in case of an internal or API error.
   21591  */
   21592 static int
   21593 xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
   21594 			    xmlSchemaPtr schema,
   21595 			    xmlNodePtr node,
   21596 			    const xmlChar *nsName,
   21597 			    const xmlChar *location)
   21598 {
   21599     int ret = 0;
   21600     xmlSchemaParserCtxtPtr pctxt;
   21601     xmlSchemaBucketPtr bucket = NULL;
   21602 
   21603     if ((vctxt == NULL) || (schema == NULL))
   21604 	return (-1);
   21605 
   21606     if (vctxt->pctxt == NULL) {
   21607 	VERROR_INT("xmlSchemaAssembleByLocation",
   21608 	    "no parser context available");
   21609 	return(-1);
   21610     }
   21611     pctxt = vctxt->pctxt;
   21612     if (pctxt->constructor == NULL) {
   21613 	PERROR_INT("xmlSchemaAssembleByLocation",
   21614 	    "no constructor");
   21615 	return(-1);
   21616     }
   21617     /*
   21618     * Acquire the schema document.
   21619     */
   21620     location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
   21621 	location, node);
   21622     /*
   21623     * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
   21624     * the process will automatically change this to
   21625     * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
   21626     */
   21627     ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
   21628 	location, NULL, NULL, 0, node, NULL, nsName,
   21629 	&bucket);
   21630     if (ret != 0)
   21631 	return(ret);
   21632     if (bucket == NULL) {
   21633 	/*
   21634 	* Generate a warning that the document could not be located.
   21635 	*/
   21636 	xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
   21637 	    node, NULL,
   21638 	    "The document at location '%s' could not be acquired",
   21639 	    location, NULL, NULL);
   21640 	return(ret);
   21641     }
   21642     /*
   21643     * The first located schema will be handled as if all other
   21644     * schemas imported by XSI were imported by this first schema.
   21645     */
   21646     if ((bucket != NULL) &&
   21647 	(WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
   21648 	WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
   21649     /*
   21650     * TODO: Is this handled like an import? I.e. is it not an error
   21651     * if the schema cannot be located?
   21652     */
   21653     if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
   21654 	return(0);
   21655     /*
   21656     * We will reuse the parser context for every schema imported
   21657     * directly via XSI. So reset the context.
   21658     */
   21659     pctxt->nberrors = 0;
   21660     pctxt->err = 0;
   21661     pctxt->doc = bucket->doc;
   21662 
   21663     ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
   21664     if (ret == -1) {
   21665 	pctxt->doc = NULL;
   21666 	goto exit_failure;
   21667     }
   21668     /* Paranoid error channelling. */
   21669     if ((ret == 0) && (pctxt->nberrors != 0))
   21670 	ret = pctxt->err;
   21671     if (pctxt->nberrors == 0) {
   21672 	/*
   21673 	* Only bother to fixup pending components, if there was
   21674 	* no error yet.
   21675 	* For every XSI acquired schema (and its sub-schemata) we will
   21676 	* fixup the components.
   21677 	*/
   21678 	xmlSchemaFixupComponents(pctxt, bucket);
   21679 	ret = pctxt->err;
   21680 	/*
   21681 	* Not nice, but we need somehow to channel the schema parser
   21682 	* error to the validation context.
   21683 	*/
   21684 	if ((ret != 0) && (vctxt->err == 0))
   21685 	    vctxt->err = ret;
   21686 	vctxt->nberrors += pctxt->nberrors;
   21687     } else {
   21688 	/* Add to validation error sum. */
   21689 	vctxt->nberrors += pctxt->nberrors;
   21690     }
   21691     pctxt->doc = NULL;
   21692     return(ret);
   21693 exit_failure:
   21694     pctxt->doc = NULL;
   21695     return (-1);
   21696 }
   21697 
   21698 static xmlSchemaAttrInfoPtr
   21699 xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
   21700 			 int metaType)
   21701 {
   21702     if (vctxt->nbAttrInfos == 0)
   21703 	return (NULL);
   21704     {
   21705 	int i;
   21706 	xmlSchemaAttrInfoPtr iattr;
   21707 
   21708 	for (i = 0; i < vctxt->nbAttrInfos; i++) {
   21709 	    iattr = vctxt->attrInfos[i];
   21710 	    if (iattr->metaType == metaType)
   21711 		return (iattr);
   21712 	}
   21713 
   21714     }
   21715     return (NULL);
   21716 }
   21717 
   21718 /**
   21719  * xmlSchemaAssembleByXSI:
   21720  * @vctxt:  a schema validation context
   21721  *
   21722  * Expands an existing schema by an additional schema using
   21723  * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
   21724  * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
   21725  * must be set to 1.
   21726  *
   21727  * Returns 0 if the new schema is correct, a positive error code
   21728  * number otherwise and -1 in case of an internal or API error.
   21729  */
   21730 static int
   21731 xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
   21732 {
   21733     const xmlChar *cur, *end;
   21734     const xmlChar *nsname = NULL, *location;
   21735     int count = 0;
   21736     int ret = 0;
   21737     xmlSchemaAttrInfoPtr iattr;
   21738 
   21739     /*
   21740     * Parse the value; we will assume an even number of values
   21741     * to be given (this is how Xerces and XSV work).
   21742     *
   21743     * URGENT TODO: !! This needs to work for both
   21744     * @noNamespaceSchemaLocation AND @schemaLocation on the same
   21745     * element !!
   21746     */
   21747     iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   21748 	XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
   21749     if (iattr == NULL)
   21750 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   21751 	XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
   21752     if (iattr == NULL)
   21753 	return (0);
   21754     cur = iattr->value;
   21755     do {
   21756 	/*
   21757 	* TODO: Move the string parsing mechanism away from here.
   21758 	*/
   21759 	if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
   21760 	    /*
   21761 	    * Get the namespace name.
   21762 	    */
   21763 	    while (IS_BLANK_CH(*cur))
   21764 		cur++;
   21765 	    end = cur;
   21766 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   21767 		end++;
   21768 	    if (end == cur)
   21769 		break;
   21770 	    count++; /* TODO: Don't use the schema's dict. */
   21771 	    nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
   21772 	    cur = end;
   21773 	}
   21774 	/*
   21775 	* Get the URI.
   21776 	*/
   21777 	while (IS_BLANK_CH(*cur))
   21778 	    cur++;
   21779 	end = cur;
   21780 	while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   21781 	    end++;
   21782 	if (end == cur) {
   21783 	    if (iattr->metaType ==
   21784 		XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
   21785 	    {
   21786 		/*
   21787 		* If using @schemaLocation then tuples are expected.
   21788 		* I.e. the namespace name *and* the document's URI.
   21789 		*/
   21790 		xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
   21791 		    iattr->node, NULL,
   21792 		    "The value must consist of tuples: the target namespace "
   21793 		    "name and the document's URI", NULL, NULL, NULL);
   21794 	    }
   21795 	    break;
   21796 	}
   21797 	count++; /* TODO: Don't use the schema's dict. */
   21798 	location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
   21799 	cur = end;
   21800 	ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
   21801 	    iattr->node, nsname, location);
   21802 	if (ret == -1) {
   21803 	    VERROR_INT("xmlSchemaAssembleByXSI",
   21804 		"assembling schemata");
   21805 	    return (-1);
   21806 	}
   21807     } while (*cur != 0);
   21808     return (ret);
   21809 }
   21810 
   21811 static const xmlChar *
   21812 xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
   21813 			 const xmlChar *prefix)
   21814 {
   21815     if (vctxt->sax != NULL) {
   21816 	int i, j;
   21817 	xmlSchemaNodeInfoPtr inode;
   21818 
   21819 	for (i = vctxt->depth; i >= 0; i--) {
   21820 	    if (vctxt->elemInfos[i]->nbNsBindings != 0) {
   21821 		inode = vctxt->elemInfos[i];
   21822 		for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
   21823 		    if (((prefix == NULL) &&
   21824 			    (inode->nsBindings[j] == NULL)) ||
   21825 			((prefix != NULL) && xmlStrEqual(prefix,
   21826 			    inode->nsBindings[j]))) {
   21827 
   21828 			/*
   21829 			* Note that the namespace bindings are already
   21830 			* in a string dict.
   21831 			*/
   21832 			return (inode->nsBindings[j+1]);
   21833 		    }
   21834 		}
   21835 	    }
   21836 	}
   21837 	return (NULL);
   21838 #ifdef LIBXML_READER_ENABLED
   21839     } else if (vctxt->reader != NULL) {
   21840 	xmlChar *nsName;
   21841 
   21842 	nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
   21843 	if (nsName != NULL) {
   21844 	    const xmlChar *ret;
   21845 
   21846 	    ret = xmlDictLookup(vctxt->dict, nsName, -1);
   21847 	    xmlFree(nsName);
   21848 	    return (ret);
   21849 	} else
   21850 	    return (NULL);
   21851 #endif
   21852     } else {
   21853 	xmlNsPtr ns;
   21854 
   21855 	if ((vctxt->inode->node == NULL) ||
   21856 	    (vctxt->inode->node->doc == NULL)) {
   21857 	    VERROR_INT("xmlSchemaLookupNamespace",
   21858 		"no node or node's doc avaliable");
   21859 	    return (NULL);
   21860 	}
   21861 	ns = xmlSearchNs(vctxt->inode->node->doc,
   21862 	    vctxt->inode->node, prefix);
   21863 	if (ns != NULL)
   21864 	    return (ns->href);
   21865 	return (NULL);
   21866     }
   21867 }
   21868 
   21869 /*
   21870 * This one works on the schema of the validation context.
   21871 */
   21872 static int
   21873 xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
   21874 			  xmlSchemaPtr schema,
   21875 			  xmlNodePtr node,
   21876 			  const xmlChar *value,
   21877 			  xmlSchemaValPtr *val,
   21878 			  int valNeeded)
   21879 {
   21880     int ret;
   21881 
   21882     if (vctxt && (vctxt->schema == NULL)) {
   21883 	VERROR_INT("xmlSchemaValidateNotation",
   21884 	    "a schema is needed on the validation context");
   21885 	return (-1);
   21886     }
   21887     ret = xmlValidateQName(value, 1);
   21888     if (ret != 0)
   21889 	return (ret);
   21890     {
   21891 	xmlChar *localName = NULL;
   21892 	xmlChar *prefix = NULL;
   21893 
   21894 	localName = xmlSplitQName2(value, &prefix);
   21895 	if (prefix != NULL) {
   21896 	    const xmlChar *nsName = NULL;
   21897 
   21898 	    if (vctxt != NULL)
   21899 		nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
   21900 	    else if (node != NULL) {
   21901 		xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
   21902 		if (ns != NULL)
   21903 		    nsName = ns->href;
   21904 	    } else {
   21905 		xmlFree(prefix);
   21906 		xmlFree(localName);
   21907 		return (1);
   21908 	    }
   21909 	    if (nsName == NULL) {
   21910 		xmlFree(prefix);
   21911 		xmlFree(localName);
   21912 		return (1);
   21913 	    }
   21914 	    if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
   21915 		if ((valNeeded) && (val != NULL)) {
   21916 		    (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
   21917 						       xmlStrdup(nsName));
   21918 		    if (*val == NULL)
   21919 			ret = -1;
   21920 		}
   21921 	    } else
   21922 		ret = 1;
   21923 	    xmlFree(prefix);
   21924 	    xmlFree(localName);
   21925 	} else {
   21926 	    if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
   21927 		if (valNeeded && (val != NULL)) {
   21928 		    (*val) = xmlSchemaNewNOTATIONValue(
   21929 			BAD_CAST xmlStrdup(value), NULL);
   21930 		    if (*val == NULL)
   21931 			ret = -1;
   21932 		}
   21933 	    } else
   21934 		return (1);
   21935 	}
   21936     }
   21937     return (ret);
   21938 }
   21939 
   21940 static int
   21941 xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
   21942 		       const xmlChar* lname,
   21943 		       const xmlChar* nsname)
   21944 {
   21945     int i;
   21946 
   21947     lname = xmlDictLookup(vctxt->dict, lname, -1);
   21948     if (lname == NULL)
   21949 	return(-1);
   21950     if (nsname != NULL) {
   21951 	nsname = xmlDictLookup(vctxt->dict, nsname, -1);
   21952 	if (nsname == NULL)
   21953 	    return(-1);
   21954     }
   21955     for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
   21956 	if ((vctxt->nodeQNames->items [i] == lname) &&
   21957 	    (vctxt->nodeQNames->items[i +1] == nsname))
   21958 	    /* Already there */
   21959 	    return(i);
   21960     }
   21961     /* Add new entry. */
   21962     i = vctxt->nodeQNames->nbItems;
   21963     xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
   21964     xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
   21965     return(i);
   21966 }
   21967 
   21968 /************************************************************************
   21969  *									*
   21970  *  Validation of identity-constraints (IDC)                            *
   21971  *									*
   21972  ************************************************************************/
   21973 
   21974 /**
   21975  * xmlSchemaAugmentIDC:
   21976  * @idcDef: the IDC definition
   21977  *
   21978  * Creates an augmented IDC definition item.
   21979  *
   21980  * Returns the item, or NULL on internal errors.
   21981  */
   21982 static void
   21983 xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef,
   21984 		    xmlSchemaValidCtxtPtr vctxt)
   21985 {
   21986     xmlSchemaIDCAugPtr aidc;
   21987 
   21988     aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
   21989     if (aidc == NULL) {
   21990 	xmlSchemaVErrMemory(vctxt,
   21991 	    "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
   21992 	    NULL);
   21993 	return;
   21994     }
   21995     aidc->keyrefDepth = -1;
   21996     aidc->def = idcDef;
   21997     aidc->next = NULL;
   21998     if (vctxt->aidcs == NULL)
   21999 	vctxt->aidcs = aidc;
   22000     else {
   22001 	aidc->next = vctxt->aidcs;
   22002 	vctxt->aidcs = aidc;
   22003     }
   22004     /*
   22005     * Save if we have keyrefs at all.
   22006     */
   22007     if ((vctxt->hasKeyrefs == 0) &&
   22008 	(idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
   22009 	vctxt->hasKeyrefs = 1;
   22010 }
   22011 
   22012 /**
   22013  * xmlSchemaAugmentImportedIDC:
   22014  * @imported: the imported schema
   22015  *
   22016  * Creates an augmented IDC definition for the imported schema.
   22017  */
   22018 static void
   22019 xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) {
   22020     if (imported->schema->idcDef != NULL) {
   22021 	    xmlHashScan(imported->schema->idcDef ,
   22022 	    (xmlHashScanner) xmlSchemaAugmentIDC, vctxt);
   22023     }
   22024 }
   22025 
   22026 /**
   22027  * xmlSchemaIDCNewBinding:
   22028  * @idcDef: the IDC definition of this binding
   22029  *
   22030  * Creates a new IDC binding.
   22031  *
   22032  * Returns the new IDC binding, NULL on internal errors.
   22033  */
   22034 static xmlSchemaPSVIIDCBindingPtr
   22035 xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
   22036 {
   22037     xmlSchemaPSVIIDCBindingPtr ret;
   22038 
   22039     ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
   22040 	    sizeof(xmlSchemaPSVIIDCBinding));
   22041     if (ret == NULL) {
   22042 	xmlSchemaVErrMemory(NULL,
   22043 	    "allocating a PSVI IDC binding item", NULL);
   22044 	return (NULL);
   22045     }
   22046     memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
   22047     ret->definition = idcDef;
   22048     return (ret);
   22049 }
   22050 
   22051 /**
   22052  * xmlSchemaIDCStoreNodeTableItem:
   22053  * @vctxt: the WXS validation context
   22054  * @item: the IDC node table item
   22055  *
   22056  * The validation context is used to store IDC node table items.
   22057  * They are stored to avoid copying them if IDC node-tables are merged
   22058  * with corresponding parent IDC node-tables (bubbling).
   22059  *
   22060  * Returns 0 if succeeded, -1 on internal errors.
   22061  */
   22062 static int
   22063 xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
   22064 			       xmlSchemaPSVIIDCNodePtr item)
   22065 {
   22066     /*
   22067     * Add to gobal list.
   22068     */
   22069     if (vctxt->idcNodes == NULL) {
   22070 	vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
   22071 	    xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
   22072 	if (vctxt->idcNodes == NULL) {
   22073 	    xmlSchemaVErrMemory(vctxt,
   22074 		"allocating the IDC node table item list", NULL);
   22075 	    return (-1);
   22076 	}
   22077 	vctxt->sizeIdcNodes = 20;
   22078     } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
   22079 	vctxt->sizeIdcNodes *= 2;
   22080 	vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
   22081 	    xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
   22082 	    sizeof(xmlSchemaPSVIIDCNodePtr));
   22083 	if (vctxt->idcNodes == NULL) {
   22084 	    xmlSchemaVErrMemory(vctxt,
   22085 		"re-allocating the IDC node table item list", NULL);
   22086 	    return (-1);
   22087 	}
   22088     }
   22089     vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
   22090 
   22091     return (0);
   22092 }
   22093 
   22094 /**
   22095  * xmlSchemaIDCStoreKey:
   22096  * @vctxt: the WXS validation context
   22097  * @item: the IDC key
   22098  *
   22099  * The validation context is used to store an IDC key.
   22100  *
   22101  * Returns 0 if succeeded, -1 on internal errors.
   22102  */
   22103 static int
   22104 xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
   22105 		     xmlSchemaPSVIIDCKeyPtr key)
   22106 {
   22107     /*
   22108     * Add to gobal list.
   22109     */
   22110     if (vctxt->idcKeys == NULL) {
   22111 	vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
   22112 	    xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
   22113 	if (vctxt->idcKeys == NULL) {
   22114 	    xmlSchemaVErrMemory(vctxt,
   22115 		"allocating the IDC key storage list", NULL);
   22116 	    return (-1);
   22117 	}
   22118 	vctxt->sizeIdcKeys = 40;
   22119     } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
   22120 	vctxt->sizeIdcKeys *= 2;
   22121 	vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
   22122 	    xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
   22123 	    sizeof(xmlSchemaPSVIIDCKeyPtr));
   22124 	if (vctxt->idcKeys == NULL) {
   22125 	    xmlSchemaVErrMemory(vctxt,
   22126 		"re-allocating the IDC key storage list", NULL);
   22127 	    return (-1);
   22128 	}
   22129     }
   22130     vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
   22131 
   22132     return (0);
   22133 }
   22134 
   22135 /**
   22136  * xmlSchemaIDCAppendNodeTableItem:
   22137  * @bind: the IDC binding
   22138  * @ntItem: the node-table item
   22139  *
   22140  * Appends the IDC node-table item to the binding.
   22141  *
   22142  * Returns 0 on success and -1 on internal errors.
   22143  */
   22144 static int
   22145 xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
   22146 				xmlSchemaPSVIIDCNodePtr ntItem)
   22147 {
   22148     if (bind->nodeTable == NULL) {
   22149 	bind->sizeNodes = 10;
   22150 	bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   22151 	    xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
   22152 	if (bind->nodeTable == NULL) {
   22153 	    xmlSchemaVErrMemory(NULL,
   22154 		"allocating an array of IDC node-table items", NULL);
   22155 	    return(-1);
   22156 	}
   22157     } else if (bind->sizeNodes <= bind->nbNodes) {
   22158 	bind->sizeNodes *= 2;
   22159 	bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   22160 	    xmlRealloc(bind->nodeTable, bind->sizeNodes *
   22161 		sizeof(xmlSchemaPSVIIDCNodePtr));
   22162 	if (bind->nodeTable == NULL) {
   22163 	    xmlSchemaVErrMemory(NULL,
   22164 		"re-allocating an array of IDC node-table items", NULL);
   22165 	    return(-1);
   22166 	}
   22167     }
   22168     bind->nodeTable[bind->nbNodes++] = ntItem;
   22169     return(0);
   22170 }
   22171 
   22172 /**
   22173  * xmlSchemaIDCAcquireBinding:
   22174  * @vctxt: the WXS validation context
   22175  * @matcher: the IDC matcher
   22176  *
   22177  * Looks up an PSVI IDC binding, for the IDC definition and
   22178  * of the given matcher. If none found, a new one is created
   22179  * and added to the IDC table.
   22180  *
   22181  * Returns an IDC binding or NULL on internal errors.
   22182  */
   22183 static xmlSchemaPSVIIDCBindingPtr
   22184 xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
   22185 			  xmlSchemaIDCMatcherPtr matcher)
   22186 {
   22187     xmlSchemaNodeInfoPtr ielem;
   22188 
   22189     ielem = vctxt->elemInfos[matcher->depth];
   22190 
   22191     if (ielem->idcTable == NULL) {
   22192 	ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
   22193 	if (ielem->idcTable == NULL)
   22194 	    return (NULL);
   22195 	return(ielem->idcTable);
   22196     } else {
   22197 	xmlSchemaPSVIIDCBindingPtr bind = NULL;
   22198 
   22199 	bind = ielem->idcTable;
   22200 	do {
   22201 	    if (bind->definition == matcher->aidc->def)
   22202 		return(bind);
   22203 	    if (bind->next == NULL) {
   22204 		bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
   22205 		if (bind->next == NULL)
   22206 		    return (NULL);
   22207 		return(bind->next);
   22208 	    }
   22209 	    bind = bind->next;
   22210 	} while (bind != NULL);
   22211     }
   22212     return (NULL);
   22213 }
   22214 
   22215 static xmlSchemaItemListPtr
   22216 xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
   22217 			     xmlSchemaIDCMatcherPtr matcher)
   22218 {
   22219     if (matcher->targets == NULL)
   22220 	matcher->targets = xmlSchemaItemListCreate();
   22221     return(matcher->targets);
   22222 }
   22223 
   22224 /**
   22225  * xmlSchemaIDCFreeKey:
   22226  * @key: the IDC key
   22227  *
   22228  * Frees an IDC key together with its compiled value.
   22229  */
   22230 static void
   22231 xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
   22232 {
   22233     if (key->val != NULL)
   22234 	xmlSchemaFreeValue(key->val);
   22235     xmlFree(key);
   22236 }
   22237 
   22238 /**
   22239  * xmlSchemaIDCFreeBinding:
   22240  *
   22241  * Frees an IDC binding. Note that the node table-items
   22242  * are not freed.
   22243  */
   22244 static void
   22245 xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
   22246 {
   22247     if (bind->nodeTable != NULL)
   22248 	xmlFree(bind->nodeTable);
   22249     if (bind->dupls != NULL)
   22250 	xmlSchemaItemListFree(bind->dupls);
   22251     xmlFree(bind);
   22252 }
   22253 
   22254 /**
   22255  * xmlSchemaIDCFreeIDCTable:
   22256  * @bind: the first IDC binding in the list
   22257  *
   22258  * Frees an IDC table, i.e. all the IDC bindings in the list.
   22259  */
   22260 static void
   22261 xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
   22262 {
   22263     xmlSchemaPSVIIDCBindingPtr prev;
   22264 
   22265     while (bind != NULL) {
   22266 	prev = bind;
   22267 	bind = bind->next;
   22268 	xmlSchemaIDCFreeBinding(prev);
   22269     }
   22270 }
   22271 
   22272 /**
   22273  * xmlSchemaIDCFreeMatcherList:
   22274  * @matcher: the first IDC matcher in the list
   22275  *
   22276  * Frees a list of IDC matchers.
   22277  */
   22278 static void
   22279 xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
   22280 {
   22281     xmlSchemaIDCMatcherPtr next;
   22282 
   22283     while (matcher != NULL) {
   22284 	next = matcher->next;
   22285 	if (matcher->keySeqs != NULL) {
   22286 	    int i;
   22287 	    for (i = 0; i < matcher->sizeKeySeqs; i++)
   22288 		if (matcher->keySeqs[i] != NULL)
   22289 		    xmlFree(matcher->keySeqs[i]);
   22290 	    xmlFree(matcher->keySeqs);
   22291 	}
   22292 	if (matcher->targets != NULL) {
   22293 	    if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
   22294 		int i;
   22295 		xmlSchemaPSVIIDCNodePtr idcNode;
   22296 		/*
   22297 		* Node-table items for keyrefs are not stored globally
   22298 		* to the validation context, since they are not bubbled.
   22299 		* We need to free them here.
   22300 		*/
   22301 		for (i = 0; i < matcher->targets->nbItems; i++) {
   22302 		    idcNode =
   22303 			(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
   22304 		    xmlFree(idcNode->keys);
   22305 		    xmlFree(idcNode);
   22306 		}
   22307 	    }
   22308 	    xmlSchemaItemListFree(matcher->targets);
   22309 	}
   22310 	xmlFree(matcher);
   22311 	matcher = next;
   22312     }
   22313 }
   22314 
   22315 /**
   22316  * xmlSchemaIDCReleaseMatcherList:
   22317  * @vctxt: the WXS validation context
   22318  * @matcher: the first IDC matcher in the list
   22319  *
   22320  * Caches a list of IDC matchers for reuse.
   22321  */
   22322 static void
   22323 xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
   22324 			       xmlSchemaIDCMatcherPtr matcher)
   22325 {
   22326     xmlSchemaIDCMatcherPtr next;
   22327 
   22328     while (matcher != NULL) {
   22329 	next = matcher->next;
   22330 	if (matcher->keySeqs != NULL) {
   22331 	    int i;
   22332 	    /*
   22333 	    * Don't free the array, but only the content.
   22334 	    */
   22335 	    for (i = 0; i < matcher->sizeKeySeqs; i++)
   22336 		if (matcher->keySeqs[i] != NULL) {
   22337 		    xmlFree(matcher->keySeqs[i]);
   22338 		    matcher->keySeqs[i] = NULL;
   22339 		}
   22340 	}
   22341 	if (matcher->targets) {
   22342 	    if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
   22343 		int i;
   22344 		xmlSchemaPSVIIDCNodePtr idcNode;
   22345 		/*
   22346 		* Node-table items for keyrefs are not stored globally
   22347 		* to the validation context, since they are not bubbled.
   22348 		* We need to free them here.
   22349 		*/
   22350 		for (i = 0; i < matcher->targets->nbItems; i++) {
   22351 		    idcNode =
   22352 			(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
   22353 		    xmlFree(idcNode->keys);
   22354 		    xmlFree(idcNode);
   22355 		}
   22356 	    }
   22357 	    xmlSchemaItemListFree(matcher->targets);
   22358 	    matcher->targets = NULL;
   22359 	}
   22360 	matcher->next = NULL;
   22361 	/*
   22362 	* Cache the matcher.
   22363 	*/
   22364 	if (vctxt->idcMatcherCache != NULL)
   22365 	    matcher->nextCached = vctxt->idcMatcherCache;
   22366 	vctxt->idcMatcherCache = matcher;
   22367 
   22368 	matcher = next;
   22369     }
   22370 }
   22371 
   22372 /**
   22373  * xmlSchemaIDCAddStateObject:
   22374  * @vctxt: the WXS validation context
   22375  * @matcher: the IDC matcher
   22376  * @sel: the XPath information
   22377  * @parent: the parent "selector" state object if any
   22378  * @type: "selector" or "field"
   22379  *
   22380  * Creates/reuses and activates state objects for the given
   22381  * XPath information; if the XPath expression consists of unions,
   22382  * multiple state objects are created for every unioned expression.
   22383  *
   22384  * Returns 0 on success and -1 on internal errors.
   22385  */
   22386 static int
   22387 xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
   22388 			xmlSchemaIDCMatcherPtr matcher,
   22389 			xmlSchemaIDCSelectPtr sel,
   22390 			int type)
   22391 {
   22392     xmlSchemaIDCStateObjPtr sto;
   22393 
   22394     /*
   22395     * Reuse the state objects from the pool.
   22396     */
   22397     if (vctxt->xpathStatePool != NULL) {
   22398 	sto = vctxt->xpathStatePool;
   22399 	vctxt->xpathStatePool = sto->next;
   22400 	sto->next = NULL;
   22401     } else {
   22402 	/*
   22403 	* Create a new state object.
   22404 	*/
   22405 	sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
   22406 	if (sto == NULL) {
   22407 	    xmlSchemaVErrMemory(NULL,
   22408 		"allocating an IDC state object", NULL);
   22409 	    return (-1);
   22410 	}
   22411 	memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
   22412     }
   22413     /*
   22414     * Add to global list.
   22415     */
   22416     if (vctxt->xpathStates != NULL)
   22417 	sto->next = vctxt->xpathStates;
   22418     vctxt->xpathStates = sto;
   22419 
   22420     /*
   22421     * Free the old xpath validation context.
   22422     */
   22423     if (sto->xpathCtxt != NULL)
   22424 	xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
   22425 
   22426     /*
   22427     * Create a new XPath (pattern) validation context.
   22428     */
   22429     sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
   22430 	(xmlPatternPtr) sel->xpathComp);
   22431     if (sto->xpathCtxt == NULL) {
   22432 	VERROR_INT("xmlSchemaIDCAddStateObject",
   22433 	    "failed to create an XPath validation context");
   22434 	return (-1);
   22435     }
   22436     sto->type = type;
   22437     sto->depth = vctxt->depth;
   22438     sto->matcher = matcher;
   22439     sto->sel = sel;
   22440     sto->nbHistory = 0;
   22441 
   22442 #ifdef DEBUG_IDC
   22443     xmlGenericError(xmlGenericErrorContext, "IDC:   STO push '%s'\n",
   22444 	sto->sel->xpath);
   22445 #endif
   22446     return (0);
   22447 }
   22448 
   22449 /**
   22450  * xmlSchemaXPathEvaluate:
   22451  * @vctxt: the WXS validation context
   22452  * @nodeType: the nodeType of the current node
   22453  *
   22454  * Evaluates all active XPath state objects.
   22455  *
   22456  * Returns the number of IC "field" state objects which resolved to
   22457  * this node, 0 if none resolved and -1 on internal errors.
   22458  */
   22459 static int
   22460 xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
   22461 		       xmlElementType nodeType)
   22462 {
   22463     xmlSchemaIDCStateObjPtr sto, head = NULL, first;
   22464     int res, resolved = 0, depth = vctxt->depth;
   22465 
   22466     if (vctxt->xpathStates == NULL)
   22467 	return (0);
   22468 
   22469     if (nodeType == XML_ATTRIBUTE_NODE)
   22470 	depth++;
   22471 #ifdef DEBUG_IDC
   22472     {
   22473 	xmlChar *str = NULL;
   22474 	xmlGenericError(xmlGenericErrorContext,
   22475 	    "IDC: EVAL on %s, depth %d, type %d\n",
   22476 	    xmlSchemaFormatQName(&str, vctxt->inode->nsName,
   22477 		vctxt->inode->localName), depth, nodeType);
   22478 	FREE_AND_NULL(str)
   22479     }
   22480 #endif
   22481     /*
   22482     * Process all active XPath state objects.
   22483     */
   22484     first = vctxt->xpathStates;
   22485     sto = first;
   22486     while (sto != head) {
   22487 #ifdef DEBUG_IDC
   22488 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
   22489 	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] selector '%s'\n",
   22490 		sto->matcher->aidc->def->name, sto->sel->xpath);
   22491 	else
   22492 	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] field '%s'\n",
   22493 		sto->matcher->aidc->def->name, sto->sel->xpath);
   22494 #endif
   22495 	if (nodeType == XML_ELEMENT_NODE)
   22496 	    res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
   22497 		vctxt->inode->localName, vctxt->inode->nsName);
   22498 	else
   22499 	    res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
   22500 		vctxt->inode->localName, vctxt->inode->nsName);
   22501 
   22502 	if (res == -1) {
   22503 	    VERROR_INT("xmlSchemaXPathEvaluate",
   22504 		"calling xmlStreamPush()");
   22505 	    return (-1);
   22506 	}
   22507 	if (res == 0)
   22508 	    goto next_sto;
   22509 	/*
   22510 	* Full match.
   22511 	*/
   22512 #ifdef DEBUG_IDC
   22513 	xmlGenericError(xmlGenericErrorContext, "IDC:     "
   22514 	    "MATCH\n");
   22515 #endif
   22516 	/*
   22517 	* Register a match in the state object history.
   22518 	*/
   22519 	if (sto->history == NULL) {
   22520 	    sto->history = (int *) xmlMalloc(5 * sizeof(int));
   22521 	    if (sto->history == NULL) {
   22522 		xmlSchemaVErrMemory(NULL,
   22523 		    "allocating the state object history", NULL);
   22524 		return(-1);
   22525 	    }
   22526 	    sto->sizeHistory = 5;
   22527 	} else if (sto->sizeHistory <= sto->nbHistory) {
   22528 	    sto->sizeHistory *= 2;
   22529 	    sto->history = (int *) xmlRealloc(sto->history,
   22530 		sto->sizeHistory * sizeof(int));
   22531 	    if (sto->history == NULL) {
   22532 		xmlSchemaVErrMemory(NULL,
   22533 		    "re-allocating the state object history", NULL);
   22534 		return(-1);
   22535 	    }
   22536 	}
   22537 	sto->history[sto->nbHistory++] = depth;
   22538 
   22539 #ifdef DEBUG_IDC
   22540 	xmlGenericError(xmlGenericErrorContext, "IDC:       push match '%d'\n",
   22541 	    vctxt->depth);
   22542 #endif
   22543 
   22544 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
   22545 	    xmlSchemaIDCSelectPtr sel;
   22546 	    /*
   22547 	    * Activate state objects for the IDC fields of
   22548 	    * the IDC selector.
   22549 	    */
   22550 #ifdef DEBUG_IDC
   22551 	    xmlGenericError(xmlGenericErrorContext, "IDC:     "
   22552 		"activating field states\n");
   22553 #endif
   22554 	    sel = sto->matcher->aidc->def->fields;
   22555 	    while (sel != NULL) {
   22556 		if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
   22557 		    sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
   22558 		    return (-1);
   22559 		sel = sel->next;
   22560 	    }
   22561 	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
   22562 	    /*
   22563 	    * An IDC key node was found by the IDC field.
   22564 	    */
   22565 #ifdef DEBUG_IDC
   22566 	    xmlGenericError(xmlGenericErrorContext,
   22567 		"IDC:     key found\n");
   22568 #endif
   22569 	    /*
   22570 	    * Notify that the character value of this node is
   22571 	    * needed.
   22572 	    */
   22573 	    if (resolved == 0) {
   22574 		if ((vctxt->inode->flags &
   22575 		    XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
   22576 		vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
   22577 	    }
   22578 	    resolved++;
   22579 	}
   22580 next_sto:
   22581 	if (sto->next == NULL) {
   22582 	    /*
   22583 	    * Evaluate field state objects created on this node as well.
   22584 	    */
   22585 	    head = first;
   22586 	    sto = vctxt->xpathStates;
   22587 	} else
   22588 	    sto = sto->next;
   22589     }
   22590     return (resolved);
   22591 }
   22592 
   22593 static const xmlChar *
   22594 xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
   22595 			      xmlChar **buf,
   22596 			      xmlSchemaPSVIIDCKeyPtr *seq,
   22597 			      int count)
   22598 {
   22599     int i, res;
   22600     xmlChar *value = NULL;
   22601 
   22602     *buf = xmlStrdup(BAD_CAST "[");
   22603     for (i = 0; i < count; i++) {
   22604 	*buf = xmlStrcat(*buf, BAD_CAST "'");
   22605 	res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
   22606 	    xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
   22607 	    &value);
   22608 	if (res == 0)
   22609 	    *buf = xmlStrcat(*buf, BAD_CAST value);
   22610 	else {
   22611 	    VERROR_INT("xmlSchemaFormatIDCKeySequence",
   22612 		"failed to compute a canonical value");
   22613 	    *buf = xmlStrcat(*buf, BAD_CAST "???");
   22614 	}
   22615 	if (i < count -1)
   22616 	    *buf = xmlStrcat(*buf, BAD_CAST "', ");
   22617 	else
   22618 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
   22619 	if (value != NULL) {
   22620 	    xmlFree(value);
   22621 	    value = NULL;
   22622 	}
   22623     }
   22624     *buf = xmlStrcat(*buf, BAD_CAST "]");
   22625 
   22626     return (BAD_CAST *buf);
   22627 }
   22628 
   22629 /**
   22630  * xmlSchemaXPathPop:
   22631  * @vctxt: the WXS validation context
   22632  *
   22633  * Pops all XPath states.
   22634  *
   22635  * Returns 0 on success and -1 on internal errors.
   22636  */
   22637 static int
   22638 xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
   22639 {
   22640     xmlSchemaIDCStateObjPtr sto;
   22641     int res;
   22642 
   22643     if (vctxt->xpathStates == NULL)
   22644 	return(0);
   22645     sto = vctxt->xpathStates;
   22646     do {
   22647 	res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
   22648 	if (res == -1)
   22649 	    return (-1);
   22650 	sto = sto->next;
   22651     } while (sto != NULL);
   22652     return(0);
   22653 }
   22654 
   22655 /**
   22656  * xmlSchemaXPathProcessHistory:
   22657  * @vctxt: the WXS validation context
   22658  * @type: the simple/complex type of the current node if any at all
   22659  * @val: the precompiled value
   22660  *
   22661  * Processes and pops the history items of the IDC state objects.
   22662  * IDC key-sequences are validated/created on IDC bindings.
   22663  *
   22664  * Returns 0 on success and -1 on internal errors.
   22665  */
   22666 static int
   22667 xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
   22668 			     int depth)
   22669 {
   22670     xmlSchemaIDCStateObjPtr sto, nextsto;
   22671     int res, matchDepth;
   22672     xmlSchemaPSVIIDCKeyPtr key = NULL;
   22673     xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
   22674 
   22675     if (vctxt->xpathStates == NULL)
   22676 	return (0);
   22677     sto = vctxt->xpathStates;
   22678 
   22679 #ifdef DEBUG_IDC
   22680     {
   22681 	xmlChar *str = NULL;
   22682 	xmlGenericError(xmlGenericErrorContext,
   22683 	    "IDC: BACK on %s, depth %d\n",
   22684 	    xmlSchemaFormatQName(&str, vctxt->inode->nsName,
   22685 		vctxt->inode->localName), vctxt->depth);
   22686 	FREE_AND_NULL(str)
   22687     }
   22688 #endif
   22689     /*
   22690     * Evaluate the state objects.
   22691     */
   22692     while (sto != NULL) {
   22693 	res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
   22694 	if (res == -1) {
   22695 	    VERROR_INT("xmlSchemaXPathProcessHistory",
   22696 		"calling xmlStreamPop()");
   22697 	    return (-1);
   22698 	}
   22699 #ifdef DEBUG_IDC
   22700 	xmlGenericError(xmlGenericErrorContext, "IDC:   stream pop '%s'\n",
   22701 	    sto->sel->xpath);
   22702 #endif
   22703 	if (sto->nbHistory == 0)
   22704 	    goto deregister_check;
   22705 
   22706 	matchDepth = sto->history[sto->nbHistory -1];
   22707 
   22708 	/*
   22709 	* Only matches at the current depth are of interest.
   22710 	*/
   22711 	if (matchDepth != depth) {
   22712 	    sto = sto->next;
   22713 	    continue;
   22714 	}
   22715 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
   22716 	    /*
   22717 	    * NOTE: According to
   22718 	    *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
   22719 	    *   ... the simple-content of complex types is also allowed.
   22720 	    */
   22721 
   22722 	    if (WXS_IS_COMPLEX(type)) {
   22723 		if (WXS_HAS_SIMPLE_CONTENT(type)) {
   22724 		    /*
   22725 		    * Sanity check for complex types with simple content.
   22726 		    */
   22727 		    simpleType = type->contentTypeDef;
   22728 		    if (simpleType == NULL) {
   22729 			VERROR_INT("xmlSchemaXPathProcessHistory",
   22730 			    "field resolves to a CT with simple content "
   22731 			    "but the CT is missing the ST definition");
   22732 			return (-1);
   22733 		    }
   22734 		} else
   22735 		    simpleType = NULL;
   22736 	    } else
   22737 		simpleType = type;
   22738 	    if (simpleType == NULL) {
   22739 		xmlChar *str = NULL;
   22740 
   22741 		/*
   22742 		* Not qualified if the field resolves to a node of non
   22743 		* simple type.
   22744 		*/
   22745 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   22746 		    XML_SCHEMAV_CVC_IDC, NULL,
   22747 		    WXS_BASIC_CAST sto->matcher->aidc->def,
   22748 		    "The XPath '%s' of a field of %s does evaluate to a node of "
   22749 		    "non-simple type",
   22750 		    sto->sel->xpath,
   22751 		    xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
   22752 		FREE_AND_NULL(str);
   22753 		sto->nbHistory--;
   22754 		goto deregister_check;
   22755 	    }
   22756 
   22757 	    if ((key == NULL) && (vctxt->inode->val == NULL)) {
   22758 		/*
   22759 		* Failed to provide the normalized value; maybe
   22760 		* the value was invalid.
   22761 		*/
   22762 		VERROR(XML_SCHEMAV_CVC_IDC,
   22763 		    WXS_BASIC_CAST sto->matcher->aidc->def,
   22764 		    "Warning: No precomputed value available, the value "
   22765 		    "was either invalid or something strange happend");
   22766 		sto->nbHistory--;
   22767 		goto deregister_check;
   22768 	    } else {
   22769 		xmlSchemaIDCMatcherPtr matcher = sto->matcher;
   22770 		xmlSchemaPSVIIDCKeyPtr *keySeq;
   22771 		int pos, idx;
   22772 
   22773 		/*
   22774 		* The key will be anchored on the matcher's list of
   22775 		* key-sequences. The position in this list is determined
   22776 		* by the target node's depth relative to the matcher's
   22777 		* depth of creation (i.e. the depth of the scope element).
   22778 		*
   22779 		* Element        Depth    Pos   List-entries
   22780 		* <scope>          0              NULL
   22781 		*   <bar>          1              NULL
   22782 		*     <target/>    2       2      target
   22783 		*   <bar>
   22784                 * </scope>
   22785 		*
   22786 		* The size of the list is only dependant on the depth of
   22787 		* the tree.
   22788 		* An entry will be NULLed in selector_leave, i.e. when
   22789 		* we hit the target's
   22790 		*/
   22791 		pos = sto->depth - matcher->depth;
   22792 		idx = sto->sel->index;
   22793 
   22794 		/*
   22795 		* Create/grow the array of key-sequences.
   22796 		*/
   22797 		if (matcher->keySeqs == NULL) {
   22798 		    if (pos > 9)
   22799 			matcher->sizeKeySeqs = pos * 2;
   22800 		    else
   22801 			matcher->sizeKeySeqs = 10;
   22802 		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
   22803 			xmlMalloc(matcher->sizeKeySeqs *
   22804 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
   22805 		    if (matcher->keySeqs == NULL) {
   22806 			xmlSchemaVErrMemory(NULL,
   22807 			    "allocating an array of key-sequences",
   22808 			    NULL);
   22809 			return(-1);
   22810 		    }
   22811 		    memset(matcher->keySeqs, 0,
   22812 			matcher->sizeKeySeqs *
   22813 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
   22814 		} else if (pos >= matcher->sizeKeySeqs) {
   22815 		    int i = matcher->sizeKeySeqs;
   22816 
   22817 		    matcher->sizeKeySeqs *= 2;
   22818 		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
   22819 			xmlRealloc(matcher->keySeqs,
   22820 			matcher->sizeKeySeqs *
   22821 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
   22822 		    if (matcher->keySeqs == NULL) {
   22823 			xmlSchemaVErrMemory(NULL,
   22824 			    "reallocating an array of key-sequences",
   22825 			    NULL);
   22826 			return (-1);
   22827 		    }
   22828 		    /*
   22829 		    * The array needs to be NULLed.
   22830 		    * TODO: Use memset?
   22831 		    */
   22832 		    for (; i < matcher->sizeKeySeqs; i++)
   22833 			matcher->keySeqs[i] = NULL;
   22834 		}
   22835 
   22836 		/*
   22837 		* Get/create the key-sequence.
   22838 		*/
   22839 		keySeq = matcher->keySeqs[pos];
   22840 		if (keySeq == NULL) {
   22841 		    goto create_sequence;
   22842 		} else if (keySeq[idx] != NULL) {
   22843 		    xmlChar *str = NULL;
   22844 		    /*
   22845 		    * cvc-identity-constraint:
   22846 		    * 3 For each node in the `target node set` all
   22847 		    * of the {fields}, with that node as the context
   22848 		    * node, evaluate to either an empty node-set or
   22849 		    * a node-set with exactly one member, which must
   22850 		    * have a simple type.
   22851 		    *
   22852 		    * The key was already set; report an error.
   22853 		    */
   22854 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
   22855 			XML_SCHEMAV_CVC_IDC, NULL,
   22856 			WXS_BASIC_CAST matcher->aidc->def,
   22857 			"The XPath '%s' of a field of %s evaluates to a "
   22858 			"node-set with more than one member",
   22859 			sto->sel->xpath,
   22860 			xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
   22861 		    FREE_AND_NULL(str);
   22862 		    sto->nbHistory--;
   22863 		    goto deregister_check;
   22864 		} else
   22865 		    goto create_key;
   22866 
   22867 create_sequence:
   22868 		/*
   22869 		* Create a key-sequence.
   22870 		*/
   22871 		keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
   22872 		    matcher->aidc->def->nbFields *
   22873 		    sizeof(xmlSchemaPSVIIDCKeyPtr));
   22874 		if (keySeq == NULL) {
   22875 		    xmlSchemaVErrMemory(NULL,
   22876 			"allocating an IDC key-sequence", NULL);
   22877 		    return(-1);
   22878 		}
   22879 		memset(keySeq, 0, matcher->aidc->def->nbFields *
   22880 		    sizeof(xmlSchemaPSVIIDCKeyPtr));
   22881 		matcher->keySeqs[pos] = keySeq;
   22882 create_key:
   22883 		/*
   22884 		* Create a key once per node only.
   22885 		*/
   22886 		if (key == NULL) {
   22887 		    key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
   22888 			sizeof(xmlSchemaPSVIIDCKey));
   22889 		    if (key == NULL) {
   22890 			xmlSchemaVErrMemory(NULL,
   22891 			    "allocating a IDC key", NULL);
   22892 			xmlFree(keySeq);
   22893 			matcher->keySeqs[pos] = NULL;
   22894 			return(-1);
   22895 		    }
   22896 		    /*
   22897 		    * Consume the compiled value.
   22898 		    */
   22899 		    key->type = simpleType;
   22900 		    key->val = vctxt->inode->val;
   22901 		    vctxt->inode->val = NULL;
   22902 		    /*
   22903 		    * Store the key in a global list.
   22904 		    */
   22905 		    if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
   22906 			xmlSchemaIDCFreeKey(key);
   22907 			return (-1);
   22908 		    }
   22909 		}
   22910 		keySeq[idx] = key;
   22911 	    }
   22912 	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
   22913 
   22914 	    xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
   22915 	    /* xmlSchemaPSVIIDCBindingPtr bind; */
   22916 	    xmlSchemaPSVIIDCNodePtr ntItem;
   22917 	    xmlSchemaIDCMatcherPtr matcher;
   22918 	    xmlSchemaIDCPtr idc;
   22919 	    xmlSchemaItemListPtr targets;
   22920 	    int pos, i, j, nbKeys;
   22921 	    /*
   22922 	    * Here we have the following scenario:
   22923 	    * An IDC 'selector' state object resolved to a target node,
   22924 	    * during the time this target node was in the
   22925 	    * ancestor-or-self axis, the 'field' state object(s) looked
   22926 	    * out for matching nodes to create a key-sequence for this
   22927 	    * target node. Now we are back to this target node and need
   22928 	    * to put the key-sequence, together with the target node
   22929 	    * itself, into the node-table of the corresponding IDC
   22930 	    * binding.
   22931 	    */
   22932 	    matcher = sto->matcher;
   22933 	    idc = matcher->aidc->def;
   22934 	    nbKeys = idc->nbFields;
   22935 	    pos = depth - matcher->depth;
   22936 	    /*
   22937 	    * Check if the matcher has any key-sequences at all, plus
   22938 	    * if it has a key-sequence for the current target node.
   22939 	    */
   22940 	    if ((matcher->keySeqs == NULL) ||
   22941 		(matcher->sizeKeySeqs <= pos)) {
   22942 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
   22943 		    goto selector_key_error;
   22944 		else
   22945 		    goto selector_leave;
   22946 	    }
   22947 
   22948 	    keySeq = &(matcher->keySeqs[pos]);
   22949 	    if (*keySeq == NULL) {
   22950 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
   22951 		    goto selector_key_error;
   22952 		else
   22953 		    goto selector_leave;
   22954 	    }
   22955 
   22956 	    for (i = 0; i < nbKeys; i++) {
   22957 		if ((*keySeq)[i] == NULL) {
   22958 		    /*
   22959 		    * Not qualified, if not all fields did resolve.
   22960 		    */
   22961 		    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
   22962 			/*
   22963 			* All fields of a "key" IDC must resolve.
   22964 			*/
   22965 			goto selector_key_error;
   22966 		    }
   22967 		    goto selector_leave;
   22968 		}
   22969 	    }
   22970 	    /*
   22971 	    * All fields did resolve.
   22972 	    */
   22973 
   22974 	    /*
   22975 	    * 4.1 If the {identity-constraint category} is unique(/key),
   22976 	    * then no two members of the `qualified node set` have
   22977 	    * `key-sequences` whose members are pairwise equal, as
   22978 	    * defined by Equal in [XML Schemas: Datatypes].
   22979 	    *
   22980 	    * Get the IDC binding from the matcher and check for
   22981 	    * duplicate key-sequences.
   22982 	    */
   22983 #if 0
   22984 	    bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
   22985 #endif
   22986 	    targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
   22987 	    if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
   22988 		(targets->nbItems != 0)) {
   22989 		xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
   22990 
   22991 		i = 0;
   22992 		res = 0;
   22993 		/*
   22994 		* Compare the key-sequences, key by key.
   22995 		*/
   22996 		do {
   22997 		    bkeySeq =
   22998 			((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys;
   22999 		    for (j = 0; j < nbKeys; j++) {
   23000 			ckey = (*keySeq)[j];
   23001 			bkey = bkeySeq[j];
   23002 			res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
   23003 			if (res == -1) {
   23004 			    return (-1);
   23005 			} else if (res == 0) {
   23006 			    /*
   23007 			    * One of the keys differs, so the key-sequence
   23008 			    * won't be equal; get out.
   23009 			    */
   23010 			    break;
   23011 			}
   23012 		    }
   23013 		    if (res == 1) {
   23014 			/*
   23015 			* Duplicate key-sequence found.
   23016 			*/
   23017 			break;
   23018 		    }
   23019 		    i++;
   23020 		} while (i < targets->nbItems);
   23021 		if (i != targets->nbItems) {
   23022 		    xmlChar *str = NULL, *strB = NULL;
   23023 		    /*
   23024 		    * TODO: Try to report the key-sequence.
   23025 		    */
   23026 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
   23027 			XML_SCHEMAV_CVC_IDC, NULL,
   23028 			WXS_BASIC_CAST idc,
   23029 			"Duplicate key-sequence %s in %s",
   23030 			xmlSchemaFormatIDCKeySequence(vctxt, &str,
   23031 			    (*keySeq), nbKeys),
   23032 			xmlSchemaGetIDCDesignation(&strB, idc));
   23033 		    FREE_AND_NULL(str);
   23034 		    FREE_AND_NULL(strB);
   23035 		    goto selector_leave;
   23036 		}
   23037 	    }
   23038 	    /*
   23039 	    * Add a node-table item to the IDC binding.
   23040 	    */
   23041 	    ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
   23042 		sizeof(xmlSchemaPSVIIDCNode));
   23043 	    if (ntItem == NULL) {
   23044 		xmlSchemaVErrMemory(NULL,
   23045 		    "allocating an IDC node-table item", NULL);
   23046 		xmlFree(*keySeq);
   23047 		*keySeq = NULL;
   23048 		return(-1);
   23049 	    }
   23050 	    memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
   23051 
   23052 	    /*
   23053 	    * Store the node-table item in a global list.
   23054 	    */
   23055 	    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
   23056 		if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
   23057 		    xmlFree(ntItem);
   23058 		    xmlFree(*keySeq);
   23059 		    *keySeq = NULL;
   23060 		    return (-1);
   23061 		}
   23062 		ntItem->nodeQNameID = -1;
   23063 	    } else {
   23064 		/*
   23065 		* Save a cached QName for this node on the IDC node, to be
   23066 		* able to report it, even if the node is not saved.
   23067 		*/
   23068 		ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
   23069 		    vctxt->inode->localName, vctxt->inode->nsName);
   23070 		if (ntItem->nodeQNameID == -1) {
   23071 		    xmlFree(ntItem);
   23072 		    xmlFree(*keySeq);
   23073 		    *keySeq = NULL;
   23074 		    return (-1);
   23075 		}
   23076 	    }
   23077 	    /*
   23078 	    * Init the node-table item: Save the node, position and
   23079 	    * consume the key-sequence.
   23080 	    */
   23081 	    ntItem->node = vctxt->node;
   23082 	    ntItem->nodeLine = vctxt->inode->nodeLine;
   23083 	    ntItem->keys = *keySeq;
   23084 	    *keySeq = NULL;
   23085 #if 0
   23086 	    if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
   23087 #endif
   23088 	    if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
   23089 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
   23090 		    /*
   23091 		    * Free the item, since keyref items won't be
   23092 		    * put on a global list.
   23093 		    */
   23094 		    xmlFree(ntItem->keys);
   23095 		    xmlFree(ntItem);
   23096 		}
   23097 		return (-1);
   23098 	    }
   23099 
   23100 	    goto selector_leave;
   23101 selector_key_error:
   23102 	    {
   23103 		xmlChar *str = NULL;
   23104 		/*
   23105 		* 4.2.1 (KEY) The `target node set` and the
   23106 		* `qualified node set` are equal, that is, every
   23107 		* member of the `target node set` is also a member
   23108 		* of the `qualified node set` and vice versa.
   23109 		*/
   23110 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   23111 		    XML_SCHEMAV_CVC_IDC, NULL,
   23112 		    WXS_BASIC_CAST idc,
   23113 		    "Not all fields of %s evaluate to a node",
   23114 		    xmlSchemaGetIDCDesignation(&str, idc), NULL);
   23115 		FREE_AND_NULL(str);
   23116 	    }
   23117 selector_leave:
   23118 	    /*
   23119 	    * Free the key-sequence if not added to the IDC table.
   23120 	    */
   23121 	    if ((keySeq != NULL) && (*keySeq != NULL)) {
   23122 		xmlFree(*keySeq);
   23123 		*keySeq = NULL;
   23124 	    }
   23125 	} /* if selector */
   23126 
   23127 	sto->nbHistory--;
   23128 
   23129 deregister_check:
   23130 	/*
   23131 	* Deregister state objects if they reach the depth of creation.
   23132 	*/
   23133 	if ((sto->nbHistory == 0) && (sto->depth == depth)) {
   23134 #ifdef DEBUG_IDC
   23135 	    xmlGenericError(xmlGenericErrorContext, "IDC:   STO pop '%s'\n",
   23136 		sto->sel->xpath);
   23137 #endif
   23138 	    if (vctxt->xpathStates != sto) {
   23139 		VERROR_INT("xmlSchemaXPathProcessHistory",
   23140 		    "The state object to be removed is not the first "
   23141 		    "in the list");
   23142 	    }
   23143 	    nextsto = sto->next;
   23144 	    /*
   23145 	    * Unlink from the list of active XPath state objects.
   23146 	    */
   23147 	    vctxt->xpathStates = sto->next;
   23148 	    sto->next = vctxt->xpathStatePool;
   23149 	    /*
   23150 	    * Link it to the pool of reusable state objects.
   23151 	    */
   23152 	    vctxt->xpathStatePool = sto;
   23153 	    sto = nextsto;
   23154 	} else
   23155 	    sto = sto->next;
   23156     } /* while (sto != NULL) */
   23157     return (0);
   23158 }
   23159 
   23160 /**
   23161  * xmlSchemaIDCRegisterMatchers:
   23162  * @vctxt: the WXS validation context
   23163  * @elemDecl: the element declaration
   23164  *
   23165  * Creates helper objects to evaluate IDC selectors/fields
   23166  * successively.
   23167  *
   23168  * Returns 0 if OK and -1 on internal errors.
   23169  */
   23170 static int
   23171 xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
   23172 			     xmlSchemaElementPtr elemDecl)
   23173 {
   23174     xmlSchemaIDCMatcherPtr matcher, last = NULL;
   23175     xmlSchemaIDCPtr idc, refIdc;
   23176     xmlSchemaIDCAugPtr aidc;
   23177 
   23178     idc = (xmlSchemaIDCPtr) elemDecl->idcs;
   23179     if (idc == NULL)
   23180 	return (0);
   23181 
   23182 #ifdef DEBUG_IDC
   23183     {
   23184 	xmlChar *str = NULL;
   23185 	xmlGenericError(xmlGenericErrorContext,
   23186 	    "IDC: REGISTER on %s, depth %d\n",
   23187 	    (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
   23188 		vctxt->inode->localName), vctxt->depth);
   23189 	FREE_AND_NULL(str)
   23190     }
   23191 #endif
   23192     if (vctxt->inode->idcMatchers != NULL) {
   23193 	VERROR_INT("xmlSchemaIDCRegisterMatchers",
   23194 	    "The chain of IDC matchers is expected to be empty");
   23195 	return (-1);
   23196     }
   23197     do {
   23198 	if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
   23199 	    /*
   23200 	    * Since IDCs bubbles are expensive we need to know the
   23201 	    * depth at which the bubbles should stop; this will be
   23202 	    * the depth of the top-most keyref IDC. If no keyref
   23203 	    * references a key/unique IDC, the keyrefDepth will
   23204 	    * be -1, indicating that no bubbles are needed.
   23205 	    */
   23206 	    refIdc = (xmlSchemaIDCPtr) idc->ref->item;
   23207 	    if (refIdc != NULL) {
   23208 		/*
   23209 		* Remember that we have keyrefs on this node.
   23210 		*/
   23211 		vctxt->inode->hasKeyrefs = 1;
   23212 		/*
   23213 		* Lookup the referenced augmented IDC info.
   23214 		*/
   23215 		aidc = vctxt->aidcs;
   23216 		while (aidc != NULL) {
   23217 		    if (aidc->def == refIdc)
   23218 			break;
   23219 		    aidc = aidc->next;
   23220 		}
   23221 		if (aidc == NULL) {
   23222 		    VERROR_INT("xmlSchemaIDCRegisterMatchers",
   23223 			"Could not find an augmented IDC item for an IDC "
   23224 			"definition");
   23225 		    return (-1);
   23226 		}
   23227 		if ((aidc->keyrefDepth == -1) ||
   23228 		    (vctxt->depth < aidc->keyrefDepth))
   23229 		    aidc->keyrefDepth = vctxt->depth;
   23230 	    }
   23231 	}
   23232 	/*
   23233 	* Lookup the augmented IDC item for the IDC definition.
   23234 	*/
   23235 	aidc = vctxt->aidcs;
   23236 	while (aidc != NULL) {
   23237 	    if (aidc->def == idc)
   23238 		break;
   23239 	    aidc = aidc->next;
   23240 	}
   23241 	if (aidc == NULL) {
   23242 	    VERROR_INT("xmlSchemaIDCRegisterMatchers",
   23243 		"Could not find an augmented IDC item for an IDC definition");
   23244 	    return (-1);
   23245 	}
   23246 	/*
   23247 	* Create an IDC matcher for every IDC definition.
   23248 	*/
   23249 	if (vctxt->idcMatcherCache != NULL) {
   23250 	    /*
   23251 	    * Reuse a cached matcher.
   23252 	    */
   23253 	    matcher = vctxt->idcMatcherCache;
   23254 	    vctxt->idcMatcherCache = matcher->nextCached;
   23255 	    matcher->nextCached = NULL;
   23256 	} else {
   23257 	    matcher = (xmlSchemaIDCMatcherPtr)
   23258 		xmlMalloc(sizeof(xmlSchemaIDCMatcher));
   23259 	    if (matcher == NULL) {
   23260 		xmlSchemaVErrMemory(vctxt,
   23261 		    "allocating an IDC matcher", NULL);
   23262 		return (-1);
   23263 	    }
   23264 	    memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
   23265 	}
   23266 	if (last == NULL)
   23267 	    vctxt->inode->idcMatchers = matcher;
   23268 	else
   23269 	    last->next = matcher;
   23270 	last = matcher;
   23271 
   23272 	matcher->type = IDC_MATCHER;
   23273 	matcher->depth = vctxt->depth;
   23274 	matcher->aidc = aidc;
   23275 	matcher->idcType = aidc->def->type;
   23276 #ifdef DEBUG_IDC
   23277 	xmlGenericError(xmlGenericErrorContext, "IDC:   register matcher\n");
   23278 #endif
   23279 	/*
   23280 	* Init the automaton state object.
   23281 	*/
   23282 	if (xmlSchemaIDCAddStateObject(vctxt, matcher,
   23283 	    idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
   23284 	    return (-1);
   23285 
   23286 	idc = idc->next;
   23287     } while (idc != NULL);
   23288     return (0);
   23289 }
   23290 
   23291 static int
   23292 xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
   23293 			   xmlSchemaNodeInfoPtr ielem)
   23294 {
   23295     xmlSchemaPSVIIDCBindingPtr bind;
   23296     int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
   23297     xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
   23298     xmlSchemaPSVIIDCNodePtr *targets, *dupls;
   23299 
   23300     xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
   23301     /* vctxt->createIDCNodeTables */
   23302     while (matcher != NULL) {
   23303 	/*
   23304 	* Skip keyref IDCs and empty IDC target-lists.
   23305 	*/
   23306 	if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
   23307 	    WXS_ILIST_IS_EMPTY(matcher->targets))
   23308 	{
   23309 	    matcher = matcher->next;
   23310 	    continue;
   23311 	}
   23312 	/*
   23313 	* If we _want_ the IDC node-table to be created in any case
   23314 	* then do so. Otherwise create them only if keyrefs need them.
   23315 	*/
   23316 	if ((! vctxt->createIDCNodeTables) &&
   23317 	    ((matcher->aidc->keyrefDepth == -1) ||
   23318 	     (matcher->aidc->keyrefDepth > vctxt->depth)))
   23319 	{
   23320 	    matcher = matcher->next;
   23321 	    continue;
   23322 	}
   23323 	/*
   23324 	* Get/create the IDC binding on this element for the IDC definition.
   23325 	*/
   23326 	bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
   23327 
   23328 	if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
   23329 	    dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
   23330 	    nbDupls = bind->dupls->nbItems;
   23331 	} else {
   23332 	    dupls = NULL;
   23333 	    nbDupls = 0;
   23334 	}
   23335 	if (bind->nodeTable != NULL) {
   23336 	    nbNodeTable = bind->nbNodes;
   23337 	} else {
   23338 	    nbNodeTable = 0;
   23339 	}
   23340 
   23341 	if ((nbNodeTable == 0) && (nbDupls == 0)) {
   23342 	    /*
   23343 	    * Transfer all IDC target-nodes to the IDC node-table.
   23344 	    */
   23345 	    bind->nodeTable =
   23346 		(xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
   23347 	    bind->sizeNodes = matcher->targets->sizeItems;
   23348 	    bind->nbNodes = matcher->targets->nbItems;
   23349 
   23350 	    matcher->targets->items = NULL;
   23351 	    matcher->targets->sizeItems = 0;
   23352 	    matcher->targets->nbItems = 0;
   23353 	} else {
   23354 	    /*
   23355 	    * Compare the key-sequences and add to the IDC node-table.
   23356 	    */
   23357 	    nbTargets = matcher->targets->nbItems;
   23358 	    targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
   23359 	    nbFields = matcher->aidc->def->nbFields;
   23360 	    i = 0;
   23361 	    do {
   23362 		keys = targets[i]->keys;
   23363 		if (nbDupls) {
   23364 		    /*
   23365 		    * Search in already found duplicates first.
   23366 		    */
   23367 		    j = 0;
   23368 		    do {
   23369 			if (nbFields == 1) {
   23370 			    res = xmlSchemaAreValuesEqual(keys[0]->val,
   23371 				dupls[j]->keys[0]->val);
   23372 			    if (res == -1)
   23373 				goto internal_error;
   23374 			    if (res == 1) {
   23375 				/*
   23376 				* Equal key-sequence.
   23377 				*/
   23378 				goto next_target;
   23379 			    }
   23380 			} else {
   23381 			    res = 0;
   23382 			    ntkeys = dupls[j]->keys;
   23383 			    for (k = 0; k < nbFields; k++) {
   23384 				res = xmlSchemaAreValuesEqual(keys[k]->val,
   23385 				    ntkeys[k]->val);
   23386 				if (res == -1)
   23387 				    goto internal_error;
   23388 				if (res == 0) {
   23389 				    /*
   23390 				    * One of the keys differs.
   23391 				    */
   23392 				    break;
   23393 				}
   23394 			    }
   23395 			    if (res == 1) {
   23396 				/*
   23397 				* Equal key-sequence found.
   23398 				*/
   23399 				goto next_target;
   23400 			    }
   23401 			}
   23402 			j++;
   23403 		    } while (j < nbDupls);
   23404 		}
   23405 		if (nbNodeTable) {
   23406 		    j = 0;
   23407 		    do {
   23408 			if (nbFields == 1) {
   23409 			    res = xmlSchemaAreValuesEqual(keys[0]->val,
   23410 				bind->nodeTable[j]->keys[0]->val);
   23411 			    if (res == -1)
   23412 				goto internal_error;
   23413 			    if (res == 0) {
   23414 				/*
   23415 				* The key-sequence differs.
   23416 				*/
   23417 				goto next_node_table_entry;
   23418 			    }
   23419 			} else {
   23420 			    res = 0;
   23421 			    ntkeys = bind->nodeTable[j]->keys;
   23422 			    for (k = 0; k < nbFields; k++) {
   23423 				res = xmlSchemaAreValuesEqual(keys[k]->val,
   23424 				    ntkeys[k]->val);
   23425 				if (res == -1)
   23426 				    goto internal_error;
   23427 				if (res == 0) {
   23428 				    /*
   23429 				    * One of the keys differs.
   23430 				    */
   23431 				    goto next_node_table_entry;
   23432 				}
   23433 			    }
   23434 			}
   23435 			/*
   23436 			* Add the duplicate to the list of duplicates.
   23437 			*/
   23438 			if (bind->dupls == NULL) {
   23439 			    bind->dupls = xmlSchemaItemListCreate();
   23440 			    if (bind->dupls == NULL)
   23441 				goto internal_error;
   23442 			}
   23443 			if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
   23444 			    goto internal_error;
   23445 			/*
   23446 			* Remove the duplicate entry from the IDC node-table.
   23447 			*/
   23448 			bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
   23449 			bind->nbNodes--;
   23450 
   23451 			goto next_target;
   23452 
   23453 next_node_table_entry:
   23454 			j++;
   23455 		    } while (j < nbNodeTable);
   23456 		}
   23457 		/*
   23458 		* If everything is fine, then add the IDC target-node to
   23459 		* the IDC node-table.
   23460 		*/
   23461 		if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
   23462 		    goto internal_error;
   23463 
   23464 next_target:
   23465 		i++;
   23466 	    } while (i < nbTargets);
   23467 	}
   23468 	matcher = matcher->next;
   23469     }
   23470     return(0);
   23471 
   23472 internal_error:
   23473     return(-1);
   23474 }
   23475 
   23476 /**
   23477  * xmlSchemaBubbleIDCNodeTables:
   23478  * @depth: the current tree depth
   23479  *
   23480  * Merges IDC bindings of an element at @depth into the corresponding IDC
   23481  * bindings of its parent element. If a duplicate note-table entry is found,
   23482  * both, the parent node-table entry and child entry are discarded from the
   23483  * node-table of the parent.
   23484  *
   23485  * Returns 0 if OK and -1 on internal errors.
   23486  */
   23487 static int
   23488 xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
   23489 {
   23490     xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
   23491     xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
   23492     xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
   23493     xmlSchemaIDCAugPtr aidc;
   23494     int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
   23495 
   23496     bind = vctxt->inode->idcTable;
   23497     if (bind == NULL) {
   23498 	/* Fine, no table, no bubbles. */
   23499 	return (0);
   23500     }
   23501 
   23502     parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
   23503     /*
   23504     * Walk all bindings; create new or add to existing bindings.
   23505     * Remove duplicate key-sequences.
   23506     */
   23507     while (bind != NULL) {
   23508 
   23509 	if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
   23510 	    goto next_binding;
   23511 	/*
   23512 	* Check if the key/unique IDC table needs to be bubbled.
   23513 	*/
   23514 	if (! vctxt->createIDCNodeTables) {
   23515 	    aidc = vctxt->aidcs;
   23516 	    do {
   23517 		if (aidc->def == bind->definition) {
   23518 		    if ((aidc->keyrefDepth == -1) ||
   23519 			(aidc->keyrefDepth >= vctxt->depth)) {
   23520 			goto next_binding;
   23521 		    }
   23522 		    break;
   23523 		}
   23524 		aidc = aidc->next;
   23525 	    } while (aidc != NULL);
   23526 	}
   23527 
   23528 	if (parTable != NULL)
   23529 	    parBind = *parTable;
   23530 	/*
   23531 	* Search a matching parent binding for the
   23532 	* IDC definition.
   23533 	*/
   23534 	while (parBind != NULL) {
   23535 	    if (parBind->definition == bind->definition)
   23536 		break;
   23537 	    parBind = parBind->next;
   23538 	}
   23539 
   23540 	if (parBind != NULL) {
   23541 	    /*
   23542 	    * Compare every node-table entry of the child node,
   23543 	    * i.e. the key-sequence within, ...
   23544 	    */
   23545 	    oldNum = parBind->nbNodes; /* Skip newly added items. */
   23546 
   23547 	    if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
   23548 		oldDupls = parBind->dupls->nbItems;
   23549 		dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
   23550 	    } else {
   23551 		dupls = NULL;
   23552 		oldDupls = 0;
   23553 	    }
   23554 
   23555 	    parNodes = parBind->nodeTable;
   23556 	    nbFields = bind->definition->nbFields;
   23557 
   23558 	    for (i = 0; i < bind->nbNodes; i++) {
   23559 		node = bind->nodeTable[i];
   23560 		if (node == NULL)
   23561 		    continue;
   23562 		/*
   23563 		* ...with every key-sequence of the parent node, already
   23564 		* evaluated to be a duplicate key-sequence.
   23565 		*/
   23566 		if (oldDupls) {
   23567 		    j = 0;
   23568 		    while (j < oldDupls) {
   23569 			if (nbFields == 1) {
   23570 			    ret = xmlSchemaAreValuesEqual(
   23571 				node->keys[0]->val,
   23572 				dupls[j]->keys[0]->val);
   23573 			    if (ret == -1)
   23574 				goto internal_error;
   23575 			    if (ret == 0) {
   23576 				j++;
   23577 				continue;
   23578 			    }
   23579 			} else {
   23580 			    parNode = dupls[j];
   23581 			    for (k = 0; k < nbFields; k++) {
   23582 				ret = xmlSchemaAreValuesEqual(
   23583 				    node->keys[k]->val,
   23584 				    parNode->keys[k]->val);
   23585 				if (ret == -1)
   23586 				    goto internal_error;
   23587 				if (ret == 0)
   23588 				    break;
   23589 			    }
   23590 			}
   23591 			if (ret == 1)
   23592 			    /* Duplicate found. */
   23593 			    break;
   23594 			j++;
   23595 		    }
   23596 		    if (j != oldDupls) {
   23597 			/* Duplicate found. Skip this entry. */
   23598 			continue;
   23599 		    }
   23600 		}
   23601 		/*
   23602 		* ... and with every key-sequence of the parent node.
   23603 		*/
   23604 		if (oldNum) {
   23605 		    j = 0;
   23606 		    while (j < oldNum) {
   23607 			parNode = parNodes[j];
   23608 			if (nbFields == 1) {
   23609 			    ret = xmlSchemaAreValuesEqual(
   23610 				node->keys[0]->val,
   23611 				parNode->keys[0]->val);
   23612 			    if (ret == -1)
   23613 				goto internal_error;
   23614 			    if (ret == 0) {
   23615 				j++;
   23616 				continue;
   23617 			    }
   23618 			} else {
   23619 			    for (k = 0; k < nbFields; k++) {
   23620 				ret = xmlSchemaAreValuesEqual(
   23621 				    node->keys[k]->val,
   23622 				    parNode->keys[k]->val);
   23623 				if (ret == -1)
   23624 				    goto internal_error;
   23625 				if (ret == 0)
   23626 				    break;
   23627 			    }
   23628 			}
   23629 			if (ret == 1)
   23630 			    /* Duplicate found. */
   23631 			    break;
   23632 			j++;
   23633 		    }
   23634 		    if (j != oldNum) {
   23635 			/*
   23636 			* Handle duplicates. Move the duplicate in
   23637 			* the parent's node-table to the list of
   23638 			* duplicates.
   23639 			*/
   23640 			oldNum--;
   23641 			parBind->nbNodes--;
   23642 			/*
   23643 			* Move last old item to pos of duplicate.
   23644 			*/
   23645 			parNodes[j] = parNodes[oldNum];
   23646 
   23647 			if (parBind->nbNodes != oldNum) {
   23648 			    /*
   23649 			    * If new items exist, move last new item to
   23650 			    * last of old items.
   23651 			    */
   23652 			    parNodes[oldNum] =
   23653 				parNodes[parBind->nbNodes];
   23654 			}
   23655 			if (parBind->dupls == NULL) {
   23656 			    parBind->dupls = xmlSchemaItemListCreate();
   23657 			    if (parBind->dupls == NULL)
   23658 				goto internal_error;
   23659 			}
   23660 			xmlSchemaItemListAdd(parBind->dupls, parNode);
   23661 		    } else {
   23662 			/*
   23663 			* Add the node-table entry (node and key-sequence) of
   23664 			* the child node to the node table of the parent node.
   23665 			*/
   23666 			if (parBind->nodeTable == NULL) {
   23667 			    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   23668 				xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
   23669 			    if (parBind->nodeTable == NULL) {
   23670 				xmlSchemaVErrMemory(NULL,
   23671 				    "allocating IDC list of node-table items", NULL);
   23672 				goto internal_error;
   23673 			    }
   23674 			    parBind->sizeNodes = 1;
   23675 			} else if (parBind->nbNodes >= parBind->sizeNodes) {
   23676 			    parBind->sizeNodes *= 2;
   23677 			    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   23678 				xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
   23679 				sizeof(xmlSchemaPSVIIDCNodePtr));
   23680 			    if (parBind->nodeTable == NULL) {
   23681 				xmlSchemaVErrMemory(NULL,
   23682 				    "re-allocating IDC list of node-table items", NULL);
   23683 				goto internal_error;
   23684 			    }
   23685 			}
   23686 			parNodes = parBind->nodeTable;
   23687 			/*
   23688 			* Append the new node-table entry to the 'new node-table
   23689 			* entries' section.
   23690 			*/
   23691 			parNodes[parBind->nbNodes++] = node;
   23692 		    }
   23693 
   23694 		}
   23695 
   23696 	    }
   23697 	} else {
   23698 	    /*
   23699 	    * No binding for the IDC was found: create a new one and
   23700 	    * copy all node-tables.
   23701 	    */
   23702 	    parBind = xmlSchemaIDCNewBinding(bind->definition);
   23703 	    if (parBind == NULL)
   23704 		goto internal_error;
   23705 
   23706 	    /*
   23707 	    * TODO: Hmm, how to optimize the initial number of
   23708 	    * allocated entries?
   23709 	    */
   23710 	    if (bind->nbNodes != 0) {
   23711 		/*
   23712 		* Add all IDC node-table entries.
   23713 		*/
   23714 		if (! vctxt->psviExposeIDCNodeTables) {
   23715 		    /*
   23716 		    * Just move the entries.
   23717 		    * NOTE: this is quite save here, since
   23718 		    * all the keyref lookups have already been
   23719 		    * performed.
   23720 		    */
   23721 		    parBind->nodeTable = bind->nodeTable;
   23722 		    bind->nodeTable = NULL;
   23723 		    parBind->sizeNodes = bind->sizeNodes;
   23724 		    bind->sizeNodes = 0;
   23725 		    parBind->nbNodes = bind->nbNodes;
   23726 		    bind->nbNodes = 0;
   23727 		} else {
   23728 		    /*
   23729 		    * Copy the entries.
   23730 		    */
   23731 		    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   23732 			xmlMalloc(bind->nbNodes *
   23733 			sizeof(xmlSchemaPSVIIDCNodePtr));
   23734 		    if (parBind->nodeTable == NULL) {
   23735 			xmlSchemaVErrMemory(NULL,
   23736 			    "allocating an array of IDC node-table "
   23737 			    "items", NULL);
   23738 			xmlSchemaIDCFreeBinding(parBind);
   23739 			goto internal_error;
   23740 		    }
   23741 		    parBind->sizeNodes = bind->nbNodes;
   23742 		    parBind->nbNodes = bind->nbNodes;
   23743 		    memcpy(parBind->nodeTable, bind->nodeTable,
   23744 			bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
   23745 		}
   23746 	    }
   23747 	    if (bind->dupls) {
   23748 		/*
   23749 		* Move the duplicates.
   23750 		*/
   23751 		if (parBind->dupls != NULL)
   23752 		    xmlSchemaItemListFree(parBind->dupls);
   23753 		parBind->dupls = bind->dupls;
   23754 		bind->dupls = NULL;
   23755 	    }
   23756             if (parTable != NULL) {
   23757                 if (*parTable == NULL)
   23758                     *parTable = parBind;
   23759                 else {
   23760                     parBind->next = *parTable;
   23761                     *parTable = parBind;
   23762                 }
   23763             }
   23764 	}
   23765 
   23766 next_binding:
   23767 	bind = bind->next;
   23768     }
   23769     return (0);
   23770 
   23771 internal_error:
   23772     return(-1);
   23773 }
   23774 
   23775 /**
   23776  * xmlSchemaCheckCVCIDCKeyRef:
   23777  * @vctxt: the WXS validation context
   23778  * @elemDecl: the element declaration
   23779  *
   23780  * Check the cvc-idc-keyref constraints.
   23781  */
   23782 static int
   23783 xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
   23784 {
   23785     xmlSchemaIDCMatcherPtr matcher;
   23786     xmlSchemaPSVIIDCBindingPtr bind;
   23787 
   23788     matcher = vctxt->inode->idcMatchers;
   23789     /*
   23790     * Find a keyref.
   23791     */
   23792     while (matcher != NULL) {
   23793 	if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
   23794 	    matcher->targets &&
   23795 	    matcher->targets->nbItems)
   23796 	{
   23797 	    int i, j, k, res, nbFields, hasDupls;
   23798 	    xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
   23799 	    xmlSchemaPSVIIDCNodePtr refNode = NULL;
   23800 
   23801 	    nbFields = matcher->aidc->def->nbFields;
   23802 
   23803 	    /*
   23804 	    * Find the IDC node-table for the referenced IDC key/unique.
   23805 	    */
   23806 	    bind = vctxt->inode->idcTable;
   23807 	    while (bind != NULL) {
   23808 		if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
   23809 		    bind->definition)
   23810 		    break;
   23811 		bind = bind->next;
   23812 	    }
   23813 	    hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
   23814 	    /*
   23815 	    * Search for a matching key-sequences.
   23816 	    */
   23817 	    for (i = 0; i < matcher->targets->nbItems; i++) {
   23818 		res = 0;
   23819 		refNode = matcher->targets->items[i];
   23820 		if (bind != NULL) {
   23821 		    refKeys = refNode->keys;
   23822 		    for (j = 0; j < bind->nbNodes; j++) {
   23823 			keys = bind->nodeTable[j]->keys;
   23824 			for (k = 0; k < nbFields; k++) {
   23825 			    res = xmlSchemaAreValuesEqual(keys[k]->val,
   23826 				refKeys[k]->val);
   23827 			    if (res == 0)
   23828 				break;
   23829 			    else if (res == -1) {
   23830 				return (-1);
   23831 			    }
   23832 			}
   23833 			if (res == 1) {
   23834 			    /*
   23835 			    * Match found.
   23836 			    */
   23837 			    break;
   23838 			}
   23839 		    }
   23840 		    if ((res == 0) && hasDupls) {
   23841 			/*
   23842 			* Search in duplicates
   23843 			*/
   23844 			for (j = 0; j < bind->dupls->nbItems; j++) {
   23845 			    keys = ((xmlSchemaPSVIIDCNodePtr)
   23846 				bind->dupls->items[j])->keys;
   23847 			    for (k = 0; k < nbFields; k++) {
   23848 				res = xmlSchemaAreValuesEqual(keys[k]->val,
   23849 				    refKeys[k]->val);
   23850 				if (res == 0)
   23851 				    break;
   23852 				else if (res == -1) {
   23853 				    return (-1);
   23854 				}
   23855 			    }
   23856 			    if (res == 1) {
   23857 				/*
   23858 				* Match in duplicates found.
   23859 				*/
   23860 				xmlChar *str = NULL, *strB = NULL;
   23861 				xmlSchemaKeyrefErr(vctxt,
   23862 				    XML_SCHEMAV_CVC_IDC, refNode,
   23863 				    (xmlSchemaTypePtr) matcher->aidc->def,
   23864 				    "More than one match found for "
   23865 				    "key-sequence %s of keyref '%s'",
   23866 				    xmlSchemaFormatIDCKeySequence(vctxt, &str,
   23867 					refNode->keys, nbFields),
   23868 				    xmlSchemaGetComponentQName(&strB,
   23869 					matcher->aidc->def));
   23870 				FREE_AND_NULL(str);
   23871 				FREE_AND_NULL(strB);
   23872 				break;
   23873 			    }
   23874 			}
   23875 		    }
   23876 		}
   23877 
   23878 		if (res == 0) {
   23879 		    xmlChar *str = NULL, *strB = NULL;
   23880 		    xmlSchemaKeyrefErr(vctxt,
   23881 			XML_SCHEMAV_CVC_IDC, refNode,
   23882 			(xmlSchemaTypePtr) matcher->aidc->def,
   23883 			"No match found for key-sequence %s of keyref '%s'",
   23884 			xmlSchemaFormatIDCKeySequence(vctxt, &str,
   23885 			    refNode->keys, nbFields),
   23886 			xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
   23887 		    FREE_AND_NULL(str);
   23888 		    FREE_AND_NULL(strB);
   23889 		}
   23890 	    }
   23891 	}
   23892 	matcher = matcher->next;
   23893     }
   23894     /* TODO: Return an error if any error encountered. */
   23895     return (0);
   23896 }
   23897 
   23898 /************************************************************************
   23899  *									*
   23900  *			XML Reader validation code                      *
   23901  *									*
   23902  ************************************************************************/
   23903 
   23904 static xmlSchemaAttrInfoPtr
   23905 xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
   23906 {
   23907     xmlSchemaAttrInfoPtr iattr;
   23908     /*
   23909     * Grow/create list of attribute infos.
   23910     */
   23911     if (vctxt->attrInfos == NULL) {
   23912 	vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
   23913 	    xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
   23914 	vctxt->sizeAttrInfos = 1;
   23915 	if (vctxt->attrInfos == NULL) {
   23916 	    xmlSchemaVErrMemory(vctxt,
   23917 		"allocating attribute info list", NULL);
   23918 	    return (NULL);
   23919 	}
   23920     } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
   23921 	vctxt->sizeAttrInfos++;
   23922 	vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
   23923 	    xmlRealloc(vctxt->attrInfos,
   23924 		vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
   23925 	if (vctxt->attrInfos == NULL) {
   23926 	    xmlSchemaVErrMemory(vctxt,
   23927 		"re-allocating attribute info list", NULL);
   23928 	    return (NULL);
   23929 	}
   23930     } else {
   23931 	iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
   23932 	if (iattr->localName != NULL) {
   23933 	    VERROR_INT("xmlSchemaGetFreshAttrInfo",
   23934 		"attr info not cleared");
   23935 	    return (NULL);
   23936 	}
   23937 	iattr->nodeType = XML_ATTRIBUTE_NODE;
   23938 	return (iattr);
   23939     }
   23940     /*
   23941     * Create an attribute info.
   23942     */
   23943     iattr = (xmlSchemaAttrInfoPtr)
   23944 	xmlMalloc(sizeof(xmlSchemaAttrInfo));
   23945     if (iattr == NULL) {
   23946 	xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
   23947 	return (NULL);
   23948     }
   23949     memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
   23950     iattr->nodeType = XML_ATTRIBUTE_NODE;
   23951     vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
   23952 
   23953     return (iattr);
   23954 }
   23955 
   23956 static int
   23957 xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
   23958 			xmlNodePtr attrNode,
   23959 			int nodeLine,
   23960 			const xmlChar *localName,
   23961 			const xmlChar *nsName,
   23962 			int ownedNames,
   23963 			xmlChar *value,
   23964 			int ownedValue)
   23965 {
   23966     xmlSchemaAttrInfoPtr attr;
   23967 
   23968     attr = xmlSchemaGetFreshAttrInfo(vctxt);
   23969     if (attr == NULL) {
   23970 	VERROR_INT("xmlSchemaPushAttribute",
   23971 	    "calling xmlSchemaGetFreshAttrInfo()");
   23972 	return (-1);
   23973     }
   23974     attr->node = attrNode;
   23975     attr->nodeLine = nodeLine;
   23976     attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
   23977     attr->localName = localName;
   23978     attr->nsName = nsName;
   23979     if (ownedNames)
   23980 	attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
   23981     /*
   23982     * Evaluate if it's an XSI attribute.
   23983     */
   23984     if (nsName != NULL) {
   23985 	if (xmlStrEqual(localName, BAD_CAST "nil")) {
   23986 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
   23987 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
   23988 	    }
   23989 	} else if (xmlStrEqual(localName, BAD_CAST "type")) {
   23990 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
   23991 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
   23992 	    }
   23993 	} else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
   23994 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
   23995 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
   23996 	    }
   23997 	} else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
   23998 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
   23999 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
   24000 	    }
   24001 	} else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
   24002 	    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
   24003 	}
   24004     }
   24005     attr->value = value;
   24006     if (ownedValue)
   24007 	attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
   24008     if (attr->metaType != 0)
   24009 	attr->state = XML_SCHEMAS_ATTR_META;
   24010     return (0);
   24011 }
   24012 
   24013 /**
   24014  * xmlSchemaClearElemInfo:
   24015  * @vctxt: the WXS validation context
   24016  * @ielem: the element information item
   24017  */
   24018 static void
   24019 xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
   24020 		       xmlSchemaNodeInfoPtr ielem)
   24021 {
   24022     ielem->hasKeyrefs = 0;
   24023     ielem->appliedXPath = 0;
   24024     if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
   24025 	FREE_AND_NULL(ielem->localName);
   24026 	FREE_AND_NULL(ielem->nsName);
   24027     } else {
   24028 	ielem->localName = NULL;
   24029 	ielem->nsName = NULL;
   24030     }
   24031     if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
   24032 	FREE_AND_NULL(ielem->value);
   24033     } else {
   24034 	ielem->value = NULL;
   24035     }
   24036     if (ielem->val != NULL) {
   24037 	/*
   24038 	* PSVI TODO: Be careful not to free it when the value is
   24039 	* exposed via PSVI.
   24040 	*/
   24041 	xmlSchemaFreeValue(ielem->val);
   24042 	ielem->val = NULL;
   24043     }
   24044     if (ielem->idcMatchers != NULL) {
   24045 	/*
   24046 	* REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
   24047 	*   Does it work?
   24048 	*/
   24049 	xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
   24050 #if 0
   24051 	xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
   24052 #endif
   24053 	ielem->idcMatchers = NULL;
   24054     }
   24055     if (ielem->idcTable != NULL) {
   24056 	/*
   24057 	* OPTIMIZE TODO: Use a pool of IDC tables??.
   24058 	*/
   24059 	xmlSchemaIDCFreeIDCTable(ielem->idcTable);
   24060 	ielem->idcTable = NULL;
   24061     }
   24062     if (ielem->regexCtxt != NULL) {
   24063 	xmlRegFreeExecCtxt(ielem->regexCtxt);
   24064 	ielem->regexCtxt = NULL;
   24065     }
   24066     if (ielem->nsBindings != NULL) {
   24067 	xmlFree((xmlChar **)ielem->nsBindings);
   24068 	ielem->nsBindings = NULL;
   24069 	ielem->nbNsBindings = 0;
   24070 	ielem->sizeNsBindings = 0;
   24071     }
   24072 }
   24073 
   24074 /**
   24075  * xmlSchemaGetFreshElemInfo:
   24076  * @vctxt: the schema validation context
   24077  *
   24078  * Creates/reuses and initializes the element info item for
   24079  * the currect tree depth.
   24080  *
   24081  * Returns the element info item or NULL on API or internal errors.
   24082  */
   24083 static xmlSchemaNodeInfoPtr
   24084 xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
   24085 {
   24086     xmlSchemaNodeInfoPtr info = NULL;
   24087 
   24088     if (vctxt->depth > vctxt->sizeElemInfos) {
   24089 	VERROR_INT("xmlSchemaGetFreshElemInfo",
   24090 	    "inconsistent depth encountered");
   24091 	return (NULL);
   24092     }
   24093     if (vctxt->elemInfos == NULL) {
   24094 	vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
   24095 	    xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
   24096 	if (vctxt->elemInfos == NULL) {
   24097 	    xmlSchemaVErrMemory(vctxt,
   24098 		"allocating the element info array", NULL);
   24099 	    return (NULL);
   24100 	}
   24101 	memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
   24102 	vctxt->sizeElemInfos = 10;
   24103     } else if (vctxt->sizeElemInfos <= vctxt->depth) {
   24104 	int i = vctxt->sizeElemInfos;
   24105 
   24106 	vctxt->sizeElemInfos *= 2;
   24107 	vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
   24108 	    xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
   24109 	    sizeof(xmlSchemaNodeInfoPtr));
   24110 	if (vctxt->elemInfos == NULL) {
   24111 	    xmlSchemaVErrMemory(vctxt,
   24112 		"re-allocating the element info array", NULL);
   24113 	    return (NULL);
   24114 	}
   24115 	/*
   24116 	* We need the new memory to be NULLed.
   24117 	* TODO: Use memset instead?
   24118 	*/
   24119 	for (; i < vctxt->sizeElemInfos; i++)
   24120 	    vctxt->elemInfos[i] = NULL;
   24121     } else
   24122 	info = vctxt->elemInfos[vctxt->depth];
   24123 
   24124     if (info == NULL) {
   24125 	info = (xmlSchemaNodeInfoPtr)
   24126 	    xmlMalloc(sizeof(xmlSchemaNodeInfo));
   24127 	if (info == NULL) {
   24128 	    xmlSchemaVErrMemory(vctxt,
   24129 		"allocating an element info", NULL);
   24130 	    return (NULL);
   24131 	}
   24132 	vctxt->elemInfos[vctxt->depth] = info;
   24133     } else {
   24134 	if (info->localName != NULL) {
   24135 	    VERROR_INT("xmlSchemaGetFreshElemInfo",
   24136 		"elem info has not been cleared");
   24137 	    return (NULL);
   24138 	}
   24139     }
   24140     memset(info, 0, sizeof(xmlSchemaNodeInfo));
   24141     info->nodeType = XML_ELEMENT_NODE;
   24142     info->depth = vctxt->depth;
   24143 
   24144     return (info);
   24145 }
   24146 
   24147 #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
   24148 #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
   24149 #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
   24150 
   24151 static int
   24152 xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
   24153 			xmlNodePtr node,
   24154 			xmlSchemaTypePtr type,
   24155 			xmlSchemaValType valType,
   24156 			const xmlChar * value,
   24157 			xmlSchemaValPtr val,
   24158 			unsigned long length,
   24159 			int fireErrors)
   24160 {
   24161     int ret, error = 0;
   24162 
   24163     xmlSchemaTypePtr tmpType;
   24164     xmlSchemaFacetLinkPtr facetLink;
   24165     xmlSchemaFacetPtr facet;
   24166     unsigned long len = 0;
   24167     xmlSchemaWhitespaceValueType ws;
   24168 
   24169     /*
   24170     * In Libxml2, derived built-in types have currently no explicit facets.
   24171     */
   24172     if (type->type == XML_SCHEMA_TYPE_BASIC)
   24173 	return (0);
   24174 
   24175     /*
   24176     * NOTE: Do not jump away, if the facetSet of the given type is
   24177     * empty: until now, "pattern" and "enumeration" facets of the
   24178     * *base types* need to be checked as well.
   24179     */
   24180     if (type->facetSet == NULL)
   24181 	goto pattern_and_enum;
   24182 
   24183     if (! WXS_IS_ATOMIC(type)) {
   24184 	if (WXS_IS_LIST(type))
   24185 	    goto WXS_IS_LIST;
   24186 	else
   24187 	    goto pattern_and_enum;
   24188     }
   24189 
   24190     /*
   24191     * Whitespace handling is only of importance for string-based
   24192     * types.
   24193     */
   24194     tmpType = xmlSchemaGetPrimitiveType(type);
   24195     if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
   24196 	WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
   24197 	ws = xmlSchemaGetWhiteSpaceFacetValue(type);
   24198     } else
   24199 	ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
   24200 
   24201     /*
   24202     * If the value was not computed (for string or
   24203     * anySimpleType based types), then use the provided
   24204     * type.
   24205     */
   24206     if (val != NULL)
   24207 	valType = xmlSchemaGetValType(val);
   24208 
   24209     ret = 0;
   24210     for (facetLink = type->facetSet; facetLink != NULL;
   24211 	facetLink = facetLink->next) {
   24212 	/*
   24213 	* Skip the pattern "whiteSpace": it is used to
   24214 	* format the character content beforehand.
   24215 	*/
   24216 	switch (facetLink->facet->type) {
   24217 	    case XML_SCHEMA_FACET_WHITESPACE:
   24218 	    case XML_SCHEMA_FACET_PATTERN:
   24219 	    case XML_SCHEMA_FACET_ENUMERATION:
   24220 		continue;
   24221 	    case XML_SCHEMA_FACET_LENGTH:
   24222 	    case XML_SCHEMA_FACET_MINLENGTH:
   24223 	    case XML_SCHEMA_FACET_MAXLENGTH:
   24224 		ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
   24225 		    valType, value, val, &len, ws);
   24226 		break;
   24227 	    default:
   24228 		ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
   24229 		    valType, value, val, ws);
   24230 		break;
   24231 	}
   24232 	if (ret < 0) {
   24233 	    AERROR_INT("xmlSchemaValidateFacets",
   24234 		"validating against a atomic type facet");
   24235 	    return (-1);
   24236 	} else if (ret > 0) {
   24237 	    if (fireErrors)
   24238 		xmlSchemaFacetErr(actxt, ret, node,
   24239 		value, len, type, facetLink->facet, NULL, NULL, NULL);
   24240 	    else
   24241 		return (ret);
   24242 	    if (error == 0)
   24243 		error = ret;
   24244 	}
   24245 	ret = 0;
   24246     }
   24247 
   24248 WXS_IS_LIST:
   24249     if (! WXS_IS_LIST(type))
   24250 	goto pattern_and_enum;
   24251     /*
   24252     * "length", "minLength" and "maxLength" of list types.
   24253     */
   24254     ret = 0;
   24255     for (facetLink = type->facetSet; facetLink != NULL;
   24256 	facetLink = facetLink->next) {
   24257 
   24258 	switch (facetLink->facet->type) {
   24259 	    case XML_SCHEMA_FACET_LENGTH:
   24260 	    case XML_SCHEMA_FACET_MINLENGTH:
   24261 	    case XML_SCHEMA_FACET_MAXLENGTH:
   24262 		ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
   24263 		    value, length, NULL);
   24264 		break;
   24265 	    default:
   24266 		continue;
   24267 	}
   24268 	if (ret < 0) {
   24269 	    AERROR_INT("xmlSchemaValidateFacets",
   24270 		"validating against a list type facet");
   24271 	    return (-1);
   24272 	} else if (ret > 0) {
   24273 	    if (fireErrors)
   24274 		xmlSchemaFacetErr(actxt, ret, node,
   24275 		value, length, type, facetLink->facet, NULL, NULL, NULL);
   24276 	    else
   24277 		return (ret);
   24278 	    if (error == 0)
   24279 		error = ret;
   24280 	}
   24281 	ret = 0;
   24282     }
   24283 
   24284 pattern_and_enum:
   24285     if (error >= 0) {
   24286 	int found = 0;
   24287 	/*
   24288 	* Process enumerations. Facet values are in the value space
   24289 	* of the defining type's base type. This seems to be a bug in the
   24290 	* XML Schema 1.0 spec. Use the whitespace type of the base type.
   24291 	* Only the first set of enumerations in the ancestor-or-self axis
   24292 	* is used for validation.
   24293 	*/
   24294 	ret = 0;
   24295 	tmpType = type;
   24296 	do {
   24297 	    for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
   24298 		if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
   24299 		    continue;
   24300 		found = 1;
   24301 		ret = xmlSchemaAreValuesEqual(facet->val, val);
   24302 		if (ret == 1)
   24303 		    break;
   24304 		else if (ret < 0) {
   24305 		    AERROR_INT("xmlSchemaValidateFacets",
   24306 			"validating against an enumeration facet");
   24307 		    return (-1);
   24308 		}
   24309 	    }
   24310 	    if (ret != 0)
   24311 		break;
   24312 	    /*
   24313 	    * Break on the first set of enumerations. Any additional
   24314 	    *  enumerations which might be existent on the ancestors
   24315 	    *  of the current type are restricted by this set; thus
   24316 	    *  *must* *not* be taken into account.
   24317 	    */
   24318 	    if (found)
   24319 		break;
   24320 	    tmpType = tmpType->baseType;
   24321 	} while ((tmpType != NULL) &&
   24322 	    (tmpType->type != XML_SCHEMA_TYPE_BASIC));
   24323 	if (found && (ret == 0)) {
   24324 	    ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
   24325 	    if (fireErrors) {
   24326 		xmlSchemaFacetErr(actxt, ret, node,
   24327 		    value, 0, type, NULL, NULL, NULL, NULL);
   24328 	    } else
   24329 		return (ret);
   24330 	    if (error == 0)
   24331 		error = ret;
   24332 	}
   24333     }
   24334 
   24335     if (error >= 0) {
   24336 	int found;
   24337 	/*
   24338 	* Process patters. Pattern facets are ORed at type level
   24339 	* and ANDed if derived. Walk the base type axis.
   24340 	*/
   24341 	tmpType = type;
   24342 	facet = NULL;
   24343 	do {
   24344 	    found = 0;
   24345 	    for (facetLink = tmpType->facetSet; facetLink != NULL;
   24346 		facetLink = facetLink->next) {
   24347 		if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
   24348 		    continue;
   24349 		found = 1;
   24350 		/*
   24351 		* NOTE that for patterns, @value needs to be the
   24352 		* normalized vaule.
   24353 		*/
   24354 		ret = xmlRegexpExec(facetLink->facet->regexp, value);
   24355 		if (ret == 1)
   24356 		    break;
   24357 		else if (ret < 0) {
   24358 		    AERROR_INT("xmlSchemaValidateFacets",
   24359 			"validating against a pattern facet");
   24360 		    return (-1);
   24361 		} else {
   24362 		    /*
   24363 		    * Save the last non-validating facet.
   24364 		    */
   24365 		    facet = facetLink->facet;
   24366 		}
   24367 	    }
   24368 	    if (found && (ret != 1)) {
   24369 		ret = XML_SCHEMAV_CVC_PATTERN_VALID;
   24370 		if (fireErrors) {
   24371 		    xmlSchemaFacetErr(actxt, ret, node,
   24372 			value, 0, type, facet, NULL, NULL, NULL);
   24373 		} else
   24374 		    return (ret);
   24375 		if (error == 0)
   24376 		    error = ret;
   24377 		break;
   24378 	    }
   24379 	    tmpType = tmpType->baseType;
   24380 	} while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
   24381     }
   24382 
   24383     return (error);
   24384 }
   24385 
   24386 static xmlChar *
   24387 xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
   24388 			const xmlChar *value)
   24389 {
   24390     switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
   24391 	case XML_SCHEMA_WHITESPACE_COLLAPSE:
   24392 	    return (xmlSchemaCollapseString(value));
   24393 	case XML_SCHEMA_WHITESPACE_REPLACE:
   24394 	    return (xmlSchemaWhiteSpaceReplace(value));
   24395 	default:
   24396 	    return (NULL);
   24397     }
   24398 }
   24399 
   24400 static int
   24401 xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
   24402 		       const xmlChar *value,
   24403 		       xmlSchemaValPtr *val,
   24404 		       int valNeeded)
   24405 {
   24406     int ret;
   24407     const xmlChar *nsName;
   24408     xmlChar *local, *prefix = NULL;
   24409 
   24410     ret = xmlValidateQName(value, 1);
   24411     if (ret != 0) {
   24412 	if (ret == -1) {
   24413 	    VERROR_INT("xmlSchemaValidateQName",
   24414 		"calling xmlValidateQName()");
   24415 	    return (-1);
   24416 	}
   24417 	return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
   24418     }
   24419     /*
   24420     * NOTE: xmlSplitQName2 will always return a duplicated
   24421     * strings.
   24422     */
   24423     local = xmlSplitQName2(value, &prefix);
   24424     if (local == NULL)
   24425 	local = xmlStrdup(value);
   24426     /*
   24427     * OPTIMIZE TODO: Use flags for:
   24428     *  - is there any namespace binding?
   24429     *  - is there a default namespace?
   24430     */
   24431     nsName = xmlSchemaLookupNamespace(vctxt, prefix);
   24432 
   24433     if (prefix != NULL) {
   24434 	xmlFree(prefix);
   24435 	/*
   24436 	* A namespace must be found if the prefix is
   24437 	* NOT NULL.
   24438 	*/
   24439 	if (nsName == NULL) {
   24440 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
   24441 	    xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
   24442 		WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
   24443 		"The QName value '%s' has no "
   24444 		"corresponding namespace declaration in "
   24445 		"scope", value, NULL);
   24446 	    if (local != NULL)
   24447 		xmlFree(local);
   24448 	    return (ret);
   24449 	}
   24450     }
   24451     if (valNeeded && val) {
   24452 	if (nsName != NULL)
   24453 	    *val = xmlSchemaNewQNameValue(
   24454 		BAD_CAST xmlStrdup(nsName), BAD_CAST local);
   24455 	else
   24456 	    *val = xmlSchemaNewQNameValue(NULL,
   24457 		BAD_CAST local);
   24458     } else
   24459 	xmlFree(local);
   24460     return (0);
   24461 }
   24462 
   24463 /*
   24464 * cvc-simple-type
   24465 */
   24466 static int
   24467 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
   24468 			     xmlNodePtr node,
   24469 			     xmlSchemaTypePtr type,
   24470 			     const xmlChar *value,
   24471 			     xmlSchemaValPtr *retVal,
   24472 			     int fireErrors,
   24473 			     int normalize,
   24474 			     int isNormalized)
   24475 {
   24476     int ret = 0, valNeeded = (retVal) ? 1 : 0;
   24477     xmlSchemaValPtr val = NULL;
   24478     /* xmlSchemaWhitespaceValueType ws; */
   24479     xmlChar *normValue = NULL;
   24480 
   24481 #define NORMALIZE(atype) \
   24482     if ((! isNormalized) && \
   24483     (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
   24484 	normValue = xmlSchemaNormalizeValue(atype, value); \
   24485 	if (normValue != NULL) \
   24486 	    value = normValue; \
   24487 	isNormalized = 1; \
   24488     }
   24489 
   24490     if ((retVal != NULL) && (*retVal != NULL)) {
   24491 	xmlSchemaFreeValue(*retVal);
   24492 	*retVal = NULL;
   24493     }
   24494     /*
   24495     * 3.14.4 Simple Type Definition Validation Rules
   24496     * Validation Rule: String Valid
   24497     */
   24498     /*
   24499     * 1 It is schema-valid with respect to that definition as defined
   24500     * by Datatype Valid in [XML Schemas: Datatypes].
   24501     */
   24502     /*
   24503     * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
   24504     * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
   24505     * the string must be a `declared entity name`.
   24506     */
   24507     /*
   24508     * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
   24509     * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
   24510     * then every whitespace-delimited substring of the string must be a `declared
   24511     * entity name`.
   24512     */
   24513     /*
   24514     * 2.3 otherwise no further condition applies.
   24515     */
   24516     if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
   24517 	valNeeded = 1;
   24518     if (value == NULL)
   24519 	value = BAD_CAST "";
   24520     if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
   24521 	xmlSchemaTypePtr biType; /* The built-in type. */
   24522 	/*
   24523 	* SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
   24524 	* a literal in the `lexical space` of {base type definition}"
   24525 	*/
   24526 	/*
   24527 	* Whitespace-normalize.
   24528 	*/
   24529 	NORMALIZE(type);
   24530 	if (type->type != XML_SCHEMA_TYPE_BASIC) {
   24531 	    /*
   24532 	    * Get the built-in type.
   24533 	    */
   24534 	    biType = type->baseType;
   24535 	    while ((biType != NULL) &&
   24536 		(biType->type != XML_SCHEMA_TYPE_BASIC))
   24537 		biType = biType->baseType;
   24538 
   24539 	    if (biType == NULL) {
   24540 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24541 		    "could not get the built-in type");
   24542 		goto internal_error;
   24543 	    }
   24544 	} else
   24545 	    biType = type;
   24546 	/*
   24547 	* NOTATIONs need to be processed here, since they need
   24548 	* to lookup in the hashtable of NOTATION declarations of the schema.
   24549 	*/
   24550 	if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
   24551 	    switch (biType->builtInType) {
   24552 		case XML_SCHEMAS_NOTATION:
   24553 		    ret = xmlSchemaValidateNotation(
   24554 			(xmlSchemaValidCtxtPtr) actxt,
   24555 			((xmlSchemaValidCtxtPtr) actxt)->schema,
   24556 			NULL, value, &val, valNeeded);
   24557 		    break;
   24558 		case XML_SCHEMAS_QNAME:
   24559 		    ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
   24560 			value, &val, valNeeded);
   24561 		    break;
   24562 		default:
   24563 		    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
   24564 		    if (valNeeded)
   24565 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
   24566 			    value, &val, node);
   24567 		    else
   24568 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
   24569 			    value, NULL, node);
   24570 		    break;
   24571 	    }
   24572 	} else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
   24573 	    switch (biType->builtInType) {
   24574 		case XML_SCHEMAS_NOTATION:
   24575 		    ret = xmlSchemaValidateNotation(NULL,
   24576 			((xmlSchemaParserCtxtPtr) actxt)->schema, node,
   24577 			value, &val, valNeeded);
   24578 		    break;
   24579 		default:
   24580 		    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
   24581 		    if (valNeeded)
   24582 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
   24583 			    value, &val, node);
   24584 		    else
   24585 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
   24586 			    value, NULL, node);
   24587 		    break;
   24588 	    }
   24589 	} else {
   24590 	    /*
   24591 	    * Validation via a public API is not implemented yet.
   24592 	    */
   24593 	    TODO
   24594 	    goto internal_error;
   24595 	}
   24596 	if (ret != 0) {
   24597 	    if (ret < 0) {
   24598 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24599 		    "validating against a built-in type");
   24600 		goto internal_error;
   24601 	    }
   24602 	    if (WXS_IS_LIST(type))
   24603 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   24604 	    else
   24605 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
   24606 	}
   24607 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
   24608 	    /*
   24609 	    * Check facets.
   24610 	    */
   24611 	    ret = xmlSchemaValidateFacets(actxt, node, type,
   24612 		(xmlSchemaValType) biType->builtInType, value, val,
   24613 		0, fireErrors);
   24614 	    if (ret != 0) {
   24615 		if (ret < 0) {
   24616 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24617 			"validating facets of atomic simple type");
   24618 		    goto internal_error;
   24619 		}
   24620 		if (WXS_IS_LIST(type))
   24621 		    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   24622 		else
   24623 		    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
   24624 	    }
   24625 	}
   24626 	if (fireErrors && (ret > 0))
   24627 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
   24628     } else if (WXS_IS_LIST(type)) {
   24629 
   24630 	xmlSchemaTypePtr itemType;
   24631 	const xmlChar *cur, *end;
   24632 	xmlChar *tmpValue = NULL;
   24633 	unsigned long len = 0;
   24634 	xmlSchemaValPtr prevVal = NULL, curVal = NULL;
   24635 	/* 1.2.2 if {variety} is `list` then the string must be a sequence
   24636 	* of white space separated tokens, each of which `match`es a literal
   24637 	* in the `lexical space` of {item type definition}
   24638 	*/
   24639 	/*
   24640 	* Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
   24641 	* the list type has an enum or pattern facet.
   24642 	*/
   24643 	NORMALIZE(type);
   24644 	/*
   24645 	* VAL TODO: Optimize validation of empty values.
   24646 	* VAL TODO: We do not have computed values for lists.
   24647 	*/
   24648 	itemType = WXS_LIST_ITEMTYPE(type);
   24649 	cur = value;
   24650 	do {
   24651 	    while (IS_BLANK_CH(*cur))
   24652 		cur++;
   24653 	    end = cur;
   24654 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   24655 		end++;
   24656 	    if (end == cur)
   24657 		break;
   24658 	    tmpValue = xmlStrndup(cur, end - cur);
   24659 	    len++;
   24660 
   24661 	    if (valNeeded)
   24662 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
   24663 		    tmpValue, &curVal, fireErrors, 0, 1);
   24664 	    else
   24665 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
   24666 		    tmpValue, NULL, fireErrors, 0, 1);
   24667 	    FREE_AND_NULL(tmpValue);
   24668 	    if (curVal != NULL) {
   24669 		/*
   24670 		* Add to list of computed values.
   24671 		*/
   24672 		if (val == NULL)
   24673 		    val = curVal;
   24674 		else
   24675 		    xmlSchemaValueAppend(prevVal, curVal);
   24676 		prevVal = curVal;
   24677 		curVal = NULL;
   24678 	    }
   24679 	    if (ret != 0) {
   24680 		if (ret < 0) {
   24681 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24682 			"validating an item of list simple type");
   24683 		    goto internal_error;
   24684 		}
   24685 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   24686 		break;
   24687 	    }
   24688 	    cur = end;
   24689 	} while (*cur != 0);
   24690 	FREE_AND_NULL(tmpValue);
   24691 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
   24692 	    /*
   24693 	    * Apply facets (pattern, enumeration).
   24694 	    */
   24695 	    ret = xmlSchemaValidateFacets(actxt, node, type,
   24696 		XML_SCHEMAS_UNKNOWN, value, val,
   24697 		len, fireErrors);
   24698 	    if (ret != 0) {
   24699 		if (ret < 0) {
   24700 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24701 			"validating facets of list simple type");
   24702 		    goto internal_error;
   24703 		}
   24704 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   24705 	    }
   24706 	}
   24707 	if (fireErrors && (ret > 0)) {
   24708 	    /*
   24709 	    * Report the normalized value.
   24710 	    */
   24711 	    normalize = 1;
   24712 	    NORMALIZE(type);
   24713 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
   24714 	}
   24715     } else if (WXS_IS_UNION(type)) {
   24716 	xmlSchemaTypeLinkPtr memberLink;
   24717 	/*
   24718 	* TODO: For all datatypes `derived` by `union`  whiteSpace does
   24719 	* not apply directly; however, the normalization behavior of `union`
   24720 	* types is controlled by the value of whiteSpace on that one of the
   24721 	* `memberTypes` against which the `union` is successfully validated.
   24722 	*
   24723 	* This means that the value is normalized by the first validating
   24724 	* member type, then the facets of the union type are applied. This
   24725 	* needs changing of the value!
   24726 	*/
   24727 
   24728 	/*
   24729 	* 1.2.3 if {variety} is `union` then the string must `match` a
   24730 	* literal in the `lexical space` of at least one member of
   24731 	* {member type definitions}
   24732 	*/
   24733 	memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
   24734 	if (memberLink == NULL) {
   24735 	    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24736 		"union simple type has no member types");
   24737 	    goto internal_error;
   24738 	}
   24739 	/*
   24740 	* Always normalize union type values, since we currently
   24741 	* cannot store the whitespace information with the value
   24742 	* itself; otherwise a later value-comparison would be
   24743 	* not possible.
   24744 	*/
   24745 	while (memberLink != NULL) {
   24746 	    if (valNeeded)
   24747 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
   24748 		    memberLink->type, value, &val, 0, 1, 0);
   24749 	    else
   24750 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
   24751 		    memberLink->type, value, NULL, 0, 1, 0);
   24752 	    if (ret <= 0)
   24753 		break;
   24754 	    memberLink = memberLink->next;
   24755 	}
   24756 	if (ret != 0) {
   24757 	    if (ret < 0) {
   24758 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24759 		    "validating members of union simple type");
   24760 		goto internal_error;
   24761 	    }
   24762 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
   24763 	}
   24764 	/*
   24765 	* Apply facets (pattern, enumeration).
   24766 	*/
   24767 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
   24768 	    /*
   24769 	    * The normalization behavior of `union` types is controlled by
   24770 	    * the value of whiteSpace on that one of the `memberTypes`
   24771 	    * against which the `union` is successfully validated.
   24772 	    */
   24773 	    NORMALIZE(memberLink->type);
   24774 	    ret = xmlSchemaValidateFacets(actxt, node, type,
   24775 		XML_SCHEMAS_UNKNOWN, value, val,
   24776 		0, fireErrors);
   24777 	    if (ret != 0) {
   24778 		if (ret < 0) {
   24779 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24780 			"validating facets of union simple type");
   24781 		    goto internal_error;
   24782 		}
   24783 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
   24784 	    }
   24785 	}
   24786 	if (fireErrors && (ret > 0))
   24787 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
   24788     }
   24789 
   24790     if (normValue != NULL)
   24791 	xmlFree(normValue);
   24792     if (ret == 0) {
   24793 	if (retVal != NULL)
   24794 	    *retVal = val;
   24795 	else if (val != NULL)
   24796 	    xmlSchemaFreeValue(val);
   24797     } else if (val != NULL)
   24798 	xmlSchemaFreeValue(val);
   24799     return (ret);
   24800 internal_error:
   24801     if (normValue != NULL)
   24802 	xmlFree(normValue);
   24803     if (val != NULL)
   24804 	xmlSchemaFreeValue(val);
   24805     return (-1);
   24806 }
   24807 
   24808 static int
   24809 xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
   24810 			   const xmlChar *value,
   24811 			   const xmlChar **nsName,
   24812 			   const xmlChar **localName)
   24813 {
   24814     int ret = 0;
   24815 
   24816     if ((nsName == NULL) || (localName == NULL))
   24817 	return (-1);
   24818     *nsName = NULL;
   24819     *localName = NULL;
   24820 
   24821     ret = xmlValidateQName(value, 1);
   24822     if (ret == -1)
   24823 	return (-1);
   24824     if (ret > 0) {
   24825 	xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
   24826 	    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
   24827 	    value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
   24828 	return (1);
   24829     }
   24830     {
   24831 	xmlChar *local = NULL;
   24832 	xmlChar *prefix;
   24833 
   24834 	/*
   24835 	* NOTE: xmlSplitQName2 will return a duplicated
   24836 	* string.
   24837 	*/
   24838 	local = xmlSplitQName2(value, &prefix);
   24839 	if (local == NULL)
   24840 	    *localName = xmlDictLookup(vctxt->dict, value, -1);
   24841 	else {
   24842 	    *localName = xmlDictLookup(vctxt->dict, local, -1);
   24843 	    xmlFree(local);
   24844 	}
   24845 
   24846 	*nsName = xmlSchemaLookupNamespace(vctxt, prefix);
   24847 
   24848 	if (prefix != NULL) {
   24849 	    xmlFree(prefix);
   24850 	    /*
   24851 	    * A namespace must be found if the prefix is NOT NULL.
   24852 	    */
   24853 	    if (*nsName == NULL) {
   24854 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   24855 		    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
   24856 		    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
   24857 		    "The QName value '%s' has no "
   24858 		    "corresponding namespace declaration in scope",
   24859 		    value, NULL);
   24860 		return (2);
   24861 	    }
   24862 	}
   24863     }
   24864     return (0);
   24865 }
   24866 
   24867 static int
   24868 xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
   24869 			xmlSchemaAttrInfoPtr iattr,
   24870 			xmlSchemaTypePtr *localType,
   24871 			xmlSchemaElementPtr elemDecl)
   24872 {
   24873     int ret = 0;
   24874     /*
   24875     * cvc-elt (3.3.4) : (4)
   24876     * AND
   24877     * Schema-Validity Assessment (Element) (cvc-assess-elt)
   24878     *   (1.2.1.2.1) - (1.2.1.2.4)
   24879     * Handle 'xsi:type'.
   24880     */
   24881     if (localType == NULL)
   24882 	return (-1);
   24883     *localType = NULL;
   24884     if (iattr == NULL)
   24885 	return (0);
   24886     else {
   24887 	const xmlChar *nsName = NULL, *local = NULL;
   24888 	/*
   24889 	* TODO: We should report a *warning* that the type was overriden
   24890 	* by the instance.
   24891 	*/
   24892 	ACTIVATE_ATTRIBUTE(iattr);
   24893 	/*
   24894 	* (cvc-elt) (3.3.4) : (4.1)
   24895 	* (cvc-assess-elt) (1.2.1.2.2)
   24896 	*/
   24897 	ret = xmlSchemaVExpandQName(vctxt, iattr->value,
   24898 	    &nsName, &local);
   24899 	if (ret != 0) {
   24900 	    if (ret < 0) {
   24901 		VERROR_INT("xmlSchemaValidateElementByDeclaration",
   24902 		    "calling xmlSchemaQNameExpand() to validate the "
   24903 		    "attribute 'xsi:type'");
   24904 		goto internal_error;
   24905 	    }
   24906 	    goto exit;
   24907 	}
   24908 	/*
   24909 	* (cvc-elt) (3.3.4) : (4.2)
   24910 	* (cvc-assess-elt) (1.2.1.2.3)
   24911 	*/
   24912 	*localType = xmlSchemaGetType(vctxt->schema, local, nsName);
   24913 	if (*localType == NULL) {
   24914 	    xmlChar *str = NULL;
   24915 
   24916 	    xmlSchemaCustomErr(ACTXT_CAST vctxt,
   24917 		XML_SCHEMAV_CVC_ELT_4_2, NULL,
   24918 		WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
   24919 		"The QName value '%s' of the xsi:type attribute does not "
   24920 		"resolve to a type definition",
   24921 		xmlSchemaFormatQName(&str, nsName, local), NULL);
   24922 	    FREE_AND_NULL(str);
   24923 	    ret = vctxt->err;
   24924 	    goto exit;
   24925 	}
   24926 	if (elemDecl != NULL) {
   24927 	    int set = 0;
   24928 
   24929 	    /*
   24930 	    * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
   24931 	    * "The `local type definition` must be validly
   24932 	    * derived from the {type definition} given the union of
   24933 	    * the {disallowed substitutions} and the {type definition}'s
   24934 	    * {prohibited substitutions}, as defined in
   24935 	    * Type Derivation OK (Complex) ($3.4.6)
   24936 	    * (if it is a complex type definition),
   24937 	    * or given {disallowed substitutions} as defined in Type
   24938 	    * Derivation OK (Simple) ($3.14.6) (if it is a simple type
   24939 	    * definition)."
   24940 	    *
   24941 	    * {disallowed substitutions}: the "block" on the element decl.
   24942 	    * {prohibited substitutions}: the "block" on the type def.
   24943 	    */
   24944 	    /*
   24945 	    * OPTIMIZE TODO: We could map types already evaluated
   24946 	    * to be validly derived from other types to avoid checking
   24947 	    * this over and over for the same types.
   24948 	    */
   24949 	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
   24950 		(elemDecl->subtypes->flags &
   24951 		    XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
   24952 		set |= SUBSET_EXTENSION;
   24953 
   24954 	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
   24955 		(elemDecl->subtypes->flags &
   24956 		    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
   24957 		set |= SUBSET_RESTRICTION;
   24958 
   24959 	    /*
   24960 	    * REMOVED and CHANGED since this produced a parser context
   24961 	    * which adds to the string dict of the schema. So this would
   24962 	    * change the schema and we don't want this. We don't need
   24963 	    * the parser context anymore.
   24964 	    *
   24965 	    * if ((vctxt->pctxt == NULL) &&
   24966 	    *	(xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
   24967 	    *	    return (-1);
   24968 	    */
   24969 
   24970 	    if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
   24971 		elemDecl->subtypes, set) != 0) {
   24972 		xmlChar *str = NULL;
   24973 
   24974 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   24975 		    XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
   24976 		    "The type definition '%s', specified by xsi:type, is "
   24977 		    "blocked or not validly derived from the type definition "
   24978 		    "of the element declaration",
   24979 		    xmlSchemaFormatQName(&str,
   24980 			(*localType)->targetNamespace,
   24981 			(*localType)->name),
   24982 		    NULL);
   24983 		FREE_AND_NULL(str);
   24984 		ret = vctxt->err;
   24985 		*localType = NULL;
   24986 	    }
   24987 	}
   24988     }
   24989 exit:
   24990     ACTIVATE_ELEM;
   24991     return (ret);
   24992 internal_error:
   24993     ACTIVATE_ELEM;
   24994     return (-1);
   24995 }
   24996 
   24997 static int
   24998 xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
   24999 {
   25000     xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
   25001     xmlSchemaTypePtr actualType;
   25002 
   25003     /*
   25004     * cvc-elt (3.3.4) : 1
   25005     */
   25006     if (elemDecl == NULL) {
   25007 	VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
   25008 	    "No matching declaration available");
   25009         return (vctxt->err);
   25010     }
   25011     actualType = WXS_ELEM_TYPEDEF(elemDecl);
   25012     /*
   25013     * cvc-elt (3.3.4) : 2
   25014     */
   25015     if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
   25016 	VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
   25017 	    "The element declaration is abstract");
   25018         return (vctxt->err);
   25019     }
   25020     if (actualType == NULL) {
   25021 	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
   25022 	    "The type definition is absent");
   25023 	return (XML_SCHEMAV_CVC_TYPE_1);
   25024     }
   25025     if (vctxt->nbAttrInfos != 0) {
   25026 	int ret;
   25027 	xmlSchemaAttrInfoPtr iattr;
   25028 	/*
   25029 	* cvc-elt (3.3.4) : 3
   25030 	* Handle 'xsi:nil'.
   25031 	*/
   25032 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   25033 	    XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
   25034 	if (iattr) {
   25035 	    ACTIVATE_ATTRIBUTE(iattr);
   25036 	    /*
   25037 	    * Validate the value.
   25038 	    */
   25039 	    ret = xmlSchemaVCheckCVCSimpleType(
   25040 		ACTXT_CAST vctxt, NULL,
   25041 		xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
   25042 		iattr->value, &(iattr->val), 1, 0, 0);
   25043 	    ACTIVATE_ELEM;
   25044 	    if (ret < 0) {
   25045 		VERROR_INT("xmlSchemaValidateElemDecl",
   25046 		    "calling xmlSchemaVCheckCVCSimpleType() to "
   25047 		    "validate the attribute 'xsi:nil'");
   25048 		return (-1);
   25049 	    }
   25050 	    if (ret == 0) {
   25051 		if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
   25052 		    /*
   25053 		    * cvc-elt (3.3.4) : 3.1
   25054 		    */
   25055 		    VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
   25056 			"The element is not 'nillable'");
   25057 		    /* Does not return an error on purpose. */
   25058 		} else {
   25059 		    if (xmlSchemaValueGetAsBoolean(iattr->val)) {
   25060 			/*
   25061 			* cvc-elt (3.3.4) : 3.2.2
   25062 			*/
   25063 			if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
   25064 			    (elemDecl->value != NULL)) {
   25065 			    VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
   25066 				"The element cannot be 'nilled' because "
   25067 				"there is a fixed value constraint defined "
   25068 				"for it");
   25069 			     /* Does not return an error on purpose. */
   25070 			} else
   25071 			    vctxt->inode->flags |=
   25072 				XML_SCHEMA_ELEM_INFO_NILLED;
   25073 		    }
   25074 		}
   25075 	    }
   25076 	}
   25077 	/*
   25078 	* cvc-elt (3.3.4) : 4
   25079 	* Handle 'xsi:type'.
   25080 	*/
   25081 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   25082 	    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
   25083 	if (iattr) {
   25084 	    xmlSchemaTypePtr localType = NULL;
   25085 
   25086 	    ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
   25087 		elemDecl);
   25088 	    if (ret != 0) {
   25089 		if (ret == -1) {
   25090 		    VERROR_INT("xmlSchemaValidateElemDecl",
   25091 			"calling xmlSchemaProcessXSIType() to "
   25092 			"process the attribute 'xsi:type'");
   25093 		    return (-1);
   25094 		}
   25095 		/* Does not return an error on purpose. */
   25096 	    }
   25097 	    if (localType != NULL) {
   25098 		vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
   25099 		actualType = localType;
   25100 	    }
   25101 	}
   25102     }
   25103     /*
   25104     * IDC: Register identity-constraint XPath matchers.
   25105     */
   25106     if ((elemDecl->idcs != NULL) &&
   25107 	(xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
   25108 	    return (-1);
   25109     /*
   25110     * No actual type definition.
   25111     */
   25112     if (actualType == NULL) {
   25113 	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
   25114 	    "The type definition is absent");
   25115 	return (XML_SCHEMAV_CVC_TYPE_1);
   25116     }
   25117     /*
   25118     * Remember the actual type definition.
   25119     */
   25120     vctxt->inode->typeDef = actualType;
   25121 
   25122     return (0);
   25123 }
   25124 
   25125 static int
   25126 xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
   25127 {
   25128     xmlSchemaAttrInfoPtr iattr;
   25129     int ret = 0, i;
   25130 
   25131     /*
   25132     * SPEC cvc-type (3.1.1)
   25133     * "The attributes of must be empty, excepting those whose namespace
   25134     * name is identical to http://www.w3.org/2001/XMLSchema-instance and
   25135     * whose local name is one of type, nil, schemaLocation or
   25136     * noNamespaceSchemaLocation."
   25137     */
   25138     if (vctxt->nbAttrInfos == 0)
   25139 	return (0);
   25140     for (i = 0; i < vctxt->nbAttrInfos; i++) {
   25141 	iattr = vctxt->attrInfos[i];
   25142 	if (! iattr->metaType) {
   25143 	    ACTIVATE_ATTRIBUTE(iattr)
   25144 	    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
   25145 		XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
   25146 	    ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
   25147         }
   25148     }
   25149     ACTIVATE_ELEM
   25150     return (ret);
   25151 }
   25152 
   25153 /*
   25154 * Cleanup currently used attribute infos.
   25155 */
   25156 static void
   25157 xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
   25158 {
   25159     int i;
   25160     xmlSchemaAttrInfoPtr attr;
   25161 
   25162     if (vctxt->nbAttrInfos == 0)
   25163 	return;
   25164     for (i = 0; i < vctxt->nbAttrInfos; i++) {
   25165 	attr = vctxt->attrInfos[i];
   25166 	if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
   25167 	    if (attr->localName != NULL)
   25168 		xmlFree((xmlChar *) attr->localName);
   25169 	    if (attr->nsName != NULL)
   25170 		xmlFree((xmlChar *) attr->nsName);
   25171 	}
   25172 	if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
   25173 	    if (attr->value != NULL)
   25174 		xmlFree((xmlChar *) attr->value);
   25175 	}
   25176 	if (attr->val != NULL) {
   25177 	    xmlSchemaFreeValue(attr->val);
   25178 	    attr->val = NULL;
   25179 	}
   25180 	memset(attr, 0, sizeof(xmlSchemaAttrInfo));
   25181     }
   25182     vctxt->nbAttrInfos = 0;
   25183 }
   25184 
   25185 /*
   25186 * 3.4.4 Complex Type Definition Validation Rules
   25187 *   Element Locally Valid (Complex Type) (cvc-complex-type)
   25188 * 3.2.4 Attribute Declaration Validation Rules
   25189 *   Validation Rule: Attribute Locally Valid (cvc-attribute)
   25190 *   Attribute Locally Valid (Use) (cvc-au)
   25191 *
   25192 * Only "assessed" attribute information items will be visible to
   25193 * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
   25194 */
   25195 static int
   25196 xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
   25197 {
   25198     xmlSchemaTypePtr type = vctxt->inode->typeDef;
   25199     xmlSchemaItemListPtr attrUseList;
   25200     xmlSchemaAttributeUsePtr attrUse = NULL;
   25201     xmlSchemaAttributePtr attrDecl = NULL;
   25202     xmlSchemaAttrInfoPtr iattr, tmpiattr;
   25203     int i, j, found, nbAttrs, nbUses;
   25204     int xpathRes = 0, res, wildIDs = 0, fixed;
   25205     xmlNodePtr defAttrOwnerElem = NULL;
   25206 
   25207     /*
   25208     * SPEC (cvc-attribute)
   25209     * (1) "The declaration must not be `absent` (see Missing
   25210     * Sub-components ($5.3) for how this can fail to be
   25211     * the case)."
   25212     * (2) "Its {type definition} must not be absent."
   25213     *
   25214     * NOTE (1) + (2): This is not handled here, since we currently do not
   25215     * allow validation against schemas which have missing sub-components.
   25216     *
   25217     * SPEC (cvc-complex-type)
   25218     * (3) "For each attribute information item in the element information
   25219     * item's [attributes] excepting those whose [namespace name] is
   25220     * identical to http://www.w3.org/2001/XMLSchema-instance and whose
   25221     * [local name] is one of type, nil, schemaLocation or
   25222     * noNamespaceSchemaLocation, the appropriate case among the following
   25223     * must be true:
   25224     *
   25225     */
   25226     attrUseList = (xmlSchemaItemListPtr) type->attrUses;
   25227     /*
   25228     * @nbAttrs is the number of attributes present in the instance.
   25229     */
   25230     nbAttrs = vctxt->nbAttrInfos;
   25231     if (attrUseList != NULL)
   25232 	nbUses = attrUseList->nbItems;
   25233     else
   25234 	nbUses = 0;
   25235     for (i = 0; i < nbUses; i++) {
   25236         found = 0;
   25237 	attrUse = attrUseList->items[i];
   25238 	attrDecl = WXS_ATTRUSE_DECL(attrUse);
   25239         for (j = 0; j < nbAttrs; j++) {
   25240 	    iattr = vctxt->attrInfos[j];
   25241 	    /*
   25242 	    * SPEC (cvc-complex-type) (3)
   25243 	    * Skip meta attributes.
   25244 	    */
   25245 	    if (iattr->metaType)
   25246 		continue;
   25247 	    if (iattr->localName[0] != attrDecl->name[0])
   25248 		continue;
   25249 	    if (!xmlStrEqual(iattr->localName, attrDecl->name))
   25250 		continue;
   25251 	    if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
   25252 		continue;
   25253 	    found = 1;
   25254 	    /*
   25255 	    * SPEC (cvc-complex-type)
   25256 	    * (3.1) "If there is among the {attribute uses} an attribute
   25257 	    * use with an {attribute declaration} whose {name} matches
   25258 	    * the attribute information item's [local name] and whose
   25259 	    * {target namespace} is identical to the attribute information
   25260 	    * item's [namespace name] (where an `absent` {target namespace}
   25261 	    * is taken to be identical to a [namespace name] with no value),
   25262 	    * then the attribute information must be `valid` with respect
   25263 	    * to that attribute use as per Attribute Locally Valid (Use)
   25264 	    * ($3.5.4). In this case the {attribute declaration} of that
   25265 	    * attribute use is the `context-determined declaration` for the
   25266 	    * attribute information item with respect to Schema-Validity
   25267 	    * Assessment (Attribute) ($3.2.4) and
   25268 	    * Assessment Outcome (Attribute) ($3.2.5).
   25269 	    */
   25270 	    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
   25271 	    iattr->use = attrUse;
   25272 	    /*
   25273 	    * Context-determined declaration.
   25274 	    */
   25275 	    iattr->decl = attrDecl;
   25276 	    iattr->typeDef = attrDecl->subtypes;
   25277 	    break;
   25278 	}
   25279 
   25280 	if (found)
   25281 	    continue;
   25282 
   25283 	if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
   25284 	    /*
   25285 	    * Handle non-existent, required attributes.
   25286 	    *
   25287 	    * SPEC (cvc-complex-type)
   25288 	    * (4) "The {attribute declaration} of each attribute use in
   25289 	    * the {attribute uses} whose {required} is true matches one
   25290 	    * of the attribute information items in the element information
   25291 	    * item's [attributes] as per clause 3.1 above."
   25292 	    */
   25293 	    tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
   25294 	    if (tmpiattr == NULL) {
   25295 		VERROR_INT(
   25296 		    "xmlSchemaVAttributesComplex",
   25297 		    "calling xmlSchemaGetFreshAttrInfo()");
   25298 		return (-1);
   25299 	    }
   25300 	    tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
   25301 	    tmpiattr->use = attrUse;
   25302 	    tmpiattr->decl = attrDecl;
   25303 	} else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
   25304 	    ((attrUse->defValue != NULL) ||
   25305 	     (attrDecl->defValue != NULL))) {
   25306 	    /*
   25307 	    * Handle non-existent, optional, default/fixed attributes.
   25308 	    */
   25309 	    tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
   25310 	    if (tmpiattr == NULL) {
   25311 		VERROR_INT(
   25312 		    "xmlSchemaVAttributesComplex",
   25313 		    "calling xmlSchemaGetFreshAttrInfo()");
   25314 		return (-1);
   25315 	    }
   25316 	    tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
   25317 	    tmpiattr->use = attrUse;
   25318 	    tmpiattr->decl = attrDecl;
   25319 	    tmpiattr->typeDef = attrDecl->subtypes;
   25320 	    tmpiattr->localName = attrDecl->name;
   25321 	    tmpiattr->nsName = attrDecl->targetNamespace;
   25322 	}
   25323     }
   25324 
   25325     if (vctxt->nbAttrInfos == 0)
   25326 	return (0);
   25327     /*
   25328     * Validate against the wildcard.
   25329     */
   25330     if (type->attributeWildcard != NULL) {
   25331 	/*
   25332 	* SPEC (cvc-complex-type)
   25333 	* (3.2.1) "There must be an {attribute wildcard}."
   25334 	*/
   25335 	for (i = 0; i < nbAttrs; i++) {
   25336 	    iattr = vctxt->attrInfos[i];
   25337 	    /*
   25338 	    * SPEC (cvc-complex-type) (3)
   25339 	    * Skip meta attributes.
   25340 	    */
   25341 	    if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
   25342 		continue;
   25343 	    /*
   25344 	    * SPEC (cvc-complex-type)
   25345 	    * (3.2.2) "The attribute information item must be `valid` with
   25346 	    * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
   25347 	    *
   25348 	    * SPEC Item Valid (Wildcard) (cvc-wildcard)
   25349 	    * "... its [namespace name] must be `valid` with respect to
   25350 	    * the wildcard constraint, as defined in Wildcard allows
   25351 	    * Namespace Name ($3.10.4)."
   25352 	    */
   25353 	    if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
   25354 		    iattr->nsName) == 0) {
   25355 		/*
   25356 		* Handle processContents.
   25357 		*
   25358 		* SPEC (cvc-wildcard):
   25359 		* processContents | context-determined declaration:
   25360 		* "strict"          "mustFind"
   25361 		* "lax"             "none"
   25362 		* "skip"            "skip"
   25363 		*/
   25364 		if (type->attributeWildcard->processContents ==
   25365 		    XML_SCHEMAS_ANY_SKIP) {
   25366 		     /*
   25367 		    * context-determined declaration = "skip"
   25368 		    *
   25369 		    * SPEC PSVI Assessment Outcome (Attribute)
   25370 		    * [validity] = "notKnown"
   25371 		    * [validation attempted] = "none"
   25372 		    */
   25373 		    iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
   25374 		    continue;
   25375 		}
   25376 		/*
   25377 		* Find an attribute declaration.
   25378 		*/
   25379 		iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
   25380 		    iattr->localName, iattr->nsName);
   25381 		if (iattr->decl != NULL) {
   25382 		    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
   25383 		    /*
   25384 		    * SPEC (cvc-complex-type)
   25385 		    * (5) "Let [Definition:]  the wild IDs be the set of
   25386 		    * all attribute information item to which clause 3.2
   25387 		    * applied and whose `validation` resulted in a
   25388 		    * `context-determined declaration` of mustFind or no
   25389 		    * `context-determined declaration` at all, and whose
   25390 		    * [local name] and [namespace name] resolve (as
   25391 		    * defined by QName resolution (Instance) ($3.15.4)) to
   25392 		    * an attribute declaration whose {type definition} is
   25393 		    * or is derived from ID. Then all of the following
   25394 		    * must be true:"
   25395 		    */
   25396 		    iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
   25397 		    if (xmlSchemaIsDerivedFromBuiltInType(
   25398 			iattr->typeDef, XML_SCHEMAS_ID)) {
   25399 			/*
   25400 			* SPEC (5.1) "There must be no more than one
   25401 			* item in `wild IDs`."
   25402 			*/
   25403 			if (wildIDs != 0) {
   25404 			    /* VAL TODO */
   25405 			    iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
   25406 			    TODO
   25407 			    continue;
   25408 			}
   25409 			wildIDs++;
   25410 			/*
   25411 			* SPEC (cvc-complex-type)
   25412 			* (5.2) "If `wild IDs` is non-empty, there must not
   25413 			* be any attribute uses among the {attribute uses}
   25414 			* whose {attribute declaration}'s {type definition}
   25415 			* is or is derived from ID."
   25416 			*/
   25417                         if (attrUseList != NULL) {
   25418                             for (j = 0; j < attrUseList->nbItems; j++) {
   25419                                 if (xmlSchemaIsDerivedFromBuiltInType(
   25420                                     WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
   25421                                     XML_SCHEMAS_ID)) {
   25422                                     /* URGENT VAL TODO: implement */
   25423                             iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
   25424                                     TODO
   25425                                     break;
   25426                                 }
   25427                             }
   25428                         }
   25429 		    }
   25430 		} else if (type->attributeWildcard->processContents ==
   25431 		    XML_SCHEMAS_ANY_LAX) {
   25432 		    iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
   25433 		    /*
   25434 		    * SPEC PSVI Assessment Outcome (Attribute)
   25435 		    * [validity] = "notKnown"
   25436 		    * [validation attempted] = "none"
   25437 		    */
   25438 		} else {
   25439 		    iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
   25440 		}
   25441 	    }
   25442 	}
   25443     }
   25444 
   25445     if (vctxt->nbAttrInfos == 0)
   25446 	return (0);
   25447 
   25448     /*
   25449     * Get the owner element; needed for creation of default attributes.
   25450     * This fixes bug #341337, reported by David Grohmann.
   25451     */
   25452     if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
   25453 	xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
   25454 	if (ielem && ielem->node && ielem->node->doc)
   25455 	    defAttrOwnerElem = ielem->node;
   25456     }
   25457     /*
   25458     * Validate values, create default attributes, evaluate IDCs.
   25459     */
   25460     for (i = 0; i < vctxt->nbAttrInfos; i++) {
   25461 	iattr = vctxt->attrInfos[i];
   25462 	/*
   25463 	* VAL TODO: Note that we won't try to resolve IDCs to
   25464 	* "lax" and "skip" validated attributes. Check what to
   25465 	* do in this case.
   25466 	*/
   25467 	if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
   25468 	    (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
   25469 	    continue;
   25470 	/*
   25471 	* VAL TODO: What to do if the type definition is missing?
   25472 	*/
   25473 	if (iattr->typeDef == NULL) {
   25474 	    iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
   25475 	    continue;
   25476 	}
   25477 
   25478 	ACTIVATE_ATTRIBUTE(iattr);
   25479 	fixed = 0;
   25480 	xpathRes = 0;
   25481 
   25482 	if (vctxt->xpathStates != NULL) {
   25483 	    /*
   25484 	    * Evaluate IDCs.
   25485 	    */
   25486 	    xpathRes = xmlSchemaXPathEvaluate(vctxt,
   25487 		XML_ATTRIBUTE_NODE);
   25488 	    if (xpathRes == -1) {
   25489 		VERROR_INT("xmlSchemaVAttributesComplex",
   25490 		    "calling xmlSchemaXPathEvaluate()");
   25491 		goto internal_error;
   25492 	    }
   25493 	}
   25494 
   25495 	if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
   25496 	    /*
   25497 	    * Default/fixed attributes.
   25498 	    * We need the value only if we need to resolve IDCs or
   25499 	    * will create default attributes.
   25500 	    */
   25501 	    if ((xpathRes) || (defAttrOwnerElem)) {
   25502 		if (iattr->use->defValue != NULL) {
   25503 		    iattr->value = (xmlChar *) iattr->use->defValue;
   25504 		    iattr->val = iattr->use->defVal;
   25505 		} else {
   25506 		    iattr->value = (xmlChar *) iattr->decl->defValue;
   25507 		    iattr->val = iattr->decl->defVal;
   25508 		}
   25509 		/*
   25510 		* IDCs will consume the precomputed default value,
   25511 		* so we need to clone it.
   25512 		*/
   25513 		if (iattr->val == NULL) {
   25514 		    VERROR_INT("xmlSchemaVAttributesComplex",
   25515 			"default/fixed value on an attribute use was "
   25516 			"not precomputed");
   25517 		    goto internal_error;
   25518 		}
   25519 		iattr->val = xmlSchemaCopyValue(iattr->val);
   25520 		if (iattr->val == NULL) {
   25521 		    VERROR_INT("xmlSchemaVAttributesComplex",
   25522 			"calling xmlSchemaCopyValue()");
   25523 		    goto internal_error;
   25524 		}
   25525 	    }
   25526 	    /*
   25527 	    * PSVI: Add the default attribute to the current element.
   25528 	    * VAL TODO: Should we use the *normalized* value? This currently
   25529 	    *   uses the *initial* value.
   25530 	    */
   25531 
   25532 	    if (defAttrOwnerElem) {
   25533 		xmlChar *normValue;
   25534 		const xmlChar *value;
   25535 
   25536 		value = iattr->value;
   25537 		/*
   25538 		* Normalize the value.
   25539 		*/
   25540 		normValue = xmlSchemaNormalizeValue(iattr->typeDef,
   25541 		    iattr->value);
   25542 		if (normValue != NULL)
   25543 		    value = BAD_CAST normValue;
   25544 
   25545 		if (iattr->nsName == NULL) {
   25546 		    if (xmlNewProp(defAttrOwnerElem,
   25547 			iattr->localName, value) == NULL) {
   25548 			VERROR_INT("xmlSchemaVAttributesComplex",
   25549 			    "calling xmlNewProp()");
   25550 			if (normValue != NULL)
   25551 			    xmlFree(normValue);
   25552 			goto internal_error;
   25553 		    }
   25554 		} else {
   25555 		    xmlNsPtr ns;
   25556 
   25557 		    ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
   25558 			defAttrOwnerElem, iattr->nsName);
   25559 		    if (ns == NULL) {
   25560 			xmlChar prefix[12];
   25561 			int counter = 0;
   25562 
   25563 			/*
   25564 			* Create a namespace declaration on the validation
   25565 			* root node if no namespace declaration is in scope.
   25566 			*/
   25567 			do {
   25568 			    snprintf((char *) prefix, 12, "p%d", counter++);
   25569 			    ns = xmlSearchNs(defAttrOwnerElem->doc,
   25570 				defAttrOwnerElem, BAD_CAST prefix);
   25571 			    if (counter > 1000) {
   25572 				VERROR_INT(
   25573 				    "xmlSchemaVAttributesComplex",
   25574 				    "could not compute a ns prefix for a "
   25575 				    "default/fixed attribute");
   25576 				if (normValue != NULL)
   25577 				    xmlFree(normValue);
   25578 				goto internal_error;
   25579 			    }
   25580 			} while (ns != NULL);
   25581 			ns = xmlNewNs(vctxt->validationRoot,
   25582 			    iattr->nsName, BAD_CAST prefix);
   25583 		    }
   25584 		    /*
   25585 		    * TODO:
   25586 		    * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
   25587 		    * If we have QNames: do we need to ensure there's a
   25588 		    * prefix defined for the QName?
   25589 		    */
   25590 		    xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
   25591 		}
   25592 		if (normValue != NULL)
   25593 		    xmlFree(normValue);
   25594 	    }
   25595 	    /*
   25596 	    * Go directly to IDC evaluation.
   25597 	    */
   25598 	    goto eval_idcs;
   25599 	}
   25600 	/*
   25601 	* Validate the value.
   25602 	*/
   25603 	if (vctxt->value != NULL) {
   25604 	    /*
   25605 	    * Free last computed value; just for safety reasons.
   25606 	    */
   25607 	    xmlSchemaFreeValue(vctxt->value);
   25608 	    vctxt->value = NULL;
   25609 	}
   25610 	/*
   25611 	* Note that the attribute *use* can be unavailable, if
   25612 	* the attribute was a wild attribute.
   25613 	*/
   25614 	if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
   25615 	    ((iattr->use != NULL) &&
   25616 	     (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
   25617 	    fixed = 1;
   25618 	else
   25619 	    fixed = 0;
   25620 	/*
   25621 	* SPEC (cvc-attribute)
   25622 	* (3) "The item's `normalized value` must be locally `valid`
   25623 	* with respect to that {type definition} as per
   25624 	* String Valid ($3.14.4)."
   25625 	*
   25626 	* VAL TODO: Do we already have the
   25627 	* "normalized attribute value" here?
   25628 	*/
   25629 	if (xpathRes || fixed) {
   25630 	    iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
   25631 	    /*
   25632 	    * Request a computed value.
   25633 	    */
   25634 	    res = xmlSchemaVCheckCVCSimpleType(
   25635 		ACTXT_CAST vctxt,
   25636 		iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
   25637 		1, 1, 0);
   25638 	} else {
   25639 	    res = xmlSchemaVCheckCVCSimpleType(
   25640 		ACTXT_CAST vctxt,
   25641 		iattr->node, iattr->typeDef, iattr->value, NULL,
   25642 		1, 0, 0);
   25643 	}
   25644 
   25645 	if (res != 0) {
   25646 	    if (res == -1) {
   25647 		VERROR_INT("xmlSchemaVAttributesComplex",
   25648 		    "calling xmlSchemaStreamValidateSimpleTypeValue()");
   25649 		goto internal_error;
   25650 	    }
   25651 	    iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
   25652 	    /*
   25653 	    * SPEC PSVI Assessment Outcome (Attribute)
   25654 	    * [validity] = "invalid"
   25655 	    */
   25656 	    goto eval_idcs;
   25657 	}
   25658 
   25659 	if (fixed) {
   25660 	    /*
   25661 	    * SPEC Attribute Locally Valid (Use) (cvc-au)
   25662 	    * "For an attribute information item to be `valid`
   25663 	    * with respect to an attribute use its *normalized*
   25664 	    * value must match the *canonical* lexical
   25665 	    * representation of the attribute use's {value
   25666 	    * constraint}value, if it is present and fixed."
   25667 	    *
   25668 	    * VAL TODO: The requirement for the *canonical* value
   25669 	    * will be removed in XML Schema 1.1.
   25670 	    */
   25671 	    /*
   25672 	    * SPEC Attribute Locally Valid (cvc-attribute)
   25673 	    * (4) "The item's *actual* value must match the *value* of
   25674 	    * the {value constraint}, if it is present and fixed."
   25675 	    */
   25676 	    if (iattr->val == NULL) {
   25677 		/* VAL TODO: A value was not precomputed. */
   25678 		TODO
   25679 		goto eval_idcs;
   25680 	    }
   25681 	    if ((iattr->use != NULL) &&
   25682 		(iattr->use->defValue != NULL)) {
   25683 		if (iattr->use->defVal == NULL) {
   25684 		    /* VAL TODO: A default value was not precomputed. */
   25685 		    TODO
   25686 		    goto eval_idcs;
   25687 		}
   25688 		iattr->vcValue = iattr->use->defValue;
   25689 		/*
   25690 		if (xmlSchemaCompareValuesWhtsp(attr->val,
   25691 		    (xmlSchemaWhitespaceValueType) ws,
   25692 		    attr->use->defVal,
   25693 		    (xmlSchemaWhitespaceValueType) ws) != 0) {
   25694 		*/
   25695 		if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
   25696 		    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
   25697 	    } else {
   25698 		if (iattr->decl->defVal == NULL) {
   25699 		    /* VAL TODO: A default value was not precomputed. */
   25700 		    TODO
   25701 		    goto eval_idcs;
   25702 		}
   25703 		iattr->vcValue = iattr->decl->defValue;
   25704 		/*
   25705 		if (xmlSchemaCompareValuesWhtsp(attr->val,
   25706 		    (xmlSchemaWhitespaceValueType) ws,
   25707 		    attrDecl->defVal,
   25708 		    (xmlSchemaWhitespaceValueType) ws) != 0) {
   25709 		*/
   25710 		if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
   25711 		    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
   25712 	    }
   25713 	    /*
   25714 	    * [validity] = "valid"
   25715 	    */
   25716 	}
   25717 eval_idcs:
   25718 	/*
   25719 	* Evaluate IDCs.
   25720 	*/
   25721 	if (xpathRes) {
   25722 	    if (xmlSchemaXPathProcessHistory(vctxt,
   25723 		vctxt->depth +1) == -1) {
   25724 		VERROR_INT("xmlSchemaVAttributesComplex",
   25725 		    "calling xmlSchemaXPathEvaluate()");
   25726 		goto internal_error;
   25727 	    }
   25728 	} else if (vctxt->xpathStates != NULL)
   25729 	    xmlSchemaXPathPop(vctxt);
   25730     }
   25731 
   25732     /*
   25733     * Report errors.
   25734     */
   25735     for (i = 0; i < vctxt->nbAttrInfos; i++) {
   25736 	iattr = vctxt->attrInfos[i];
   25737 	if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
   25738 	    (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
   25739 	    (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
   25740 	    (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
   25741 	    continue;
   25742 	ACTIVATE_ATTRIBUTE(iattr);
   25743 	switch (iattr->state) {
   25744 	    case XML_SCHEMAS_ATTR_ERR_MISSING: {
   25745 		    xmlChar *str = NULL;
   25746 		    ACTIVATE_ELEM;
   25747 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
   25748 			XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
   25749 			"The attribute '%s' is required but missing",
   25750 			xmlSchemaFormatQName(&str,
   25751 			    iattr->decl->targetNamespace,
   25752 			    iattr->decl->name),
   25753 			NULL);
   25754 		    FREE_AND_NULL(str)
   25755 		    break;
   25756 		}
   25757 	    case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
   25758 		VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
   25759 		    "The type definition is absent");
   25760 		break;
   25761 	    case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
   25762 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   25763 		    XML_SCHEMAV_CVC_AU, NULL, NULL,
   25764 		    "The value '%s' does not match the fixed "
   25765 		    "value constraint '%s'",
   25766 		    iattr->value, iattr->vcValue);
   25767 		break;
   25768 	    case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
   25769 		VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
   25770 		    "No matching global attribute declaration available, but "
   25771 		    "demanded by the strict wildcard");
   25772 		break;
   25773 	    case XML_SCHEMAS_ATTR_UNKNOWN:
   25774 		if (iattr->metaType)
   25775 		    break;
   25776 		/*
   25777 		* MAYBE VAL TODO: One might report different error messages
   25778 		* for the following errors.
   25779 		*/
   25780 		if (type->attributeWildcard == NULL) {
   25781 		    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
   25782 			XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
   25783 		} else {
   25784 		    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
   25785 			XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
   25786 		}
   25787 		break;
   25788 	    default:
   25789 		break;
   25790 	}
   25791     }
   25792 
   25793     ACTIVATE_ELEM;
   25794     return (0);
   25795 internal_error:
   25796     ACTIVATE_ELEM;
   25797     return (-1);
   25798 }
   25799 
   25800 static int
   25801 xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
   25802 			      int *skip)
   25803 {
   25804     xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
   25805     /*
   25806     * The namespace of the element was already identified to be
   25807     * matching the wildcard.
   25808     */
   25809     if ((skip == NULL) || (wild == NULL) ||
   25810 	(wild->type != XML_SCHEMA_TYPE_ANY)) {
   25811 	VERROR_INT("xmlSchemaValidateElemWildcard",
   25812 	    "bad arguments");
   25813 	return (-1);
   25814     }
   25815     *skip = 0;
   25816     if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
   25817 	/*
   25818 	* URGENT VAL TODO: Either we need to position the stream to the
   25819 	* next sibling, or walk the whole subtree.
   25820 	*/
   25821 	*skip = 1;
   25822 	return (0);
   25823     }
   25824     {
   25825 	xmlSchemaElementPtr decl = NULL;
   25826 
   25827 	decl = xmlSchemaGetElem(vctxt->schema,
   25828 	    vctxt->inode->localName, vctxt->inode->nsName);
   25829 	if (decl != NULL) {
   25830 	    vctxt->inode->decl = decl;
   25831 	    return (0);
   25832 	}
   25833     }
   25834     if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
   25835 	/* VAL TODO: Change to proper error code. */
   25836 	VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
   25837 	    "No matching global element declaration available, but "
   25838 	    "demanded by the strict wildcard");
   25839 	return (vctxt->err);
   25840     }
   25841     if (vctxt->nbAttrInfos != 0) {
   25842 	xmlSchemaAttrInfoPtr iattr;
   25843 	/*
   25844 	* SPEC Validation Rule: Schema-Validity Assessment (Element)
   25845 	* (1.2.1.2.1) - (1.2.1.2.3 )
   25846 	*
   25847 	* Use the xsi:type attribute for the type definition.
   25848 	*/
   25849 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   25850 	    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
   25851 	if (iattr != NULL) {
   25852 	    if (xmlSchemaProcessXSIType(vctxt, iattr,
   25853 		&(vctxt->inode->typeDef), NULL) == -1) {
   25854 		VERROR_INT("xmlSchemaValidateElemWildcard",
   25855 		    "calling xmlSchemaProcessXSIType() to "
   25856 		    "process the attribute 'xsi:nil'");
   25857 		return (-1);
   25858 	    }
   25859 	    /*
   25860 	    * Don't return an error on purpose.
   25861 	    */
   25862 	    return (0);
   25863 	}
   25864     }
   25865     /*
   25866     * SPEC Validation Rule: Schema-Validity Assessment (Element)
   25867     *
   25868     * Fallback to "anyType".
   25869     */
   25870     vctxt->inode->typeDef =
   25871 	xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
   25872     return (0);
   25873 }
   25874 
   25875 /*
   25876 * xmlSchemaCheckCOSValidDefault:
   25877 *
   25878 * This will be called if: not nilled, no content and a default/fixed
   25879 * value is provided.
   25880 */
   25881 
   25882 static int
   25883 xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
   25884 			      const xmlChar *value,
   25885 			      xmlSchemaValPtr *val)
   25886 {
   25887     int ret = 0;
   25888     xmlSchemaNodeInfoPtr inode = vctxt->inode;
   25889 
   25890     /*
   25891     * cos-valid-default:
   25892     * Schema Component Constraint: Element Default Valid (Immediate)
   25893     * For a string to be a valid default with respect to a type
   25894     * definition the appropriate case among the following must be true:
   25895     */
   25896     if WXS_IS_COMPLEX(inode->typeDef) {
   25897 	/*
   25898 	* Complex type.
   25899 	*
   25900 	* SPEC (2.1) "its {content type} must be a simple type definition
   25901 	* or mixed."
   25902 	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
   25903 	* type}'s particle must be `emptiable` as defined by
   25904 	* Particle Emptiable ($3.9.6)."
   25905 	*/
   25906 	if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
   25907 	    ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
   25908 	     (! WXS_EMPTIABLE(inode->typeDef)))) {
   25909 	    ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
   25910 	    /* NOTE that this covers (2.2.2) as well. */
   25911 	    VERROR(ret, NULL,
   25912 		"For a string to be a valid default, the type definition "
   25913 		"must be a simple type or a complex type with simple content "
   25914 		"or mixed content and a particle emptiable");
   25915 	    return(ret);
   25916 	}
   25917     }
   25918     /*
   25919     * 1 If the type definition is a simple type definition, then the string
   25920     * must be `valid` with respect to that definition as defined by String
   25921     * Valid ($3.14.4).
   25922     *
   25923     * AND
   25924     *
   25925     * 2.2.1 If the {content type} is a simple type definition, then the
   25926     * string must be `valid` with respect to that simple type definition
   25927     * as defined by String Valid ($3.14.4).
   25928     */
   25929     if (WXS_IS_SIMPLE(inode->typeDef)) {
   25930 
   25931 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
   25932 	    NULL, inode->typeDef, value, val, 1, 1, 0);
   25933 
   25934     } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   25935 
   25936 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
   25937 	    NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
   25938     }
   25939     if (ret < 0) {
   25940 	VERROR_INT("xmlSchemaCheckCOSValidDefault",
   25941 	    "calling xmlSchemaVCheckCVCSimpleType()");
   25942     }
   25943     return (ret);
   25944 }
   25945 
   25946 static void
   25947 xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
   25948 			       const xmlChar * name ATTRIBUTE_UNUSED,
   25949 			       xmlSchemaElementPtr item,
   25950 			       xmlSchemaNodeInfoPtr inode)
   25951 {
   25952     inode->decl = item;
   25953 #ifdef DEBUG_CONTENT
   25954     {
   25955 	xmlChar *str = NULL;
   25956 
   25957 	if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
   25958 	    xmlGenericError(xmlGenericErrorContext,
   25959 		"AUTOMATON callback for '%s' [declaration]\n",
   25960 		xmlSchemaFormatQName(&str,
   25961 		inode->localName, inode->nsName));
   25962 	} else {
   25963 	    xmlGenericError(xmlGenericErrorContext,
   25964 		    "AUTOMATON callback for '%s' [wildcard]\n",
   25965 		    xmlSchemaFormatQName(&str,
   25966 		    inode->localName, inode->nsName));
   25967 
   25968 	}
   25969 	FREE_AND_NULL(str)
   25970     }
   25971 #endif
   25972 }
   25973 
   25974 static int
   25975 xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
   25976 {
   25977     vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
   25978     if (vctxt->inode == NULL) {
   25979 	VERROR_INT("xmlSchemaValidatorPushElem",
   25980 	    "calling xmlSchemaGetFreshElemInfo()");
   25981 	return (-1);
   25982     }
   25983     vctxt->nbAttrInfos = 0;
   25984     return (0);
   25985 }
   25986 
   25987 static int
   25988 xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
   25989 			     xmlSchemaNodeInfoPtr inode,
   25990 			     xmlSchemaTypePtr type,
   25991 			     const xmlChar *value)
   25992 {
   25993     if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
   25994 	return (xmlSchemaVCheckCVCSimpleType(
   25995 	    ACTXT_CAST vctxt, NULL,
   25996 	    type, value, &(inode->val), 1, 1, 0));
   25997     else
   25998 	return (xmlSchemaVCheckCVCSimpleType(
   25999 	    ACTXT_CAST vctxt, NULL,
   26000 	    type, value, NULL, 1, 0, 0));
   26001 }
   26002 
   26003 
   26004 
   26005 /*
   26006 * Process END of element.
   26007 */
   26008 static int
   26009 xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
   26010 {
   26011     int ret = 0;
   26012     xmlSchemaNodeInfoPtr inode = vctxt->inode;
   26013 
   26014     if (vctxt->nbAttrInfos != 0)
   26015 	xmlSchemaClearAttrInfos(vctxt);
   26016     if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
   26017 	/*
   26018 	* This element was not expected;
   26019 	* we will not validate child elements of broken parents.
   26020 	* Skip validation of all content of the parent.
   26021 	*/
   26022 	vctxt->skipDepth = vctxt->depth -1;
   26023 	goto end_elem;
   26024     }
   26025     if ((inode->typeDef == NULL) ||
   26026 	(inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
   26027 	/*
   26028 	* 1. the type definition might be missing if the element was
   26029 	*    error prone
   26030 	* 2. it might be abstract.
   26031 	*/
   26032 	goto end_elem;
   26033     }
   26034     /*
   26035     * Check the content model.
   26036     */
   26037     if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
   26038 	(inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
   26039 
   26040 	/*
   26041 	* Workaround for "anyType".
   26042 	*/
   26043 	if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
   26044 	    goto character_content;
   26045 
   26046 	if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
   26047 	    xmlChar *values[10];
   26048 	    int terminal, nbval = 10, nbneg;
   26049 
   26050 	    if (inode->regexCtxt == NULL) {
   26051 		/*
   26052 		* Create the regex context.
   26053 		*/
   26054 		inode->regexCtxt =
   26055 		    xmlRegNewExecCtxt(inode->typeDef->contModel,
   26056 		    (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
   26057 		    vctxt);
   26058 		if (inode->regexCtxt == NULL) {
   26059 		    VERROR_INT("xmlSchemaValidatorPopElem",
   26060 			"failed to create a regex context");
   26061 		    goto internal_error;
   26062 		}
   26063 #ifdef DEBUG_AUTOMATA
   26064 		xmlGenericError(xmlGenericErrorContext,
   26065 		    "AUTOMATON create on '%s'\n", inode->localName);
   26066 #endif
   26067 	    }
   26068 
   26069 	    /*
   26070 	     * Do not check further content if the node has been nilled
   26071 	     */
   26072 	    if (INODE_NILLED(inode)) {
   26073 		ret = 0;
   26074 #ifdef DEBUG_AUTOMATA
   26075 		xmlGenericError(xmlGenericErrorContext,
   26076 		    "AUTOMATON succeeded on nilled '%s'\n",
   26077 		    inode->localName);
   26078 #endif
   26079                 goto skip_nilled;
   26080 	    }
   26081 
   26082 	    /*
   26083 	    * Get hold of the still expected content, since a further
   26084 	    * call to xmlRegExecPushString() will loose this information.
   26085 	    */
   26086 	    xmlRegExecNextValues(inode->regexCtxt,
   26087 		&nbval, &nbneg, &values[0], &terminal);
   26088 	    ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
   26089 	    if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
   26090 		/*
   26091 		* Still missing something.
   26092 		*/
   26093 		ret = 1;
   26094 		inode->flags |=
   26095 		    XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
   26096 		xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
   26097 		    XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
   26098 		    "Missing child element(s)",
   26099 		    nbval, nbneg, values);
   26100 #ifdef DEBUG_AUTOMATA
   26101 		xmlGenericError(xmlGenericErrorContext,
   26102 		    "AUTOMATON missing ERROR on '%s'\n",
   26103 		    inode->localName);
   26104 #endif
   26105 	    } else {
   26106 		/*
   26107 		* Content model is satisfied.
   26108 		*/
   26109 		ret = 0;
   26110 #ifdef DEBUG_AUTOMATA
   26111 		xmlGenericError(xmlGenericErrorContext,
   26112 		    "AUTOMATON succeeded on '%s'\n",
   26113 		    inode->localName);
   26114 #endif
   26115 	    }
   26116 
   26117 	}
   26118     }
   26119 
   26120 skip_nilled:
   26121 
   26122     if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
   26123 	goto end_elem;
   26124 
   26125 character_content:
   26126 
   26127     if (vctxt->value != NULL) {
   26128 	xmlSchemaFreeValue(vctxt->value);
   26129 	vctxt->value = NULL;
   26130     }
   26131     /*
   26132     * Check character content.
   26133     */
   26134     if (inode->decl == NULL) {
   26135 	/*
   26136 	* Speedup if no declaration exists.
   26137 	*/
   26138 	if (WXS_IS_SIMPLE(inode->typeDef)) {
   26139 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26140 		inode, inode->typeDef, inode->value);
   26141 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   26142 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26143 		inode, inode->typeDef->contentTypeDef,
   26144 		inode->value);
   26145 	}
   26146 	if (ret < 0) {
   26147 	    VERROR_INT("xmlSchemaValidatorPopElem",
   26148 		"calling xmlSchemaVCheckCVCSimpleType()");
   26149 	    goto internal_error;
   26150 	}
   26151 	goto end_elem;
   26152     }
   26153     /*
   26154     * cvc-elt (3.3.4) : 5
   26155     * The appropriate case among the following must be true:
   26156     */
   26157     /*
   26158     * cvc-elt (3.3.4) : 5.1
   26159     * If the declaration has a {value constraint},
   26160     * the item has neither element nor character [children] and
   26161     * clause 3.2 has not applied, then all of the following must be true:
   26162     */
   26163     if ((inode->decl->value != NULL) &&
   26164 	(inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
   26165 	(! INODE_NILLED(inode))) {
   26166 	/*
   26167 	* cvc-elt (3.3.4) : 5.1.1
   26168 	* If the `actual type definition` is a `local type definition`
   26169 	* then the canonical lexical representation of the {value constraint}
   26170 	* value must be a valid default for the `actual type definition` as
   26171 	* defined in Element Default Valid (Immediate) ($3.3.6).
   26172 	*/
   26173 	/*
   26174 	* NOTE: 'local' above means types acquired by xsi:type.
   26175 	* NOTE: Although the *canonical* value is stated, it is not
   26176 	* relevant if canonical or not. Additionally XML Schema 1.1
   26177 	* will removed this requirement as well.
   26178 	*/
   26179 	if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
   26180 
   26181 	    ret = xmlSchemaCheckCOSValidDefault(vctxt,
   26182 		inode->decl->value, &(inode->val));
   26183 	    if (ret != 0) {
   26184 		if (ret < 0) {
   26185 		    VERROR_INT("xmlSchemaValidatorPopElem",
   26186 			"calling xmlSchemaCheckCOSValidDefault()");
   26187 		    goto internal_error;
   26188 		}
   26189 		goto end_elem;
   26190 	    }
   26191 	    /*
   26192 	    * Stop here, to avoid redundant validation of the value
   26193 	    * (see following).
   26194 	    */
   26195 	    goto default_psvi;
   26196 	}
   26197 	/*
   26198 	* cvc-elt (3.3.4) : 5.1.2
   26199 	* The element information item with the canonical lexical
   26200 	* representation of the {value constraint} value used as its
   26201 	* `normalized value` must be `valid` with respect to the
   26202 	* `actual type definition` as defined by Element Locally Valid (Type)
   26203 	* ($3.3.4).
   26204 	*/
   26205 	if (WXS_IS_SIMPLE(inode->typeDef)) {
   26206 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26207 		inode, inode->typeDef, inode->decl->value);
   26208 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   26209 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26210 		inode, inode->typeDef->contentTypeDef,
   26211 		inode->decl->value);
   26212 	}
   26213 	if (ret != 0) {
   26214 	    if (ret < 0) {
   26215 		VERROR_INT("xmlSchemaValidatorPopElem",
   26216 		    "calling xmlSchemaVCheckCVCSimpleType()");
   26217 		goto internal_error;
   26218 	    }
   26219 	    goto end_elem;
   26220 	}
   26221 
   26222 default_psvi:
   26223 	/*
   26224 	* PSVI: Create a text node on the instance element.
   26225 	*/
   26226 	if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
   26227 	    (inode->node != NULL)) {
   26228 	    xmlNodePtr textChild;
   26229 	    xmlChar *normValue;
   26230 	    /*
   26231 	    * VAL TODO: Normalize the value.
   26232 	    */
   26233 	    normValue = xmlSchemaNormalizeValue(inode->typeDef,
   26234 		inode->decl->value);
   26235 	    if (normValue != NULL) {
   26236 		textChild = xmlNewText(BAD_CAST normValue);
   26237 		xmlFree(normValue);
   26238 	    } else
   26239 		textChild = xmlNewText(inode->decl->value);
   26240 	    if (textChild == NULL) {
   26241 		VERROR_INT("xmlSchemaValidatorPopElem",
   26242 		    "calling xmlNewText()");
   26243 		goto internal_error;
   26244 	    } else
   26245 		xmlAddChild(inode->node, textChild);
   26246 	}
   26247 
   26248     } else if (! INODE_NILLED(inode)) {
   26249 	/*
   26250 	* 5.2.1 The element information item must be `valid` with respect
   26251 	* to the `actual type definition` as defined by Element Locally
   26252 	* Valid (Type) ($3.3.4).
   26253 	*/
   26254 	if (WXS_IS_SIMPLE(inode->typeDef)) {
   26255 	     /*
   26256 	    * SPEC (cvc-type) (3.1)
   26257 	    * "If the type definition is a simple type definition, ..."
   26258 	    * (3.1.3) "If clause 3.2 of Element Locally Valid
   26259 	    * (Element) ($3.3.4) did not apply, then the `normalized value`
   26260 	    * must be `valid` with respect to the type definition as defined
   26261 	    * by String Valid ($3.14.4).
   26262 	    */
   26263 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26264 		    inode, inode->typeDef, inode->value);
   26265 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   26266 	    /*
   26267 	    * SPEC (cvc-type) (3.2) "If the type definition is a complex type
   26268 	    * definition, then the element information item must be
   26269 	    * `valid` with respect to the type definition as per
   26270 	    * Element Locally Valid (Complex Type) ($3.4.4);"
   26271 	    *
   26272 	    * SPEC (cvc-complex-type) (2.2)
   26273 	    * "If the {content type} is a simple type definition, ...
   26274 	    * the `normalized value` of the element information item is
   26275 	    * `valid` with respect to that simple type definition as
   26276 	    * defined by String Valid ($3.14.4)."
   26277 	    */
   26278 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26279 		inode, inode->typeDef->contentTypeDef, inode->value);
   26280 	}
   26281 	if (ret != 0) {
   26282 	    if (ret < 0) {
   26283 		VERROR_INT("xmlSchemaValidatorPopElem",
   26284 		    "calling xmlSchemaVCheckCVCSimpleType()");
   26285 		goto internal_error;
   26286 	    }
   26287 	    goto end_elem;
   26288 	}
   26289 	/*
   26290 	* 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
   26291 	* not applied, all of the following must be true:
   26292 	*/
   26293 	if ((inode->decl->value != NULL) &&
   26294 	    (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
   26295 
   26296 	    /*
   26297 	    * TODO: We will need a computed value, when comparison is
   26298 	    * done on computed values.
   26299 	    */
   26300 	    /*
   26301 	    * 5.2.2.1 The element information item must have no element
   26302 	    * information item [children].
   26303 	    */
   26304 	    if (inode->flags &
   26305 		    XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
   26306 		ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
   26307 		VERROR(ret, NULL,
   26308 		    "The content must not containt element nodes since "
   26309 		    "there is a fixed value constraint");
   26310 		goto end_elem;
   26311 	    } else {
   26312 		/*
   26313 		* 5.2.2.2 The appropriate case among the following must
   26314 		* be true:
   26315 		*/
   26316 		if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
   26317 		    /*
   26318 		    * 5.2.2.2.1 If the {content type} of the `actual type
   26319 		    * definition` is mixed, then the *initial value* of the
   26320 		    * item must match the canonical lexical representation
   26321 		    * of the {value constraint} value.
   26322 		    *
   26323 		    * ... the *initial value* of an element information
   26324 		    * item is the string composed of, in order, the
   26325 		    * [character code] of each character information item in
   26326 		    * the [children] of that element information item.
   26327 		    */
   26328 		    if (! xmlStrEqual(inode->value, inode->decl->value)){
   26329 			/*
   26330 			* VAL TODO: Report invalid & expected values as well.
   26331 			* VAL TODO: Implement the canonical stuff.
   26332 			*/
   26333 			ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
   26334 			xmlSchemaCustomErr(ACTXT_CAST vctxt,
   26335 			    ret, NULL, NULL,
   26336 			    "The initial value '%s' does not match the fixed "
   26337 			    "value constraint '%s'",
   26338 			    inode->value, inode->decl->value);
   26339 			goto end_elem;
   26340 		    }
   26341 		} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   26342 		    /*
   26343 		    * 5.2.2.2.2 If the {content type} of the `actual type
   26344 		    * definition` is a simple type definition, then the
   26345 		    * *actual value* of the item must match the canonical
   26346 		    * lexical representation of the {value constraint} value.
   26347 		    */
   26348 		    /*
   26349 		    * VAL TODO: *actual value* is the normalized value, impl.
   26350 		    *           this.
   26351 		    * VAL TODO: Report invalid & expected values as well.
   26352 		    * VAL TODO: Implement a comparison with the computed values.
   26353 		    */
   26354 		    if (! xmlStrEqual(inode->value,
   26355 			    inode->decl->value)) {
   26356 			ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
   26357 			xmlSchemaCustomErr(ACTXT_CAST vctxt,
   26358 			    ret, NULL, NULL,
   26359 			    "The actual value '%s' does not match the fixed "
   26360 			    "value constraint '%s'",
   26361 			    inode->value,
   26362 			    inode->decl->value);
   26363 			goto end_elem;
   26364 		    }
   26365 		}
   26366 	    }
   26367 	}
   26368     }
   26369 
   26370 end_elem:
   26371     if (vctxt->depth < 0) {
   26372 	/* TODO: raise error? */
   26373 	return (0);
   26374     }
   26375     if (vctxt->depth == vctxt->skipDepth)
   26376 	vctxt->skipDepth = -1;
   26377     /*
   26378     * Evaluate the history of XPath state objects.
   26379     */
   26380     if (inode->appliedXPath &&
   26381 	(xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
   26382 	goto internal_error;
   26383     /*
   26384     * MAYBE TODO:
   26385     * SPEC (6) "The element information item must be `valid` with
   26386     * respect to each of the {identity-constraint definitions} as per
   26387     * Identity-constraint Satisfied ($3.11.4)."
   26388     */
   26389     /*
   26390     * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
   26391     *   need to be built in any case.
   26392     *   We will currently build IDC node-tables and bubble them only if
   26393     *   keyrefs do exist.
   26394     */
   26395 
   26396     /*
   26397     * Add the current IDC target-nodes to the IDC node-tables.
   26398     */
   26399     if ((inode->idcMatchers != NULL) &&
   26400 	(vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
   26401     {
   26402 	if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
   26403 	    goto internal_error;
   26404     }
   26405     /*
   26406     * Validate IDC keyrefs.
   26407     */
   26408     if (vctxt->inode->hasKeyrefs)
   26409 	if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
   26410 	    goto internal_error;
   26411     /*
   26412     * Merge/free the IDC table.
   26413     */
   26414     if (inode->idcTable != NULL) {
   26415 #ifdef DEBUG_IDC_NODE_TABLE
   26416 	xmlSchemaDebugDumpIDCTable(stdout,
   26417 	    inode->nsName,
   26418 	    inode->localName,
   26419 	    inode->idcTable);
   26420 #endif
   26421 	if ((vctxt->depth > 0) &&
   26422 	    (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
   26423 	{
   26424 	    /*
   26425 	    * Merge the IDC node table with the table of the parent node.
   26426 	    */
   26427 	    if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
   26428 		goto internal_error;
   26429 	}
   26430     }
   26431     /*
   26432     * Clear the current ielem.
   26433     * VAL TODO: Don't free the PSVI IDC tables if they are
   26434     * requested for the PSVI.
   26435     */
   26436     xmlSchemaClearElemInfo(vctxt, inode);
   26437     /*
   26438     * Skip further processing if we are on the validation root.
   26439     */
   26440     if (vctxt->depth == 0) {
   26441 	vctxt->depth--;
   26442 	vctxt->inode = NULL;
   26443 	return (0);
   26444     }
   26445     /*
   26446     * Reset the keyrefDepth if needed.
   26447     */
   26448     if (vctxt->aidcs != NULL) {
   26449 	xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
   26450 	do {
   26451 	    if (aidc->keyrefDepth == vctxt->depth) {
   26452 		/*
   26453 		* A 'keyrefDepth' of a key/unique IDC matches the current
   26454 		* depth, this means that we are leaving the scope of the
   26455 		* top-most keyref IDC which refers to this IDC.
   26456 		*/
   26457 		aidc->keyrefDepth = -1;
   26458 	    }
   26459 	    aidc = aidc->next;
   26460 	} while (aidc != NULL);
   26461     }
   26462     vctxt->depth--;
   26463     vctxt->inode = vctxt->elemInfos[vctxt->depth];
   26464     /*
   26465     * VAL TODO: 7 If the element information item is the `validation root`, it must be
   26466     * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
   26467     */
   26468     return (ret);
   26469 
   26470 internal_error:
   26471     vctxt->err = -1;
   26472     return (-1);
   26473 }
   26474 
   26475 /*
   26476 * 3.4.4 Complex Type Definition Validation Rules
   26477 * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
   26478 */
   26479 static int
   26480 xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
   26481 {
   26482     xmlSchemaNodeInfoPtr pielem;
   26483     xmlSchemaTypePtr ptype;
   26484     int ret = 0;
   26485 
   26486     if (vctxt->depth <= 0) {
   26487 	VERROR_INT("xmlSchemaValidateChildElem",
   26488 	    "not intended for the validation root");
   26489 	return (-1);
   26490     }
   26491     pielem = vctxt->elemInfos[vctxt->depth -1];
   26492     if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
   26493 	pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
   26494     /*
   26495     * Handle 'nilled' elements.
   26496     */
   26497     if (INODE_NILLED(pielem)) {
   26498 	/*
   26499 	* SPEC (cvc-elt) (3.3.4) : (3.2.1)
   26500 	*/
   26501 	ACTIVATE_PARENT_ELEM;
   26502 	ret = XML_SCHEMAV_CVC_ELT_3_2_1;
   26503 	VERROR(ret, NULL,
   26504 	    "Neither character nor element content is allowed, "
   26505 	    "because the element was 'nilled'");
   26506 	ACTIVATE_ELEM;
   26507 	goto unexpected_elem;
   26508     }
   26509 
   26510     ptype = pielem->typeDef;
   26511 
   26512     if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
   26513 	/*
   26514 	* Workaround for "anyType": we have currently no content model
   26515 	* assigned for "anyType", so handle it explicitely.
   26516 	* "anyType" has an unbounded, lax "any" wildcard.
   26517 	*/
   26518 	vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
   26519 	    vctxt->inode->localName,
   26520 	    vctxt->inode->nsName);
   26521 
   26522 	if (vctxt->inode->decl == NULL) {
   26523 	    xmlSchemaAttrInfoPtr iattr;
   26524 	    /*
   26525 	    * Process "xsi:type".
   26526 	    * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
   26527 	    */
   26528 	    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   26529 		XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
   26530 	    if (iattr != NULL) {
   26531 		ret = xmlSchemaProcessXSIType(vctxt, iattr,
   26532 		    &(vctxt->inode->typeDef), NULL);
   26533 		if (ret != 0) {
   26534 		    if (ret == -1) {
   26535 			VERROR_INT("xmlSchemaValidateChildElem",
   26536 			    "calling xmlSchemaProcessXSIType() to "
   26537 			    "process the attribute 'xsi:nil'");
   26538 			return (-1);
   26539 		    }
   26540 		    return (ret);
   26541 		}
   26542 	    } else {
   26543 		 /*
   26544 		 * Fallback to "anyType".
   26545 		 *
   26546 		 * SPEC (cvc-assess-elt)
   26547 		 * "If the item cannot be `strictly assessed`, [...]
   26548 		 * an element information item's schema validity may be laxly
   26549 		 * assessed if its `context-determined declaration` is not
   26550 		 * skip by `validating` with respect to the `ur-type
   26551 		 * definition` as per Element Locally Valid (Type) ($3.3.4)."
   26552 		*/
   26553 		vctxt->inode->typeDef =
   26554 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
   26555 	    }
   26556 	}
   26557 	return (0);
   26558     }
   26559 
   26560     switch (ptype->contentType) {
   26561 	case XML_SCHEMA_CONTENT_EMPTY:
   26562 	    /*
   26563 	    * SPEC (2.1) "If the {content type} is empty, then the
   26564 	    * element information item has no character or element
   26565 	    * information item [children]."
   26566 	    */
   26567 	    ACTIVATE_PARENT_ELEM
   26568 	    ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
   26569 	    VERROR(ret, NULL,
   26570 		"Element content is not allowed, "
   26571 		"because the content type is empty");
   26572 	    ACTIVATE_ELEM
   26573 	    goto unexpected_elem;
   26574 	    break;
   26575 
   26576 	case XML_SCHEMA_CONTENT_MIXED:
   26577         case XML_SCHEMA_CONTENT_ELEMENTS: {
   26578 	    xmlRegExecCtxtPtr regexCtxt;
   26579 	    xmlChar *values[10];
   26580 	    int terminal, nbval = 10, nbneg;
   26581 
   26582 	    /* VAL TODO: Optimized "anyType" validation.*/
   26583 
   26584 	    if (ptype->contModel == NULL) {
   26585 		VERROR_INT("xmlSchemaValidateChildElem",
   26586 		    "type has elem content but no content model");
   26587 		return (-1);
   26588 	    }
   26589 	    /*
   26590 	    * Safety belf for evaluation if the cont. model was already
   26591 	    * examined to be invalid.
   26592 	    */
   26593 	    if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
   26594 		VERROR_INT("xmlSchemaValidateChildElem",
   26595 		    "validating elem, but elem content is already invalid");
   26596 		return (-1);
   26597 	    }
   26598 
   26599 	    regexCtxt = pielem->regexCtxt;
   26600 	    if (regexCtxt == NULL) {
   26601 		/*
   26602 		* Create the regex context.
   26603 		*/
   26604 		regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
   26605 		    (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
   26606 		    vctxt);
   26607 		if (regexCtxt == NULL) {
   26608 		    VERROR_INT("xmlSchemaValidateChildElem",
   26609 			"failed to create a regex context");
   26610 		    return (-1);
   26611 		}
   26612 		pielem->regexCtxt = regexCtxt;
   26613 #ifdef DEBUG_AUTOMATA
   26614 		xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
   26615 		    pielem->localName);
   26616 #endif
   26617 	    }
   26618 
   26619 	    /*
   26620 	    * SPEC (2.4) "If the {content type} is element-only or mixed,
   26621 	    * then the sequence of the element information item's
   26622 	    * element information item [children], if any, taken in
   26623 	    * order, is `valid` with respect to the {content type}'s
   26624 	    * particle, as defined in Element Sequence Locally Valid
   26625 	    * (Particle) ($3.9.4)."
   26626 	    */
   26627 	    ret = xmlRegExecPushString2(regexCtxt,
   26628 		vctxt->inode->localName,
   26629 		vctxt->inode->nsName,
   26630 		vctxt->inode);
   26631 #ifdef DEBUG_AUTOMATA
   26632 	    if (ret < 0)
   26633 		xmlGenericError(xmlGenericErrorContext,
   26634 		"AUTOMATON push ERROR for '%s' on '%s'\n",
   26635 		vctxt->inode->localName, pielem->localName);
   26636 	    else
   26637 		xmlGenericError(xmlGenericErrorContext,
   26638 		"AUTOMATON push OK for '%s' on '%s'\n",
   26639 		vctxt->inode->localName, pielem->localName);
   26640 #endif
   26641 	    if (vctxt->err == XML_SCHEMAV_INTERNAL) {
   26642 		VERROR_INT("xmlSchemaValidateChildElem",
   26643 		    "calling xmlRegExecPushString2()");
   26644 		return (-1);
   26645 	    }
   26646 	    if (ret < 0) {
   26647 		xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
   26648 		    &values[0], &terminal);
   26649 		xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
   26650 		    XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
   26651 		    "This element is not expected",
   26652 		    nbval, nbneg, values);
   26653 		ret = vctxt->err;
   26654 		goto unexpected_elem;
   26655 	    } else
   26656 		ret = 0;
   26657 	}
   26658 	    break;
   26659 	case XML_SCHEMA_CONTENT_SIMPLE:
   26660 	case XML_SCHEMA_CONTENT_BASIC:
   26661 	    ACTIVATE_PARENT_ELEM
   26662 	    if (WXS_IS_COMPLEX(ptype)) {
   26663 		/*
   26664 		* SPEC (cvc-complex-type) (2.2)
   26665 		* "If the {content type} is a simple type definition, then
   26666 		* the element information item has no element information
   26667 		* item [children], ..."
   26668 		*/
   26669 		ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
   26670 		VERROR(ret, NULL, "Element content is not allowed, "
   26671 		    "because the content type is a simple type definition");
   26672 	    } else {
   26673 		/*
   26674 		* SPEC (cvc-type) (3.1.2) "The element information item must
   26675 		* have no element information item [children]."
   26676 		*/
   26677 		ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
   26678 		VERROR(ret, NULL, "Element content is not allowed, "
   26679 		    "because the type definition is simple");
   26680 	    }
   26681 	    ACTIVATE_ELEM
   26682 	    ret = vctxt->err;
   26683 	    goto unexpected_elem;
   26684 	    break;
   26685 
   26686 	default:
   26687 	    break;
   26688     }
   26689     return (ret);
   26690 unexpected_elem:
   26691     /*
   26692     * Pop this element and set the skipDepth to skip
   26693     * all further content of the parent element.
   26694     */
   26695     vctxt->skipDepth = vctxt->depth;
   26696     vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
   26697     pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
   26698     return (ret);
   26699 }
   26700 
   26701 #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
   26702 #define XML_SCHEMA_PUSH_TEXT_CREATED 2
   26703 #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
   26704 
   26705 static int
   26706 xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
   26707 		  int nodeType, const xmlChar *value, int len,
   26708 		  int mode, int *consumed)
   26709 {
   26710     /*
   26711     * Unfortunately we have to duplicate the text sometimes.
   26712     * OPTIMIZE: Maybe we could skip it, if:
   26713     *   1. content type is simple
   26714     *   2. whitespace is "collapse"
   26715     *   3. it consists of whitespace only
   26716     *
   26717     * Process character content.
   26718     */
   26719     if (consumed != NULL)
   26720 	*consumed = 0;
   26721     if (INODE_NILLED(vctxt->inode)) {
   26722 	/*
   26723 	* SPEC cvc-elt (3.3.4 - 3.2.1)
   26724 	* "The element information item must have no character or
   26725 	* element information item [children]."
   26726 	*/
   26727 	VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
   26728 	    "Neither character nor element content is allowed "
   26729 	    "because the element is 'nilled'");
   26730 	return (vctxt->err);
   26731     }
   26732     /*
   26733     * SPEC (2.1) "If the {content type} is empty, then the
   26734     * element information item has no character or element
   26735     * information item [children]."
   26736     */
   26737     if (vctxt->inode->typeDef->contentType ==
   26738 	    XML_SCHEMA_CONTENT_EMPTY) {
   26739 	VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
   26740 	    "Character content is not allowed, "
   26741 	    "because the content type is empty");
   26742 	return (vctxt->err);
   26743     }
   26744 
   26745     if (vctxt->inode->typeDef->contentType ==
   26746 	    XML_SCHEMA_CONTENT_ELEMENTS) {
   26747 	if ((nodeType != XML_TEXT_NODE) ||
   26748 	    (! xmlSchemaIsBlank((xmlChar *) value, len))) {
   26749 	    /*
   26750 	    * SPEC cvc-complex-type (2.3)
   26751 	    * "If the {content type} is element-only, then the
   26752 	    * element information item has no character information
   26753 	    * item [children] other than those whose [character
   26754 	    * code] is defined as a white space in [XML 1.0 (Second
   26755 	    * Edition)]."
   26756 	    */
   26757 	    VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
   26758 		"Character content other than whitespace is not allowed "
   26759 		"because the content type is 'element-only'");
   26760 	    return (vctxt->err);
   26761 	}
   26762 	return (0);
   26763     }
   26764 
   26765     if ((value == NULL) || (value[0] == 0))
   26766 	return (0);
   26767     /*
   26768     * Save the value.
   26769     * NOTE that even if the content type is *mixed*, we need the
   26770     * *initial value* for default/fixed value constraints.
   26771     */
   26772     if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
   26773 	((vctxt->inode->decl == NULL) ||
   26774 	(vctxt->inode->decl->value == NULL)))
   26775 	return (0);
   26776 
   26777     if (vctxt->inode->value == NULL) {
   26778 	/*
   26779 	* Set the value.
   26780 	*/
   26781 	switch (mode) {
   26782 	    case XML_SCHEMA_PUSH_TEXT_PERSIST:
   26783 		/*
   26784 		* When working on a tree.
   26785 		*/
   26786 		vctxt->inode->value = value;
   26787 		break;
   26788 	    case XML_SCHEMA_PUSH_TEXT_CREATED:
   26789 		/*
   26790 		* When working with the reader.
   26791 		* The value will be freed by the element info.
   26792 		*/
   26793 		vctxt->inode->value = value;
   26794 		if (consumed != NULL)
   26795 		    *consumed = 1;
   26796 		vctxt->inode->flags |=
   26797 		    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
   26798 		break;
   26799 	    case XML_SCHEMA_PUSH_TEXT_VOLATILE:
   26800 		/*
   26801 		* When working with SAX.
   26802 		* The value will be freed by the element info.
   26803 		*/
   26804 		if (len != -1)
   26805 		    vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
   26806 		else
   26807 		    vctxt->inode->value = BAD_CAST xmlStrdup(value);
   26808 		vctxt->inode->flags |=
   26809 		    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
   26810 		break;
   26811 	    default:
   26812 		break;
   26813 	}
   26814     } else {
   26815 	if (len < 0)
   26816 	    len = xmlStrlen(value);
   26817 	/*
   26818 	* Concat the value.
   26819 	*/
   26820 	if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
   26821 	    vctxt->inode->value = BAD_CAST xmlStrncat(
   26822 		(xmlChar *) vctxt->inode->value, value, len);
   26823 	} else {
   26824 	    vctxt->inode->value =
   26825 		BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
   26826 	    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
   26827 	}
   26828     }
   26829 
   26830     return (0);
   26831 }
   26832 
   26833 static int
   26834 xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
   26835 {
   26836     int ret = 0;
   26837 
   26838     if ((vctxt->skipDepth != -1) &&
   26839 	(vctxt->depth >= vctxt->skipDepth)) {
   26840 	VERROR_INT("xmlSchemaValidateElem",
   26841 	    "in skip-state");
   26842 	goto internal_error;
   26843     }
   26844     if (vctxt->xsiAssemble) {
   26845 	/*
   26846 	* We will stop validation if there was an error during
   26847 	* dynamic schema construction.
   26848 	* Note that we simply set @skipDepth to 0, this could
   26849 	* mean that a streaming document via SAX would be
   26850 	* still read to the end but it won't be validated any more.
   26851 	* TODO: If we are sure how to stop the validation at once
   26852 	*   for all input scenarios, then this should be changed to
   26853 	*   instantly stop the validation.
   26854 	*/
   26855 	ret = xmlSchemaAssembleByXSI(vctxt);
   26856 	if (ret != 0) {
   26857 	    if (ret == -1)
   26858 		goto internal_error;
   26859 	    vctxt->skipDepth = 0;
   26860 	    return(ret);
   26861 	}
   26862         /*
   26863          * Augment the IDC definitions for the main schema and all imported ones
   26864          * NOTE: main schema is the first in the imported list
   26865          */
   26866         xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
   26867     }
   26868     if (vctxt->depth > 0) {
   26869 	/*
   26870 	* Validate this element against the content model
   26871 	* of the parent.
   26872 	*/
   26873 	ret = xmlSchemaValidateChildElem(vctxt);
   26874 	if (ret != 0) {
   26875 	    if (ret < 0) {
   26876 		VERROR_INT("xmlSchemaValidateElem",
   26877 		    "calling xmlSchemaStreamValidateChildElement()");
   26878 		goto internal_error;
   26879 	    }
   26880 	    goto exit;
   26881 	}
   26882 	if (vctxt->depth == vctxt->skipDepth)
   26883 	    goto exit;
   26884 	if ((vctxt->inode->decl == NULL) &&
   26885 	    (vctxt->inode->typeDef == NULL)) {
   26886 	    VERROR_INT("xmlSchemaValidateElem",
   26887 		"the child element was valid but neither the "
   26888 		"declaration nor the type was set");
   26889 	    goto internal_error;
   26890 	}
   26891     } else {
   26892 	/*
   26893 	* Get the declaration of the validation root.
   26894 	*/
   26895 	vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
   26896 	    vctxt->inode->localName,
   26897 	    vctxt->inode->nsName);
   26898 	if (vctxt->inode->decl == NULL) {
   26899 	    ret = XML_SCHEMAV_CVC_ELT_1;
   26900 	    VERROR(ret, NULL,
   26901 		"No matching global declaration available "
   26902 		"for the validation root");
   26903 	    goto exit;
   26904 	}
   26905     }
   26906 
   26907     if (vctxt->inode->decl == NULL)
   26908 	goto type_validation;
   26909 
   26910     if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
   26911 	int skip;
   26912 	/*
   26913 	* Wildcards.
   26914 	*/
   26915 	ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
   26916 	if (ret != 0) {
   26917 	    if (ret < 0) {
   26918 		VERROR_INT("xmlSchemaValidateElem",
   26919 		    "calling xmlSchemaValidateElemWildcard()");
   26920 		goto internal_error;
   26921 	    }
   26922 	    goto exit;
   26923 	}
   26924 	if (skip) {
   26925 	    vctxt->skipDepth = vctxt->depth;
   26926 	    goto exit;
   26927 	}
   26928 	/*
   26929 	* The declaration might be set by the wildcard validation,
   26930 	* when the processContents is "lax" or "strict".
   26931 	*/
   26932 	if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
   26933 	    /*
   26934 	    * Clear the "decl" field to not confuse further processing.
   26935 	    */
   26936 	    vctxt->inode->decl = NULL;
   26937 	    goto type_validation;
   26938 	}
   26939     }
   26940     /*
   26941     * Validate against the declaration.
   26942     */
   26943     ret = xmlSchemaValidateElemDecl(vctxt);
   26944     if (ret != 0) {
   26945 	if (ret < 0) {
   26946 	    VERROR_INT("xmlSchemaValidateElem",
   26947 		"calling xmlSchemaValidateElemDecl()");
   26948 	    goto internal_error;
   26949 	}
   26950 	goto exit;
   26951     }
   26952     /*
   26953     * Validate against the type definition.
   26954     */
   26955 type_validation:
   26956 
   26957     if (vctxt->inode->typeDef == NULL) {
   26958 	vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
   26959 	ret = XML_SCHEMAV_CVC_TYPE_1;
   26960 	VERROR(ret, NULL,
   26961 	    "The type definition is absent");
   26962 	goto exit;
   26963     }
   26964     if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
   26965 	vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
   26966 	ret = XML_SCHEMAV_CVC_TYPE_2;
   26967 	    VERROR(ret, NULL,
   26968 	    "The type definition is abstract");
   26969 	goto exit;
   26970     }
   26971     /*
   26972     * Evaluate IDCs. Do it here, since new IDC matchers are registered
   26973     * during validation against the declaration. This must be done
   26974     * _before_ attribute validation.
   26975     */
   26976     if (vctxt->xpathStates != NULL) {
   26977 	ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
   26978 	vctxt->inode->appliedXPath = 1;
   26979 	if (ret == -1) {
   26980 	    VERROR_INT("xmlSchemaValidateElem",
   26981 		"calling xmlSchemaXPathEvaluate()");
   26982 	    goto internal_error;
   26983 	}
   26984     }
   26985     /*
   26986     * Validate attributes.
   26987     */
   26988     if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
   26989 	if ((vctxt->nbAttrInfos != 0) ||
   26990 	    (vctxt->inode->typeDef->attrUses != NULL)) {
   26991 
   26992 	    ret = xmlSchemaVAttributesComplex(vctxt);
   26993 	}
   26994     } else if (vctxt->nbAttrInfos != 0) {
   26995 
   26996 	ret = xmlSchemaVAttributesSimple(vctxt);
   26997     }
   26998     /*
   26999     * Clear registered attributes.
   27000     */
   27001     if (vctxt->nbAttrInfos != 0)
   27002 	xmlSchemaClearAttrInfos(vctxt);
   27003     if (ret == -1) {
   27004 	VERROR_INT("xmlSchemaValidateElem",
   27005 	    "calling attributes validation");
   27006 	goto internal_error;
   27007     }
   27008     /*
   27009     * Don't return an error if attributes are invalid on purpose.
   27010     */
   27011     ret = 0;
   27012 
   27013 exit:
   27014     if (ret != 0)
   27015 	vctxt->skipDepth = vctxt->depth;
   27016     return (ret);
   27017 internal_error:
   27018     return (-1);
   27019 }
   27020 
   27021 #ifdef XML_SCHEMA_READER_ENABLED
   27022 static int
   27023 xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
   27024 {
   27025     const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
   27026     int depth, nodeType, ret = 0, consumed;
   27027     xmlSchemaNodeInfoPtr ielem;
   27028 
   27029     vctxt->depth = -1;
   27030     ret = xmlTextReaderRead(vctxt->reader);
   27031     /*
   27032     * Move to the document element.
   27033     */
   27034     while (ret == 1) {
   27035 	nodeType = xmlTextReaderNodeType(vctxt->reader);
   27036 	if (nodeType == XML_ELEMENT_NODE)
   27037 	    goto root_found;
   27038 	ret = xmlTextReaderRead(vctxt->reader);
   27039     }
   27040     goto exit;
   27041 
   27042 root_found:
   27043 
   27044     do {
   27045 	depth = xmlTextReaderDepth(vctxt->reader);
   27046 	nodeType = xmlTextReaderNodeType(vctxt->reader);
   27047 
   27048 	if (nodeType == XML_ELEMENT_NODE) {
   27049 
   27050 	    vctxt->depth++;
   27051 	    if (xmlSchemaValidatorPushElem(vctxt) == -1) {
   27052 		VERROR_INT("xmlSchemaVReaderWalk",
   27053 		    "calling xmlSchemaValidatorPushElem()");
   27054 		goto internal_error;
   27055 	    }
   27056 	    ielem = vctxt->inode;
   27057 	    ielem->localName = xmlTextReaderLocalName(vctxt->reader);
   27058 	    ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
   27059 	    ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
   27060 	    /*
   27061 	    * Is the element empty?
   27062 	    */
   27063 	    ret = xmlTextReaderIsEmptyElement(vctxt->reader);
   27064 	    if (ret == -1) {
   27065 		VERROR_INT("xmlSchemaVReaderWalk",
   27066 		    "calling xmlTextReaderIsEmptyElement()");
   27067 		goto internal_error;
   27068 	    }
   27069 	    if (ret) {
   27070 		ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
   27071 	    }
   27072 	    /*
   27073 	    * Register attributes.
   27074 	    */
   27075 	    vctxt->nbAttrInfos = 0;
   27076 	    ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
   27077 	    if (ret == -1) {
   27078 		VERROR_INT("xmlSchemaVReaderWalk",
   27079 		    "calling xmlTextReaderMoveToFirstAttribute()");
   27080 		goto internal_error;
   27081 	    }
   27082 	    if (ret == 1) {
   27083 		do {
   27084 		    /*
   27085 		    * VAL TODO: How do we know that the reader works on a
   27086 		    * node tree, to be able to pass a node here?
   27087 		    */
   27088 		    if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
   27089 			(const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
   27090 			xmlTextReaderNamespaceUri(vctxt->reader), 1,
   27091 			xmlTextReaderValue(vctxt->reader), 1) == -1) {
   27092 
   27093 			VERROR_INT("xmlSchemaVReaderWalk",
   27094 			    "calling xmlSchemaValidatorPushAttribute()");
   27095 			goto internal_error;
   27096 		    }
   27097 		    ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
   27098 		    if (ret == -1) {
   27099 			VERROR_INT("xmlSchemaVReaderWalk",
   27100 			    "calling xmlTextReaderMoveToFirstAttribute()");
   27101 			goto internal_error;
   27102 		    }
   27103 		} while (ret == 1);
   27104 		/*
   27105 		* Back to element position.
   27106 		*/
   27107 		ret = xmlTextReaderMoveToElement(vctxt->reader);
   27108 		if (ret == -1) {
   27109 		    VERROR_INT("xmlSchemaVReaderWalk",
   27110 			"calling xmlTextReaderMoveToElement()");
   27111 		    goto internal_error;
   27112 		}
   27113 	    }
   27114 	    /*
   27115 	    * Validate the element.
   27116 	    */
   27117 	    ret= xmlSchemaValidateElem(vctxt);
   27118 	    if (ret != 0) {
   27119 		if (ret == -1) {
   27120 		    VERROR_INT("xmlSchemaVReaderWalk",
   27121 			"calling xmlSchemaValidateElem()");
   27122 		    goto internal_error;
   27123 		}
   27124 		goto exit;
   27125 	    }
   27126 	    if (vctxt->depth == vctxt->skipDepth) {
   27127 		int curDepth;
   27128 		/*
   27129 		* Skip all content.
   27130 		*/
   27131 		if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
   27132 		    ret = xmlTextReaderRead(vctxt->reader);
   27133 		    curDepth = xmlTextReaderDepth(vctxt->reader);
   27134 		    while ((ret == 1) && (curDepth != depth)) {
   27135 			ret = xmlTextReaderRead(vctxt->reader);
   27136 			curDepth = xmlTextReaderDepth(vctxt->reader);
   27137 		    }
   27138 		    if (ret < 0) {
   27139 			/*
   27140 			* VAL TODO: A reader error occured; what to do here?
   27141 			*/
   27142 			ret = 1;
   27143 			goto exit;
   27144 		    }
   27145 		}
   27146 		goto leave_elem;
   27147 	    }
   27148 	    /*
   27149 	    * READER VAL TODO: Is an END_ELEM really never called
   27150 	    * if the elem is empty?
   27151 	    */
   27152 	    if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
   27153 		goto leave_elem;
   27154 	} else if (nodeType == END_ELEM) {
   27155 	    /*
   27156 	    * Process END of element.
   27157 	    */
   27158 leave_elem:
   27159 	    ret = xmlSchemaValidatorPopElem(vctxt);
   27160 	    if (ret != 0) {
   27161 		if (ret < 0) {
   27162 		    VERROR_INT("xmlSchemaVReaderWalk",
   27163 			"calling xmlSchemaValidatorPopElem()");
   27164 		    goto internal_error;
   27165 		}
   27166 		goto exit;
   27167 	    }
   27168 	    if (vctxt->depth >= 0)
   27169 		ielem = vctxt->inode;
   27170 	    else
   27171 		ielem = NULL;
   27172 	} else if ((nodeType == XML_TEXT_NODE) ||
   27173 	    (nodeType == XML_CDATA_SECTION_NODE) ||
   27174 	    (nodeType == WHTSP) ||
   27175 	    (nodeType == SIGN_WHTSP)) {
   27176 	    /*
   27177 	    * Process character content.
   27178 	    */
   27179 	    xmlChar *value;
   27180 
   27181 	    if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
   27182 		nodeType = XML_TEXT_NODE;
   27183 
   27184 	    value = xmlTextReaderValue(vctxt->reader);
   27185 	    ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
   27186 		-1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
   27187 	    if (! consumed)
   27188 		xmlFree(value);
   27189 	    if (ret == -1) {
   27190 		VERROR_INT("xmlSchemaVReaderWalk",
   27191 		    "calling xmlSchemaVPushText()");
   27192 		goto internal_error;
   27193 	    }
   27194 	} else if ((nodeType == XML_ENTITY_NODE) ||
   27195 	    (nodeType == XML_ENTITY_REF_NODE)) {
   27196 	    /*
   27197 	    * VAL TODO: What to do with entities?
   27198 	    */
   27199 	    TODO
   27200 	}
   27201 	/*
   27202 	* Read next node.
   27203 	*/
   27204 	ret = xmlTextReaderRead(vctxt->reader);
   27205     } while (ret == 1);
   27206 
   27207 exit:
   27208     return (ret);
   27209 internal_error:
   27210     return (-1);
   27211 }
   27212 #endif
   27213 
   27214 /************************************************************************
   27215  *									*
   27216  *			SAX validation handlers				*
   27217  *									*
   27218  ************************************************************************/
   27219 
   27220 /*
   27221 * Process text content.
   27222 */
   27223 static void
   27224 xmlSchemaSAXHandleText(void *ctx,
   27225 		       const xmlChar * ch,
   27226 		       int len)
   27227 {
   27228     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27229 
   27230     if (vctxt->depth < 0)
   27231 	return;
   27232     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27233 	return;
   27234     if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
   27235 	vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
   27236     if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
   27237 	XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
   27238 	VERROR_INT("xmlSchemaSAXHandleCDataSection",
   27239 	    "calling xmlSchemaVPushText()");
   27240 	vctxt->err = -1;
   27241 	xmlStopParser(vctxt->parserCtxt);
   27242     }
   27243 }
   27244 
   27245 /*
   27246 * Process CDATA content.
   27247 */
   27248 static void
   27249 xmlSchemaSAXHandleCDataSection(void *ctx,
   27250 			     const xmlChar * ch,
   27251 			     int len)
   27252 {
   27253     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27254 
   27255     if (vctxt->depth < 0)
   27256 	return;
   27257     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27258 	return;
   27259     if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
   27260 	vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
   27261     if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
   27262 	XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
   27263 	VERROR_INT("xmlSchemaSAXHandleCDataSection",
   27264 	    "calling xmlSchemaVPushText()");
   27265 	vctxt->err = -1;
   27266 	xmlStopParser(vctxt->parserCtxt);
   27267     }
   27268 }
   27269 
   27270 static void
   27271 xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
   27272 			    const xmlChar * name ATTRIBUTE_UNUSED)
   27273 {
   27274     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27275 
   27276     if (vctxt->depth < 0)
   27277 	return;
   27278     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27279 	return;
   27280     /* SAX VAL TODO: What to do here? */
   27281     TODO
   27282 }
   27283 
   27284 static void
   27285 xmlSchemaSAXHandleStartElementNs(void *ctx,
   27286 				 const xmlChar * localname,
   27287 				 const xmlChar * prefix ATTRIBUTE_UNUSED,
   27288 				 const xmlChar * URI,
   27289 				 int nb_namespaces,
   27290 				 const xmlChar ** namespaces,
   27291 				 int nb_attributes,
   27292 				 int nb_defaulted ATTRIBUTE_UNUSED,
   27293 				 const xmlChar ** attributes)
   27294 {
   27295     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27296     int ret;
   27297     xmlSchemaNodeInfoPtr ielem;
   27298     int i, j;
   27299 
   27300     /*
   27301     * SAX VAL TODO: What to do with nb_defaulted?
   27302     */
   27303     /*
   27304     * Skip elements if inside a "skip" wildcard or invalid.
   27305     */
   27306     vctxt->depth++;
   27307     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27308 	return;
   27309     /*
   27310     * Push the element.
   27311     */
   27312     if (xmlSchemaValidatorPushElem(vctxt) == -1) {
   27313 	VERROR_INT("xmlSchemaSAXHandleStartElementNs",
   27314 	    "calling xmlSchemaValidatorPushElem()");
   27315 	goto internal_error;
   27316     }
   27317     ielem = vctxt->inode;
   27318     /*
   27319     * TODO: Is this OK?
   27320     */
   27321     ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
   27322     ielem->localName = localname;
   27323     ielem->nsName = URI;
   27324     ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
   27325     /*
   27326     * Register namespaces on the elem info.
   27327     */
   27328     if (nb_namespaces != 0) {
   27329 	/*
   27330 	* Although the parser builds its own namespace list,
   27331 	* we have no access to it, so we'll use an own one.
   27332 	*/
   27333         for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
   27334 	    /*
   27335 	    * Store prefix and namespace name.
   27336 	    */
   27337 	    if (ielem->nsBindings == NULL) {
   27338 		ielem->nsBindings =
   27339 		    (const xmlChar **) xmlMalloc(10 *
   27340 			sizeof(const xmlChar *));
   27341 		if (ielem->nsBindings == NULL) {
   27342 		    xmlSchemaVErrMemory(vctxt,
   27343 			"allocating namespace bindings for SAX validation",
   27344 			NULL);
   27345 		    goto internal_error;
   27346 		}
   27347 		ielem->nbNsBindings = 0;
   27348 		ielem->sizeNsBindings = 5;
   27349 	    } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
   27350 		ielem->sizeNsBindings *= 2;
   27351 		ielem->nsBindings =
   27352 		    (const xmlChar **) xmlRealloc(
   27353 			(void *) ielem->nsBindings,
   27354 			ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
   27355 		if (ielem->nsBindings == NULL) {
   27356 		    xmlSchemaVErrMemory(vctxt,
   27357 			"re-allocating namespace bindings for SAX validation",
   27358 			NULL);
   27359 		    goto internal_error;
   27360 		}
   27361 	    }
   27362 
   27363 	    ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
   27364 	    if (namespaces[j+1][0] == 0) {
   27365 		/*
   27366 		* Handle xmlns="".
   27367 		*/
   27368 		ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
   27369 	    } else
   27370 		ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
   27371 		    namespaces[j+1];
   27372 	    ielem->nbNsBindings++;
   27373 	}
   27374     }
   27375     /*
   27376     * Register attributes.
   27377     * SAX VAL TODO: We are not adding namespace declaration
   27378     * attributes yet.
   27379     */
   27380     if (nb_attributes != 0) {
   27381 	xmlChar *value;
   27382 
   27383         for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
   27384 	    /*
   27385 	    * Duplicate the value.
   27386 	    */
   27387 	    value = xmlStrndup(attributes[j+3],
   27388 		attributes[j+4] - attributes[j+3]);
   27389 	    /*
   27390 	    * TODO: Set the node line.
   27391 	    */
   27392 	    ret = xmlSchemaValidatorPushAttribute(vctxt,
   27393 		NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
   27394 		value, 1);
   27395 	    if (ret == -1) {
   27396 		VERROR_INT("xmlSchemaSAXHandleStartElementNs",
   27397 		    "calling xmlSchemaValidatorPushAttribute()");
   27398 		goto internal_error;
   27399 	    }
   27400 	}
   27401     }
   27402     /*
   27403     * Validate the element.
   27404     */
   27405     ret = xmlSchemaValidateElem(vctxt);
   27406     if (ret != 0) {
   27407 	if (ret == -1) {
   27408 	    VERROR_INT("xmlSchemaSAXHandleStartElementNs",
   27409 		"calling xmlSchemaValidateElem()");
   27410 	    goto internal_error;
   27411 	}
   27412 	goto exit;
   27413     }
   27414 
   27415 exit:
   27416     return;
   27417 internal_error:
   27418     vctxt->err = -1;
   27419     xmlStopParser(vctxt->parserCtxt);
   27420     return;
   27421 }
   27422 
   27423 static void
   27424 xmlSchemaSAXHandleEndElementNs(void *ctx,
   27425 			       const xmlChar * localname ATTRIBUTE_UNUSED,
   27426 			       const xmlChar * prefix ATTRIBUTE_UNUSED,
   27427 			       const xmlChar * URI ATTRIBUTE_UNUSED)
   27428 {
   27429     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27430     int res;
   27431 
   27432     /*
   27433     * Skip elements if inside a "skip" wildcard or if invalid.
   27434     */
   27435     if (vctxt->skipDepth != -1) {
   27436 	if (vctxt->depth > vctxt->skipDepth) {
   27437 	    vctxt->depth--;
   27438 	    return;
   27439 	} else
   27440 	    vctxt->skipDepth = -1;
   27441     }
   27442     /*
   27443     * SAX VAL TODO: Just a temporary check.
   27444     */
   27445     if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
   27446 	(!xmlStrEqual(vctxt->inode->nsName, URI))) {
   27447 	VERROR_INT("xmlSchemaSAXHandleEndElementNs",
   27448 	    "elem pop mismatch");
   27449     }
   27450     res = xmlSchemaValidatorPopElem(vctxt);
   27451     if (res != 0) {
   27452 	if (res < 0) {
   27453 	    VERROR_INT("xmlSchemaSAXHandleEndElementNs",
   27454 		"calling xmlSchemaValidatorPopElem()");
   27455 	    goto internal_error;
   27456 	}
   27457 	goto exit;
   27458     }
   27459 exit:
   27460     return;
   27461 internal_error:
   27462     vctxt->err = -1;
   27463     xmlStopParser(vctxt->parserCtxt);
   27464     return;
   27465 }
   27466 
   27467 /************************************************************************
   27468  *									*
   27469  *			Validation interfaces				*
   27470  *									*
   27471  ************************************************************************/
   27472 
   27473 /**
   27474  * xmlSchemaNewValidCtxt:
   27475  * @schema:  a precompiled XML Schemas
   27476  *
   27477  * Create an XML Schemas validation context based on the given schema.
   27478  *
   27479  * Returns the validation context or NULL in case of error
   27480  */
   27481 xmlSchemaValidCtxtPtr
   27482 xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
   27483 {
   27484     xmlSchemaValidCtxtPtr ret;
   27485 
   27486     ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
   27487     if (ret == NULL) {
   27488         xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
   27489         return (NULL);
   27490     }
   27491     memset(ret, 0, sizeof(xmlSchemaValidCtxt));
   27492     ret->type = XML_SCHEMA_CTXT_VALIDATOR;
   27493     ret->dict = xmlDictCreate();
   27494     ret->nodeQNames = xmlSchemaItemListCreate();
   27495     ret->schema = schema;
   27496     return (ret);
   27497 }
   27498 
   27499 /**
   27500  * xmlSchemaValidateSetFilename:
   27501  * @vctxt: the schema validation context
   27502  * @filename: the file name
   27503  *
   27504  * Workaround to provide file error reporting information when this is
   27505  * not provided by current APIs
   27506  */
   27507 void
   27508 xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
   27509     if (vctxt == NULL)
   27510         return;
   27511     if (vctxt->filename != NULL)
   27512         xmlFree(vctxt->filename);
   27513     if (filename != NULL)
   27514         vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
   27515     else
   27516         vctxt->filename = NULL;
   27517 }
   27518 
   27519 /**
   27520  * xmlSchemaClearValidCtxt:
   27521  * @vctxt: the schema validation context
   27522  *
   27523  * Free the resources associated to the schema validation context;
   27524  * leaves some fields alive intended for reuse of the context.
   27525  */
   27526 static void
   27527 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
   27528 {
   27529     if (vctxt == NULL)
   27530         return;
   27531 
   27532     /*
   27533     * TODO: Should we clear the flags?
   27534     *   Might be problematic if one reuses the context
   27535     *   and assumes that the options remain the same.
   27536     */
   27537     vctxt->flags = 0;
   27538     vctxt->validationRoot = NULL;
   27539     vctxt->doc = NULL;
   27540 #ifdef LIBXML_READER_ENABLED
   27541     vctxt->reader = NULL;
   27542 #endif
   27543     vctxt->hasKeyrefs = 0;
   27544 
   27545     if (vctxt->value != NULL) {
   27546         xmlSchemaFreeValue(vctxt->value);
   27547 	vctxt->value = NULL;
   27548     }
   27549     /*
   27550     * Augmented IDC information.
   27551     */
   27552     if (vctxt->aidcs != NULL) {
   27553 	xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
   27554 	do {
   27555 	    next = cur->next;
   27556 	    xmlFree(cur);
   27557 	    cur = next;
   27558 	} while (cur != NULL);
   27559 	vctxt->aidcs = NULL;
   27560     }
   27561     if (vctxt->idcMatcherCache != NULL) {
   27562 	xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
   27563 
   27564 	while (matcher) {
   27565 	    tmp = matcher;
   27566 	    matcher = matcher->nextCached;
   27567 	    xmlSchemaIDCFreeMatcherList(tmp);
   27568 	}
   27569 	vctxt->idcMatcherCache = NULL;
   27570     }
   27571 
   27572 
   27573     if (vctxt->idcNodes != NULL) {
   27574 	int i;
   27575 	xmlSchemaPSVIIDCNodePtr item;
   27576 
   27577 	for (i = 0; i < vctxt->nbIdcNodes; i++) {
   27578 	    item = vctxt->idcNodes[i];
   27579 	    xmlFree(item->keys);
   27580 	    xmlFree(item);
   27581 	}
   27582 	xmlFree(vctxt->idcNodes);
   27583 	vctxt->idcNodes = NULL;
   27584 	vctxt->nbIdcNodes = 0;
   27585 	vctxt->sizeIdcNodes = 0;
   27586     }
   27587     /*
   27588     * Note that we won't delete the XPath state pool here.
   27589     */
   27590     if (vctxt->xpathStates != NULL) {
   27591 	xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
   27592 	vctxt->xpathStates = NULL;
   27593     }
   27594     /*
   27595     * Attribute info.
   27596     */
   27597     if (vctxt->nbAttrInfos != 0) {
   27598 	xmlSchemaClearAttrInfos(vctxt);
   27599     }
   27600     /*
   27601     * Element info.
   27602     */
   27603     if (vctxt->elemInfos != NULL) {
   27604 	int i;
   27605 	xmlSchemaNodeInfoPtr ei;
   27606 
   27607 	for (i = 0; i < vctxt->sizeElemInfos; i++) {
   27608 	    ei = vctxt->elemInfos[i];
   27609 	    if (ei == NULL)
   27610 		break;
   27611 	    xmlSchemaClearElemInfo(vctxt, ei);
   27612 	}
   27613     }
   27614     xmlSchemaItemListClear(vctxt->nodeQNames);
   27615     /* Recreate the dict. */
   27616     xmlDictFree(vctxt->dict);
   27617     /*
   27618     * TODO: Is is save to recreate it? Do we have a scenario
   27619     * where the user provides the dict?
   27620     */
   27621     vctxt->dict = xmlDictCreate();
   27622 
   27623     if (vctxt->filename != NULL) {
   27624         xmlFree(vctxt->filename);
   27625 	vctxt->filename = NULL;
   27626     }
   27627 }
   27628 
   27629 /**
   27630  * xmlSchemaFreeValidCtxt:
   27631  * @ctxt:  the schema validation context
   27632  *
   27633  * Free the resources associated to the schema validation context
   27634  */
   27635 void
   27636 xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
   27637 {
   27638     if (ctxt == NULL)
   27639         return;
   27640     if (ctxt->value != NULL)
   27641         xmlSchemaFreeValue(ctxt->value);
   27642     if (ctxt->pctxt != NULL)
   27643 	xmlSchemaFreeParserCtxt(ctxt->pctxt);
   27644     if (ctxt->idcNodes != NULL) {
   27645 	int i;
   27646 	xmlSchemaPSVIIDCNodePtr item;
   27647 
   27648 	for (i = 0; i < ctxt->nbIdcNodes; i++) {
   27649 	    item = ctxt->idcNodes[i];
   27650 	    xmlFree(item->keys);
   27651 	    xmlFree(item);
   27652 	}
   27653 	xmlFree(ctxt->idcNodes);
   27654     }
   27655     if (ctxt->idcKeys != NULL) {
   27656 	int i;
   27657 	for (i = 0; i < ctxt->nbIdcKeys; i++)
   27658 	    xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
   27659 	xmlFree(ctxt->idcKeys);
   27660     }
   27661 
   27662     if (ctxt->xpathStates != NULL) {
   27663 	xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
   27664 	ctxt->xpathStates = NULL;
   27665     }
   27666     if (ctxt->xpathStatePool != NULL) {
   27667 	xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
   27668 	ctxt->xpathStatePool = NULL;
   27669     }
   27670 
   27671     /*
   27672     * Augmented IDC information.
   27673     */
   27674     if (ctxt->aidcs != NULL) {
   27675 	xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
   27676 	do {
   27677 	    next = cur->next;
   27678 	    xmlFree(cur);
   27679 	    cur = next;
   27680 	} while (cur != NULL);
   27681     }
   27682     if (ctxt->attrInfos != NULL) {
   27683 	int i;
   27684 	xmlSchemaAttrInfoPtr attr;
   27685 
   27686 	/* Just a paranoid call to the cleanup. */
   27687 	if (ctxt->nbAttrInfos != 0)
   27688 	    xmlSchemaClearAttrInfos(ctxt);
   27689 	for (i = 0; i < ctxt->sizeAttrInfos; i++) {
   27690 	    attr = ctxt->attrInfos[i];
   27691 	    xmlFree(attr);
   27692 	}
   27693 	xmlFree(ctxt->attrInfos);
   27694     }
   27695     if (ctxt->elemInfos != NULL) {
   27696 	int i;
   27697 	xmlSchemaNodeInfoPtr ei;
   27698 
   27699 	for (i = 0; i < ctxt->sizeElemInfos; i++) {
   27700 	    ei = ctxt->elemInfos[i];
   27701 	    if (ei == NULL)
   27702 		break;
   27703 	    xmlSchemaClearElemInfo(ctxt, ei);
   27704 	    xmlFree(ei);
   27705 	}
   27706 	xmlFree(ctxt->elemInfos);
   27707     }
   27708     if (ctxt->nodeQNames != NULL)
   27709 	xmlSchemaItemListFree(ctxt->nodeQNames);
   27710     if (ctxt->dict != NULL)
   27711 	xmlDictFree(ctxt->dict);
   27712     if (ctxt->filename != NULL)
   27713 	xmlFree(ctxt->filename);
   27714     xmlFree(ctxt);
   27715 }
   27716 
   27717 /**
   27718  * xmlSchemaIsValid:
   27719  * @ctxt: the schema validation context
   27720  *
   27721  * Check if any error was detected during validation.
   27722  *
   27723  * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
   27724  *         of internal error.
   27725  */
   27726 int
   27727 xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
   27728 {
   27729     if (ctxt == NULL)
   27730         return(-1);
   27731     return(ctxt->err == 0);
   27732 }
   27733 
   27734 /**
   27735  * xmlSchemaSetValidErrors:
   27736  * @ctxt:  a schema validation context
   27737  * @err:  the error function
   27738  * @warn: the warning function
   27739  * @ctx: the functions context
   27740  *
   27741  * Set the error and warning callback informations
   27742  */
   27743 void
   27744 xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
   27745                         xmlSchemaValidityErrorFunc err,
   27746                         xmlSchemaValidityWarningFunc warn, void *ctx)
   27747 {
   27748     if (ctxt == NULL)
   27749         return;
   27750     ctxt->error = err;
   27751     ctxt->warning = warn;
   27752     ctxt->errCtxt = ctx;
   27753     if (ctxt->pctxt != NULL)
   27754 	xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
   27755 }
   27756 
   27757 /**
   27758  * xmlSchemaSetValidStructuredErrors:
   27759  * @ctxt:  a schema validation context
   27760  * @serror:  the structured error function
   27761  * @ctx: the functions context
   27762  *
   27763  * Set the structured error callback
   27764  */
   27765 void
   27766 xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
   27767 				  xmlStructuredErrorFunc serror, void *ctx)
   27768 {
   27769     if (ctxt == NULL)
   27770         return;
   27771 	ctxt->serror = serror;
   27772     ctxt->error = NULL;
   27773     ctxt->warning = NULL;
   27774     ctxt->errCtxt = ctx;
   27775     if (ctxt->pctxt != NULL)
   27776 	xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
   27777 }
   27778 
   27779 /**
   27780  * xmlSchemaGetValidErrors:
   27781  * @ctxt: a XML-Schema validation context
   27782  * @err: the error function result
   27783  * @warn: the warning function result
   27784  * @ctx: the functions context result
   27785  *
   27786  * Get the error and warning callback informations
   27787  *
   27788  * Returns -1 in case of error and 0 otherwise
   27789  */
   27790 int
   27791 xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
   27792 			xmlSchemaValidityErrorFunc * err,
   27793 			xmlSchemaValidityWarningFunc * warn, void **ctx)
   27794 {
   27795 	if (ctxt == NULL)
   27796 		return (-1);
   27797 	if (err != NULL)
   27798 		*err = ctxt->error;
   27799 	if (warn != NULL)
   27800 		*warn = ctxt->warning;
   27801 	if (ctx != NULL)
   27802 		*ctx = ctxt->errCtxt;
   27803 	return (0);
   27804 }
   27805 
   27806 
   27807 /**
   27808  * xmlSchemaSetValidOptions:
   27809  * @ctxt:	a schema validation context
   27810  * @options: a combination of xmlSchemaValidOption
   27811  *
   27812  * Sets the options to be used during the validation.
   27813  *
   27814  * Returns 0 in case of success, -1 in case of an
   27815  * API error.
   27816  */
   27817 int
   27818 xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
   27819 			 int options)
   27820 
   27821 {
   27822     int i;
   27823 
   27824     if (ctxt == NULL)
   27825 	return (-1);
   27826     /*
   27827     * WARNING: Change the start value if adding to the
   27828     * xmlSchemaValidOption.
   27829     * TODO: Is there an other, more easy to maintain,
   27830     * way?
   27831     */
   27832     for (i = 1; i < (int) sizeof(int) * 8; i++) {
   27833         if (options & 1<<i)
   27834 	    return (-1);
   27835     }
   27836     ctxt->options = options;
   27837     return (0);
   27838 }
   27839 
   27840 /**
   27841  * xmlSchemaValidCtxtGetOptions:
   27842  * @ctxt: a schema validation context
   27843  *
   27844  * Get the validation context options.
   27845  *
   27846  * Returns the option combination or -1 on error.
   27847  */
   27848 int
   27849 xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
   27850 
   27851 {
   27852     if (ctxt == NULL)
   27853 	return (-1);
   27854     else
   27855 	return (ctxt->options);
   27856 }
   27857 
   27858 static int
   27859 xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
   27860 {
   27861     xmlAttrPtr attr;
   27862     int ret = 0;
   27863     xmlSchemaNodeInfoPtr ielem = NULL;
   27864     xmlNodePtr node, valRoot;
   27865     const xmlChar *nsName;
   27866 
   27867     /* DOC VAL TODO: Move this to the start function. */
   27868     if (vctxt->validationRoot != NULL)
   27869         valRoot = vctxt->validationRoot;
   27870     else
   27871 	valRoot = xmlDocGetRootElement(vctxt->doc);
   27872     if (valRoot == NULL) {
   27873 	/* VAL TODO: Error code? */
   27874 	VERROR(1, NULL, "The document has no document element");
   27875 	return (1);
   27876     }
   27877     vctxt->depth = -1;
   27878     vctxt->validationRoot = valRoot;
   27879     node = valRoot;
   27880     while (node != NULL) {
   27881 	if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27882 	    goto next_sibling;
   27883 	if (node->type == XML_ELEMENT_NODE) {
   27884 
   27885 	    /*
   27886 	    * Init the node-info.
   27887 	    */
   27888 	    vctxt->depth++;
   27889 	    if (xmlSchemaValidatorPushElem(vctxt) == -1)
   27890 		goto internal_error;
   27891 	    ielem = vctxt->inode;
   27892 	    ielem->node = node;
   27893 	    ielem->nodeLine = node->line;
   27894 	    ielem->localName = node->name;
   27895 	    if (node->ns != NULL)
   27896 		ielem->nsName = node->ns->href;
   27897 	    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
   27898 	    /*
   27899 	    * Register attributes.
   27900 	    * DOC VAL TODO: We do not register namespace declaration
   27901 	    * attributes yet.
   27902 	    */
   27903 	    vctxt->nbAttrInfos = 0;
   27904 	    if (node->properties != NULL) {
   27905 		attr = node->properties;
   27906 		do {
   27907 		    if (attr->ns != NULL)
   27908 			nsName = attr->ns->href;
   27909 		    else
   27910 			nsName = NULL;
   27911 		    ret = xmlSchemaValidatorPushAttribute(vctxt,
   27912 			(xmlNodePtr) attr,
   27913 			/*
   27914 			* Note that we give it the line number of the
   27915 			* parent element.
   27916 			*/
   27917 			ielem->nodeLine,
   27918 			attr->name, nsName, 0,
   27919 			xmlNodeListGetString(attr->doc, attr->children, 1), 1);
   27920 		    if (ret == -1) {
   27921 			VERROR_INT("xmlSchemaDocWalk",
   27922 			    "calling xmlSchemaValidatorPushAttribute()");
   27923 			goto internal_error;
   27924 		    }
   27925 		    attr = attr->next;
   27926 		} while (attr);
   27927 	    }
   27928 	    /*
   27929 	    * Validate the element.
   27930 	    */
   27931 	    ret = xmlSchemaValidateElem(vctxt);
   27932 	    if (ret != 0) {
   27933 		if (ret == -1) {
   27934 		    VERROR_INT("xmlSchemaDocWalk",
   27935 			"calling xmlSchemaValidateElem()");
   27936 		    goto internal_error;
   27937 		}
   27938 		/*
   27939 		* Don't stop validation; just skip the content
   27940 		* of this element.
   27941 		*/
   27942 		goto leave_node;
   27943 	    }
   27944 	    if ((vctxt->skipDepth != -1) &&
   27945 		(vctxt->depth >= vctxt->skipDepth))
   27946 		goto leave_node;
   27947 	} else if ((node->type == XML_TEXT_NODE) ||
   27948 	    (node->type == XML_CDATA_SECTION_NODE)) {
   27949 	    /*
   27950 	    * Process character content.
   27951 	    */
   27952 	    if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
   27953 		ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
   27954 	    ret = xmlSchemaVPushText(vctxt, node->type, node->content,
   27955 		-1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
   27956 	    if (ret < 0) {
   27957 		VERROR_INT("xmlSchemaVDocWalk",
   27958 		    "calling xmlSchemaVPushText()");
   27959 		goto internal_error;
   27960 	    }
   27961 	    /*
   27962 	    * DOC VAL TODO: Should we skip further validation of the
   27963 	    * element content here?
   27964 	    */
   27965 	} else if ((node->type == XML_ENTITY_NODE) ||
   27966 	    (node->type == XML_ENTITY_REF_NODE)) {
   27967 	    /*
   27968 	    * DOC VAL TODO: What to do with entities?
   27969 	    */
   27970 	    VERROR_INT("xmlSchemaVDocWalk",
   27971 		"there is at least one entity reference in the node-tree "
   27972 		"currently being validated. Processing of entities with "
   27973 		"this XML Schema processor is not supported (yet). Please "
   27974 		"substitute entities before validation.");
   27975 	    goto internal_error;
   27976 	} else {
   27977 	    goto leave_node;
   27978 	    /*
   27979 	    * DOC VAL TODO: XInclude nodes, etc.
   27980 	    */
   27981 	}
   27982 	/*
   27983 	* Walk the doc.
   27984 	*/
   27985 	if (node->children != NULL) {
   27986 	    node = node->children;
   27987 	    continue;
   27988 	}
   27989 leave_node:
   27990 	if (node->type == XML_ELEMENT_NODE) {
   27991 	    /*
   27992 	    * Leaving the scope of an element.
   27993 	    */
   27994 	    if (node != vctxt->inode->node) {
   27995 		VERROR_INT("xmlSchemaVDocWalk",
   27996 		    "element position mismatch");
   27997 		goto internal_error;
   27998 	    }
   27999 	    ret = xmlSchemaValidatorPopElem(vctxt);
   28000 	    if (ret != 0) {
   28001 		if (ret < 0) {
   28002 		    VERROR_INT("xmlSchemaVDocWalk",
   28003 			"calling xmlSchemaValidatorPopElem()");
   28004 		    goto internal_error;
   28005 		}
   28006 	    }
   28007 	    if (node == valRoot)
   28008 		goto exit;
   28009 	}
   28010 next_sibling:
   28011 	if (node->next != NULL)
   28012 	    node = node->next;
   28013 	else {
   28014 	    node = node->parent;
   28015 	    goto leave_node;
   28016 	}
   28017     }
   28018 
   28019 exit:
   28020     return (ret);
   28021 internal_error:
   28022     return (-1);
   28023 }
   28024 
   28025 static int
   28026 xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
   28027     /*
   28028     * Some initialization.
   28029     */
   28030     vctxt->err = 0;
   28031     vctxt->nberrors = 0;
   28032     vctxt->depth = -1;
   28033     vctxt->skipDepth = -1;
   28034     vctxt->xsiAssemble = 0;
   28035     vctxt->hasKeyrefs = 0;
   28036 #ifdef ENABLE_IDC_NODE_TABLES_TEST
   28037     vctxt->createIDCNodeTables = 1;
   28038 #else
   28039     vctxt->createIDCNodeTables = 0;
   28040 #endif
   28041     /*
   28042     * Create a schema + parser if necessary.
   28043     */
   28044     if (vctxt->schema == NULL) {
   28045 	xmlSchemaParserCtxtPtr pctxt;
   28046 
   28047 	vctxt->xsiAssemble = 1;
   28048 	/*
   28049 	* If not schema was given then we will create a schema
   28050 	* dynamically using XSI schema locations.
   28051 	*
   28052 	* Create the schema parser context.
   28053 	*/
   28054 	if ((vctxt->pctxt == NULL) &&
   28055 	   (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
   28056 	   return (-1);
   28057 	pctxt = vctxt->pctxt;
   28058 	pctxt->xsiAssemble = 1;
   28059 	/*
   28060 	* Create the schema.
   28061 	*/
   28062 	vctxt->schema = xmlSchemaNewSchema(pctxt);
   28063 	if (vctxt->schema == NULL)
   28064 	    return (-1);
   28065 	/*
   28066 	* Create the schema construction context.
   28067 	*/
   28068 	pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
   28069 	if (pctxt->constructor == NULL)
   28070 	    return(-1);
   28071 	pctxt->constructor->mainSchema = vctxt->schema;
   28072 	/*
   28073 	* Take ownership of the constructor to be able to free it.
   28074 	*/
   28075 	pctxt->ownsConstructor = 1;
   28076     }
   28077     /*
   28078     * Augment the IDC definitions for the main schema and all imported ones
   28079     * NOTE: main schema if the first in the imported list
   28080     */
   28081     xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
   28082 
   28083     return(0);
   28084 }
   28085 
   28086 static void
   28087 xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
   28088     if (vctxt->xsiAssemble) {
   28089 	if (vctxt->schema != NULL) {
   28090 	    xmlSchemaFree(vctxt->schema);
   28091 	    vctxt->schema = NULL;
   28092 	}
   28093     }
   28094     xmlSchemaClearValidCtxt(vctxt);
   28095 }
   28096 
   28097 static int
   28098 xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
   28099 {
   28100     int ret = 0;
   28101 
   28102     if (xmlSchemaPreRun(vctxt) < 0)
   28103         return(-1);
   28104 
   28105     if (vctxt->doc != NULL) {
   28106 	/*
   28107 	 * Tree validation.
   28108 	 */
   28109 	ret = xmlSchemaVDocWalk(vctxt);
   28110 #ifdef LIBXML_READER_ENABLED
   28111     } else if (vctxt->reader != NULL) {
   28112 	/*
   28113 	 * XML Reader validation.
   28114 	 */
   28115 #ifdef XML_SCHEMA_READER_ENABLED
   28116 	ret = xmlSchemaVReaderWalk(vctxt);
   28117 #endif
   28118 #endif
   28119     } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
   28120 	/*
   28121 	 * SAX validation.
   28122 	 */
   28123 	ret = xmlParseDocument(vctxt->parserCtxt);
   28124     } else {
   28125 	VERROR_INT("xmlSchemaVStart",
   28126 	    "no instance to validate");
   28127 	ret = -1;
   28128     }
   28129 
   28130     xmlSchemaPostRun(vctxt);
   28131     if (ret == 0)
   28132 	ret = vctxt->err;
   28133     return (ret);
   28134 }
   28135 
   28136 /**
   28137  * xmlSchemaValidateOneElement:
   28138  * @ctxt:  a schema validation context
   28139  * @elem:  an element node
   28140  *
   28141  * Validate a branch of a tree, starting with the given @elem.
   28142  *
   28143  * Returns 0 if the element and its subtree is valid, a positive error
   28144  * code number otherwise and -1 in case of an internal or API error.
   28145  */
   28146 int
   28147 xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
   28148 {
   28149     if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
   28150 	return (-1);
   28151 
   28152     if (ctxt->schema == NULL)
   28153 	return (-1);
   28154 
   28155     ctxt->doc = elem->doc;
   28156     ctxt->node = elem;
   28157     ctxt->validationRoot = elem;
   28158     return(xmlSchemaVStart(ctxt));
   28159 }
   28160 
   28161 /**
   28162  * xmlSchemaValidateDoc:
   28163  * @ctxt:  a schema validation context
   28164  * @doc:  a parsed document tree
   28165  *
   28166  * Validate a document tree in memory.
   28167  *
   28168  * Returns 0 if the document is schemas valid, a positive error code
   28169  *     number otherwise and -1 in case of internal or API error.
   28170  */
   28171 int
   28172 xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
   28173 {
   28174     if ((ctxt == NULL) || (doc == NULL))
   28175         return (-1);
   28176 
   28177     ctxt->doc = doc;
   28178     ctxt->node = xmlDocGetRootElement(doc);
   28179     if (ctxt->node == NULL) {
   28180         xmlSchemaCustomErr(ACTXT_CAST ctxt,
   28181 	    XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
   28182 	    (xmlNodePtr) doc, NULL,
   28183 	    "The document has no document element", NULL, NULL);
   28184         return (ctxt->err);
   28185     }
   28186     ctxt->validationRoot = ctxt->node;
   28187     return (xmlSchemaVStart(ctxt));
   28188 }
   28189 
   28190 
   28191 /************************************************************************
   28192  *									*
   28193  *		Function and data for SAX streaming API			*
   28194  *									*
   28195  ************************************************************************/
   28196 typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
   28197 typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
   28198 
   28199 struct _xmlSchemaSplitSAXData {
   28200     xmlSAXHandlerPtr      user_sax;
   28201     void                 *user_data;
   28202     xmlSchemaValidCtxtPtr ctxt;
   28203     xmlSAXHandlerPtr      schemas_sax;
   28204 };
   28205 
   28206 #define XML_SAX_PLUG_MAGIC 0xdc43ba21
   28207 
   28208 struct _xmlSchemaSAXPlug {
   28209     unsigned int magic;
   28210 
   28211     /* the original callbacks informations */
   28212     xmlSAXHandlerPtr     *user_sax_ptr;
   28213     xmlSAXHandlerPtr      user_sax;
   28214     void                **user_data_ptr;
   28215     void                 *user_data;
   28216 
   28217     /* the block plugged back and validation informations */
   28218     xmlSAXHandler         schemas_sax;
   28219     xmlSchemaValidCtxtPtr ctxt;
   28220 };
   28221 
   28222 /* All those functions just bounces to the user provided SAX handlers */
   28223 static void
   28224 internalSubsetSplit(void *ctx, const xmlChar *name,
   28225 	       const xmlChar *ExternalID, const xmlChar *SystemID)
   28226 {
   28227     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28228     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28229         (ctxt->user_sax->internalSubset != NULL))
   28230 	ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
   28231 	                               SystemID);
   28232 }
   28233 
   28234 static int
   28235 isStandaloneSplit(void *ctx)
   28236 {
   28237     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28238     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28239         (ctxt->user_sax->isStandalone != NULL))
   28240 	return(ctxt->user_sax->isStandalone(ctxt->user_data));
   28241     return(0);
   28242 }
   28243 
   28244 static int
   28245 hasInternalSubsetSplit(void *ctx)
   28246 {
   28247     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28248     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28249         (ctxt->user_sax->hasInternalSubset != NULL))
   28250 	return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
   28251     return(0);
   28252 }
   28253 
   28254 static int
   28255 hasExternalSubsetSplit(void *ctx)
   28256 {
   28257     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28258     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28259         (ctxt->user_sax->hasExternalSubset != NULL))
   28260 	return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
   28261     return(0);
   28262 }
   28263 
   28264 static void
   28265 externalSubsetSplit(void *ctx, const xmlChar *name,
   28266 	       const xmlChar *ExternalID, const xmlChar *SystemID)
   28267 {
   28268     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28269     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28270         (ctxt->user_sax->externalSubset != NULL))
   28271 	ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
   28272 	                               SystemID);
   28273 }
   28274 
   28275 static xmlParserInputPtr
   28276 resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
   28277 {
   28278     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28279     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28280         (ctxt->user_sax->resolveEntity != NULL))
   28281 	return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
   28282 	                                     systemId));
   28283     return(NULL);
   28284 }
   28285 
   28286 static xmlEntityPtr
   28287 getEntitySplit(void *ctx, const xmlChar *name)
   28288 {
   28289     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28290     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28291         (ctxt->user_sax->getEntity != NULL))
   28292 	return(ctxt->user_sax->getEntity(ctxt->user_data, name));
   28293     return(NULL);
   28294 }
   28295 
   28296 static xmlEntityPtr
   28297 getParameterEntitySplit(void *ctx, const xmlChar *name)
   28298 {
   28299     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28300     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28301         (ctxt->user_sax->getParameterEntity != NULL))
   28302 	return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
   28303     return(NULL);
   28304 }
   28305 
   28306 
   28307 static void
   28308 entityDeclSplit(void *ctx, const xmlChar *name, int type,
   28309           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
   28310 {
   28311     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28312     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28313         (ctxt->user_sax->entityDecl != NULL))
   28314 	ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
   28315 	                           systemId, content);
   28316 }
   28317 
   28318 static void
   28319 attributeDeclSplit(void *ctx, const xmlChar * elem,
   28320                    const xmlChar * name, int type, int def,
   28321                    const xmlChar * defaultValue, xmlEnumerationPtr tree)
   28322 {
   28323     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28324     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28325         (ctxt->user_sax->attributeDecl != NULL)) {
   28326 	ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
   28327 	                              def, defaultValue, tree);
   28328     } else {
   28329 	xmlFreeEnumeration(tree);
   28330     }
   28331 }
   28332 
   28333 static void
   28334 elementDeclSplit(void *ctx, const xmlChar *name, int type,
   28335 	    xmlElementContentPtr content)
   28336 {
   28337     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28338     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28339         (ctxt->user_sax->elementDecl != NULL))
   28340 	ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
   28341 }
   28342 
   28343 static void
   28344 notationDeclSplit(void *ctx, const xmlChar *name,
   28345 	     const xmlChar *publicId, const xmlChar *systemId)
   28346 {
   28347     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28348     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28349         (ctxt->user_sax->notationDecl != NULL))
   28350 	ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
   28351 	                             systemId);
   28352 }
   28353 
   28354 static void
   28355 unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
   28356 		   const xmlChar *publicId, const xmlChar *systemId,
   28357 		   const xmlChar *notationName)
   28358 {
   28359     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28360     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28361         (ctxt->user_sax->unparsedEntityDecl != NULL))
   28362 	ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
   28363 	                                   systemId, notationName);
   28364 }
   28365 
   28366 static void
   28367 setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
   28368 {
   28369     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28370     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28371         (ctxt->user_sax->setDocumentLocator != NULL))
   28372 	ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
   28373 }
   28374 
   28375 static void
   28376 startDocumentSplit(void *ctx)
   28377 {
   28378     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28379     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28380         (ctxt->user_sax->startDocument != NULL))
   28381 	ctxt->user_sax->startDocument(ctxt->user_data);
   28382 }
   28383 
   28384 static void
   28385 endDocumentSplit(void *ctx)
   28386 {
   28387     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28388     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28389         (ctxt->user_sax->endDocument != NULL))
   28390 	ctxt->user_sax->endDocument(ctxt->user_data);
   28391 }
   28392 
   28393 static void
   28394 processingInstructionSplit(void *ctx, const xmlChar *target,
   28395                       const xmlChar *data)
   28396 {
   28397     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28398     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28399         (ctxt->user_sax->processingInstruction != NULL))
   28400 	ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
   28401 }
   28402 
   28403 static void
   28404 commentSplit(void *ctx, const xmlChar *value)
   28405 {
   28406     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28407     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28408         (ctxt->user_sax->comment != NULL))
   28409 	ctxt->user_sax->comment(ctxt->user_data, value);
   28410 }
   28411 
   28412 /*
   28413  * Varargs error callbacks to the user application, harder ...
   28414  */
   28415 
   28416 static void XMLCDECL
   28417 warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
   28418     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28419     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28420         (ctxt->user_sax->warning != NULL)) {
   28421 	TODO
   28422     }
   28423 }
   28424 static void XMLCDECL
   28425 errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
   28426     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28427     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28428         (ctxt->user_sax->error != NULL)) {
   28429 	TODO
   28430     }
   28431 }
   28432 static void XMLCDECL
   28433 fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
   28434     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28435     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28436         (ctxt->user_sax->fatalError != NULL)) {
   28437 	TODO
   28438     }
   28439 }
   28440 
   28441 /*
   28442  * Those are function where both the user handler and the schemas handler
   28443  * need to be called.
   28444  */
   28445 static void
   28446 charactersSplit(void *ctx, const xmlChar *ch, int len)
   28447 {
   28448     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28449     if (ctxt == NULL)
   28450         return;
   28451     if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
   28452 	ctxt->user_sax->characters(ctxt->user_data, ch, len);
   28453     if (ctxt->ctxt != NULL)
   28454 	xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
   28455 }
   28456 
   28457 static void
   28458 ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
   28459 {
   28460     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28461     if (ctxt == NULL)
   28462         return;
   28463     if ((ctxt->user_sax != NULL) &&
   28464         (ctxt->user_sax->ignorableWhitespace != NULL))
   28465 	ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
   28466     if (ctxt->ctxt != NULL)
   28467 	xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
   28468 }
   28469 
   28470 static void
   28471 cdataBlockSplit(void *ctx, const xmlChar *value, int len)
   28472 {
   28473     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28474     if (ctxt == NULL)
   28475         return;
   28476     if ((ctxt->user_sax != NULL) &&
   28477         (ctxt->user_sax->cdataBlock != NULL))
   28478 	ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
   28479     if (ctxt->ctxt != NULL)
   28480 	xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
   28481 }
   28482 
   28483 static void
   28484 referenceSplit(void *ctx, const xmlChar *name)
   28485 {
   28486     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28487     if (ctxt == NULL)
   28488         return;
   28489     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28490         (ctxt->user_sax->reference != NULL))
   28491 	ctxt->user_sax->reference(ctxt->user_data, name);
   28492     if (ctxt->ctxt != NULL)
   28493         xmlSchemaSAXHandleReference(ctxt->user_data, name);
   28494 }
   28495 
   28496 static void
   28497 startElementNsSplit(void *ctx, const xmlChar * localname,
   28498 		    const xmlChar * prefix, const xmlChar * URI,
   28499 		    int nb_namespaces, const xmlChar ** namespaces,
   28500 		    int nb_attributes, int nb_defaulted,
   28501 		    const xmlChar ** attributes) {
   28502     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28503     if (ctxt == NULL)
   28504         return;
   28505     if ((ctxt->user_sax != NULL) &&
   28506         (ctxt->user_sax->startElementNs != NULL))
   28507 	ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
   28508 	                               URI, nb_namespaces, namespaces,
   28509 				       nb_attributes, nb_defaulted,
   28510 				       attributes);
   28511     if (ctxt->ctxt != NULL)
   28512 	xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
   28513 	                                 URI, nb_namespaces, namespaces,
   28514 					 nb_attributes, nb_defaulted,
   28515 					 attributes);
   28516 }
   28517 
   28518 static void
   28519 endElementNsSplit(void *ctx, const xmlChar * localname,
   28520 		    const xmlChar * prefix, const xmlChar * URI) {
   28521     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28522     if (ctxt == NULL)
   28523         return;
   28524     if ((ctxt->user_sax != NULL) &&
   28525         (ctxt->user_sax->endElementNs != NULL))
   28526 	ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
   28527     if (ctxt->ctxt != NULL)
   28528 	xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
   28529 }
   28530 
   28531 /**
   28532  * xmlSchemaSAXPlug:
   28533  * @ctxt:  a schema validation context
   28534  * @sax:  a pointer to the original xmlSAXHandlerPtr
   28535  * @user_data:  a pointer to the original SAX user data pointer
   28536  *
   28537  * Plug a SAX based validation layer in a SAX parsing event flow.
   28538  * The original @saxptr and @dataptr data are replaced by new pointers
   28539  * but the calls to the original will be maintained.
   28540  *
   28541  * Returns a pointer to a data structure needed to unplug the validation layer
   28542  *         or NULL in case of errors.
   28543  */
   28544 xmlSchemaSAXPlugPtr
   28545 xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
   28546 		 xmlSAXHandlerPtr *sax, void **user_data)
   28547 {
   28548     xmlSchemaSAXPlugPtr ret;
   28549     xmlSAXHandlerPtr old_sax;
   28550 
   28551     if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
   28552         return(NULL);
   28553 
   28554     /*
   28555      * We only allow to plug into SAX2 event streams
   28556      */
   28557     old_sax = *sax;
   28558     if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
   28559         return(NULL);
   28560     if ((old_sax != NULL) &&
   28561         (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
   28562         ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
   28563         return(NULL);
   28564 
   28565     /*
   28566      * everything seems right allocate the local data needed for that layer
   28567      */
   28568     ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
   28569     if (ret == NULL) {
   28570         return(NULL);
   28571     }
   28572     memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
   28573     ret->magic = XML_SAX_PLUG_MAGIC;
   28574     ret->schemas_sax.initialized = XML_SAX2_MAGIC;
   28575     ret->ctxt = ctxt;
   28576     ret->user_sax_ptr = sax;
   28577     ret->user_sax = old_sax;
   28578     if (old_sax == NULL) {
   28579         /*
   28580 	 * go direct, no need for the split block and functions.
   28581 	 */
   28582 	ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
   28583 	ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
   28584 	/*
   28585 	 * Note that we use the same text-function for both, to prevent
   28586 	 * the parser from testing for ignorable whitespace.
   28587 	 */
   28588 	ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
   28589 	ret->schemas_sax.characters = xmlSchemaSAXHandleText;
   28590 
   28591 	ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
   28592 	ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
   28593 
   28594 	ret->user_data = ctxt;
   28595 	*user_data = ctxt;
   28596     } else {
   28597        /*
   28598         * for each callback unused by Schemas initialize it to the Split
   28599 	* routine only if non NULL in the user block, this can speed up
   28600 	* things at the SAX level.
   28601 	*/
   28602         if (old_sax->internalSubset != NULL)
   28603             ret->schemas_sax.internalSubset = internalSubsetSplit;
   28604         if (old_sax->isStandalone != NULL)
   28605             ret->schemas_sax.isStandalone = isStandaloneSplit;
   28606         if (old_sax->hasInternalSubset != NULL)
   28607             ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
   28608         if (old_sax->hasExternalSubset != NULL)
   28609             ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
   28610         if (old_sax->resolveEntity != NULL)
   28611             ret->schemas_sax.resolveEntity = resolveEntitySplit;
   28612         if (old_sax->getEntity != NULL)
   28613             ret->schemas_sax.getEntity = getEntitySplit;
   28614         if (old_sax->entityDecl != NULL)
   28615             ret->schemas_sax.entityDecl = entityDeclSplit;
   28616         if (old_sax->notationDecl != NULL)
   28617             ret->schemas_sax.notationDecl = notationDeclSplit;
   28618         if (old_sax->attributeDecl != NULL)
   28619             ret->schemas_sax.attributeDecl = attributeDeclSplit;
   28620         if (old_sax->elementDecl != NULL)
   28621             ret->schemas_sax.elementDecl = elementDeclSplit;
   28622         if (old_sax->unparsedEntityDecl != NULL)
   28623             ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
   28624         if (old_sax->setDocumentLocator != NULL)
   28625             ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
   28626         if (old_sax->startDocument != NULL)
   28627             ret->schemas_sax.startDocument = startDocumentSplit;
   28628         if (old_sax->endDocument != NULL)
   28629             ret->schemas_sax.endDocument = endDocumentSplit;
   28630         if (old_sax->processingInstruction != NULL)
   28631             ret->schemas_sax.processingInstruction = processingInstructionSplit;
   28632         if (old_sax->comment != NULL)
   28633             ret->schemas_sax.comment = commentSplit;
   28634         if (old_sax->warning != NULL)
   28635             ret->schemas_sax.warning = warningSplit;
   28636         if (old_sax->error != NULL)
   28637             ret->schemas_sax.error = errorSplit;
   28638         if (old_sax->fatalError != NULL)
   28639             ret->schemas_sax.fatalError = fatalErrorSplit;
   28640         if (old_sax->getParameterEntity != NULL)
   28641             ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
   28642         if (old_sax->externalSubset != NULL)
   28643             ret->schemas_sax.externalSubset = externalSubsetSplit;
   28644 
   28645 	/*
   28646 	 * the 6 schemas callback have to go to the splitter functions
   28647 	 * Note that we use the same text-function for ignorableWhitespace
   28648 	 * if possible, to prevent the parser from testing for ignorable
   28649 	 * whitespace.
   28650 	 */
   28651         ret->schemas_sax.characters = charactersSplit;
   28652 	if ((old_sax->ignorableWhitespace != NULL) &&
   28653 	    (old_sax->ignorableWhitespace != old_sax->characters))
   28654 	    ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
   28655 	else
   28656 	    ret->schemas_sax.ignorableWhitespace = charactersSplit;
   28657         ret->schemas_sax.cdataBlock = cdataBlockSplit;
   28658         ret->schemas_sax.reference = referenceSplit;
   28659         ret->schemas_sax.startElementNs = startElementNsSplit;
   28660         ret->schemas_sax.endElementNs = endElementNsSplit;
   28661 
   28662 	ret->user_data_ptr = user_data;
   28663 	ret->user_data = *user_data;
   28664 	*user_data = ret;
   28665     }
   28666 
   28667     /*
   28668      * plug the pointers back.
   28669      */
   28670     *sax = &(ret->schemas_sax);
   28671     ctxt->sax = *sax;
   28672     ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
   28673     xmlSchemaPreRun(ctxt);
   28674     return(ret);
   28675 }
   28676 
   28677 /**
   28678  * xmlSchemaSAXUnplug:
   28679  * @plug:  a data structure returned by xmlSchemaSAXPlug
   28680  *
   28681  * Unplug a SAX based validation layer in a SAX parsing event flow.
   28682  * The original pointers used in the call are restored.
   28683  *
   28684  * Returns 0 in case of success and -1 in case of failure.
   28685  */
   28686 int
   28687 xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
   28688 {
   28689     xmlSAXHandlerPtr *sax;
   28690     void **user_data;
   28691 
   28692     if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
   28693         return(-1);
   28694     plug->magic = 0;
   28695 
   28696     xmlSchemaPostRun(plug->ctxt);
   28697     /* restore the data */
   28698     sax = plug->user_sax_ptr;
   28699     *sax = plug->user_sax;
   28700     if (plug->user_sax != NULL) {
   28701 	user_data = plug->user_data_ptr;
   28702 	*user_data = plug->user_data;
   28703     }
   28704 
   28705     /* free and return */
   28706     xmlFree(plug);
   28707     return(0);
   28708 }
   28709 
   28710 /**
   28711  * xmlSchemaValidateSetLocator:
   28712  * @vctxt: a schema validation context
   28713  * @f: the locator function pointer
   28714  * @ctxt: the locator context
   28715  *
   28716  * Allows to set a locator function to the validation context,
   28717  * which will be used to provide file and line information since
   28718  * those are not provided as part of the SAX validation flow
   28719  * Setting @f to NULL disable the locator.
   28720  */
   28721 
   28722 void
   28723 xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
   28724                             xmlSchemaValidityLocatorFunc f,
   28725 			    void *ctxt)
   28726 {
   28727     if (vctxt == NULL) return;
   28728     vctxt->locFunc = f;
   28729     vctxt->locCtxt = ctxt;
   28730 }
   28731 
   28732 /**
   28733  * xmlSchemaValidateStreamLocator:
   28734  * @ctx: the xmlTextReaderPtr used
   28735  * @file: returned file information
   28736  * @line: returned line information
   28737  *
   28738  * Internal locator function for the readers
   28739  *
   28740  * Returns 0 in case the Schema validation could be (des)activated and
   28741  *         -1 in case of error.
   28742  */
   28743 static int
   28744 xmlSchemaValidateStreamLocator(void *ctx, const char **file,
   28745                                unsigned long *line) {
   28746     xmlParserCtxtPtr ctxt;
   28747 
   28748     if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
   28749         return(-1);
   28750 
   28751     if (file != NULL)
   28752         *file = NULL;
   28753     if (line != NULL)
   28754         *line = 0;
   28755 
   28756     ctxt = (xmlParserCtxtPtr) ctx;
   28757     if (ctxt->input != NULL) {
   28758        if (file != NULL)
   28759            *file = ctxt->input->filename;
   28760        if (line != NULL)
   28761            *line = ctxt->input->line;
   28762        return(0);
   28763     }
   28764     return(-1);
   28765 }
   28766 
   28767 /**
   28768  * xmlSchemaValidateStream:
   28769  * @ctxt:  a schema validation context
   28770  * @input:  the input to use for reading the data
   28771  * @enc:  an optional encoding information
   28772  * @sax:  a SAX handler for the resulting events
   28773  * @user_data:  the context to provide to the SAX handler.
   28774  *
   28775  * Validate an input based on a flow of SAX event from the parser
   28776  * and forward the events to the @sax handler with the provided @user_data
   28777  * the user provided @sax handler must be a SAX2 one.
   28778  *
   28779  * Returns 0 if the document is schemas valid, a positive error code
   28780  *     number otherwise and -1 in case of internal or API error.
   28781  */
   28782 int
   28783 xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
   28784                         xmlParserInputBufferPtr input, xmlCharEncoding enc,
   28785                         xmlSAXHandlerPtr sax, void *user_data)
   28786 {
   28787     xmlSchemaSAXPlugPtr plug = NULL;
   28788     xmlSAXHandlerPtr old_sax = NULL;
   28789     xmlParserCtxtPtr pctxt = NULL;
   28790     xmlParserInputPtr inputStream = NULL;
   28791     int ret;
   28792 
   28793     if ((ctxt == NULL) || (input == NULL))
   28794         return (-1);
   28795 
   28796     /*
   28797      * prepare the parser
   28798      */
   28799     pctxt = xmlNewParserCtxt();
   28800     if (pctxt == NULL)
   28801         return (-1);
   28802     old_sax = pctxt->sax;
   28803     pctxt->sax = sax;
   28804     pctxt->userData = user_data;
   28805 #if 0
   28806     if (options)
   28807         xmlCtxtUseOptions(pctxt, options);
   28808 #endif
   28809     pctxt->linenumbers = 1;
   28810     xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
   28811 
   28812     inputStream = xmlNewIOInputStream(pctxt, input, enc);;
   28813     if (inputStream == NULL) {
   28814         ret = -1;
   28815 	goto done;
   28816     }
   28817     inputPush(pctxt, inputStream);
   28818     ctxt->parserCtxt = pctxt;
   28819     ctxt->input = input;
   28820 
   28821     /*
   28822      * Plug the validation and launch the parsing
   28823      */
   28824     plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
   28825     if (plug == NULL) {
   28826         ret = -1;
   28827 	goto done;
   28828     }
   28829     ctxt->input = input;
   28830     ctxt->enc = enc;
   28831     ctxt->sax = pctxt->sax;
   28832     ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
   28833     ret = xmlSchemaVStart(ctxt);
   28834 
   28835     if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
   28836 	ret = ctxt->parserCtxt->errNo;
   28837 	if (ret == 0)
   28838 	    ret = 1;
   28839     }
   28840 
   28841 done:
   28842     ctxt->parserCtxt = NULL;
   28843     ctxt->sax = NULL;
   28844     ctxt->input = NULL;
   28845     if (plug != NULL) {
   28846         xmlSchemaSAXUnplug(plug);
   28847     }
   28848     /* cleanup */
   28849     if (pctxt != NULL) {
   28850 	pctxt->sax = old_sax;
   28851 	xmlFreeParserCtxt(pctxt);
   28852     }
   28853     return (ret);
   28854 }
   28855 
   28856 /**
   28857  * xmlSchemaValidateFile:
   28858  * @ctxt: a schema validation context
   28859  * @filename: the URI of the instance
   28860  * @options: a future set of options, currently unused
   28861  *
   28862  * Do a schemas validation of the given resource, it will use the
   28863  * SAX streamable validation internally.
   28864  *
   28865  * Returns 0 if the document is valid, a positive error code
   28866  *     number otherwise and -1 in case of an internal or API error.
   28867  */
   28868 int
   28869 xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
   28870                       const char * filename,
   28871 		      int options ATTRIBUTE_UNUSED)
   28872 {
   28873     int ret;
   28874     xmlParserInputBufferPtr input;
   28875 
   28876     if ((ctxt == NULL) || (filename == NULL))
   28877         return (-1);
   28878 
   28879     input = xmlParserInputBufferCreateFilename(filename,
   28880 	XML_CHAR_ENCODING_NONE);
   28881     if (input == NULL)
   28882 	return (-1);
   28883     ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
   28884 	NULL, NULL);
   28885     return (ret);
   28886 }
   28887 
   28888 /**
   28889  * xmlSchemaValidCtxtGetParserCtxt:
   28890  * @ctxt: a schema validation context
   28891  *
   28892  * allow access to the parser context of the schema validation context
   28893  *
   28894  * Returns the parser context of the schema validation context or NULL
   28895  *         in case of error.
   28896  */
   28897 xmlParserCtxtPtr
   28898 xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
   28899 {
   28900     if (ctxt == NULL)
   28901         return(NULL);
   28902     return (ctxt->parserCtxt);
   28903 }
   28904 
   28905 #define bottom_xmlschemas
   28906 #include "elfgcchack.h"
   28907 #endif /* LIBXML_SCHEMAS_ENABLED */
   28908