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;		/* dictionary 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) LIBXML_ATTR_FORMAT(3,0);
   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 (xmlEscapeFormatString(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 LIBXML_ATTR_FORMAT(4,0)
   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 LIBXML_ATTR_FORMAT(5,0)
   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 LIBXML_ATTR_FORMAT(7,0)
   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 LIBXML_ATTR_FORMAT(2,0)
   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  * xmlSchemaErr4Line:
   2017  * @ctxt: the validation context
   2018  * @errorLevel: the error level
   2019  * @error: the error code
   2020  * @node: the context node
   2021  * @line: the line number
   2022  * @msg: the error message
   2023  * @str1: extra data
   2024  * @str2: extra data
   2025  * @str3: extra data
   2026  * @str4: extra data
   2027  *
   2028  * Handle a validation error
   2029  */
   2030 static void LIBXML_ATTR_FORMAT(6,0)
   2031 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
   2032 		  xmlErrorLevel errorLevel,
   2033 		  int error, xmlNodePtr node, int line, const char *msg,
   2034 		  const xmlChar *str1, const xmlChar *str2,
   2035 		  const xmlChar *str3, const xmlChar *str4)
   2036 {
   2037     xmlStructuredErrorFunc schannel = NULL;
   2038     xmlGenericErrorFunc channel = NULL;
   2039     void *data = NULL;
   2040 
   2041     if (ctxt != NULL) {
   2042 	if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
   2043 	    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
   2044 	    const char *file = NULL;
   2045 	    int col = 0;
   2046 	    if (errorLevel != XML_ERR_WARNING) {
   2047 		vctxt->nberrors++;
   2048 		vctxt->err = error;
   2049 		channel = vctxt->error;
   2050 	    } else {
   2051 		channel = vctxt->warning;
   2052 	    }
   2053 	    schannel = vctxt->serror;
   2054 	    data = vctxt->errCtxt;
   2055 
   2056 	    /*
   2057 	    * Error node. If we specify a line number, then
   2058 	    * do not channel any node to the error function.
   2059 	    */
   2060 	    if (line == 0) {
   2061 		if ((node == NULL) &&
   2062 		    (vctxt->depth >= 0) &&
   2063 		    (vctxt->inode != NULL)) {
   2064 		    node = vctxt->inode->node;
   2065 		}
   2066 		/*
   2067 		* Get filename and line if no node-tree.
   2068 		*/
   2069 		if ((node == NULL) &&
   2070 		    (vctxt->parserCtxt != NULL) &&
   2071 		    (vctxt->parserCtxt->input != NULL)) {
   2072 		    file = vctxt->parserCtxt->input->filename;
   2073 		    line = vctxt->parserCtxt->input->line;
   2074 		    col = vctxt->parserCtxt->input->col;
   2075 		}
   2076 	    } else {
   2077 		/*
   2078 		* Override the given node's (if any) position
   2079 		* and channel only the given line number.
   2080 		*/
   2081 		node = NULL;
   2082 		/*
   2083 		* Get filename.
   2084 		*/
   2085 		if (vctxt->doc != NULL)
   2086 		    file = (const char *) vctxt->doc->URL;
   2087 		else if ((vctxt->parserCtxt != NULL) &&
   2088 		    (vctxt->parserCtxt->input != NULL))
   2089 		    file = vctxt->parserCtxt->input->filename;
   2090 	    }
   2091 	    if (vctxt->locFunc != NULL) {
   2092 	        if ((file == NULL) || (line == 0)) {
   2093 		    unsigned long l;
   2094 		    const char *f;
   2095 		    vctxt->locFunc(vctxt->locCtxt, &f, &l);
   2096 		    if (file == NULL)
   2097 		        file = f;
   2098 		    if (line == 0)
   2099 		        line = (int) l;
   2100 		}
   2101 	    }
   2102 	    if ((file == NULL) && (vctxt->filename != NULL))
   2103 	        file = vctxt->filename;
   2104 
   2105 	    __xmlRaiseError(schannel, channel, data, ctxt,
   2106 		node, XML_FROM_SCHEMASV,
   2107 		error, errorLevel, file, line,
   2108 		(const char *) str1, (const char *) str2,
   2109 		(const char *) str3, 0, col, msg, str1, str2, str3, str4);
   2110 
   2111 	} else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
   2112 	    xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
   2113 	    if (errorLevel != XML_ERR_WARNING) {
   2114 		pctxt->nberrors++;
   2115 		pctxt->err = error;
   2116 		channel = pctxt->error;
   2117 	    } else {
   2118 		channel = pctxt->warning;
   2119 	    }
   2120 	    schannel = pctxt->serror;
   2121 	    data = pctxt->errCtxt;
   2122 	    __xmlRaiseError(schannel, channel, data, ctxt,
   2123 		node, XML_FROM_SCHEMASP, error,
   2124 		errorLevel, NULL, 0,
   2125 		(const char *) str1, (const char *) str2,
   2126 		(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
   2127 	} else {
   2128 	    TODO
   2129 	}
   2130     }
   2131 }
   2132 
   2133 /**
   2134  * xmlSchemaErr3:
   2135  * @ctxt: the validation context
   2136  * @node: the context node
   2137  * @error: the error code
   2138  * @msg: the error message
   2139  * @str1: extra data
   2140  * @str2: extra data
   2141  * @str3: extra data
   2142  *
   2143  * Handle a validation error
   2144  */
   2145 static void LIBXML_ATTR_FORMAT(4,0)
   2146 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
   2147 	      int error, xmlNodePtr node, const char *msg,
   2148 	      const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
   2149 {
   2150     xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
   2151 	msg, str1, str2, str3, NULL);
   2152 }
   2153 
   2154 static void LIBXML_ATTR_FORMAT(4,0)
   2155 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
   2156 	      int error, xmlNodePtr node, const char *msg,
   2157 	      const xmlChar *str1, const xmlChar *str2,
   2158 	      const xmlChar *str3, const xmlChar *str4)
   2159 {
   2160     xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
   2161 	msg, str1, str2, str3, str4);
   2162 }
   2163 
   2164 static void LIBXML_ATTR_FORMAT(4,0)
   2165 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
   2166 	     int error, xmlNodePtr node, const char *msg,
   2167 	     const xmlChar *str1, const xmlChar *str2)
   2168 {
   2169     xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
   2170 }
   2171 
   2172 static xmlChar *
   2173 xmlSchemaFormatNodeForError(xmlChar ** msg,
   2174 			    xmlSchemaAbstractCtxtPtr actxt,
   2175 			    xmlNodePtr node)
   2176 {
   2177     xmlChar *str = NULL;
   2178 
   2179     *msg = NULL;
   2180     if ((node != NULL) &&
   2181 	(node->type != XML_ELEMENT_NODE) &&
   2182 	(node->type != XML_ATTRIBUTE_NODE))
   2183     {
   2184 	/*
   2185 	* Don't try to format other nodes than element and
   2186 	* attribute nodes.
   2187 	* Play safe and return an empty string.
   2188 	*/
   2189 	*msg = xmlStrdup(BAD_CAST "");
   2190 	return(*msg);
   2191     }
   2192     if (node != NULL) {
   2193 	/*
   2194 	* Work on tree nodes.
   2195 	*/
   2196 	if (node->type == XML_ATTRIBUTE_NODE) {
   2197 	    xmlNodePtr elem = node->parent;
   2198 
   2199 	    *msg = xmlStrdup(BAD_CAST "Element '");
   2200 	    if (elem->ns != NULL)
   2201 		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2202 		    elem->ns->href, elem->name));
   2203 	    else
   2204 		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2205 		    NULL, elem->name));
   2206 	    FREE_AND_NULL(str);
   2207 	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
   2208 	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
   2209 	} else {
   2210 	    *msg = xmlStrdup(BAD_CAST "Element '");
   2211 	}
   2212 	if (node->ns != NULL)
   2213 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2214 	    node->ns->href, node->name));
   2215 	else
   2216 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2217 	    NULL, node->name));
   2218 	FREE_AND_NULL(str);
   2219 	*msg = xmlStrcat(*msg, BAD_CAST "': ");
   2220     } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
   2221 	xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
   2222 	/*
   2223 	* Work on node infos.
   2224 	*/
   2225 	if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
   2226 	    xmlSchemaNodeInfoPtr ielem =
   2227 		vctxt->elemInfos[vctxt->depth];
   2228 
   2229 	    *msg = xmlStrdup(BAD_CAST "Element '");
   2230 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2231 		ielem->nsName, ielem->localName));
   2232 	    FREE_AND_NULL(str);
   2233 	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
   2234 	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
   2235 	} else {
   2236 	    *msg = xmlStrdup(BAD_CAST "Element '");
   2237 	}
   2238 	*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2239 	    vctxt->inode->nsName, vctxt->inode->localName));
   2240 	FREE_AND_NULL(str);
   2241 	*msg = xmlStrcat(*msg, BAD_CAST "': ");
   2242     } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
   2243 	/*
   2244 	* Hmm, no node while parsing?
   2245 	* Return an empty string, in case NULL will break something.
   2246 	*/
   2247 	*msg = xmlStrdup(BAD_CAST "");
   2248     } else {
   2249 	TODO
   2250 	return (NULL);
   2251     }
   2252 
   2253     /*
   2254      * xmlSchemaFormatItemForReport() also returns an escaped format
   2255      * string, so do this before calling it below (in the future).
   2256      */
   2257     xmlEscapeFormatString(msg);
   2258 
   2259     /*
   2260     * VAL TODO: The output of the given schema component is currently
   2261     * disabled.
   2262     */
   2263 #if 0
   2264     if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
   2265 	*msg = xmlStrcat(*msg, BAD_CAST " [");
   2266 	*msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
   2267 	    NULL, type, NULL, 0));
   2268 	FREE_AND_NULL(str)
   2269 	*msg = xmlStrcat(*msg, BAD_CAST "]");
   2270     }
   2271 #endif
   2272     return (*msg);
   2273 }
   2274 
   2275 static void LIBXML_ATTR_FORMAT(3,0)
   2276 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
   2277 		     const char *funcName,
   2278 		     const char *message,
   2279 		     const xmlChar *str1,
   2280 		     const xmlChar *str2)
   2281 {
   2282     xmlChar *msg = NULL;
   2283 
   2284     if (actxt == NULL)
   2285         return;
   2286     msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
   2287     msg = xmlStrcat(msg, BAD_CAST message);
   2288     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2289 
   2290     if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
   2291 	xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
   2292 	    (const char *) msg, (const xmlChar *) funcName, str1, str2);
   2293     else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
   2294 	xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
   2295 	    (const char *) msg, (const xmlChar *) funcName, str1, str2);
   2296 
   2297     FREE_AND_NULL(msg)
   2298 }
   2299 
   2300 static void LIBXML_ATTR_FORMAT(3,0)
   2301 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
   2302 		     const char *funcName,
   2303 		     const char *message)
   2304 {
   2305     xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
   2306 }
   2307 
   2308 #if 0
   2309 static void LIBXML_ATTR_FORMAT(3,0)
   2310 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
   2311 		     const char *funcName,
   2312 		     const char *message,
   2313 		     const xmlChar *str1,
   2314 		     const xmlChar *str2)
   2315 {
   2316     xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
   2317 	str1, str2);
   2318 }
   2319 #endif
   2320 
   2321 static void LIBXML_ATTR_FORMAT(5,0)
   2322 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
   2323 		   xmlParserErrors error,
   2324 		   xmlNodePtr node,
   2325 		   xmlSchemaBasicItemPtr item,
   2326 		   const char *message,
   2327 		   const xmlChar *str1, const xmlChar *str2,
   2328 		   const xmlChar *str3, const xmlChar *str4)
   2329 {
   2330     xmlChar *msg = NULL;
   2331 
   2332     if ((node == NULL) && (item != NULL) &&
   2333 	(actxt->type == XML_SCHEMA_CTXT_PARSER)) {
   2334 	node = WXS_ITEM_NODE(item);
   2335 	xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
   2336 	msg = xmlStrcat(msg, BAD_CAST ": ");
   2337     } else
   2338 	xmlSchemaFormatNodeForError(&msg, actxt, node);
   2339     msg = xmlStrcat(msg, (const xmlChar *) message);
   2340     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2341     xmlSchemaErr4(actxt, error, node,
   2342 	(const char *) msg, str1, str2, str3, str4);
   2343     FREE_AND_NULL(msg)
   2344 }
   2345 
   2346 static void LIBXML_ATTR_FORMAT(5,0)
   2347 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
   2348 		   xmlParserErrors error,
   2349 		   xmlNodePtr node,
   2350 		   xmlSchemaBasicItemPtr item,
   2351 		   const char *message,
   2352 		   const xmlChar *str1,
   2353 		   const xmlChar *str2)
   2354 {
   2355     xmlSchemaCustomErr4(actxt, error, node, item,
   2356 	message, str1, str2, NULL, NULL);
   2357 }
   2358 
   2359 
   2360 
   2361 static void LIBXML_ATTR_FORMAT(5,0)
   2362 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
   2363 		   xmlParserErrors error,
   2364 		   xmlNodePtr node,
   2365 		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
   2366 		   const char *message,
   2367 		   const xmlChar *str1,
   2368 		   const xmlChar *str2,
   2369 		   const xmlChar *str3)
   2370 {
   2371     xmlChar *msg = NULL;
   2372 
   2373     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2374     msg = xmlStrcat(msg, (const xmlChar *) message);
   2375     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2376 
   2377     /* URGENT TODO: Set the error code to something sane. */
   2378     xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
   2379 	(const char *) msg, str1, str2, str3, NULL);
   2380 
   2381     FREE_AND_NULL(msg)
   2382 }
   2383 
   2384 
   2385 
   2386 static void LIBXML_ATTR_FORMAT(5,0)
   2387 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
   2388 		   xmlParserErrors error,
   2389 		   xmlSchemaPSVIIDCNodePtr idcNode,
   2390 		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
   2391 		   const char *message,
   2392 		   const xmlChar *str1,
   2393 		   const xmlChar *str2)
   2394 {
   2395     xmlChar *msg = NULL, *qname = NULL;
   2396 
   2397     msg = xmlStrdup(BAD_CAST "Element '%s': ");
   2398     msg = xmlStrcat(msg, (const xmlChar *) message);
   2399     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2400     xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
   2401 	error, NULL, idcNode->nodeLine, (const char *) msg,
   2402 	xmlSchemaFormatQName(&qname,
   2403 	    vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
   2404 	    vctxt->nodeQNames->items[idcNode->nodeQNameID]),
   2405 	str1, str2, NULL);
   2406     FREE_AND_NULL(qname);
   2407     FREE_AND_NULL(msg);
   2408 }
   2409 
   2410 static int
   2411 xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
   2412 			   xmlNodePtr node)
   2413 {
   2414     if (node != NULL)
   2415 	return (node->type);
   2416     if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
   2417 	(((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
   2418 	return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
   2419     return (-1);
   2420 }
   2421 
   2422 static int
   2423 xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
   2424 {
   2425     switch (item->type) {
   2426 	case XML_SCHEMA_TYPE_COMPLEX:
   2427 	case XML_SCHEMA_TYPE_SIMPLE:
   2428 	    if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
   2429 		return(1);
   2430 	    break;
   2431 	case XML_SCHEMA_TYPE_GROUP:
   2432 	    return (1);
   2433 	case XML_SCHEMA_TYPE_ELEMENT:
   2434 	    if ( ((xmlSchemaElementPtr) item)->flags &
   2435 		XML_SCHEMAS_ELEM_GLOBAL)
   2436 		return(1);
   2437 	    break;
   2438 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   2439 	    if ( ((xmlSchemaAttributePtr) item)->flags &
   2440 		XML_SCHEMAS_ATTR_GLOBAL)
   2441 		return(1);
   2442 	    break;
   2443 	/* Note that attribute groups are always global. */
   2444 	default:
   2445 	    return(1);
   2446     }
   2447     return (0);
   2448 }
   2449 
   2450 static void
   2451 xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
   2452 		       xmlParserErrors error,
   2453 		       xmlNodePtr node,
   2454 		       const xmlChar *value,
   2455 		       xmlSchemaTypePtr type,
   2456 		       int displayValue)
   2457 {
   2458     xmlChar *msg = NULL;
   2459 
   2460     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2461 
   2462     if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
   2463 	    XML_ATTRIBUTE_NODE))
   2464 	msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
   2465     else
   2466 	msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
   2467 	    "value of ");
   2468 
   2469     if (! xmlSchemaIsGlobalItem(type))
   2470 	msg = xmlStrcat(msg, BAD_CAST "the local ");
   2471     else
   2472 	msg = xmlStrcat(msg, BAD_CAST "the ");
   2473 
   2474     if (WXS_IS_ATOMIC(type))
   2475 	msg = xmlStrcat(msg, BAD_CAST "atomic type");
   2476     else if (WXS_IS_LIST(type))
   2477 	msg = xmlStrcat(msg, BAD_CAST "list type");
   2478     else if (WXS_IS_UNION(type))
   2479 	msg = xmlStrcat(msg, BAD_CAST "union type");
   2480 
   2481     if (xmlSchemaIsGlobalItem(type)) {
   2482 	xmlChar *str = NULL;
   2483 	msg = xmlStrcat(msg, BAD_CAST " '");
   2484 	if (type->builtInType != 0) {
   2485 	    msg = xmlStrcat(msg, BAD_CAST "xs:");
   2486 	    str = xmlStrdup(type->name);
   2487 	} else {
   2488 	    const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
   2489 	    if (!str)
   2490 		str = xmlStrdup(qName);
   2491 	}
   2492 	msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
   2493 	msg = xmlStrcat(msg, BAD_CAST "'");
   2494 	FREE_AND_NULL(str);
   2495     }
   2496     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2497     if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
   2498 	    XML_ATTRIBUTE_NODE))
   2499 	xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
   2500     else
   2501 	xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
   2502     FREE_AND_NULL(msg)
   2503 }
   2504 
   2505 static const xmlChar *
   2506 xmlSchemaFormatErrorNodeQName(xmlChar ** str,
   2507 			      xmlSchemaNodeInfoPtr ni,
   2508 			      xmlNodePtr node)
   2509 {
   2510     if (node != NULL) {
   2511 	if (node->ns != NULL)
   2512 	    return (xmlSchemaFormatQName(str, node->ns->href, node->name));
   2513 	else
   2514 	    return (xmlSchemaFormatQName(str, NULL, node->name));
   2515     } else if (ni != NULL)
   2516 	return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
   2517     return (NULL);
   2518 }
   2519 
   2520 static void
   2521 xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
   2522 			xmlParserErrors error,
   2523 			xmlSchemaAttrInfoPtr ni,
   2524 			xmlNodePtr node)
   2525 {
   2526     xmlChar *msg = NULL, *str = NULL;
   2527 
   2528     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2529     msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
   2530     xmlSchemaErr(actxt, error, node, (const char *) msg,
   2531 	xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
   2532 	NULL);
   2533     FREE_AND_NULL(str)
   2534     FREE_AND_NULL(msg)
   2535 }
   2536 
   2537 static void LIBXML_ATTR_FORMAT(5,0)
   2538 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
   2539 		        xmlParserErrors error,
   2540 		        xmlNodePtr node,
   2541 			xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
   2542 			const char *message,
   2543 			int nbval,
   2544 			int nbneg,
   2545 			xmlChar **values)
   2546 {
   2547     xmlChar *str = NULL, *msg = NULL;
   2548     xmlChar *localName, *nsName;
   2549     const xmlChar *cur, *end;
   2550     int i;
   2551 
   2552     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2553     msg = xmlStrcat(msg, (const xmlChar *) message);
   2554     msg = xmlStrcat(msg, BAD_CAST ".");
   2555     /*
   2556     * Note that is does not make sense to report that we have a
   2557     * wildcard here, since the wildcard might be unfolded into
   2558     * multiple transitions.
   2559     */
   2560     if (nbval + nbneg > 0) {
   2561 	if (nbval + nbneg > 1) {
   2562 	    str = xmlStrdup(BAD_CAST " Expected is one of ( ");
   2563 	} else
   2564 	    str = xmlStrdup(BAD_CAST " Expected is ( ");
   2565 	nsName = NULL;
   2566 
   2567 	for (i = 0; i < nbval + nbneg; i++) {
   2568 	    cur = values[i];
   2569 	    if (cur == NULL)
   2570 	        continue;
   2571 	    if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
   2572 	        (cur[3] == ' ')) {
   2573 		cur += 4;
   2574 		str = xmlStrcat(str, BAD_CAST "##other");
   2575 	    }
   2576 	    /*
   2577 	    * Get the local name.
   2578 	    */
   2579 	    localName = NULL;
   2580 
   2581 	    end = cur;
   2582 	    if (*end == '*') {
   2583 		localName = xmlStrdup(BAD_CAST "*");
   2584 		end++;
   2585 	    } else {
   2586 		while ((*end != 0) && (*end != '|'))
   2587 		    end++;
   2588 		localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
   2589 	    }
   2590 	    if (*end != 0) {
   2591 		end++;
   2592 		/*
   2593 		* Skip "*|*" if they come with negated expressions, since
   2594 		* they represent the same negated wildcard.
   2595 		*/
   2596 		if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
   2597 		    /*
   2598 		    * Get the namespace name.
   2599 		    */
   2600 		    cur = end;
   2601 		    if (*end == '*') {
   2602 			nsName = xmlStrdup(BAD_CAST "{*}");
   2603 		    } else {
   2604 			while (*end != 0)
   2605 			    end++;
   2606 
   2607 			if (i >= nbval)
   2608 			    nsName = xmlStrdup(BAD_CAST "{##other:");
   2609 			else
   2610 			    nsName = xmlStrdup(BAD_CAST "{");
   2611 
   2612 			nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
   2613 			nsName = xmlStrcat(nsName, BAD_CAST "}");
   2614 		    }
   2615 		    str = xmlStrcat(str, BAD_CAST nsName);
   2616 		    FREE_AND_NULL(nsName)
   2617 		} else {
   2618 		    FREE_AND_NULL(localName);
   2619 		    continue;
   2620 		}
   2621 	    }
   2622 	    str = xmlStrcat(str, BAD_CAST localName);
   2623 	    FREE_AND_NULL(localName);
   2624 
   2625 	    if (i < nbval + nbneg -1)
   2626 		str = xmlStrcat(str, BAD_CAST ", ");
   2627 	}
   2628 	str = xmlStrcat(str, BAD_CAST " ).\n");
   2629 	msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
   2630 	FREE_AND_NULL(str)
   2631     } else
   2632       msg = xmlStrcat(msg, BAD_CAST "\n");
   2633     xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
   2634     xmlFree(msg);
   2635 }
   2636 
   2637 static void LIBXML_ATTR_FORMAT(8,0)
   2638 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
   2639 		  xmlParserErrors error,
   2640 		  xmlNodePtr node,
   2641 		  const xmlChar *value,
   2642 		  unsigned long length,
   2643 		  xmlSchemaTypePtr type,
   2644 		  xmlSchemaFacetPtr facet,
   2645 		  const char *message,
   2646 		  const xmlChar *str1,
   2647 		  const xmlChar *str2)
   2648 {
   2649     xmlChar *str = NULL, *msg = NULL;
   2650     xmlSchemaTypeType facetType;
   2651     int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
   2652 
   2653     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2654     if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
   2655 	facetType = XML_SCHEMA_FACET_ENUMERATION;
   2656 	/*
   2657 	* If enumerations are validated, one must not expect the
   2658 	* facet to be given.
   2659 	*/
   2660     } else
   2661 	facetType = facet->type;
   2662     msg = xmlStrcat(msg, BAD_CAST "[");
   2663     msg = xmlStrcat(msg, BAD_CAST "facet '");
   2664     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
   2665     msg = xmlStrcat(msg, BAD_CAST "'] ");
   2666     if (message == NULL) {
   2667 	/*
   2668 	* Use a default message.
   2669 	*/
   2670 	if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
   2671 	    (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
   2672 	    (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
   2673 
   2674 	    char len[25], actLen[25];
   2675 
   2676 	    /* FIXME, TODO: What is the max expected string length of the
   2677 	    * this value?
   2678 	    */
   2679 	    if (nodeType == XML_ATTRIBUTE_NODE)
   2680 		msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
   2681 	    else
   2682 		msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
   2683 
   2684 	    snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
   2685 	    snprintf(actLen, 24, "%lu", length);
   2686 
   2687 	    if (facetType == XML_SCHEMA_FACET_LENGTH)
   2688 		msg = xmlStrcat(msg,
   2689 		BAD_CAST "this differs from the allowed length of '%s'.\n");
   2690 	    else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
   2691 		msg = xmlStrcat(msg,
   2692 		BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
   2693 	    else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
   2694 		msg = xmlStrcat(msg,
   2695 		BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
   2696 
   2697 	    if (nodeType == XML_ATTRIBUTE_NODE)
   2698 		xmlSchemaErr3(actxt, error, node, (const char *) msg,
   2699 		    value, (const xmlChar *) actLen, (const xmlChar *) len);
   2700 	    else
   2701 		xmlSchemaErr(actxt, error, node, (const char *) msg,
   2702 		    (const xmlChar *) actLen, (const xmlChar *) len);
   2703 
   2704 	} else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
   2705 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
   2706 		"of the set {%s}.\n");
   2707 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2708 		xmlSchemaFormatFacetEnumSet(actxt, &str, type));
   2709 	} else if (facetType == XML_SCHEMA_FACET_PATTERN) {
   2710 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
   2711 		"by the pattern '%s'.\n");
   2712 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2713 		facet->value);
   2714 	} else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
   2715 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
   2716 		"minimum value allowed ('%s').\n");
   2717 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2718 		facet->value);
   2719 	} else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
   2720 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
   2721 		"maximum value allowed ('%s').\n");
   2722 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2723 		facet->value);
   2724 	} else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
   2725 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
   2726 		"'%s'.\n");
   2727 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2728 		facet->value);
   2729 	} else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
   2730 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
   2731 		"'%s'.\n");
   2732 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2733 		facet->value);
   2734 	} else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
   2735 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
   2736 		"digits than are allowed ('%s').\n");
   2737 	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
   2738 		facet->value);
   2739 	} else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
   2740 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
   2741 		"digits than are allowed ('%s').\n");
   2742 	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
   2743 		facet->value);
   2744 	} else if (nodeType == XML_ATTRIBUTE_NODE) {
   2745 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
   2746 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
   2747 	} else {
   2748 	    msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
   2749 	    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
   2750 	}
   2751     } else {
   2752 	msg = xmlStrcat(msg, (const xmlChar *) message);
   2753 	msg = xmlStrcat(msg, BAD_CAST ".\n");
   2754 	xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
   2755     }
   2756     FREE_AND_NULL(str)
   2757     xmlFree(msg);
   2758 }
   2759 
   2760 #define VERROR(err, type, msg) \
   2761     xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
   2762 
   2763 #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
   2764 
   2765 #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
   2766 #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
   2767 
   2768 #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
   2769 
   2770 
   2771 /**
   2772  * xmlSchemaPMissingAttrErr:
   2773  * @ctxt: the schema validation context
   2774  * @ownerDes: the designation of  the owner
   2775  * @ownerName: the name of the owner
   2776  * @ownerItem: the owner as a schema object
   2777  * @ownerElem: the owner as an element node
   2778  * @node: the parent element node of the missing attribute node
   2779  * @type: the corresponding type of the attribute node
   2780  *
   2781  * Reports an illegal attribute.
   2782  */
   2783 static void
   2784 xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
   2785 			 xmlParserErrors error,
   2786 			 xmlSchemaBasicItemPtr ownerItem,
   2787 			 xmlNodePtr ownerElem,
   2788 			 const char *name,
   2789 			 const char *message)
   2790 {
   2791     xmlChar *des = NULL;
   2792 
   2793     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
   2794 
   2795     if (message != NULL)
   2796 	xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
   2797     else
   2798 	xmlSchemaPErr(ctxt, ownerElem, error,
   2799 	    "%s: The attribute '%s' is required but missing.\n",
   2800 	    BAD_CAST des, BAD_CAST name);
   2801     FREE_AND_NULL(des);
   2802 }
   2803 
   2804 
   2805 /**
   2806  * xmlSchemaPResCompAttrErr:
   2807  * @ctxt: the schema validation context
   2808  * @error: the error code
   2809  * @ownerDes: the designation of  the owner
   2810  * @ownerItem: the owner as a schema object
   2811  * @ownerElem: the owner as an element node
   2812  * @name: the name of the attribute holding the QName
   2813  * @refName: the referenced local name
   2814  * @refURI: the referenced namespace URI
   2815  * @message: optional message
   2816  *
   2817  * Used to report QName attribute values that failed to resolve
   2818  * to schema components.
   2819  */
   2820 static void
   2821 xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
   2822 			 xmlParserErrors error,
   2823 			 xmlSchemaBasicItemPtr ownerItem,
   2824 			 xmlNodePtr ownerElem,
   2825 			 const char *name,
   2826 			 const xmlChar *refName,
   2827 			 const xmlChar *refURI,
   2828 			 xmlSchemaTypeType refType,
   2829 			 const char *refTypeStr)
   2830 {
   2831     xmlChar *des = NULL, *strA = NULL;
   2832 
   2833     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
   2834     if (refTypeStr == NULL)
   2835 	refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
   2836 	xmlSchemaPErrExt(ctxt, ownerElem, error,
   2837 	    NULL, NULL, NULL,
   2838 	    "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
   2839 	    "%s.\n", BAD_CAST des, BAD_CAST name,
   2840 	    xmlSchemaFormatQName(&strA, refURI, refName),
   2841 	    BAD_CAST refTypeStr, NULL);
   2842     FREE_AND_NULL(des)
   2843     FREE_AND_NULL(strA)
   2844 }
   2845 
   2846 /**
   2847  * xmlSchemaPCustomAttrErr:
   2848  * @ctxt: the schema parser context
   2849  * @error: the error code
   2850  * @ownerDes: the designation of the owner
   2851  * @ownerItem: the owner as a schema object
   2852  * @attr: the illegal attribute node
   2853  *
   2854  * Reports an illegal attribute during the parse.
   2855  */
   2856 static void
   2857 xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
   2858 			xmlParserErrors error,
   2859 			xmlChar **ownerDes,
   2860 			xmlSchemaBasicItemPtr ownerItem,
   2861 			xmlAttrPtr attr,
   2862 			const char *msg)
   2863 {
   2864     xmlChar *des = NULL;
   2865 
   2866     if (ownerDes == NULL)
   2867 	xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
   2868     else if (*ownerDes == NULL) {
   2869 	xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
   2870 	des = *ownerDes;
   2871     } else
   2872 	des = *ownerDes;
   2873     if (attr == NULL) {
   2874 	xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
   2875 	    "%s, attribute '%s': %s.\n",
   2876 	    BAD_CAST des, (const xmlChar *) "Unknown",
   2877 	    (const xmlChar *) msg, NULL, NULL);
   2878     } else {
   2879 	xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
   2880 	    "%s, attribute '%s': %s.\n",
   2881 	    BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
   2882     }
   2883     if (ownerDes == NULL)
   2884 	FREE_AND_NULL(des);
   2885 }
   2886 
   2887 /**
   2888  * xmlSchemaPIllegalAttrErr:
   2889  * @ctxt: the schema parser context
   2890  * @error: the error code
   2891  * @ownerDes: the designation of the attribute's owner
   2892  * @ownerItem: the attribute's owner item
   2893  * @attr: the illegal attribute node
   2894  *
   2895  * Reports an illegal attribute during the parse.
   2896  */
   2897 static void
   2898 xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
   2899 			 xmlParserErrors error,
   2900 			 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
   2901 			 xmlAttrPtr attr)
   2902 {
   2903     xmlChar *strA = NULL, *strB = NULL;
   2904 
   2905     xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
   2906     xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
   2907 	"%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
   2908 	xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
   2909 	NULL, NULL);
   2910     FREE_AND_NULL(strA);
   2911     FREE_AND_NULL(strB);
   2912 }
   2913 
   2914 /**
   2915  * xmlSchemaPCustomErr:
   2916  * @ctxt: the schema parser context
   2917  * @error: the error code
   2918  * @itemDes: the designation of the schema item
   2919  * @item: the schema item
   2920  * @itemElem: the node of the schema item
   2921  * @message: the error message
   2922  * @str1: an optional param for the error message
   2923  * @str2: an optional param for the error message
   2924  * @str3: an optional param for the error message
   2925  *
   2926  * Reports an error during parsing.
   2927  */
   2928 static void LIBXML_ATTR_FORMAT(5,0)
   2929 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
   2930 		    xmlParserErrors error,
   2931 		    xmlSchemaBasicItemPtr item,
   2932 		    xmlNodePtr itemElem,
   2933 		    const char *message,
   2934 		    const xmlChar *str1,
   2935 		    const xmlChar *str2,
   2936 		    const xmlChar *str3)
   2937 {
   2938     xmlChar *des = NULL, *msg = NULL;
   2939 
   2940     xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
   2941     msg = xmlStrdup(BAD_CAST "%s: ");
   2942     msg = xmlStrcat(msg, (const xmlChar *) message);
   2943     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2944     if ((itemElem == NULL) && (item != NULL))
   2945 	itemElem = WXS_ITEM_NODE(item);
   2946     xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
   2947 	(const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
   2948     FREE_AND_NULL(des);
   2949     FREE_AND_NULL(msg);
   2950 }
   2951 
   2952 /**
   2953  * xmlSchemaPCustomErr:
   2954  * @ctxt: the schema parser context
   2955  * @error: the error code
   2956  * @itemDes: the designation of the schema item
   2957  * @item: the schema item
   2958  * @itemElem: the node of the schema item
   2959  * @message: the error message
   2960  * @str1: the optional param for the error message
   2961  *
   2962  * Reports an error during parsing.
   2963  */
   2964 static void LIBXML_ATTR_FORMAT(5,0)
   2965 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
   2966 		    xmlParserErrors error,
   2967 		    xmlSchemaBasicItemPtr item,
   2968 		    xmlNodePtr itemElem,
   2969 		    const char *message,
   2970 		    const xmlChar *str1)
   2971 {
   2972     xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
   2973 	str1, NULL, NULL);
   2974 }
   2975 
   2976 /**
   2977  * xmlSchemaPAttrUseErr:
   2978  * @ctxt: the schema parser context
   2979  * @error: the error code
   2980  * @itemDes: the designation of the schema type
   2981  * @item: the schema type
   2982  * @itemElem: the node of the schema type
   2983  * @attr: the invalid schema attribute
   2984  * @message: the error message
   2985  * @str1: the optional param for the error message
   2986  *
   2987  * Reports an attribute use error during parsing.
   2988  */
   2989 static void LIBXML_ATTR_FORMAT(6,0)
   2990 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
   2991 		    xmlParserErrors error,
   2992 		    xmlNodePtr node,
   2993 		    xmlSchemaBasicItemPtr ownerItem,
   2994 		    const xmlSchemaAttributeUsePtr attruse,
   2995 		    const char *message,
   2996 		    const xmlChar *str1, const xmlChar *str2,
   2997 		    const xmlChar *str3,const xmlChar *str4)
   2998 {
   2999     xmlChar *str = NULL, *msg = NULL;
   3000 
   3001     xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
   3002     msg = xmlStrcat(msg, BAD_CAST ", ");
   3003     msg = xmlStrcat(msg,
   3004 	BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
   3005 	WXS_BASIC_CAST attruse, NULL));
   3006     FREE_AND_NULL(str);
   3007     msg = xmlStrcat(msg, BAD_CAST ": ");
   3008     msg = xmlStrcat(msg, (const xmlChar *) message);
   3009     msg = xmlStrcat(msg, BAD_CAST ".\n");
   3010     xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
   3011 	(const char *) msg, str1, str2, str3, str4);
   3012     xmlFree(msg);
   3013 }
   3014 
   3015 /**
   3016  * xmlSchemaPIllegalFacetAtomicErr:
   3017  * @ctxt: the schema parser context
   3018  * @error: the error code
   3019  * @type: the schema type
   3020  * @baseType: the base type of type
   3021  * @facet: the illegal facet
   3022  *
   3023  * Reports an illegal facet for atomic simple types.
   3024  */
   3025 static void
   3026 xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
   3027 			  xmlParserErrors error,
   3028 			  xmlSchemaTypePtr type,
   3029 			  xmlSchemaTypePtr baseType,
   3030 			  xmlSchemaFacetPtr facet)
   3031 {
   3032     xmlChar *des = NULL, *strT = NULL;
   3033 
   3034     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
   3035     xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
   3036 	"%s: The facet '%s' is not allowed on types derived from the "
   3037 	"type %s.\n",
   3038 	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
   3039 	xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
   3040 	NULL, NULL);
   3041     FREE_AND_NULL(des);
   3042     FREE_AND_NULL(strT);
   3043 }
   3044 
   3045 /**
   3046  * xmlSchemaPIllegalFacetListUnionErr:
   3047  * @ctxt: the schema parser context
   3048  * @error: the error code
   3049  * @itemDes: the designation of the schema item involved
   3050  * @item: the schema item involved
   3051  * @facet: the illegal facet
   3052  *
   3053  * Reports an illegal facet for <list> and <union>.
   3054  */
   3055 static void
   3056 xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
   3057 			  xmlParserErrors error,
   3058 			  xmlSchemaTypePtr type,
   3059 			  xmlSchemaFacetPtr facet)
   3060 {
   3061     xmlChar *des = NULL;
   3062 
   3063     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
   3064 	type->node);
   3065     xmlSchemaPErr(ctxt, type->node, error,
   3066 	"%s: The facet '%s' is not allowed.\n",
   3067 	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
   3068     FREE_AND_NULL(des);
   3069 }
   3070 
   3071 /**
   3072  * xmlSchemaPMutualExclAttrErr:
   3073  * @ctxt: the schema validation context
   3074  * @error: the error code
   3075  * @elemDes: the designation of the parent element node
   3076  * @attr: the bad attribute node
   3077  * @type: the corresponding type of the attribute node
   3078  *
   3079  * Reports an illegal attribute.
   3080  */
   3081 static void
   3082 xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
   3083 			 xmlParserErrors error,
   3084 			 xmlSchemaBasicItemPtr ownerItem,
   3085 			 xmlAttrPtr attr,
   3086 			 const char *name1,
   3087 			 const char *name2)
   3088 {
   3089     xmlChar *des = NULL;
   3090 
   3091     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
   3092     xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
   3093 	"%s: The attributes '%s' and '%s' are mutually exclusive.\n",
   3094 	BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
   3095     FREE_AND_NULL(des);
   3096 }
   3097 
   3098 /**
   3099  * xmlSchemaPSimpleTypeErr:
   3100  * @ctxt:  the schema validation context
   3101  * @error: the error code
   3102  * @type: the type specifier
   3103  * @ownerDes: the designation of the owner
   3104  * @ownerItem: the schema object if existent
   3105  * @node: the validated node
   3106  * @value: the validated value
   3107  *
   3108  * Reports a simple type validation error.
   3109  * TODO: Should this report the value of an element as well?
   3110  */
   3111 static void LIBXML_ATTR_FORMAT(8,0)
   3112 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
   3113 			xmlParserErrors error,
   3114 			xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
   3115 			xmlNodePtr node,
   3116 			xmlSchemaTypePtr type,
   3117 			const char *expected,
   3118 			const xmlChar *value,
   3119 			const char *message,
   3120 			const xmlChar *str1,
   3121 			const xmlChar *str2)
   3122 {
   3123     xmlChar *msg = NULL;
   3124 
   3125     xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
   3126     if (message == NULL) {
   3127 	/*
   3128 	* Use default messages.
   3129 	*/
   3130 	if (type != NULL) {
   3131 	    if (node->type == XML_ATTRIBUTE_NODE)
   3132 		msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
   3133 	    else
   3134 		msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
   3135 		"valid value of ");
   3136 	    if (! xmlSchemaIsGlobalItem(type))
   3137 		msg = xmlStrcat(msg, BAD_CAST "the local ");
   3138 	    else
   3139 		msg = xmlStrcat(msg, BAD_CAST "the ");
   3140 
   3141 	    if (WXS_IS_ATOMIC(type))
   3142 		msg = xmlStrcat(msg, BAD_CAST "atomic type");
   3143 	    else if (WXS_IS_LIST(type))
   3144 		msg = xmlStrcat(msg, BAD_CAST "list type");
   3145 	    else if (WXS_IS_UNION(type))
   3146 		msg = xmlStrcat(msg, BAD_CAST "union type");
   3147 
   3148 	    if (xmlSchemaIsGlobalItem(type)) {
   3149 		xmlChar *str = NULL;
   3150 		msg = xmlStrcat(msg, BAD_CAST " '");
   3151 		if (type->builtInType != 0) {
   3152 		    msg = xmlStrcat(msg, BAD_CAST "xs:");
   3153 		    str = xmlStrdup(type->name);
   3154 		} else {
   3155 		    const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
   3156 		    if (!str)
   3157 			str = xmlStrdup(qName);
   3158 		}
   3159 		msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
   3160 		msg = xmlStrcat(msg, BAD_CAST "'.");
   3161 		FREE_AND_NULL(str);
   3162 	    }
   3163 	} else {
   3164 	    if (node->type == XML_ATTRIBUTE_NODE)
   3165 		msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
   3166 	    else
   3167 		msg = xmlStrcat(msg, BAD_CAST "The character content is not "
   3168 		"valid.");
   3169 	}
   3170 	if (expected) {
   3171 	    xmlChar *expectedEscaped = xmlCharStrdup(expected);
   3172 	    msg = xmlStrcat(msg, BAD_CAST " Expected is '");
   3173 	    msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
   3174 	    FREE_AND_NULL(expectedEscaped);
   3175 	    msg = xmlStrcat(msg, BAD_CAST "'.\n");
   3176 	} else
   3177 	    msg = xmlStrcat(msg, BAD_CAST "\n");
   3178 	if (node->type == XML_ATTRIBUTE_NODE)
   3179 	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
   3180 	else
   3181 	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
   3182     } else {
   3183 	msg = xmlStrcat(msg, BAD_CAST message);
   3184 	msg = xmlStrcat(msg, BAD_CAST ".\n");
   3185 	xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
   3186 	     (const char*) msg, str1, str2, NULL, NULL, NULL);
   3187     }
   3188     /* Cleanup. */
   3189     FREE_AND_NULL(msg)
   3190 }
   3191 
   3192 /**
   3193  * xmlSchemaPContentErr:
   3194  * @ctxt: the schema parser context
   3195  * @error: the error code
   3196  * @onwerDes: the designation of the holder of the content
   3197  * @ownerItem: the owner item of the holder of the content
   3198  * @ownerElem: the node of the holder of the content
   3199  * @child: the invalid child node
   3200  * @message: the optional error message
   3201  * @content: the optional string describing the correct content
   3202  *
   3203  * Reports an error concerning the content of a schema element.
   3204  */
   3205 static void
   3206 xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
   3207 		     xmlParserErrors error,
   3208 		     xmlSchemaBasicItemPtr ownerItem,
   3209 		     xmlNodePtr ownerElem,
   3210 		     xmlNodePtr child,
   3211 		     const char *message,
   3212 		     const char *content)
   3213 {
   3214     xmlChar *des = NULL;
   3215 
   3216     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
   3217     if (message != NULL)
   3218 	xmlSchemaPErr2(ctxt, ownerElem, child, error,
   3219 	    "%s: %s.\n",
   3220 	    BAD_CAST des, BAD_CAST message);
   3221     else {
   3222 	if (content != NULL) {
   3223 	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
   3224 		"%s: The content is not valid. Expected is %s.\n",
   3225 		BAD_CAST des, BAD_CAST content);
   3226 	} else {
   3227 	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
   3228 		"%s: The content is not valid.\n",
   3229 		BAD_CAST des, NULL);
   3230 	}
   3231     }
   3232     FREE_AND_NULL(des)
   3233 }
   3234 
   3235 /************************************************************************
   3236  *									*
   3237  *			Streamable error functions                      *
   3238  *									*
   3239  ************************************************************************/
   3240 
   3241 
   3242 
   3243 
   3244 /************************************************************************
   3245  *									*
   3246  *			Validation helper functions			*
   3247  *									*
   3248  ************************************************************************/
   3249 
   3250 
   3251 /************************************************************************
   3252  *									*
   3253  *			Allocation functions				*
   3254  *									*
   3255  ************************************************************************/
   3256 
   3257 /**
   3258  * xmlSchemaNewSchemaForParserCtxt:
   3259  * @ctxt:  a schema validation context
   3260  *
   3261  * Allocate a new Schema structure.
   3262  *
   3263  * Returns the newly allocated structure or NULL in case or error
   3264  */
   3265 static xmlSchemaPtr
   3266 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
   3267 {
   3268     xmlSchemaPtr ret;
   3269 
   3270     ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
   3271     if (ret == NULL) {
   3272         xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
   3273         return (NULL);
   3274     }
   3275     memset(ret, 0, sizeof(xmlSchema));
   3276     ret->dict = ctxt->dict;
   3277     xmlDictReference(ret->dict);
   3278 
   3279     return (ret);
   3280 }
   3281 
   3282 /**
   3283  * xmlSchemaNewFacet:
   3284  *
   3285  * Allocate a new Facet structure.
   3286  *
   3287  * Returns the newly allocated structure or NULL in case or error
   3288  */
   3289 xmlSchemaFacetPtr
   3290 xmlSchemaNewFacet(void)
   3291 {
   3292     xmlSchemaFacetPtr ret;
   3293 
   3294     ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
   3295     if (ret == NULL) {
   3296         return (NULL);
   3297     }
   3298     memset(ret, 0, sizeof(xmlSchemaFacet));
   3299 
   3300     return (ret);
   3301 }
   3302 
   3303 /**
   3304  * xmlSchemaNewAnnot:
   3305  * @ctxt:  a schema validation context
   3306  * @node:  a node
   3307  *
   3308  * Allocate a new annotation structure.
   3309  *
   3310  * Returns the newly allocated structure or NULL in case or error
   3311  */
   3312 static xmlSchemaAnnotPtr
   3313 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
   3314 {
   3315     xmlSchemaAnnotPtr ret;
   3316 
   3317     ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
   3318     if (ret == NULL) {
   3319         xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
   3320         return (NULL);
   3321     }
   3322     memset(ret, 0, sizeof(xmlSchemaAnnot));
   3323     ret->content = node;
   3324     return (ret);
   3325 }
   3326 
   3327 static xmlSchemaItemListPtr
   3328 xmlSchemaItemListCreate(void)
   3329 {
   3330     xmlSchemaItemListPtr ret;
   3331 
   3332     ret = xmlMalloc(sizeof(xmlSchemaItemList));
   3333     if (ret == NULL) {
   3334 	xmlSchemaPErrMemory(NULL,
   3335 	    "allocating an item list structure", NULL);
   3336 	return (NULL);
   3337     }
   3338     memset(ret, 0, sizeof(xmlSchemaItemList));
   3339     return (ret);
   3340 }
   3341 
   3342 static void
   3343 xmlSchemaItemListClear(xmlSchemaItemListPtr list)
   3344 {
   3345     if (list->items != NULL) {
   3346 	xmlFree(list->items);
   3347 	list->items = NULL;
   3348     }
   3349     list->nbItems = 0;
   3350     list->sizeItems = 0;
   3351 }
   3352 
   3353 static int
   3354 xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
   3355 {
   3356     if (list->items == NULL) {
   3357 	list->items = (void **) xmlMalloc(
   3358 	    20 * sizeof(void *));
   3359 	if (list->items == NULL) {
   3360 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
   3361 	    return(-1);
   3362 	}
   3363 	list->sizeItems = 20;
   3364     } else if (list->sizeItems <= list->nbItems) {
   3365 	list->sizeItems *= 2;
   3366 	list->items = (void **) xmlRealloc(list->items,
   3367 	    list->sizeItems * sizeof(void *));
   3368 	if (list->items == NULL) {
   3369 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
   3370 	    list->sizeItems = 0;
   3371 	    return(-1);
   3372 	}
   3373     }
   3374     list->items[list->nbItems++] = item;
   3375     return(0);
   3376 }
   3377 
   3378 static int
   3379 xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
   3380 			 int initialSize,
   3381 			 void *item)
   3382 {
   3383     if (list->items == NULL) {
   3384 	if (initialSize <= 0)
   3385 	    initialSize = 1;
   3386 	list->items = (void **) xmlMalloc(
   3387 	    initialSize * sizeof(void *));
   3388 	if (list->items == NULL) {
   3389 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
   3390 	    return(-1);
   3391 	}
   3392 	list->sizeItems = initialSize;
   3393     } else if (list->sizeItems <= list->nbItems) {
   3394 	list->sizeItems *= 2;
   3395 	list->items = (void **) xmlRealloc(list->items,
   3396 	    list->sizeItems * sizeof(void *));
   3397 	if (list->items == NULL) {
   3398 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
   3399 	    list->sizeItems = 0;
   3400 	    return(-1);
   3401 	}
   3402     }
   3403     list->items[list->nbItems++] = item;
   3404     return(0);
   3405 }
   3406 
   3407 static int
   3408 xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
   3409 {
   3410     if (list->items == NULL) {
   3411 	list->items = (void **) xmlMalloc(
   3412 	    20 * sizeof(void *));
   3413 	if (list->items == NULL) {
   3414 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
   3415 	    return(-1);
   3416 	}
   3417 	list->sizeItems = 20;
   3418     } else if (list->sizeItems <= list->nbItems) {
   3419 	list->sizeItems *= 2;
   3420 	list->items = (void **) xmlRealloc(list->items,
   3421 	    list->sizeItems * sizeof(void *));
   3422 	if (list->items == NULL) {
   3423 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
   3424 	    list->sizeItems = 0;
   3425 	    return(-1);
   3426 	}
   3427     }
   3428     /*
   3429     * Just append if the index is greater/equal than the item count.
   3430     */
   3431     if (idx >= list->nbItems) {
   3432 	list->items[list->nbItems++] = item;
   3433     } else {
   3434 	int i;
   3435 	for (i = list->nbItems; i > idx; i--)
   3436 	    list->items[i] = list->items[i-1];
   3437 	list->items[idx] = item;
   3438 	list->nbItems++;
   3439     }
   3440     return(0);
   3441 }
   3442 
   3443 #if 0 /* enable if ever needed */
   3444 static int
   3445 xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
   3446 			    int initialSize,
   3447 			    void *item,
   3448 			    int idx)
   3449 {
   3450     if (list->items == NULL) {
   3451 	if (initialSize <= 0)
   3452 	    initialSize = 1;
   3453 	list->items = (void **) xmlMalloc(
   3454 	    initialSize * sizeof(void *));
   3455 	if (list->items == NULL) {
   3456 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
   3457 	    return(-1);
   3458 	}
   3459 	list->sizeItems = initialSize;
   3460     } else if (list->sizeItems <= list->nbItems) {
   3461 	list->sizeItems *= 2;
   3462 	list->items = (void **) xmlRealloc(list->items,
   3463 	    list->sizeItems * sizeof(void *));
   3464 	if (list->items == NULL) {
   3465 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
   3466 	    list->sizeItems = 0;
   3467 	    return(-1);
   3468 	}
   3469     }
   3470     /*
   3471     * Just append if the index is greater/equal than the item count.
   3472     */
   3473     if (idx >= list->nbItems) {
   3474 	list->items[list->nbItems++] = item;
   3475     } else {
   3476 	int i;
   3477 	for (i = list->nbItems; i > idx; i--)
   3478 	    list->items[i] = list->items[i-1];
   3479 	list->items[idx] = item;
   3480 	list->nbItems++;
   3481     }
   3482     return(0);
   3483 }
   3484 #endif
   3485 
   3486 static int
   3487 xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
   3488 {
   3489     int i;
   3490     if ((list->items == NULL) || (idx >= list->nbItems)) {
   3491 	xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
   3492 	    "index error.\n");
   3493 	return(-1);
   3494     }
   3495 
   3496     if (list->nbItems == 1) {
   3497 	/* TODO: Really free the list? */
   3498 	xmlFree(list->items);
   3499 	list->items = NULL;
   3500 	list->nbItems = 0;
   3501 	list->sizeItems = 0;
   3502     } else if (list->nbItems -1 == idx) {
   3503 	list->nbItems--;
   3504     } else {
   3505 	for (i = idx; i < list->nbItems -1; i++)
   3506 	    list->items[i] = list->items[i+1];
   3507 	list->nbItems--;
   3508     }
   3509     return(0);
   3510 }
   3511 
   3512 /**
   3513  * xmlSchemaItemListFree:
   3514  * @annot:  a schema type structure
   3515  *
   3516  * Deallocate a annotation structure
   3517  */
   3518 static void
   3519 xmlSchemaItemListFree(xmlSchemaItemListPtr list)
   3520 {
   3521     if (list == NULL)
   3522 	return;
   3523     if (list->items != NULL)
   3524 	xmlFree(list->items);
   3525     xmlFree(list);
   3526 }
   3527 
   3528 static void
   3529 xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
   3530 {
   3531     if (bucket == NULL)
   3532 	return;
   3533     if (bucket->globals != NULL) {
   3534 	xmlSchemaComponentListFree(bucket->globals);
   3535 	xmlSchemaItemListFree(bucket->globals);
   3536     }
   3537     if (bucket->locals != NULL) {
   3538 	xmlSchemaComponentListFree(bucket->locals);
   3539 	xmlSchemaItemListFree(bucket->locals);
   3540     }
   3541     if (bucket->relations != NULL) {
   3542 	xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
   3543 	do {
   3544 	    prev = cur;
   3545 	    cur = cur->next;
   3546 	    xmlFree(prev);
   3547 	} while (cur != NULL);
   3548     }
   3549     if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
   3550 	xmlFreeDoc(bucket->doc);
   3551     }
   3552     if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
   3553 	if (WXS_IMPBUCKET(bucket)->schema != NULL)
   3554 	    xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
   3555     }
   3556     xmlFree(bucket);
   3557 }
   3558 
   3559 static xmlSchemaBucketPtr
   3560 xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
   3561 			 int type, const xmlChar *targetNamespace)
   3562 {
   3563     xmlSchemaBucketPtr ret;
   3564     int size;
   3565     xmlSchemaPtr mainSchema;
   3566 
   3567     if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
   3568 	PERROR_INT("xmlSchemaBucketCreate",
   3569 	    "no main schema on constructor");
   3570 	return(NULL);
   3571     }
   3572     mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
   3573     /* Create the schema bucket. */
   3574     if (WXS_IS_BUCKET_INCREDEF(type))
   3575 	size = sizeof(xmlSchemaInclude);
   3576     else
   3577 	size = sizeof(xmlSchemaImport);
   3578     ret = (xmlSchemaBucketPtr) xmlMalloc(size);
   3579     if (ret == NULL) {
   3580 	xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
   3581 	return(NULL);
   3582     }
   3583     memset(ret, 0, size);
   3584     ret->targetNamespace = targetNamespace;
   3585     ret->type = type;
   3586     ret->globals = xmlSchemaItemListCreate();
   3587     if (ret->globals == NULL) {
   3588 	xmlFree(ret);
   3589 	return(NULL);
   3590     }
   3591     ret->locals = xmlSchemaItemListCreate();
   3592     if (ret->locals == NULL) {
   3593 	xmlFree(ret);
   3594 	return(NULL);
   3595     }
   3596     /*
   3597     * The following will assure that only the first bucket is marked as
   3598     * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
   3599     * For each following import buckets an xmlSchema will be created.
   3600     * An xmlSchema will be created for every distinct targetNamespace.
   3601     * We assign the targetNamespace to the schemata here.
   3602     */
   3603     if (! WXS_HAS_BUCKETS(pctxt)) {
   3604 	if (WXS_IS_BUCKET_INCREDEF(type)) {
   3605 	    PERROR_INT("xmlSchemaBucketCreate",
   3606 		"first bucket but it's an include or redefine");
   3607 	    xmlSchemaBucketFree(ret);
   3608 	    return(NULL);
   3609 	}
   3610 	/* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
   3611 	ret->type = XML_SCHEMA_SCHEMA_MAIN;
   3612 	/* Point to the *main* schema. */
   3613 	WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
   3614 	WXS_IMPBUCKET(ret)->schema = mainSchema;
   3615 	/*
   3616 	* Ensure that the main schema gets a targetNamespace.
   3617 	*/
   3618 	mainSchema->targetNamespace = targetNamespace;
   3619     } else {
   3620 	if (type == XML_SCHEMA_SCHEMA_MAIN) {
   3621 	    PERROR_INT("xmlSchemaBucketCreate",
   3622 		"main bucket but it's not the first one");
   3623 	    xmlSchemaBucketFree(ret);
   3624 	    return(NULL);
   3625 	} else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
   3626 	    /*
   3627 	    * Create a schema for imports and assign the
   3628 	    * targetNamespace.
   3629 	    */
   3630 	    WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
   3631 	    if (WXS_IMPBUCKET(ret)->schema == NULL) {
   3632 		xmlSchemaBucketFree(ret);
   3633 		return(NULL);
   3634 	    }
   3635 	    WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
   3636 	}
   3637     }
   3638     if (WXS_IS_BUCKET_IMPMAIN(type)) {
   3639 	int res;
   3640 	/*
   3641 	* Imports go into the "schemasImports" slot of the main *schema*.
   3642 	* Note that we create an import entry for the main schema as well; i.e.,
   3643 	* even if there's only one schema, we'll get an import.
   3644 	*/
   3645 	if (mainSchema->schemasImports == NULL) {
   3646 	    mainSchema->schemasImports = xmlHashCreateDict(5,
   3647 		WXS_CONSTRUCTOR(pctxt)->dict);
   3648 	    if (mainSchema->schemasImports == NULL) {
   3649 		xmlSchemaBucketFree(ret);
   3650 		return(NULL);
   3651 	    }
   3652 	}
   3653 	if (targetNamespace == NULL)
   3654 	    res = xmlHashAddEntry(mainSchema->schemasImports,
   3655 		XML_SCHEMAS_NO_NAMESPACE, ret);
   3656 	else
   3657 	    res = xmlHashAddEntry(mainSchema->schemasImports,
   3658 		targetNamespace, ret);
   3659 	if (res != 0) {
   3660 	    PERROR_INT("xmlSchemaBucketCreate",
   3661 		"failed to add the schema bucket to the hash");
   3662 	    xmlSchemaBucketFree(ret);
   3663 	    return(NULL);
   3664 	}
   3665     } else {
   3666 	/* Set the @ownerImport of an include bucket. */
   3667 	if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
   3668 	    WXS_INCBUCKET(ret)->ownerImport =
   3669 		WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
   3670 	else
   3671 	    WXS_INCBUCKET(ret)->ownerImport =
   3672 		WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
   3673 
   3674 	/* Includes got into the "includes" slot of the *main* schema. */
   3675 	if (mainSchema->includes == NULL) {
   3676 	    mainSchema->includes = xmlSchemaItemListCreate();
   3677 	    if (mainSchema->includes == NULL) {
   3678 		xmlSchemaBucketFree(ret);
   3679 		return(NULL);
   3680 	    }
   3681 	}
   3682 	xmlSchemaItemListAdd(mainSchema->includes, ret);
   3683     }
   3684     /*
   3685     * Add to list of all buckets; this is used for lookup
   3686     * during schema construction time only.
   3687     */
   3688     if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
   3689 	return(NULL);
   3690     return(ret);
   3691 }
   3692 
   3693 static int
   3694 xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
   3695 {
   3696     if (*list == NULL) {
   3697 	*list = xmlSchemaItemListCreate();
   3698 	if (*list == NULL)
   3699 	    return(-1);
   3700     }
   3701     xmlSchemaItemListAddSize(*list, initialSize, item);
   3702     return(0);
   3703 }
   3704 
   3705 /**
   3706  * xmlSchemaFreeAnnot:
   3707  * @annot:  a schema type structure
   3708  *
   3709  * Deallocate a annotation structure
   3710  */
   3711 static void
   3712 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
   3713 {
   3714     if (annot == NULL)
   3715         return;
   3716     if (annot->next == NULL) {
   3717 	xmlFree(annot);
   3718     } else {
   3719 	xmlSchemaAnnotPtr prev;
   3720 
   3721 	do {
   3722 	    prev = annot;
   3723 	    annot = annot->next;
   3724 	    xmlFree(prev);
   3725 	} while (annot != NULL);
   3726     }
   3727 }
   3728 
   3729 /**
   3730  * xmlSchemaFreeNotation:
   3731  * @schema:  a schema notation structure
   3732  *
   3733  * Deallocate a Schema Notation structure.
   3734  */
   3735 static void
   3736 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
   3737 {
   3738     if (nota == NULL)
   3739         return;
   3740     xmlFree(nota);
   3741 }
   3742 
   3743 /**
   3744  * xmlSchemaFreeAttribute:
   3745  * @attr:  an attribute declaration
   3746  *
   3747  * Deallocates an attribute declaration structure.
   3748  */
   3749 static void
   3750 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
   3751 {
   3752     if (attr == NULL)
   3753         return;
   3754     if (attr->annot != NULL)
   3755 	xmlSchemaFreeAnnot(attr->annot);
   3756     if (attr->defVal != NULL)
   3757 	xmlSchemaFreeValue(attr->defVal);
   3758     xmlFree(attr);
   3759 }
   3760 
   3761 /**
   3762  * xmlSchemaFreeAttributeUse:
   3763  * @use:  an attribute use
   3764  *
   3765  * Deallocates an attribute use structure.
   3766  */
   3767 static void
   3768 xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
   3769 {
   3770     if (use == NULL)
   3771         return;
   3772     if (use->annot != NULL)
   3773 	xmlSchemaFreeAnnot(use->annot);
   3774     if (use->defVal != NULL)
   3775 	xmlSchemaFreeValue(use->defVal);
   3776     xmlFree(use);
   3777 }
   3778 
   3779 /**
   3780  * xmlSchemaFreeAttributeUseProhib:
   3781  * @prohib:  an attribute use prohibition
   3782  *
   3783  * Deallocates an attribute use structure.
   3784  */
   3785 static void
   3786 xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
   3787 {
   3788     if (prohib == NULL)
   3789         return;
   3790     xmlFree(prohib);
   3791 }
   3792 
   3793 /**
   3794  * xmlSchemaFreeWildcardNsSet:
   3795  * set:  a schema wildcard namespace
   3796  *
   3797  * Deallocates a list of wildcard constraint structures.
   3798  */
   3799 static void
   3800 xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
   3801 {
   3802     xmlSchemaWildcardNsPtr next;
   3803 
   3804     while (set != NULL) {
   3805 	next = set->next;
   3806 	xmlFree(set);
   3807 	set = next;
   3808     }
   3809 }
   3810 
   3811 /**
   3812  * xmlSchemaFreeWildcard:
   3813  * @wildcard:  a wildcard structure
   3814  *
   3815  * Deallocates a wildcard structure.
   3816  */
   3817 void
   3818 xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
   3819 {
   3820     if (wildcard == NULL)
   3821         return;
   3822     if (wildcard->annot != NULL)
   3823         xmlSchemaFreeAnnot(wildcard->annot);
   3824     if (wildcard->nsSet != NULL)
   3825 	xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
   3826     if (wildcard->negNsSet != NULL)
   3827 	xmlFree(wildcard->negNsSet);
   3828     xmlFree(wildcard);
   3829 }
   3830 
   3831 /**
   3832  * xmlSchemaFreeAttributeGroup:
   3833  * @schema:  a schema attribute group structure
   3834  *
   3835  * Deallocate a Schema Attribute Group structure.
   3836  */
   3837 static void
   3838 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
   3839 {
   3840     if (attrGr == NULL)
   3841         return;
   3842     if (attrGr->annot != NULL)
   3843         xmlSchemaFreeAnnot(attrGr->annot);
   3844     if (attrGr->attrUses != NULL)
   3845 	xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
   3846     xmlFree(attrGr);
   3847 }
   3848 
   3849 /**
   3850  * xmlSchemaFreeQNameRef:
   3851  * @item: a QName reference structure
   3852  *
   3853  * Deallocatea a QName reference structure.
   3854  */
   3855 static void
   3856 xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
   3857 {
   3858     xmlFree(item);
   3859 }
   3860 
   3861 /**
   3862  * xmlSchemaFreeTypeLinkList:
   3863  * @alink: a type link
   3864  *
   3865  * Deallocate a list of types.
   3866  */
   3867 static void
   3868 xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
   3869 {
   3870     xmlSchemaTypeLinkPtr next;
   3871 
   3872     while (link != NULL) {
   3873 	next = link->next;
   3874 	xmlFree(link);
   3875 	link = next;
   3876     }
   3877 }
   3878 
   3879 static void
   3880 xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
   3881 {
   3882     xmlSchemaIDCStateObjPtr next;
   3883     while (sto != NULL) {
   3884 	next = sto->next;
   3885 	if (sto->history != NULL)
   3886 	    xmlFree(sto->history);
   3887 	if (sto->xpathCtxt != NULL)
   3888 	    xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
   3889 	xmlFree(sto);
   3890 	sto = next;
   3891     }
   3892 }
   3893 
   3894 /**
   3895  * xmlSchemaFreeIDC:
   3896  * @idc: a identity-constraint definition
   3897  *
   3898  * Deallocates an identity-constraint definition.
   3899  */
   3900 static void
   3901 xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
   3902 {
   3903     xmlSchemaIDCSelectPtr cur, prev;
   3904 
   3905     if (idcDef == NULL)
   3906 	return;
   3907     if (idcDef->annot != NULL)
   3908         xmlSchemaFreeAnnot(idcDef->annot);
   3909     /* Selector */
   3910     if (idcDef->selector != NULL) {
   3911 	if (idcDef->selector->xpathComp != NULL)
   3912 	    xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
   3913 	xmlFree(idcDef->selector);
   3914     }
   3915     /* Fields */
   3916     if (idcDef->fields != NULL) {
   3917 	cur = idcDef->fields;
   3918 	do {
   3919 	    prev = cur;
   3920 	    cur = cur->next;
   3921 	    if (prev->xpathComp != NULL)
   3922 		xmlFreePattern((xmlPatternPtr) prev->xpathComp);
   3923 	    xmlFree(prev);
   3924 	} while (cur != NULL);
   3925     }
   3926     xmlFree(idcDef);
   3927 }
   3928 
   3929 /**
   3930  * xmlSchemaFreeElement:
   3931  * @schema:  a schema element structure
   3932  *
   3933  * Deallocate a Schema Element structure.
   3934  */
   3935 static void
   3936 xmlSchemaFreeElement(xmlSchemaElementPtr elem)
   3937 {
   3938     if (elem == NULL)
   3939         return;
   3940     if (elem->annot != NULL)
   3941         xmlSchemaFreeAnnot(elem->annot);
   3942     if (elem->contModel != NULL)
   3943         xmlRegFreeRegexp(elem->contModel);
   3944     if (elem->defVal != NULL)
   3945 	xmlSchemaFreeValue(elem->defVal);
   3946     xmlFree(elem);
   3947 }
   3948 
   3949 /**
   3950  * xmlSchemaFreeFacet:
   3951  * @facet:  a schema facet structure
   3952  *
   3953  * Deallocate a Schema Facet structure.
   3954  */
   3955 void
   3956 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
   3957 {
   3958     if (facet == NULL)
   3959         return;
   3960     if (facet->val != NULL)
   3961         xmlSchemaFreeValue(facet->val);
   3962     if (facet->regexp != NULL)
   3963         xmlRegFreeRegexp(facet->regexp);
   3964     if (facet->annot != NULL)
   3965         xmlSchemaFreeAnnot(facet->annot);
   3966     xmlFree(facet);
   3967 }
   3968 
   3969 /**
   3970  * xmlSchemaFreeType:
   3971  * @type:  a schema type structure
   3972  *
   3973  * Deallocate a Schema Type structure.
   3974  */
   3975 void
   3976 xmlSchemaFreeType(xmlSchemaTypePtr type)
   3977 {
   3978     if (type == NULL)
   3979         return;
   3980     if (type->annot != NULL)
   3981         xmlSchemaFreeAnnot(type->annot);
   3982     if (type->facets != NULL) {
   3983         xmlSchemaFacetPtr facet, next;
   3984 
   3985         facet = type->facets;
   3986         while (facet != NULL) {
   3987             next = facet->next;
   3988             xmlSchemaFreeFacet(facet);
   3989             facet = next;
   3990         }
   3991     }
   3992     if (type->attrUses != NULL)
   3993 	xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
   3994     if (type->memberTypes != NULL)
   3995 	xmlSchemaFreeTypeLinkList(type->memberTypes);
   3996     if (type->facetSet != NULL) {
   3997 	xmlSchemaFacetLinkPtr next, link;
   3998 
   3999 	link = type->facetSet;
   4000 	do {
   4001 	    next = link->next;
   4002 	    xmlFree(link);
   4003 	    link = next;
   4004 	} while (link != NULL);
   4005     }
   4006     if (type->contModel != NULL)
   4007         xmlRegFreeRegexp(type->contModel);
   4008     xmlFree(type);
   4009 }
   4010 
   4011 /**
   4012  * xmlSchemaFreeModelGroupDef:
   4013  * @item:  a schema model group definition
   4014  *
   4015  * Deallocates a schema model group definition.
   4016  */
   4017 static void
   4018 xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
   4019 {
   4020     if (item->annot != NULL)
   4021 	xmlSchemaFreeAnnot(item->annot);
   4022     xmlFree(item);
   4023 }
   4024 
   4025 /**
   4026  * xmlSchemaFreeModelGroup:
   4027  * @item:  a schema model group
   4028  *
   4029  * Deallocates a schema model group structure.
   4030  */
   4031 static void
   4032 xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
   4033 {
   4034     if (item->annot != NULL)
   4035 	xmlSchemaFreeAnnot(item->annot);
   4036     xmlFree(item);
   4037 }
   4038 
   4039 static void
   4040 xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
   4041 {
   4042     if ((list == NULL) || (list->nbItems == 0))
   4043 	return;
   4044     {
   4045 	xmlSchemaTreeItemPtr item;
   4046 	xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
   4047 	int i;
   4048 
   4049 	for (i = 0; i < list->nbItems; i++) {
   4050 	    item = items[i];
   4051 	    if (item == NULL)
   4052 		continue;
   4053 	    switch (item->type) {
   4054 		case XML_SCHEMA_TYPE_SIMPLE:
   4055 		case XML_SCHEMA_TYPE_COMPLEX:
   4056 		    xmlSchemaFreeType((xmlSchemaTypePtr) item);
   4057 		    break;
   4058 		case XML_SCHEMA_TYPE_ATTRIBUTE:
   4059 		    xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
   4060 		    break;
   4061 		case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   4062 		    xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
   4063 		    break;
   4064 		case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
   4065 		    xmlSchemaFreeAttributeUseProhib(
   4066 			(xmlSchemaAttributeUseProhibPtr) item);
   4067 		    break;
   4068 		case XML_SCHEMA_TYPE_ELEMENT:
   4069 		    xmlSchemaFreeElement((xmlSchemaElementPtr) item);
   4070 		    break;
   4071 		case XML_SCHEMA_TYPE_PARTICLE:
   4072 		    if (item->annot != NULL)
   4073 			xmlSchemaFreeAnnot(item->annot);
   4074 		    xmlFree(item);
   4075 		    break;
   4076 		case XML_SCHEMA_TYPE_SEQUENCE:
   4077 		case XML_SCHEMA_TYPE_CHOICE:
   4078 		case XML_SCHEMA_TYPE_ALL:
   4079 		    xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
   4080 		    break;
   4081 		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   4082 		    xmlSchemaFreeAttributeGroup(
   4083 			(xmlSchemaAttributeGroupPtr) item);
   4084 		    break;
   4085 		case XML_SCHEMA_TYPE_GROUP:
   4086 		    xmlSchemaFreeModelGroupDef(
   4087 			(xmlSchemaModelGroupDefPtr) item);
   4088 		    break;
   4089 		case XML_SCHEMA_TYPE_ANY:
   4090 		case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   4091 		    xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
   4092 		    break;
   4093 		case XML_SCHEMA_TYPE_IDC_KEY:
   4094 		case XML_SCHEMA_TYPE_IDC_UNIQUE:
   4095 		case XML_SCHEMA_TYPE_IDC_KEYREF:
   4096 		    xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
   4097 		    break;
   4098 		case XML_SCHEMA_TYPE_NOTATION:
   4099 		    xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
   4100 		    break;
   4101 		case XML_SCHEMA_EXTRA_QNAMEREF:
   4102 		    xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
   4103 		    break;
   4104 		default: {
   4105 		    /* TODO: This should never be hit. */
   4106 		    xmlSchemaPSimpleInternalErr(NULL,
   4107 			"Internal error: xmlSchemaComponentListFree, "
   4108 			"unexpected component type '%s'\n",
   4109 			(const xmlChar *) WXS_ITEM_TYPE_NAME(item));
   4110 			 }
   4111 		    break;
   4112 	    }
   4113 	}
   4114 	list->nbItems = 0;
   4115     }
   4116 }
   4117 
   4118 /**
   4119  * xmlSchemaFree:
   4120  * @schema:  a schema structure
   4121  *
   4122  * Deallocate a Schema structure.
   4123  */
   4124 void
   4125 xmlSchemaFree(xmlSchemaPtr schema)
   4126 {
   4127     if (schema == NULL)
   4128         return;
   4129     /* @volatiles is not used anymore :-/ */
   4130     if (schema->volatiles != NULL)
   4131 	TODO
   4132     /*
   4133     * Note that those slots are not responsible for freeing
   4134     * schema components anymore; this will now be done by
   4135     * the schema buckets.
   4136     */
   4137     if (schema->notaDecl != NULL)
   4138         xmlHashFree(schema->notaDecl, NULL);
   4139     if (schema->attrDecl != NULL)
   4140         xmlHashFree(schema->attrDecl, NULL);
   4141     if (schema->attrgrpDecl != NULL)
   4142         xmlHashFree(schema->attrgrpDecl, NULL);
   4143     if (schema->elemDecl != NULL)
   4144         xmlHashFree(schema->elemDecl, NULL);
   4145     if (schema->typeDecl != NULL)
   4146         xmlHashFree(schema->typeDecl, NULL);
   4147     if (schema->groupDecl != NULL)
   4148         xmlHashFree(schema->groupDecl, NULL);
   4149     if (schema->idcDef != NULL)
   4150         xmlHashFree(schema->idcDef, NULL);
   4151 
   4152     if (schema->schemasImports != NULL)
   4153 	xmlHashFree(schema->schemasImports,
   4154 		    (xmlHashDeallocator) xmlSchemaBucketFree);
   4155     if (schema->includes != NULL) {
   4156 	xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
   4157 	int i;
   4158 	for (i = 0; i < list->nbItems; i++) {
   4159 	    xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
   4160 	}
   4161 	xmlSchemaItemListFree(list);
   4162     }
   4163     if (schema->annot != NULL)
   4164         xmlSchemaFreeAnnot(schema->annot);
   4165     /* Never free the doc here, since this will be done by the buckets. */
   4166 
   4167     xmlDictFree(schema->dict);
   4168     xmlFree(schema);
   4169 }
   4170 
   4171 /************************************************************************
   4172  *									*
   4173  *			Debug functions					*
   4174  *									*
   4175  ************************************************************************/
   4176 
   4177 #ifdef LIBXML_OUTPUT_ENABLED
   4178 
   4179 static void
   4180 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
   4181 
   4182 /**
   4183  * xmlSchemaElementDump:
   4184  * @elem:  an element
   4185  * @output:  the file output
   4186  *
   4187  * Dump the element
   4188  */
   4189 static void
   4190 xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output,
   4191                      const xmlChar * name ATTRIBUTE_UNUSED,
   4192 		     const xmlChar * namespace ATTRIBUTE_UNUSED,
   4193                      const xmlChar * context ATTRIBUTE_UNUSED)
   4194 {
   4195     if (elem == NULL)
   4196         return;
   4197 
   4198 
   4199     fprintf(output, "Element");
   4200     if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
   4201 	fprintf(output, " (global)");
   4202     fprintf(output, ": '%s' ", elem->name);
   4203     if (namespace != NULL)
   4204 	fprintf(output, "ns '%s'", namespace);
   4205     fprintf(output, "\n");
   4206 #if 0
   4207     if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
   4208 	fprintf(output, "  min %d ", elem->minOccurs);
   4209         if (elem->maxOccurs >= UNBOUNDED)
   4210             fprintf(output, "max: unbounded\n");
   4211         else if (elem->maxOccurs != 1)
   4212             fprintf(output, "max: %d\n", elem->maxOccurs);
   4213         else
   4214             fprintf(output, "\n");
   4215     }
   4216 #endif
   4217     /*
   4218     * Misc other properties.
   4219     */
   4220     if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
   4221 	(elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
   4222 	(elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
   4223 	(elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
   4224 	fprintf(output, "  props: ");
   4225 	if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
   4226 	    fprintf(output, "[fixed] ");
   4227 	if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
   4228 	    fprintf(output, "[default] ");
   4229 	if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
   4230 	    fprintf(output, "[abstract] ");
   4231 	if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
   4232 	    fprintf(output, "[nillable] ");
   4233 	fprintf(output, "\n");
   4234     }
   4235     /*
   4236     * Default/fixed value.
   4237     */
   4238     if (elem->value != NULL)
   4239 	fprintf(output, "  value: '%s'\n", elem->value);
   4240     /*
   4241     * Type.
   4242     */
   4243     if (elem->namedType != NULL) {
   4244 	fprintf(output, "  type: '%s' ", elem->namedType);
   4245 	if (elem->namedTypeNs != NULL)
   4246 	    fprintf(output, "ns '%s'\n", elem->namedTypeNs);
   4247 	else
   4248 	    fprintf(output, "\n");
   4249     } else if (elem->subtypes != NULL) {
   4250 	/*
   4251 	* Dump local types.
   4252 	*/
   4253 	xmlSchemaTypeDump(elem->subtypes, output);
   4254     }
   4255     /*
   4256     * Substitution group.
   4257     */
   4258     if (elem->substGroup != NULL) {
   4259 	fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
   4260 	if (elem->substGroupNs != NULL)
   4261 	    fprintf(output, "ns '%s'\n", elem->substGroupNs);
   4262 	else
   4263 	    fprintf(output, "\n");
   4264     }
   4265 }
   4266 
   4267 /**
   4268  * xmlSchemaAnnotDump:
   4269  * @output:  the file output
   4270  * @annot:  a annotation
   4271  *
   4272  * Dump the annotation
   4273  */
   4274 static void
   4275 xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
   4276 {
   4277     xmlChar *content;
   4278 
   4279     if (annot == NULL)
   4280         return;
   4281 
   4282     content = xmlNodeGetContent(annot->content);
   4283     if (content != NULL) {
   4284         fprintf(output, "  Annot: %s\n", content);
   4285         xmlFree(content);
   4286     } else
   4287         fprintf(output, "  Annot: empty\n");
   4288 }
   4289 
   4290 /**
   4291  * xmlSchemaContentModelDump:
   4292  * @particle: the schema particle
   4293  * @output: the file output
   4294  * @depth: the depth used for intentation
   4295  *
   4296  * Dump a SchemaType structure
   4297  */
   4298 static void
   4299 xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
   4300 {
   4301     xmlChar *str = NULL;
   4302     xmlSchemaTreeItemPtr term;
   4303     char shift[100];
   4304     int i;
   4305 
   4306     if (particle == NULL)
   4307 	return;
   4308     for (i = 0;((i < depth) && (i < 25));i++)
   4309         shift[2 * i] = shift[2 * i + 1] = ' ';
   4310     shift[2 * i] = shift[2 * i + 1] = 0;
   4311     fprintf(output, "%s", shift);
   4312     if (particle->children == NULL) {
   4313 	fprintf(output, "MISSING particle term\n");
   4314 	return;
   4315     }
   4316     term = particle->children;
   4317     if (term == NULL) {
   4318 	fprintf(output, "(NULL)");
   4319     } else {
   4320 	switch (term->type) {
   4321 	    case XML_SCHEMA_TYPE_ELEMENT:
   4322 		fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
   4323 		    ((xmlSchemaElementPtr)term)->targetNamespace,
   4324 		    ((xmlSchemaElementPtr)term)->name));
   4325 		FREE_AND_NULL(str);
   4326 		break;
   4327 	    case XML_SCHEMA_TYPE_SEQUENCE:
   4328 		fprintf(output, "SEQUENCE");
   4329 		break;
   4330 	    case XML_SCHEMA_TYPE_CHOICE:
   4331 		fprintf(output, "CHOICE");
   4332 		break;
   4333 	    case XML_SCHEMA_TYPE_ALL:
   4334 		fprintf(output, "ALL");
   4335 		break;
   4336 	    case XML_SCHEMA_TYPE_ANY:
   4337 		fprintf(output, "ANY");
   4338 		break;
   4339 	    default:
   4340 		fprintf(output, "UNKNOWN\n");
   4341 		return;
   4342 	}
   4343     }
   4344     if (particle->minOccurs != 1)
   4345 	fprintf(output, " min: %d", particle->minOccurs);
   4346     if (particle->maxOccurs >= UNBOUNDED)
   4347 	fprintf(output, " max: unbounded");
   4348     else if (particle->maxOccurs != 1)
   4349 	fprintf(output, " max: %d", particle->maxOccurs);
   4350     fprintf(output, "\n");
   4351     if (term &&
   4352 	((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
   4353 	 (term->type == XML_SCHEMA_TYPE_CHOICE) ||
   4354 	 (term->type == XML_SCHEMA_TYPE_ALL)) &&
   4355 	 (term->children != NULL)) {
   4356 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
   4357 	    output, depth +1);
   4358     }
   4359     if (particle->next != NULL)
   4360 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
   4361 		output, depth);
   4362 }
   4363 
   4364 /**
   4365  * xmlSchemaAttrUsesDump:
   4366  * @uses:  attribute uses list
   4367  * @output:  the file output
   4368  *
   4369  * Dumps a list of attribute use components.
   4370  */
   4371 static void
   4372 xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
   4373 {
   4374     xmlSchemaAttributeUsePtr use;
   4375     xmlSchemaAttributeUseProhibPtr prohib;
   4376     xmlSchemaQNameRefPtr ref;
   4377     const xmlChar *name, *tns;
   4378     xmlChar *str = NULL;
   4379     int i;
   4380 
   4381     if ((uses == NULL) || (uses->nbItems == 0))
   4382         return;
   4383 
   4384     fprintf(output, "  attributes:\n");
   4385     for (i = 0; i < uses->nbItems; i++) {
   4386 	use = uses->items[i];
   4387 	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
   4388 	    fprintf(output, "  [prohibition] ");
   4389 	    prohib = (xmlSchemaAttributeUseProhibPtr) use;
   4390 	    name = prohib->name;
   4391 	    tns = prohib->targetNamespace;
   4392 	} else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
   4393 	    fprintf(output, "  [reference] ");
   4394 	    ref = (xmlSchemaQNameRefPtr) use;
   4395 	    name = ref->name;
   4396 	    tns = ref->targetNamespace;
   4397 	} else {
   4398 	    fprintf(output, "  [use] ");
   4399 	    name = WXS_ATTRUSE_DECL_NAME(use);
   4400 	    tns = WXS_ATTRUSE_DECL_TNS(use);
   4401 	}
   4402 	fprintf(output, "'%s'\n",
   4403 	    (const char *) xmlSchemaFormatQName(&str, tns, name));
   4404 	FREE_AND_NULL(str);
   4405     }
   4406 }
   4407 
   4408 /**
   4409  * xmlSchemaTypeDump:
   4410  * @output:  the file output
   4411  * @type:  a type structure
   4412  *
   4413  * Dump a SchemaType structure
   4414  */
   4415 static void
   4416 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
   4417 {
   4418     if (type == NULL) {
   4419         fprintf(output, "Type: NULL\n");
   4420         return;
   4421     }
   4422     fprintf(output, "Type: ");
   4423     if (type->name != NULL)
   4424         fprintf(output, "'%s' ", type->name);
   4425     else
   4426         fprintf(output, "(no name) ");
   4427     if (type->targetNamespace != NULL)
   4428 	fprintf(output, "ns '%s' ", type->targetNamespace);
   4429     switch (type->type) {
   4430         case XML_SCHEMA_TYPE_BASIC:
   4431             fprintf(output, "[basic] ");
   4432             break;
   4433         case XML_SCHEMA_TYPE_SIMPLE:
   4434             fprintf(output, "[simple] ");
   4435             break;
   4436         case XML_SCHEMA_TYPE_COMPLEX:
   4437             fprintf(output, "[complex] ");
   4438             break;
   4439         case XML_SCHEMA_TYPE_SEQUENCE:
   4440             fprintf(output, "[sequence] ");
   4441             break;
   4442         case XML_SCHEMA_TYPE_CHOICE:
   4443             fprintf(output, "[choice] ");
   4444             break;
   4445         case XML_SCHEMA_TYPE_ALL:
   4446             fprintf(output, "[all] ");
   4447             break;
   4448         case XML_SCHEMA_TYPE_UR:
   4449             fprintf(output, "[ur] ");
   4450             break;
   4451         case XML_SCHEMA_TYPE_RESTRICTION:
   4452             fprintf(output, "[restriction] ");
   4453             break;
   4454         case XML_SCHEMA_TYPE_EXTENSION:
   4455             fprintf(output, "[extension] ");
   4456             break;
   4457         default:
   4458             fprintf(output, "[unknown type %d] ", type->type);
   4459             break;
   4460     }
   4461     fprintf(output, "content: ");
   4462     switch (type->contentType) {
   4463         case XML_SCHEMA_CONTENT_UNKNOWN:
   4464             fprintf(output, "[unknown] ");
   4465             break;
   4466         case XML_SCHEMA_CONTENT_EMPTY:
   4467             fprintf(output, "[empty] ");
   4468             break;
   4469         case XML_SCHEMA_CONTENT_ELEMENTS:
   4470             fprintf(output, "[element] ");
   4471             break;
   4472         case XML_SCHEMA_CONTENT_MIXED:
   4473             fprintf(output, "[mixed] ");
   4474             break;
   4475         case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
   4476 	/* not used. */
   4477             break;
   4478         case XML_SCHEMA_CONTENT_BASIC:
   4479             fprintf(output, "[basic] ");
   4480             break;
   4481         case XML_SCHEMA_CONTENT_SIMPLE:
   4482             fprintf(output, "[simple] ");
   4483             break;
   4484         case XML_SCHEMA_CONTENT_ANY:
   4485             fprintf(output, "[any] ");
   4486             break;
   4487     }
   4488     fprintf(output, "\n");
   4489     if (type->base != NULL) {
   4490         fprintf(output, "  base type: '%s'", type->base);
   4491 	if (type->baseNs != NULL)
   4492 	    fprintf(output, " ns '%s'\n", type->baseNs);
   4493 	else
   4494 	    fprintf(output, "\n");
   4495     }
   4496     if (type->attrUses != NULL)
   4497 	xmlSchemaAttrUsesDump(type->attrUses, output);
   4498     if (type->annot != NULL)
   4499         xmlSchemaAnnotDump(output, type->annot);
   4500 #ifdef DUMP_CONTENT_MODEL
   4501     if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
   4502 	(type->subtypes != NULL)) {
   4503 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
   4504 	    output, 1);
   4505     }
   4506 #endif
   4507 }
   4508 
   4509 /**
   4510  * xmlSchemaDump:
   4511  * @output:  the file output
   4512  * @schema:  a schema structure
   4513  *
   4514  * Dump a Schema structure.
   4515  */
   4516 void
   4517 xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
   4518 {
   4519     if (output == NULL)
   4520         return;
   4521     if (schema == NULL) {
   4522         fprintf(output, "Schemas: NULL\n");
   4523         return;
   4524     }
   4525     fprintf(output, "Schemas: ");
   4526     if (schema->name != NULL)
   4527         fprintf(output, "%s, ", schema->name);
   4528     else
   4529         fprintf(output, "no name, ");
   4530     if (schema->targetNamespace != NULL)
   4531         fprintf(output, "%s", (const char *) schema->targetNamespace);
   4532     else
   4533         fprintf(output, "no target namespace");
   4534     fprintf(output, "\n");
   4535     if (schema->annot != NULL)
   4536         xmlSchemaAnnotDump(output, schema->annot);
   4537     xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump,
   4538                 output);
   4539     xmlHashScanFull(schema->elemDecl,
   4540                     (xmlHashScannerFull) xmlSchemaElementDump, output);
   4541 }
   4542 
   4543 #ifdef DEBUG_IDC_NODE_TABLE
   4544 /**
   4545  * xmlSchemaDebugDumpIDCTable:
   4546  * @vctxt: the WXS validation context
   4547  *
   4548  * Displays the current IDC table for debug purposes.
   4549  */
   4550 static void
   4551 xmlSchemaDebugDumpIDCTable(FILE * output,
   4552 			   const xmlChar *namespaceName,
   4553 			   const xmlChar *localName,
   4554 			   xmlSchemaPSVIIDCBindingPtr bind)
   4555 {
   4556     xmlChar *str = NULL;
   4557     const xmlChar *value;
   4558     xmlSchemaPSVIIDCNodePtr tab;
   4559     xmlSchemaPSVIIDCKeyPtr key;
   4560     int i, j, res;
   4561 
   4562     fprintf(output, "IDC: TABLES on '%s'\n",
   4563 	xmlSchemaFormatQName(&str, namespaceName, localName));
   4564     FREE_AND_NULL(str)
   4565 
   4566     if (bind == NULL)
   4567 	return;
   4568     do {
   4569 	fprintf(output, "IDC:   BINDING '%s' (%d)\n",
   4570 	    xmlSchemaGetComponentQName(&str,
   4571 		bind->definition), bind->nbNodes);
   4572 	FREE_AND_NULL(str)
   4573 	for (i = 0; i < bind->nbNodes; i++) {
   4574 	    tab = bind->nodeTable[i];
   4575 	    fprintf(output, "         ( ");
   4576 	    for (j = 0; j < bind->definition->nbFields; j++) {
   4577 		key = tab->keys[j];
   4578 		if ((key != NULL) && (key->val != NULL)) {
   4579 		    res = xmlSchemaGetCanonValue(key->val, &value);
   4580 		    if (res >= 0)
   4581 			fprintf(output, "'%s' ", value);
   4582 		    else
   4583 			fprintf(output, "CANON-VALUE-FAILED ");
   4584 		    if (res == 0)
   4585 			FREE_AND_NULL(value)
   4586 		} else if (key != NULL)
   4587 		    fprintf(output, "(no val), ");
   4588 		else
   4589 		    fprintf(output, "(key missing), ");
   4590 	    }
   4591 	    fprintf(output, ")\n");
   4592 	}
   4593 	if (bind->dupls && bind->dupls->nbItems) {
   4594 	    fprintf(output, "IDC:     dupls (%d):\n", bind->dupls->nbItems);
   4595 	    for (i = 0; i < bind->dupls->nbItems; i++) {
   4596 		tab = bind->dupls->items[i];
   4597 		fprintf(output, "         ( ");
   4598 		for (j = 0; j < bind->definition->nbFields; j++) {
   4599 		    key = tab->keys[j];
   4600 		    if ((key != NULL) && (key->val != NULL)) {
   4601 			res = xmlSchemaGetCanonValue(key->val, &value);
   4602 			if (res >= 0)
   4603 			    fprintf(output, "'%s' ", value);
   4604 			else
   4605 			    fprintf(output, "CANON-VALUE-FAILED ");
   4606 			if (res == 0)
   4607 			    FREE_AND_NULL(value)
   4608 		    } else if (key != NULL)
   4609 		    fprintf(output, "(no val), ");
   4610 			else
   4611 			    fprintf(output, "(key missing), ");
   4612 		}
   4613 		fprintf(output, ")\n");
   4614 	    }
   4615 	}
   4616 	bind = bind->next;
   4617     } while (bind != NULL);
   4618 }
   4619 #endif /* DEBUG_IDC */
   4620 #endif /* LIBXML_OUTPUT_ENABLED */
   4621 
   4622 /************************************************************************
   4623  *									*
   4624  *			Utilities					*
   4625  *									*
   4626  ************************************************************************/
   4627 
   4628 /**
   4629  * xmlSchemaGetPropNode:
   4630  * @node: the element node
   4631  * @name: the name of the attribute
   4632  *
   4633  * Seeks an attribute with a name of @name in
   4634  * no namespace.
   4635  *
   4636  * Returns the attribute or NULL if not present.
   4637  */
   4638 static xmlAttrPtr
   4639 xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
   4640 {
   4641     xmlAttrPtr prop;
   4642 
   4643     if ((node == NULL) || (name == NULL))
   4644 	return(NULL);
   4645     prop = node->properties;
   4646     while (prop != NULL) {
   4647         if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
   4648 	    return(prop);
   4649 	prop = prop->next;
   4650     }
   4651     return (NULL);
   4652 }
   4653 
   4654 /**
   4655  * xmlSchemaGetPropNodeNs:
   4656  * @node: the element node
   4657  * @uri: the uri
   4658  * @name: the name of the attribute
   4659  *
   4660  * Seeks an attribute with a local name of @name and
   4661  * a namespace URI of @uri.
   4662  *
   4663  * Returns the attribute or NULL if not present.
   4664  */
   4665 static xmlAttrPtr
   4666 xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
   4667 {
   4668     xmlAttrPtr prop;
   4669 
   4670     if ((node == NULL) || (name == NULL))
   4671 	return(NULL);
   4672     prop = node->properties;
   4673     while (prop != NULL) {
   4674 	if ((prop->ns != NULL) &&
   4675 	    xmlStrEqual(prop->name, BAD_CAST name) &&
   4676 	    xmlStrEqual(prop->ns->href, BAD_CAST uri))
   4677 	    return(prop);
   4678 	prop = prop->next;
   4679     }
   4680     return (NULL);
   4681 }
   4682 
   4683 static const xmlChar *
   4684 xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
   4685 {
   4686     xmlChar *val;
   4687     const xmlChar *ret;
   4688 
   4689     val = xmlNodeGetContent(node);
   4690     if (val == NULL)
   4691 	val = xmlStrdup((xmlChar *)"");
   4692     ret = xmlDictLookup(ctxt->dict, val, -1);
   4693     xmlFree(val);
   4694     return(ret);
   4695 }
   4696 
   4697 static const xmlChar *
   4698 xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
   4699 {
   4700     return((const xmlChar*) xmlNodeGetContent(node));
   4701 }
   4702 
   4703 /**
   4704  * xmlSchemaGetProp:
   4705  * @ctxt: the parser context
   4706  * @node: the node
   4707  * @name: the property name
   4708  *
   4709  * Read a attribute value and internalize the string
   4710  *
   4711  * Returns the string or NULL if not present.
   4712  */
   4713 static const xmlChar *
   4714 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
   4715                  const char *name)
   4716 {
   4717     xmlChar *val;
   4718     const xmlChar *ret;
   4719 
   4720     val = xmlGetNoNsProp(node, BAD_CAST name);
   4721     if (val == NULL)
   4722         return(NULL);
   4723     ret = xmlDictLookup(ctxt->dict, val, -1);
   4724     xmlFree(val);
   4725     return(ret);
   4726 }
   4727 
   4728 /************************************************************************
   4729  *									*
   4730  *			Parsing functions				*
   4731  *									*
   4732  ************************************************************************/
   4733 
   4734 #define WXS_FIND_GLOBAL_ITEM(slot)			\
   4735     if (xmlStrEqual(nsName, schema->targetNamespace)) { \
   4736 	ret = xmlHashLookup(schema->slot, name); \
   4737 	if (ret != NULL) goto exit; \
   4738     } \
   4739     if (xmlHashSize(schema->schemasImports) > 1) { \
   4740 	xmlSchemaImportPtr import; \
   4741 	if (nsName == NULL) \
   4742 	    import = xmlHashLookup(schema->schemasImports, \
   4743 		XML_SCHEMAS_NO_NAMESPACE); \
   4744 	else \
   4745 	    import = xmlHashLookup(schema->schemasImports, nsName); \
   4746 	if (import == NULL) \
   4747 	    goto exit; \
   4748 	ret = xmlHashLookup(import->schema->slot, name); \
   4749     }
   4750 
   4751 /**
   4752  * xmlSchemaGetElem:
   4753  * @schema:  the schema context
   4754  * @name:  the element name
   4755  * @ns:  the element namespace
   4756  *
   4757  * Lookup a global element declaration in the schema.
   4758  *
   4759  * Returns the element declaration or NULL if not found.
   4760  */
   4761 static xmlSchemaElementPtr
   4762 xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
   4763                  const xmlChar * nsName)
   4764 {
   4765     xmlSchemaElementPtr ret = NULL;
   4766 
   4767     if ((name == NULL) || (schema == NULL))
   4768         return(NULL);
   4769     if (schema != NULL) {
   4770 	WXS_FIND_GLOBAL_ITEM(elemDecl)
   4771     }
   4772 exit:
   4773 #ifdef DEBUG
   4774     if (ret == NULL) {
   4775         if (nsName == NULL)
   4776             fprintf(stderr, "Unable to lookup element decl. %s", name);
   4777         else
   4778             fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
   4779                     nsName);
   4780     }
   4781 #endif
   4782     return (ret);
   4783 }
   4784 
   4785 /**
   4786  * xmlSchemaGetType:
   4787  * @schema:  the main schema
   4788  * @name:  the type's name
   4789  * nsName:  the type's namespace
   4790  *
   4791  * Lookup a type in the schemas or the predefined types
   4792  *
   4793  * Returns the group definition or NULL if not found.
   4794  */
   4795 static xmlSchemaTypePtr
   4796 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
   4797                  const xmlChar * nsName)
   4798 {
   4799     xmlSchemaTypePtr ret = NULL;
   4800 
   4801     if (name == NULL)
   4802         return (NULL);
   4803     /* First try the built-in types. */
   4804     if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
   4805 	ret = xmlSchemaGetPredefinedType(name, nsName);
   4806 	if (ret != NULL)
   4807 	    goto exit;
   4808 	/*
   4809 	* Note that we try the parsed schemas as well here
   4810 	* since one might have parsed the S4S, which contain more
   4811 	* than the built-in types.
   4812 	* TODO: Can we optimize this?
   4813 	*/
   4814     }
   4815     if (schema != NULL) {
   4816 	WXS_FIND_GLOBAL_ITEM(typeDecl)
   4817     }
   4818 exit:
   4819 
   4820 #ifdef DEBUG
   4821     if (ret == NULL) {
   4822         if (nsName == NULL)
   4823             fprintf(stderr, "Unable to lookup type %s", name);
   4824         else
   4825             fprintf(stderr, "Unable to lookup type %s:%s", name,
   4826                     nsName);
   4827     }
   4828 #endif
   4829     return (ret);
   4830 }
   4831 
   4832 /**
   4833  * xmlSchemaGetAttributeDecl:
   4834  * @schema:  the context of the schema
   4835  * @name:  the name of the attribute
   4836  * @ns:  the target namespace of the attribute
   4837  *
   4838  * Lookup a an attribute in the schema or imported schemas
   4839  *
   4840  * Returns the attribute declaration or NULL if not found.
   4841  */
   4842 static xmlSchemaAttributePtr
   4843 xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
   4844                  const xmlChar * nsName)
   4845 {
   4846     xmlSchemaAttributePtr ret = NULL;
   4847 
   4848     if ((name == NULL) || (schema == NULL))
   4849         return (NULL);
   4850     if (schema != NULL) {
   4851 	WXS_FIND_GLOBAL_ITEM(attrDecl)
   4852     }
   4853 exit:
   4854 #ifdef DEBUG
   4855     if (ret == NULL) {
   4856         if (nsName == NULL)
   4857             fprintf(stderr, "Unable to lookup attribute %s", name);
   4858         else
   4859             fprintf(stderr, "Unable to lookup attribute %s:%s", name,
   4860                     nsName);
   4861     }
   4862 #endif
   4863     return (ret);
   4864 }
   4865 
   4866 /**
   4867  * xmlSchemaGetAttributeGroup:
   4868  * @schema:  the context of the schema
   4869  * @name:  the name of the attribute group
   4870  * @ns:  the target namespace of the attribute group
   4871  *
   4872  * Lookup a an attribute group in the schema or imported schemas
   4873  *
   4874  * Returns the attribute group definition or NULL if not found.
   4875  */
   4876 static xmlSchemaAttributeGroupPtr
   4877 xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
   4878                  const xmlChar * nsName)
   4879 {
   4880     xmlSchemaAttributeGroupPtr ret = NULL;
   4881 
   4882     if ((name == NULL) || (schema == NULL))
   4883         return (NULL);
   4884     if (schema != NULL) {
   4885 	WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
   4886     }
   4887 exit:
   4888     /* TODO:
   4889     if ((ret != NULL) && (ret->redef != NULL)) {
   4890 	* Return the last redefinition. *
   4891 	ret = ret->redef;
   4892     }
   4893     */
   4894 #ifdef DEBUG
   4895     if (ret == NULL) {
   4896         if (nsName == NULL)
   4897             fprintf(stderr, "Unable to lookup attribute group %s", name);
   4898         else
   4899             fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
   4900                     nsName);
   4901     }
   4902 #endif
   4903     return (ret);
   4904 }
   4905 
   4906 /**
   4907  * xmlSchemaGetGroup:
   4908  * @schema:  the context of the schema
   4909  * @name:  the name of the group
   4910  * @ns:  the target namespace of the group
   4911  *
   4912  * Lookup a group in the schema or imported schemas
   4913  *
   4914  * Returns the group definition or NULL if not found.
   4915  */
   4916 static xmlSchemaModelGroupDefPtr
   4917 xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
   4918                  const xmlChar * nsName)
   4919 {
   4920     xmlSchemaModelGroupDefPtr ret = NULL;
   4921 
   4922     if ((name == NULL) || (schema == NULL))
   4923         return (NULL);
   4924     if (schema != NULL) {
   4925 	WXS_FIND_GLOBAL_ITEM(groupDecl)
   4926     }
   4927 exit:
   4928 
   4929 #ifdef DEBUG
   4930     if (ret == NULL) {
   4931         if (nsName == NULL)
   4932             fprintf(stderr, "Unable to lookup group %s", name);
   4933         else
   4934             fprintf(stderr, "Unable to lookup group %s:%s", name,
   4935                     nsName);
   4936     }
   4937 #endif
   4938     return (ret);
   4939 }
   4940 
   4941 static xmlSchemaNotationPtr
   4942 xmlSchemaGetNotation(xmlSchemaPtr schema,
   4943 		     const xmlChar *name,
   4944 		     const xmlChar *nsName)
   4945 {
   4946     xmlSchemaNotationPtr ret = NULL;
   4947 
   4948     if ((name == NULL) || (schema == NULL))
   4949         return (NULL);
   4950     if (schema != NULL) {
   4951 	WXS_FIND_GLOBAL_ITEM(notaDecl)
   4952     }
   4953 exit:
   4954     return (ret);
   4955 }
   4956 
   4957 static xmlSchemaIDCPtr
   4958 xmlSchemaGetIDC(xmlSchemaPtr schema,
   4959 		const xmlChar *name,
   4960 		const xmlChar *nsName)
   4961 {
   4962     xmlSchemaIDCPtr ret = NULL;
   4963 
   4964     if ((name == NULL) || (schema == NULL))
   4965         return (NULL);
   4966     if (schema != NULL) {
   4967 	WXS_FIND_GLOBAL_ITEM(idcDef)
   4968     }
   4969 exit:
   4970     return (ret);
   4971 }
   4972 
   4973 /**
   4974  * xmlSchemaGetNamedComponent:
   4975  * @schema:  the schema
   4976  * @name:  the name of the group
   4977  * @ns:  the target namespace of the group
   4978  *
   4979  * Lookup a group in the schema or imported schemas
   4980  *
   4981  * Returns the group definition or NULL if not found.
   4982  */
   4983 static xmlSchemaBasicItemPtr
   4984 xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
   4985 			   xmlSchemaTypeType itemType,
   4986 			   const xmlChar *name,
   4987 			   const xmlChar *targetNs)
   4988 {
   4989     switch (itemType) {
   4990 	case XML_SCHEMA_TYPE_GROUP:
   4991 	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
   4992 		name, targetNs));
   4993 	case XML_SCHEMA_TYPE_ELEMENT:
   4994 	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
   4995 		name, targetNs));
   4996 	default:
   4997 	    TODO
   4998 	    return (NULL);
   4999     }
   5000 }
   5001 
   5002 /************************************************************************
   5003  *									*
   5004  *			Parsing functions				*
   5005  *									*
   5006  ************************************************************************/
   5007 
   5008 #define IS_BLANK_NODE(n)						\
   5009     (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
   5010 
   5011 /**
   5012  * xmlSchemaIsBlank:
   5013  * @str:  a string
   5014  * @len: the length of the string or -1
   5015  *
   5016  * Check if a string is ignorable
   5017  *
   5018  * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
   5019  */
   5020 static int
   5021 xmlSchemaIsBlank(xmlChar * str, int len)
   5022 {
   5023     if (str == NULL)
   5024         return (1);
   5025     if (len < 0) {
   5026 	while (*str != 0) {
   5027 	    if (!(IS_BLANK_CH(*str)))
   5028 		return (0);
   5029 	    str++;
   5030 	}
   5031     } else while ((*str != 0) && (len != 0)) {
   5032 	if (!(IS_BLANK_CH(*str)))
   5033 	    return (0);
   5034 	str++;
   5035 	len--;
   5036     }
   5037 
   5038     return (1);
   5039 }
   5040 
   5041 #define WXS_COMP_NAME(c, t) ((t) (c))->name
   5042 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
   5043 /*
   5044 * xmlSchemaFindRedefCompInGraph:
   5045 * ATTENTION TODO: This uses pointer comp. for strings.
   5046 */
   5047 static xmlSchemaBasicItemPtr
   5048 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
   5049 			      xmlSchemaTypeType type,
   5050 			      const xmlChar *name,
   5051 			      const xmlChar *nsName)
   5052 {
   5053     xmlSchemaBasicItemPtr ret;
   5054     int i;
   5055 
   5056     if ((bucket == NULL) || (name == NULL))
   5057 	return(NULL);
   5058     if ((bucket->globals == NULL) ||
   5059 	(bucket->globals->nbItems == 0))
   5060 	goto subschemas;
   5061     /*
   5062     * Search in global components.
   5063     */
   5064     for (i = 0; i < bucket->globals->nbItems; i++) {
   5065 	ret = bucket->globals->items[i];
   5066 	if (ret->type == type) {
   5067 	    switch (type) {
   5068 		case XML_SCHEMA_TYPE_COMPLEX:
   5069 		case XML_SCHEMA_TYPE_SIMPLE:
   5070 		    if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
   5071 			(WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
   5072 			nsName))
   5073 		    {
   5074 			return(ret);
   5075 		    }
   5076 		    break;
   5077 		case XML_SCHEMA_TYPE_GROUP:
   5078 		    if ((WXS_COMP_NAME(ret,
   5079 			    xmlSchemaModelGroupDefPtr) == name) &&
   5080 			(WXS_COMP_TNS(ret,
   5081 			    xmlSchemaModelGroupDefPtr) == nsName))
   5082 		    {
   5083 			return(ret);
   5084 		    }
   5085 		    break;
   5086 		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   5087 		    if ((WXS_COMP_NAME(ret,
   5088 			    xmlSchemaAttributeGroupPtr) == name) &&
   5089 			(WXS_COMP_TNS(ret,
   5090 			    xmlSchemaAttributeGroupPtr) == nsName))
   5091 		    {
   5092 			return(ret);
   5093 		    }
   5094 		    break;
   5095 		default:
   5096 		    /* Should not be hit. */
   5097 		    return(NULL);
   5098 	    }
   5099 	}
   5100     }
   5101 subschemas:
   5102     /*
   5103     * Process imported/included schemas.
   5104     */
   5105     if (bucket->relations != NULL) {
   5106 	xmlSchemaSchemaRelationPtr rel = bucket->relations;
   5107 
   5108 	/*
   5109 	* TODO: Marking the bucket will not avoid multiple searches
   5110 	* in the same schema, but avoids at least circularity.
   5111 	*/
   5112 	bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
   5113 	do {
   5114 	    if ((rel->bucket != NULL) &&
   5115 		((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
   5116 		ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
   5117 		    type, name, nsName);
   5118 		if (ret != NULL)
   5119 		    return(ret);
   5120 	    }
   5121 	    rel = rel->next;
   5122 	} while (rel != NULL);
   5123 	 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
   5124     }
   5125     return(NULL);
   5126 }
   5127 
   5128 /**
   5129  * xmlSchemaAddNotation:
   5130  * @ctxt:  a schema parser context
   5131  * @schema:  the schema being built
   5132  * @name:  the item name
   5133  *
   5134  * Add an XML schema annotation declaration
   5135  * *WARNING* this interface is highly subject to change
   5136  *
   5137  * Returns the new struture or NULL in case of error
   5138  */
   5139 static xmlSchemaNotationPtr
   5140 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5141                      const xmlChar *name, const xmlChar *nsName,
   5142 		     xmlNodePtr node ATTRIBUTE_UNUSED)
   5143 {
   5144     xmlSchemaNotationPtr ret = NULL;
   5145 
   5146     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
   5147         return (NULL);
   5148 
   5149     ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
   5150     if (ret == NULL) {
   5151         xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
   5152         return (NULL);
   5153     }
   5154     memset(ret, 0, sizeof(xmlSchemaNotation));
   5155     ret->type = XML_SCHEMA_TYPE_NOTATION;
   5156     ret->name = name;
   5157     ret->targetNamespace = nsName;
   5158     /* TODO: do we need the node to be set?
   5159     * ret->node = node;*/
   5160     WXS_ADD_GLOBAL(ctxt, ret);
   5161     return (ret);
   5162 }
   5163 
   5164 /**
   5165  * xmlSchemaAddAttribute:
   5166  * @ctxt:  a schema parser context
   5167  * @schema:  the schema being built
   5168  * @name:  the item name
   5169  * @namespace:  the namespace
   5170  *
   5171  * Add an XML schema Attrribute declaration
   5172  * *WARNING* this interface is highly subject to change
   5173  *
   5174  * Returns the new struture or NULL in case of error
   5175  */
   5176 static xmlSchemaAttributePtr
   5177 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5178                       const xmlChar * name, const xmlChar * nsName,
   5179 		      xmlNodePtr node, int topLevel)
   5180 {
   5181     xmlSchemaAttributePtr ret = NULL;
   5182 
   5183     if ((ctxt == NULL) || (schema == NULL))
   5184         return (NULL);
   5185 
   5186     ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
   5187     if (ret == NULL) {
   5188         xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
   5189         return (NULL);
   5190     }
   5191     memset(ret, 0, sizeof(xmlSchemaAttribute));
   5192     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
   5193     ret->node = node;
   5194     ret->name = name;
   5195     ret->targetNamespace = nsName;
   5196 
   5197     if (topLevel)
   5198 	WXS_ADD_GLOBAL(ctxt, ret);
   5199     else
   5200 	WXS_ADD_LOCAL(ctxt, ret);
   5201     WXS_ADD_PENDING(ctxt, ret);
   5202     return (ret);
   5203 }
   5204 
   5205 /**
   5206  * xmlSchemaAddAttributeUse:
   5207  * @ctxt:  a schema parser context
   5208  * @schema:  the schema being built
   5209  * @name:  the item name
   5210  * @namespace:  the namespace
   5211  *
   5212  * Add an XML schema Attrribute declaration
   5213  * *WARNING* this interface is highly subject to change
   5214  *
   5215  * Returns the new struture or NULL in case of error
   5216  */
   5217 static xmlSchemaAttributeUsePtr
   5218 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
   5219 			 xmlNodePtr node)
   5220 {
   5221     xmlSchemaAttributeUsePtr ret = NULL;
   5222 
   5223     if (pctxt == NULL)
   5224         return (NULL);
   5225 
   5226     ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
   5227     if (ret == NULL) {
   5228         xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
   5229         return (NULL);
   5230     }
   5231     memset(ret, 0, sizeof(xmlSchemaAttributeUse));
   5232     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
   5233     ret->node = node;
   5234 
   5235     WXS_ADD_LOCAL(pctxt, ret);
   5236     return (ret);
   5237 }
   5238 
   5239 /*
   5240 * xmlSchemaAddRedef:
   5241 *
   5242 * Adds a redefinition information. This is used at a later stage to:
   5243 * resolve references to the redefined components and to check constraints.
   5244 */
   5245 static xmlSchemaRedefPtr
   5246 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
   5247 		  xmlSchemaBucketPtr targetBucket,
   5248 		  void *item,
   5249 		  const xmlChar *refName,
   5250 		  const xmlChar *refTargetNs)
   5251 {
   5252     xmlSchemaRedefPtr ret;
   5253 
   5254     ret = (xmlSchemaRedefPtr)
   5255 	xmlMalloc(sizeof(xmlSchemaRedef));
   5256     if (ret == NULL) {
   5257 	xmlSchemaPErrMemory(pctxt,
   5258 	    "allocating redefinition info", NULL);
   5259 	return (NULL);
   5260     }
   5261     memset(ret, 0, sizeof(xmlSchemaRedef));
   5262     ret->item = item;
   5263     ret->targetBucket = targetBucket;
   5264     ret->refName = refName;
   5265     ret->refTargetNs = refTargetNs;
   5266     if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
   5267 	WXS_CONSTRUCTOR(pctxt)->redefs = ret;
   5268     else
   5269 	WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
   5270     WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
   5271 
   5272     return (ret);
   5273 }
   5274 
   5275 /**
   5276  * xmlSchemaAddAttributeGroupDefinition:
   5277  * @ctxt:  a schema parser context
   5278  * @schema:  the schema being built
   5279  * @name:  the item name
   5280  * @nsName:  the target namespace
   5281  * @node: the corresponding node
   5282  *
   5283  * Add an XML schema Attrribute Group definition.
   5284  *
   5285  * Returns the new struture or NULL in case of error
   5286  */
   5287 static xmlSchemaAttributeGroupPtr
   5288 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
   5289                            xmlSchemaPtr schema ATTRIBUTE_UNUSED,
   5290 			   const xmlChar *name,
   5291 			   const xmlChar *nsName,
   5292 			   xmlNodePtr node)
   5293 {
   5294     xmlSchemaAttributeGroupPtr ret = NULL;
   5295 
   5296     if ((pctxt == NULL) || (name == NULL))
   5297         return (NULL);
   5298 
   5299     ret = (xmlSchemaAttributeGroupPtr)
   5300         xmlMalloc(sizeof(xmlSchemaAttributeGroup));
   5301     if (ret == NULL) {
   5302 	xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
   5303 	return (NULL);
   5304     }
   5305     memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
   5306     ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
   5307     ret->name = name;
   5308     ret->targetNamespace = nsName;
   5309     ret->node = node;
   5310 
   5311     /* TODO: Remove the flag. */
   5312     ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
   5313     if (pctxt->isRedefine) {
   5314 	pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
   5315 	    ret, name, nsName);
   5316 	if (pctxt->redef == NULL) {
   5317 	    xmlFree(ret);
   5318 	    return(NULL);
   5319 	}
   5320 	pctxt->redefCounter = 0;
   5321     }
   5322     WXS_ADD_GLOBAL(pctxt, ret);
   5323     WXS_ADD_PENDING(pctxt, ret);
   5324     return (ret);
   5325 }
   5326 
   5327 /**
   5328  * xmlSchemaAddElement:
   5329  * @ctxt:  a schema parser context
   5330  * @schema:  the schema being built
   5331  * @name:  the type name
   5332  * @namespace:  the type namespace
   5333  *
   5334  * Add an XML schema Element declaration
   5335  * *WARNING* this interface is highly subject to change
   5336  *
   5337  * Returns the new struture or NULL in case of error
   5338  */
   5339 static xmlSchemaElementPtr
   5340 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
   5341                     const xmlChar * name, const xmlChar * nsName,
   5342 		    xmlNodePtr node, int topLevel)
   5343 {
   5344     xmlSchemaElementPtr ret = NULL;
   5345 
   5346     if ((ctxt == NULL) || (name == NULL))
   5347         return (NULL);
   5348 
   5349     ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
   5350     if (ret == NULL) {
   5351         xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
   5352         return (NULL);
   5353     }
   5354     memset(ret, 0, sizeof(xmlSchemaElement));
   5355     ret->type = XML_SCHEMA_TYPE_ELEMENT;
   5356     ret->name = name;
   5357     ret->targetNamespace = nsName;
   5358     ret->node = node;
   5359 
   5360     if (topLevel)
   5361 	WXS_ADD_GLOBAL(ctxt, ret);
   5362     else
   5363 	WXS_ADD_LOCAL(ctxt, ret);
   5364     WXS_ADD_PENDING(ctxt, ret);
   5365     return (ret);
   5366 }
   5367 
   5368 /**
   5369  * xmlSchemaAddType:
   5370  * @ctxt:  a schema parser context
   5371  * @schema:  the schema being built
   5372  * @name:  the item name
   5373  * @namespace:  the namespace
   5374  *
   5375  * Add an XML schema item
   5376  * *WARNING* this interface is highly subject to change
   5377  *
   5378  * Returns the new struture or NULL in case of error
   5379  */
   5380 static xmlSchemaTypePtr
   5381 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5382 		 xmlSchemaTypeType type,
   5383                  const xmlChar * name, const xmlChar * nsName,
   5384 		 xmlNodePtr node, int topLevel)
   5385 {
   5386     xmlSchemaTypePtr ret = NULL;
   5387 
   5388     if ((ctxt == NULL) || (schema == NULL))
   5389         return (NULL);
   5390 
   5391     ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
   5392     if (ret == NULL) {
   5393         xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
   5394         return (NULL);
   5395     }
   5396     memset(ret, 0, sizeof(xmlSchemaType));
   5397     ret->type = type;
   5398     ret->name = name;
   5399     ret->targetNamespace = nsName;
   5400     ret->node = node;
   5401     if (topLevel) {
   5402 	if (ctxt->isRedefine) {
   5403 	    ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
   5404 		ret, name, nsName);
   5405 	    if (ctxt->redef == NULL) {
   5406 		xmlFree(ret);
   5407 		return(NULL);
   5408 	    }
   5409 	    ctxt->redefCounter = 0;
   5410 	}
   5411 	WXS_ADD_GLOBAL(ctxt, ret);
   5412     } else
   5413 	WXS_ADD_LOCAL(ctxt, ret);
   5414     WXS_ADD_PENDING(ctxt, ret);
   5415     return (ret);
   5416 }
   5417 
   5418 static xmlSchemaQNameRefPtr
   5419 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
   5420 		     xmlSchemaTypeType refType,
   5421 		     const xmlChar *refName,
   5422 		     const xmlChar *refNs)
   5423 {
   5424     xmlSchemaQNameRefPtr ret;
   5425 
   5426     ret = (xmlSchemaQNameRefPtr)
   5427 	xmlMalloc(sizeof(xmlSchemaQNameRef));
   5428     if (ret == NULL) {
   5429 	xmlSchemaPErrMemory(pctxt,
   5430 	    "allocating QName reference item", NULL);
   5431 	return (NULL);
   5432     }
   5433     ret->node = NULL;
   5434     ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
   5435     ret->name = refName;
   5436     ret->targetNamespace = refNs;
   5437     ret->item = NULL;
   5438     ret->itemType = refType;
   5439     /*
   5440     * Store the reference item in the schema.
   5441     */
   5442     WXS_ADD_LOCAL(pctxt, ret);
   5443     return (ret);
   5444 }
   5445 
   5446 static xmlSchemaAttributeUseProhibPtr
   5447 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
   5448 {
   5449     xmlSchemaAttributeUseProhibPtr ret;
   5450 
   5451     ret = (xmlSchemaAttributeUseProhibPtr)
   5452 	xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
   5453     if (ret == NULL) {
   5454 	xmlSchemaPErrMemory(pctxt,
   5455 	    "allocating attribute use prohibition", NULL);
   5456 	return (NULL);
   5457     }
   5458     memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
   5459     ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
   5460     WXS_ADD_LOCAL(pctxt, ret);
   5461     return (ret);
   5462 }
   5463 
   5464 
   5465 /**
   5466  * xmlSchemaAddModelGroup:
   5467  * @ctxt:  a schema parser context
   5468  * @schema:  the schema being built
   5469  * @type: the "compositor" type of the model group
   5470  * @node: the node in the schema doc
   5471  *
   5472  * Adds a schema model group
   5473  * *WARNING* this interface is highly subject to change
   5474  *
   5475  * Returns the new struture or NULL in case of error
   5476  */
   5477 static xmlSchemaModelGroupPtr
   5478 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
   5479 		       xmlSchemaPtr schema,
   5480 		       xmlSchemaTypeType type,
   5481 		       xmlNodePtr node)
   5482 {
   5483     xmlSchemaModelGroupPtr ret = NULL;
   5484 
   5485     if ((ctxt == NULL) || (schema == NULL))
   5486         return (NULL);
   5487 
   5488     ret = (xmlSchemaModelGroupPtr)
   5489 	xmlMalloc(sizeof(xmlSchemaModelGroup));
   5490     if (ret == NULL) {
   5491 	xmlSchemaPErrMemory(ctxt, "allocating model group component",
   5492 	    NULL);
   5493 	return (NULL);
   5494     }
   5495     memset(ret, 0, sizeof(xmlSchemaModelGroup));
   5496     ret->type = type;
   5497     ret->node = node;
   5498     WXS_ADD_LOCAL(ctxt, ret);
   5499     if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
   5500 	(type == XML_SCHEMA_TYPE_CHOICE))
   5501 	WXS_ADD_PENDING(ctxt, ret);
   5502     return (ret);
   5503 }
   5504 
   5505 
   5506 /**
   5507  * xmlSchemaAddParticle:
   5508  * @ctxt:  a schema parser context
   5509  * @schema:  the schema being built
   5510  * @node: the corresponding node in the schema doc
   5511  * @min: the minOccurs
   5512  * @max: the maxOccurs
   5513  *
   5514  * Adds an XML schema particle component.
   5515  * *WARNING* this interface is highly subject to change
   5516  *
   5517  * Returns the new struture or NULL in case of error
   5518  */
   5519 static xmlSchemaParticlePtr
   5520 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
   5521 		     xmlNodePtr node, int min, int max)
   5522 {
   5523     xmlSchemaParticlePtr ret = NULL;
   5524     if (ctxt == NULL)
   5525         return (NULL);
   5526 
   5527 #ifdef DEBUG
   5528     fprintf(stderr, "Adding particle component\n");
   5529 #endif
   5530     ret = (xmlSchemaParticlePtr)
   5531 	xmlMalloc(sizeof(xmlSchemaParticle));
   5532     if (ret == NULL) {
   5533 	xmlSchemaPErrMemory(ctxt, "allocating particle component",
   5534 	    NULL);
   5535 	return (NULL);
   5536     }
   5537     ret->type = XML_SCHEMA_TYPE_PARTICLE;
   5538     ret->annot = NULL;
   5539     ret->node = node;
   5540     ret->minOccurs = min;
   5541     ret->maxOccurs = max;
   5542     ret->next = NULL;
   5543     ret->children = NULL;
   5544 
   5545     WXS_ADD_LOCAL(ctxt, ret);
   5546     /*
   5547     * Note that addition to pending components will be done locally
   5548     * to the specific parsing function, since the most particles
   5549     * need not to be fixed up (i.e. the reference to be resolved).
   5550     * REMOVED: WXS_ADD_PENDING(ctxt, ret);
   5551     */
   5552     return (ret);
   5553 }
   5554 
   5555 /**
   5556  * xmlSchemaAddModelGroupDefinition:
   5557  * @ctxt:  a schema validation context
   5558  * @schema:  the schema being built
   5559  * @name:  the group name
   5560  *
   5561  * Add an XML schema Group definition
   5562  *
   5563  * Returns the new struture or NULL in case of error
   5564  */
   5565 static xmlSchemaModelGroupDefPtr
   5566 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
   5567 				 xmlSchemaPtr schema,
   5568 				 const xmlChar *name,
   5569 				 const xmlChar *nsName,
   5570 				 xmlNodePtr node)
   5571 {
   5572     xmlSchemaModelGroupDefPtr ret = NULL;
   5573 
   5574     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
   5575         return (NULL);
   5576 
   5577     ret = (xmlSchemaModelGroupDefPtr)
   5578 	xmlMalloc(sizeof(xmlSchemaModelGroupDef));
   5579     if (ret == NULL) {
   5580         xmlSchemaPErrMemory(ctxt, "adding group", NULL);
   5581         return (NULL);
   5582     }
   5583     memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
   5584     ret->name = name;
   5585     ret->type = XML_SCHEMA_TYPE_GROUP;
   5586     ret->node = node;
   5587     ret->targetNamespace = nsName;
   5588 
   5589     if (ctxt->isRedefine) {
   5590 	ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
   5591 	    ret, name, nsName);
   5592 	if (ctxt->redef == NULL) {
   5593 	    xmlFree(ret);
   5594 	    return(NULL);
   5595 	}
   5596 	ctxt->redefCounter = 0;
   5597     }
   5598     WXS_ADD_GLOBAL(ctxt, ret);
   5599     WXS_ADD_PENDING(ctxt, ret);
   5600     return (ret);
   5601 }
   5602 
   5603 /**
   5604  * xmlSchemaNewWildcardNs:
   5605  * @ctxt:  a schema validation context
   5606  *
   5607  * Creates a new wildcard namespace constraint.
   5608  *
   5609  * Returns the new struture or NULL in case of error
   5610  */
   5611 static xmlSchemaWildcardNsPtr
   5612 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
   5613 {
   5614     xmlSchemaWildcardNsPtr ret;
   5615 
   5616     ret = (xmlSchemaWildcardNsPtr)
   5617 	xmlMalloc(sizeof(xmlSchemaWildcardNs));
   5618     if (ret == NULL) {
   5619 	xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
   5620 	return (NULL);
   5621     }
   5622     ret->value = NULL;
   5623     ret->next = NULL;
   5624     return (ret);
   5625 }
   5626 
   5627 static xmlSchemaIDCPtr
   5628 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5629                   const xmlChar *name, const xmlChar *nsName,
   5630 		  int category, xmlNodePtr node)
   5631 {
   5632     xmlSchemaIDCPtr ret = NULL;
   5633 
   5634     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
   5635         return (NULL);
   5636 
   5637     ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
   5638     if (ret == NULL) {
   5639         xmlSchemaPErrMemory(ctxt,
   5640 	    "allocating an identity-constraint definition", NULL);
   5641         return (NULL);
   5642     }
   5643     memset(ret, 0, sizeof(xmlSchemaIDC));
   5644     /* The target namespace of the parent element declaration. */
   5645     ret->targetNamespace = nsName;
   5646     ret->name = name;
   5647     ret->type = category;
   5648     ret->node = node;
   5649 
   5650     WXS_ADD_GLOBAL(ctxt, ret);
   5651     /*
   5652     * Only keyrefs need to be fixup up.
   5653     */
   5654     if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
   5655 	WXS_ADD_PENDING(ctxt, ret);
   5656     return (ret);
   5657 }
   5658 
   5659 /**
   5660  * xmlSchemaAddWildcard:
   5661  * @ctxt:  a schema validation context
   5662  * @schema: a schema
   5663  *
   5664  * Adds a wildcard.
   5665  * It corresponds to a xsd:anyAttribute and xsd:any.
   5666  *
   5667  * Returns the new struture or NULL in case of error
   5668  */
   5669 static xmlSchemaWildcardPtr
   5670 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5671 		     xmlSchemaTypeType type, xmlNodePtr node)
   5672 {
   5673     xmlSchemaWildcardPtr ret = NULL;
   5674 
   5675     if ((ctxt == NULL) || (schema == NULL))
   5676         return (NULL);
   5677 
   5678     ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
   5679     if (ret == NULL) {
   5680         xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
   5681         return (NULL);
   5682     }
   5683     memset(ret, 0, sizeof(xmlSchemaWildcard));
   5684     ret->type = type;
   5685     ret->node = node;
   5686     WXS_ADD_LOCAL(ctxt, ret);
   5687     return (ret);
   5688 }
   5689 
   5690 static void
   5691 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
   5692 {
   5693     if (group == NULL)
   5694 	return;
   5695     if (group->members != NULL)
   5696 	xmlSchemaItemListFree(group->members);
   5697     xmlFree(group);
   5698 }
   5699 
   5700 static xmlSchemaSubstGroupPtr
   5701 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
   5702 		       xmlSchemaElementPtr head)
   5703 {
   5704     xmlSchemaSubstGroupPtr ret;
   5705 
   5706     /* Init subst group hash. */
   5707     if (WXS_SUBST_GROUPS(pctxt) == NULL) {
   5708 	WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
   5709 	if (WXS_SUBST_GROUPS(pctxt) == NULL)
   5710 	    return(NULL);
   5711     }
   5712     /* Create a new substitution group. */
   5713     ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
   5714     if (ret == NULL) {
   5715 	xmlSchemaPErrMemory(NULL,
   5716 	    "allocating a substitution group container", NULL);
   5717 	return(NULL);
   5718     }
   5719     memset(ret, 0, sizeof(xmlSchemaSubstGroup));
   5720     ret->head = head;
   5721     /* Create list of members. */
   5722     ret->members = xmlSchemaItemListCreate();
   5723     if (ret->members == NULL) {
   5724 	xmlSchemaSubstGroupFree(ret);
   5725 	return(NULL);
   5726     }
   5727     /* Add subst group to hash. */
   5728     if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
   5729 	head->name, head->targetNamespace, ret) != 0) {
   5730 	PERROR_INT("xmlSchemaSubstGroupAdd",
   5731 	    "failed to add a new substitution container");
   5732 	xmlSchemaSubstGroupFree(ret);
   5733 	return(NULL);
   5734     }
   5735     return(ret);
   5736 }
   5737 
   5738 static xmlSchemaSubstGroupPtr
   5739 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
   5740 		       xmlSchemaElementPtr head)
   5741 {
   5742     if (WXS_SUBST_GROUPS(pctxt) == NULL)
   5743 	return(NULL);
   5744     return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
   5745 	head->name, head->targetNamespace));
   5746 
   5747 }
   5748 
   5749 /**
   5750  * xmlSchemaAddElementSubstitutionMember:
   5751  * @pctxt:  a schema parser context
   5752  * @head:  the head of the substitution group
   5753  * @member: the new member of the substitution group
   5754  *
   5755  * Allocate a new annotation structure.
   5756  *
   5757  * Returns the newly allocated structure or NULL in case or error
   5758  */
   5759 static int
   5760 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
   5761 				      xmlSchemaElementPtr head,
   5762 				      xmlSchemaElementPtr member)
   5763 {
   5764     xmlSchemaSubstGroupPtr substGroup = NULL;
   5765 
   5766     if ((pctxt == NULL) || (head == NULL) || (member == NULL))
   5767 	return (-1);
   5768 
   5769     substGroup = xmlSchemaSubstGroupGet(pctxt, head);
   5770     if (substGroup == NULL)
   5771 	substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
   5772     if (substGroup == NULL)
   5773 	return(-1);
   5774     if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
   5775 	return(-1);
   5776     return(0);
   5777 }
   5778 
   5779 /************************************************************************
   5780  *									*
   5781  *		Utilities for parsing					*
   5782  *									*
   5783  ************************************************************************/
   5784 
   5785 /**
   5786  * xmlSchemaPValAttrNodeQNameValue:
   5787  * @ctxt:  a schema parser context
   5788  * @schema: the schema context
   5789  * @ownerDes: the designation of the parent element
   5790  * @ownerItem: the parent as a schema object
   5791  * @value:  the QName value
   5792  * @local: the resulting local part if found, the attribute value otherwise
   5793  * @uri:  the resulting namespace URI if found
   5794  *
   5795  * Extracts the local name and the URI of a QName value and validates it.
   5796  * This one is intended to be used on attribute values that
   5797  * should resolve to schema components.
   5798  *
   5799  * Returns 0, in case the QName is valid, a positive error code
   5800  * if not valid and -1 if an internal error occurs.
   5801  */
   5802 static int
   5803 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
   5804 				       xmlSchemaPtr schema,
   5805 				       xmlSchemaBasicItemPtr ownerItem,
   5806 				       xmlAttrPtr attr,
   5807 				       const xmlChar *value,
   5808 				       const xmlChar **uri,
   5809 				       const xmlChar **local)
   5810 {
   5811     const xmlChar *pref;
   5812     xmlNsPtr ns;
   5813     int len, ret;
   5814 
   5815     *uri = NULL;
   5816     *local = NULL;
   5817     ret = xmlValidateQName(value, 1);
   5818     if (ret > 0) {
   5819 	xmlSchemaPSimpleTypeErr(ctxt,
   5820 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5821 	    ownerItem, (xmlNodePtr) attr,
   5822 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
   5823 	    NULL, value, NULL, NULL, NULL);
   5824 	*local = value;
   5825 	return (ctxt->err);
   5826     } else if (ret < 0)
   5827 	return (-1);
   5828 
   5829     if (!strchr((char *) value, ':')) {
   5830 	ns = xmlSearchNs(attr->doc, attr->parent, NULL);
   5831 	if (ns)
   5832 	    *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
   5833 	else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
   5834 	    /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
   5835 	    * parser context. */
   5836 	    /*
   5837 	    * This one takes care of included schemas with no
   5838 	    * target namespace.
   5839 	    */
   5840 	    *uri = ctxt->targetNamespace;
   5841 	}
   5842 	*local = xmlDictLookup(ctxt->dict, value, -1);
   5843 	return (0);
   5844     }
   5845     /*
   5846     * At this point xmlSplitQName3 has to return a local name.
   5847     */
   5848     *local = xmlSplitQName3(value, &len);
   5849     *local = xmlDictLookup(ctxt->dict, *local, -1);
   5850     pref = xmlDictLookup(ctxt->dict, value, len);
   5851     ns = xmlSearchNs(attr->doc, attr->parent, pref);
   5852     if (ns == NULL) {
   5853 	xmlSchemaPSimpleTypeErr(ctxt,
   5854 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5855 	    ownerItem, (xmlNodePtr) attr,
   5856 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
   5857 	    "The value '%s' of simple type 'xs:QName' has no "
   5858 	    "corresponding namespace declaration in scope", value, NULL);
   5859 	return (ctxt->err);
   5860     } else {
   5861         *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
   5862     }
   5863     return (0);
   5864 }
   5865 
   5866 /**
   5867  * xmlSchemaPValAttrNodeQName:
   5868  * @ctxt:  a schema parser context
   5869  * @schema: the schema context
   5870  * @ownerDes: the designation of the owner element
   5871  * @ownerItem: the owner as a schema object
   5872  * @attr:  the attribute node
   5873  * @local: the resulting local part if found, the attribute value otherwise
   5874  * @uri:  the resulting namespace URI if found
   5875  *
   5876  * Extracts and validates the QName of an attribute value.
   5877  * This one is intended to be used on attribute values that
   5878  * should resolve to schema components.
   5879  *
   5880  * Returns 0, in case the QName is valid, a positive error code
   5881  * if not valid and -1 if an internal error occurs.
   5882  */
   5883 static int
   5884 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
   5885 				       xmlSchemaPtr schema,
   5886 				       xmlSchemaBasicItemPtr ownerItem,
   5887 				       xmlAttrPtr attr,
   5888 				       const xmlChar **uri,
   5889 				       const xmlChar **local)
   5890 {
   5891     const xmlChar *value;
   5892 
   5893     value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   5894     return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
   5895 	ownerItem, attr, value, uri, local));
   5896 }
   5897 
   5898 /**
   5899  * xmlSchemaPValAttrQName:
   5900  * @ctxt:  a schema parser context
   5901  * @schema: the schema context
   5902  * @ownerDes: the designation of the parent element
   5903  * @ownerItem: the owner as a schema object
   5904  * @ownerElem:  the parent node of the attribute
   5905  * @name:  the name of the attribute
   5906  * @local: the resulting local part if found, the attribute value otherwise
   5907  * @uri:  the resulting namespace URI if found
   5908  *
   5909  * Extracts and validates the QName of an attribute value.
   5910  *
   5911  * Returns 0, in case the QName is valid, a positive error code
   5912  * if not valid and -1 if an internal error occurs.
   5913  */
   5914 static int
   5915 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
   5916 				   xmlSchemaPtr schema,
   5917 				   xmlSchemaBasicItemPtr ownerItem,
   5918 				   xmlNodePtr ownerElem,
   5919 				   const char *name,
   5920 				   const xmlChar **uri,
   5921 				   const xmlChar **local)
   5922 {
   5923     xmlAttrPtr attr;
   5924 
   5925     attr = xmlSchemaGetPropNode(ownerElem, name);
   5926     if (attr == NULL) {
   5927 	*local = NULL;
   5928 	*uri = NULL;
   5929 	return (0);
   5930     }
   5931     return (xmlSchemaPValAttrNodeQName(ctxt, schema,
   5932 	ownerItem, attr, uri, local));
   5933 }
   5934 
   5935 /**
   5936  * xmlSchemaPValAttrID:
   5937  * @ctxt:  a schema parser context
   5938  * @schema: the schema context
   5939  * @ownerDes: the designation of the parent element
   5940  * @ownerItem: the owner as a schema object
   5941  * @ownerElem:  the parent node of the attribute
   5942  * @name:  the name of the attribute
   5943  *
   5944  * Extracts and validates the ID of an attribute value.
   5945  *
   5946  * Returns 0, in case the ID is valid, a positive error code
   5947  * if not valid and -1 if an internal error occurs.
   5948  */
   5949 static int
   5950 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
   5951 {
   5952     int ret;
   5953     const xmlChar *value;
   5954 
   5955     if (attr == NULL)
   5956 	return(0);
   5957     value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
   5958     ret = xmlValidateNCName(value, 1);
   5959     if (ret == 0) {
   5960 	/*
   5961 	* NOTE: the IDness might have already be declared in the DTD
   5962 	*/
   5963 	if (attr->atype != XML_ATTRIBUTE_ID) {
   5964 	    xmlIDPtr res;
   5965 	    xmlChar *strip;
   5966 
   5967 	    /*
   5968 	    * TODO: Use xmlSchemaStrip here; it's not exported at this
   5969 	    * moment.
   5970 	    */
   5971 	    strip = xmlSchemaCollapseString(value);
   5972 	    if (strip != NULL) {
   5973 		xmlFree((xmlChar *) value);
   5974 		value = strip;
   5975 	    }
   5976 	    res = xmlAddID(NULL, attr->doc, value, attr);
   5977 	    if (res == NULL) {
   5978 		ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   5979 		xmlSchemaPSimpleTypeErr(ctxt,
   5980 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5981 		    NULL, (xmlNodePtr) attr,
   5982 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
   5983 		    NULL, NULL, "Duplicate value '%s' of simple "
   5984 		    "type 'xs:ID'", value, NULL);
   5985 	    } else
   5986 		attr->atype = XML_ATTRIBUTE_ID;
   5987 	}
   5988     } else if (ret > 0) {
   5989 	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   5990 	xmlSchemaPSimpleTypeErr(ctxt,
   5991 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5992 	    NULL, (xmlNodePtr) attr,
   5993 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
   5994 	    NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
   5995 	    "not a valid 'xs:NCName'",
   5996 	    value, NULL);
   5997     }
   5998     if (value != NULL)
   5999 	xmlFree((xmlChar *)value);
   6000 
   6001     return (ret);
   6002 }
   6003 
   6004 static int
   6005 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
   6006 		    xmlNodePtr ownerElem,
   6007 		    const xmlChar *name)
   6008 {
   6009     xmlAttrPtr attr;
   6010 
   6011     attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
   6012     if (attr == NULL)
   6013 	return(0);
   6014     return(xmlSchemaPValAttrNodeID(ctxt, attr));
   6015 
   6016 }
   6017 
   6018 /**
   6019  * xmlGetMaxOccurs:
   6020  * @ctxt:  a schema validation context
   6021  * @node:  a subtree containing XML Schema informations
   6022  *
   6023  * Get the maxOccurs property
   6024  *
   6025  * Returns the default if not found, or the value
   6026  */
   6027 static int
   6028 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
   6029 		int min, int max, int def, const char *expected)
   6030 {
   6031     const xmlChar *val, *cur;
   6032     int ret = 0;
   6033     xmlAttrPtr attr;
   6034 
   6035     attr = xmlSchemaGetPropNode(node, "maxOccurs");
   6036     if (attr == NULL)
   6037 	return (def);
   6038     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6039 
   6040     if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
   6041 	if (max != UNBOUNDED) {
   6042 	    xmlSchemaPSimpleTypeErr(ctxt,
   6043 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6044 		/* XML_SCHEMAP_INVALID_MINOCCURS, */
   6045 		NULL, (xmlNodePtr) attr, NULL, expected,
   6046 		val, NULL, NULL, NULL);
   6047 	    return (def);
   6048 	} else
   6049 	    return (UNBOUNDED);  /* encoding it with -1 might be another option */
   6050     }
   6051 
   6052     cur = val;
   6053     while (IS_BLANK_CH(*cur))
   6054         cur++;
   6055     if (*cur == 0) {
   6056         xmlSchemaPSimpleTypeErr(ctxt,
   6057 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6058 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6059 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6060 	    val, NULL, NULL, NULL);
   6061 	return (def);
   6062     }
   6063     while ((*cur >= '0') && (*cur <= '9')) {
   6064         ret = ret * 10 + (*cur - '0');
   6065         cur++;
   6066     }
   6067     while (IS_BLANK_CH(*cur))
   6068         cur++;
   6069     /*
   6070     * TODO: Restrict the maximal value to Integer.
   6071     */
   6072     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
   6073 	xmlSchemaPSimpleTypeErr(ctxt,
   6074 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6075 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6076 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6077 	    val, NULL, NULL, NULL);
   6078         return (def);
   6079     }
   6080     return (ret);
   6081 }
   6082 
   6083 /**
   6084  * xmlGetMinOccurs:
   6085  * @ctxt:  a schema validation context
   6086  * @node:  a subtree containing XML Schema informations
   6087  *
   6088  * Get the minOccurs property
   6089  *
   6090  * Returns the default if not found, or the value
   6091  */
   6092 static int
   6093 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
   6094 		int min, int max, int def, const char *expected)
   6095 {
   6096     const xmlChar *val, *cur;
   6097     int ret = 0;
   6098     xmlAttrPtr attr;
   6099 
   6100     attr = xmlSchemaGetPropNode(node, "minOccurs");
   6101     if (attr == NULL)
   6102 	return (def);
   6103     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6104     cur = val;
   6105     while (IS_BLANK_CH(*cur))
   6106         cur++;
   6107     if (*cur == 0) {
   6108         xmlSchemaPSimpleTypeErr(ctxt,
   6109 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6110 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6111 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6112 	    val, NULL, NULL, NULL);
   6113         return (def);
   6114     }
   6115     while ((*cur >= '0') && (*cur <= '9')) {
   6116         ret = ret * 10 + (*cur - '0');
   6117         cur++;
   6118     }
   6119     while (IS_BLANK_CH(*cur))
   6120         cur++;
   6121     /*
   6122     * TODO: Restrict the maximal value to Integer.
   6123     */
   6124     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
   6125 	xmlSchemaPSimpleTypeErr(ctxt,
   6126 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6127 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6128 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6129 	    val, NULL, NULL, NULL);
   6130         return (def);
   6131     }
   6132     return (ret);
   6133 }
   6134 
   6135 /**
   6136  * xmlSchemaPGetBoolNodeValue:
   6137  * @ctxt:  a schema validation context
   6138  * @ownerDes:  owner designation
   6139  * @ownerItem:  the owner as a schema item
   6140  * @node: the node holding the value
   6141  *
   6142  * Converts a boolean string value into 1 or 0.
   6143  *
   6144  * Returns 0 or 1.
   6145  */
   6146 static int
   6147 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
   6148 			   xmlSchemaBasicItemPtr ownerItem,
   6149 			   xmlNodePtr node)
   6150 {
   6151     xmlChar *value = NULL;
   6152     int res = 0;
   6153 
   6154     value = xmlNodeGetContent(node);
   6155     /*
   6156     * 3.2.2.1 Lexical representation
   6157     * An instance of a datatype that is defined as `boolean`
   6158     * can have the following legal literals {true, false, 1, 0}.
   6159     */
   6160     if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
   6161         res = 1;
   6162     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
   6163         res = 0;
   6164     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
   6165 	res = 1;
   6166     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
   6167         res = 0;
   6168     else {
   6169         xmlSchemaPSimpleTypeErr(ctxt,
   6170 	    XML_SCHEMAP_INVALID_BOOLEAN,
   6171 	    ownerItem, node,
   6172 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
   6173 	    NULL, BAD_CAST value,
   6174 	    NULL, NULL, NULL);
   6175     }
   6176     if (value != NULL)
   6177 	xmlFree(value);
   6178     return (res);
   6179 }
   6180 
   6181 /**
   6182  * xmlGetBooleanProp:
   6183  * @ctxt:  a schema validation context
   6184  * @node:  a subtree containing XML Schema informations
   6185  * @name:  the attribute name
   6186  * @def:  the default value
   6187  *
   6188  * Evaluate if a boolean property is set
   6189  *
   6190  * Returns the default if not found, 0 if found to be false,
   6191  * 1 if found to be true
   6192  */
   6193 static int
   6194 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
   6195 		  xmlNodePtr node,
   6196                   const char *name, int def)
   6197 {
   6198     const xmlChar *val;
   6199 
   6200     val = xmlSchemaGetProp(ctxt, node, name);
   6201     if (val == NULL)
   6202         return (def);
   6203     /*
   6204     * 3.2.2.1 Lexical representation
   6205     * An instance of a datatype that is defined as `boolean`
   6206     * can have the following legal literals {true, false, 1, 0}.
   6207     */
   6208     if (xmlStrEqual(val, BAD_CAST "true"))
   6209         def = 1;
   6210     else if (xmlStrEqual(val, BAD_CAST "false"))
   6211         def = 0;
   6212     else if (xmlStrEqual(val, BAD_CAST "1"))
   6213 	def = 1;
   6214     else if (xmlStrEqual(val, BAD_CAST "0"))
   6215         def = 0;
   6216     else {
   6217         xmlSchemaPSimpleTypeErr(ctxt,
   6218 	    XML_SCHEMAP_INVALID_BOOLEAN,
   6219 	    NULL,
   6220 	    (xmlNodePtr) xmlSchemaGetPropNode(node, name),
   6221 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
   6222 	    NULL, val, NULL, NULL, NULL);
   6223     }
   6224     return (def);
   6225 }
   6226 
   6227 /************************************************************************
   6228  *									*
   6229  *		Shema extraction from an Infoset			*
   6230  *									*
   6231  ************************************************************************/
   6232 static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
   6233                                                  ctxt, xmlSchemaPtr schema,
   6234                                                  xmlNodePtr node,
   6235 						 int topLevel);
   6236 static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
   6237                                                   ctxt,
   6238                                                   xmlSchemaPtr schema,
   6239                                                   xmlNodePtr node,
   6240 						  int topLevel);
   6241 static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
   6242                                                   ctxt,
   6243                                                   xmlSchemaPtr schema,
   6244                                                   xmlNodePtr node,
   6245 						  xmlSchemaTypeType parentType);
   6246 static xmlSchemaBasicItemPtr
   6247 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
   6248 			     xmlSchemaPtr schema,
   6249 			     xmlNodePtr node,
   6250 			     xmlSchemaItemListPtr uses,
   6251 			     int parentType);
   6252 static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
   6253                                            xmlSchemaPtr schema,
   6254                                            xmlNodePtr node);
   6255 static xmlSchemaWildcardPtr
   6256 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
   6257                            xmlSchemaPtr schema, xmlNodePtr node);
   6258 
   6259 /**
   6260  * xmlSchemaPValAttrNodeValue:
   6261  *
   6262  * @ctxt:  a schema parser context
   6263  * @ownerDes: the designation of the parent element
   6264  * @ownerItem: the schema object owner if existent
   6265  * @attr:  the schema attribute node being validated
   6266  * @value: the value
   6267  * @type: the built-in type to be validated against
   6268  *
   6269  * Validates a value against the given built-in type.
   6270  * This one is intended to be used internally for validation
   6271  * of schema attribute values during parsing of the schema.
   6272  *
   6273  * Returns 0 if the value is valid, a positive error code
   6274  * number otherwise and -1 in case of an internal or API error.
   6275  */
   6276 static int
   6277 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
   6278 			   xmlSchemaBasicItemPtr ownerItem,
   6279 			   xmlAttrPtr attr,
   6280 			   const xmlChar *value,
   6281 			   xmlSchemaTypePtr type)
   6282 {
   6283 
   6284     int ret = 0;
   6285 
   6286     /*
   6287     * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
   6288     * one is really meant to be used internally, so better not.
   6289     */
   6290     if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
   6291 	return (-1);
   6292     if (type->type != XML_SCHEMA_TYPE_BASIC) {
   6293 	PERROR_INT("xmlSchemaPValAttrNodeValue",
   6294 	    "the given type is not a built-in type");
   6295 	return (-1);
   6296     }
   6297     switch (type->builtInType) {
   6298 	case XML_SCHEMAS_NCNAME:
   6299 	case XML_SCHEMAS_QNAME:
   6300 	case XML_SCHEMAS_ANYURI:
   6301 	case XML_SCHEMAS_TOKEN:
   6302 	case XML_SCHEMAS_LANGUAGE:
   6303 	    ret = xmlSchemaValPredefTypeNode(type, value, NULL,
   6304 		(xmlNodePtr) attr);
   6305 	    break;
   6306 	default: {
   6307 	    PERROR_INT("xmlSchemaPValAttrNodeValue",
   6308 		"validation using the given type is not supported while "
   6309 		"parsing a schema");
   6310 	    return (-1);
   6311 	}
   6312     }
   6313     /*
   6314     * TODO: Should we use the S4S error codes instead?
   6315     */
   6316     if (ret < 0) {
   6317 	PERROR_INT("xmlSchemaPValAttrNodeValue",
   6318 	    "failed to validate a schema attribute value");
   6319 	return (-1);
   6320     } else if (ret > 0) {
   6321 	if (WXS_IS_LIST(type))
   6322 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   6323 	else
   6324 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
   6325 	xmlSchemaPSimpleTypeErr(pctxt,
   6326 	    ret, ownerItem, (xmlNodePtr) attr,
   6327 	    type, NULL, value, NULL, NULL, NULL);
   6328     }
   6329     return (ret);
   6330 }
   6331 
   6332 /**
   6333  * xmlSchemaPValAttrNode:
   6334  *
   6335  * @ctxt:  a schema parser context
   6336  * @ownerDes: the designation of the parent element
   6337  * @ownerItem: the schema object owner if existent
   6338  * @attr:  the schema attribute node being validated
   6339  * @type: the built-in type to be validated against
   6340  * @value: the resulting value if any
   6341  *
   6342  * Extracts and validates a value against the given built-in type.
   6343  * This one is intended to be used internally for validation
   6344  * of schema attribute values during parsing of the schema.
   6345  *
   6346  * Returns 0 if the value is valid, a positive error code
   6347  * number otherwise and -1 in case of an internal or API error.
   6348  */
   6349 static int
   6350 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
   6351 			   xmlSchemaBasicItemPtr ownerItem,
   6352 			   xmlAttrPtr attr,
   6353 			   xmlSchemaTypePtr type,
   6354 			   const xmlChar **value)
   6355 {
   6356     const xmlChar *val;
   6357 
   6358     if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
   6359 	return (-1);
   6360 
   6361     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6362     if (value != NULL)
   6363 	*value = val;
   6364 
   6365     return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
   6366 	val, type));
   6367 }
   6368 
   6369 /**
   6370  * xmlSchemaPValAttr:
   6371  *
   6372  * @ctxt:  a schema parser context
   6373  * @node: the element node of the attribute
   6374  * @ownerDes: the designation of the parent element
   6375  * @ownerItem: the schema object owner if existent
   6376  * @ownerElem: the owner element node
   6377  * @name:  the name of the schema attribute node
   6378  * @type: the built-in type to be validated against
   6379  * @value: the resulting value if any
   6380  *
   6381  * Extracts and validates a value against the given built-in type.
   6382  * This one is intended to be used internally for validation
   6383  * of schema attribute values during parsing of the schema.
   6384  *
   6385  * Returns 0 if the value is valid, a positive error code
   6386  * number otherwise and -1 in case of an internal or API error.
   6387  */
   6388 static int
   6389 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
   6390 		       xmlSchemaBasicItemPtr ownerItem,
   6391 		       xmlNodePtr ownerElem,
   6392 		       const char *name,
   6393 		       xmlSchemaTypePtr type,
   6394 		       const xmlChar **value)
   6395 {
   6396     xmlAttrPtr attr;
   6397 
   6398     if ((ctxt == NULL) || (type == NULL)) {
   6399 	if (value != NULL)
   6400 	    *value = NULL;
   6401 	return (-1);
   6402     }
   6403     if (type->type != XML_SCHEMA_TYPE_BASIC) {
   6404 	if (value != NULL)
   6405 	    *value = NULL;
   6406 	xmlSchemaPErr(ctxt, ownerElem,
   6407 	    XML_SCHEMAP_INTERNAL,
   6408 	    "Internal error: xmlSchemaPValAttr, the given "
   6409 	    "type '%s' is not a built-in type.\n",
   6410 	    type->name, NULL);
   6411 	return (-1);
   6412     }
   6413     attr = xmlSchemaGetPropNode(ownerElem, name);
   6414     if (attr == NULL) {
   6415 	if (value != NULL)
   6416 	    *value = NULL;
   6417 	return (0);
   6418     }
   6419     return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
   6420 	type, value));
   6421 }
   6422 
   6423 static int
   6424 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
   6425 		  xmlSchemaPtr schema ATTRIBUTE_UNUSED,
   6426 		  xmlNodePtr node,
   6427 		  xmlAttrPtr attr,
   6428 		  const xmlChar *namespaceName)
   6429 {
   6430     /* TODO: Pointer comparison instead? */
   6431     if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
   6432 	return (0);
   6433     if (xmlStrEqual(xmlSchemaNs, namespaceName))
   6434 	return (0);
   6435     /*
   6436     * Check if the referenced namespace was <import>ed.
   6437     */
   6438     if (WXS_BUCKET(pctxt)->relations != NULL) {
   6439 	xmlSchemaSchemaRelationPtr rel;
   6440 
   6441 	rel = WXS_BUCKET(pctxt)->relations;
   6442 	do {
   6443 	    if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
   6444 		xmlStrEqual(namespaceName, rel->importNamespace))
   6445 		return (0);
   6446 	    rel = rel->next;
   6447 	} while (rel != NULL);
   6448     }
   6449     /*
   6450     * No matching <import>ed namespace found.
   6451     */
   6452     {
   6453 	xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
   6454 
   6455 	if (namespaceName == NULL)
   6456 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   6457 		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
   6458 		"References from this schema to components in no "
   6459 		"namespace are not allowed, since not indicated by an "
   6460 		"import statement", NULL, NULL);
   6461 	else
   6462 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   6463 		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
   6464 		"References from this schema to components in the "
   6465 		"namespace '%s' are not allowed, since not indicated by an "
   6466 		"import statement", namespaceName, NULL);
   6467     }
   6468     return (XML_SCHEMAP_SRC_RESOLVE);
   6469 }
   6470 
   6471 /**
   6472  * xmlSchemaParseLocalAttributes:
   6473  * @ctxt:  a schema validation context
   6474  * @schema:  the schema being built
   6475  * @node:  a subtree containing XML Schema informations
   6476  * @type:  the hosting type where the attributes will be anchored
   6477  *
   6478  * Parses attribute uses and attribute declarations and
   6479  * attribute group references.
   6480  */
   6481 static int
   6482 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6483                         xmlNodePtr *child, xmlSchemaItemListPtr *list,
   6484 			int parentType, int *hasRefs)
   6485 {
   6486     void *item;
   6487 
   6488     while ((IS_SCHEMA((*child), "attribute")) ||
   6489            (IS_SCHEMA((*child), "attributeGroup"))) {
   6490         if (IS_SCHEMA((*child), "attribute")) {
   6491 	    item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
   6492 		*list, parentType);
   6493         } else {
   6494             item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
   6495 	    if ((item != NULL) && (hasRefs != NULL))
   6496 		*hasRefs = 1;
   6497         }
   6498 	if (item != NULL) {
   6499 	    if (*list == NULL) {
   6500 		/* TODO: Customize grow factor. */
   6501 		*list = xmlSchemaItemListCreate();
   6502 		if (*list == NULL)
   6503 		    return(-1);
   6504 	    }
   6505 	    if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
   6506 		return(-1);
   6507 	}
   6508         *child = (*child)->next;
   6509     }
   6510     return (0);
   6511 }
   6512 
   6513 /**
   6514  * xmlSchemaParseAnnotation:
   6515  * @ctxt:  a schema validation context
   6516  * @schema:  the schema being built
   6517  * @node:  a subtree containing XML Schema informations
   6518  *
   6519  * parse a XML schema Attrribute declaration
   6520  * *WARNING* this interface is highly subject to change
   6521  *
   6522  * Returns -1 in case of error, 0 if the declaration is improper and
   6523  *         1 in case of success.
   6524  */
   6525 static xmlSchemaAnnotPtr
   6526 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
   6527 {
   6528     xmlSchemaAnnotPtr ret;
   6529     xmlNodePtr child = NULL;
   6530     xmlAttrPtr attr;
   6531     int barked = 0;
   6532 
   6533     /*
   6534     * INFO: S4S completed.
   6535     */
   6536     /*
   6537     * id = ID
   6538     * {any attributes with non-schema namespace . . .}>
   6539     * Content: (appinfo | documentation)*
   6540     */
   6541     if ((ctxt == NULL) || (node == NULL))
   6542         return (NULL);
   6543     if (needed)
   6544 	ret = xmlSchemaNewAnnot(ctxt, node);
   6545     else
   6546 	ret = NULL;
   6547     attr = node->properties;
   6548     while (attr != NULL) {
   6549 	if (((attr->ns == NULL) &&
   6550 	    (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
   6551 	    ((attr->ns != NULL) &&
   6552 	    xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
   6553 
   6554 	    xmlSchemaPIllegalAttrErr(ctxt,
   6555 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6556 	}
   6557 	attr = attr->next;
   6558     }
   6559     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   6560     /*
   6561     * And now for the children...
   6562     */
   6563     child = node->children;
   6564     while (child != NULL) {
   6565 	if (IS_SCHEMA(child, "appinfo")) {
   6566 	    /* TODO: make available the content of "appinfo". */
   6567 	    /*
   6568 	    * source = anyURI
   6569 	    * {any attributes with non-schema namespace . . .}>
   6570 	    * Content: ({any})*
   6571 	    */
   6572 	    attr = child->properties;
   6573 	    while (attr != NULL) {
   6574 		if (((attr->ns == NULL) &&
   6575 		     (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
   6576 		     ((attr->ns != NULL) &&
   6577 		      xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
   6578 
   6579 		    xmlSchemaPIllegalAttrErr(ctxt,
   6580 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6581 		}
   6582 		attr = attr->next;
   6583 	    }
   6584 	    xmlSchemaPValAttr(ctxt, NULL, child, "source",
   6585 		xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
   6586 	    child = child->next;
   6587 	} else if (IS_SCHEMA(child, "documentation")) {
   6588 	    /* TODO: make available the content of "documentation". */
   6589 	    /*
   6590 	    * source = anyURI
   6591 	    * {any attributes with non-schema namespace . . .}>
   6592 	    * Content: ({any})*
   6593 	    */
   6594 	    attr = child->properties;
   6595 	    while (attr != NULL) {
   6596 		if (attr->ns == NULL) {
   6597 		    if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
   6598 			xmlSchemaPIllegalAttrErr(ctxt,
   6599 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6600 		    }
   6601 		} else {
   6602 		    if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
   6603 			(xmlStrEqual(attr->name, BAD_CAST "lang") &&
   6604 			(!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
   6605 
   6606 			xmlSchemaPIllegalAttrErr(ctxt,
   6607 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6608 		    }
   6609 		}
   6610 		attr = attr->next;
   6611 	    }
   6612 	    /*
   6613 	    * Attribute "xml:lang".
   6614 	    */
   6615 	    attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
   6616 	    if (attr != NULL)
   6617 		xmlSchemaPValAttrNode(ctxt, NULL, attr,
   6618 		xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
   6619 	    child = child->next;
   6620 	} else {
   6621 	    if (!barked)
   6622 		xmlSchemaPContentErr(ctxt,
   6623 		    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   6624 		    NULL, node, child, NULL, "(appinfo | documentation)*");
   6625 	    barked = 1;
   6626 	    child = child->next;
   6627 	}
   6628     }
   6629 
   6630     return (ret);
   6631 }
   6632 
   6633 /**
   6634  * xmlSchemaParseFacet:
   6635  * @ctxt:  a schema validation context
   6636  * @schema:  the schema being built
   6637  * @node:  a subtree containing XML Schema informations
   6638  *
   6639  * parse a XML schema Facet declaration
   6640  * *WARNING* this interface is highly subject to change
   6641  *
   6642  * Returns the new type structure or NULL in case of error
   6643  */
   6644 static xmlSchemaFacetPtr
   6645 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6646                     xmlNodePtr node)
   6647 {
   6648     xmlSchemaFacetPtr facet;
   6649     xmlNodePtr child = NULL;
   6650     const xmlChar *value;
   6651 
   6652     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   6653         return (NULL);
   6654 
   6655     facet = xmlSchemaNewFacet();
   6656     if (facet == NULL) {
   6657         xmlSchemaPErrMemory(ctxt, "allocating facet", node);
   6658         return (NULL);
   6659     }
   6660     facet->node = node;
   6661     value = xmlSchemaGetProp(ctxt, node, "value");
   6662     if (value == NULL) {
   6663         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
   6664                        "Facet %s has no value\n", node->name, NULL);
   6665         xmlSchemaFreeFacet(facet);
   6666         return (NULL);
   6667     }
   6668     if (IS_SCHEMA(node, "minInclusive")) {
   6669         facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
   6670     } else if (IS_SCHEMA(node, "minExclusive")) {
   6671         facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
   6672     } else if (IS_SCHEMA(node, "maxInclusive")) {
   6673         facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
   6674     } else if (IS_SCHEMA(node, "maxExclusive")) {
   6675         facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
   6676     } else if (IS_SCHEMA(node, "totalDigits")) {
   6677         facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
   6678     } else if (IS_SCHEMA(node, "fractionDigits")) {
   6679         facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
   6680     } else if (IS_SCHEMA(node, "pattern")) {
   6681         facet->type = XML_SCHEMA_FACET_PATTERN;
   6682     } else if (IS_SCHEMA(node, "enumeration")) {
   6683         facet->type = XML_SCHEMA_FACET_ENUMERATION;
   6684     } else if (IS_SCHEMA(node, "whiteSpace")) {
   6685         facet->type = XML_SCHEMA_FACET_WHITESPACE;
   6686     } else if (IS_SCHEMA(node, "length")) {
   6687         facet->type = XML_SCHEMA_FACET_LENGTH;
   6688     } else if (IS_SCHEMA(node, "maxLength")) {
   6689         facet->type = XML_SCHEMA_FACET_MAXLENGTH;
   6690     } else if (IS_SCHEMA(node, "minLength")) {
   6691         facet->type = XML_SCHEMA_FACET_MINLENGTH;
   6692     } else {
   6693         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
   6694                        "Unknown facet type %s\n", node->name, NULL);
   6695         xmlSchemaFreeFacet(facet);
   6696         return (NULL);
   6697     }
   6698     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   6699     facet->value = value;
   6700     if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
   6701 	(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
   6702 	const xmlChar *fixed;
   6703 
   6704 	fixed = xmlSchemaGetProp(ctxt, node, "fixed");
   6705 	if (fixed != NULL) {
   6706 	    if (xmlStrEqual(fixed, BAD_CAST "true"))
   6707 		facet->fixed = 1;
   6708 	}
   6709     }
   6710     child = node->children;
   6711 
   6712     if (IS_SCHEMA(child, "annotation")) {
   6713         facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   6714         child = child->next;
   6715     }
   6716     if (child != NULL) {
   6717         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
   6718                        "Facet %s has unexpected child content\n",
   6719                        node->name, NULL);
   6720     }
   6721     return (facet);
   6722 }
   6723 
   6724 /**
   6725  * xmlSchemaParseWildcardNs:
   6726  * @ctxt:  a schema parser context
   6727  * @wildc:  the wildcard, already created
   6728  * @node:  a subtree containing XML Schema informations
   6729  *
   6730  * Parses the attribute "processContents" and "namespace"
   6731  * of a xsd:anyAttribute and xsd:any.
   6732  * *WARNING* this interface is highly subject to change
   6733  *
   6734  * Returns 0 if everything goes fine, a positive error code
   6735  * if something is not valid and -1 if an internal error occurs.
   6736  */
   6737 static int
   6738 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
   6739 			 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
   6740 			 xmlSchemaWildcardPtr wildc,
   6741 			 xmlNodePtr node)
   6742 {
   6743     const xmlChar *pc, *ns, *dictnsItem;
   6744     int ret = 0;
   6745     xmlChar *nsItem;
   6746     xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
   6747     xmlAttrPtr attr;
   6748 
   6749     pc = xmlSchemaGetProp(ctxt, node, "processContents");
   6750     if ((pc == NULL)
   6751         || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
   6752         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
   6753     } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
   6754         wildc->processContents = XML_SCHEMAS_ANY_SKIP;
   6755     } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
   6756         wildc->processContents = XML_SCHEMAS_ANY_LAX;
   6757     } else {
   6758         xmlSchemaPSimpleTypeErr(ctxt,
   6759 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6760 	    NULL, node,
   6761 	    NULL, "(strict | skip | lax)", pc,
   6762 	    NULL, NULL, NULL);
   6763         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
   6764 	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   6765     }
   6766     /*
   6767      * Build the namespace constraints.
   6768      */
   6769     attr = xmlSchemaGetPropNode(node, "namespace");
   6770     ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6771     if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
   6772 	wildc->any = 1;
   6773     else if (xmlStrEqual(ns, BAD_CAST "##other")) {
   6774 	wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   6775 	if (wildc->negNsSet == NULL) {
   6776 	    return (-1);
   6777 	}
   6778 	wildc->negNsSet->value = ctxt->targetNamespace;
   6779     } else {
   6780 	const xmlChar *end, *cur;
   6781 
   6782 	cur = ns;
   6783 	do {
   6784 	    while (IS_BLANK_CH(*cur))
   6785 		cur++;
   6786 	    end = cur;
   6787 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   6788 		end++;
   6789 	    if (end == cur)
   6790 		break;
   6791 	    nsItem = xmlStrndup(cur, end - cur);
   6792 	    if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
   6793 		    (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
   6794 		xmlSchemaPSimpleTypeErr(ctxt,
   6795 		    XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
   6796 		    NULL, (xmlNodePtr) attr,
   6797 		    NULL,
   6798 		    "((##any | ##other) | List of (xs:anyURI | "
   6799 		    "(##targetNamespace | ##local)))",
   6800 		    nsItem, NULL, NULL, NULL);
   6801 		ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
   6802 	    } else {
   6803 		if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
   6804 		    dictnsItem = ctxt->targetNamespace;
   6805 		} else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
   6806 		    dictnsItem = NULL;
   6807 		} else {
   6808 		    /*
   6809 		    * Validate the item (anyURI).
   6810 		    */
   6811 		    xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
   6812 			nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
   6813 		    dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
   6814 		}
   6815 		/*
   6816 		* Avoid dublicate namespaces.
   6817 		*/
   6818 		tmp = wildc->nsSet;
   6819 		while (tmp != NULL) {
   6820 		    if (dictnsItem == tmp->value)
   6821 			break;
   6822 		    tmp = tmp->next;
   6823 		}
   6824 		if (tmp == NULL) {
   6825 		    tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
   6826 		    if (tmp == NULL) {
   6827 			xmlFree(nsItem);
   6828 			return (-1);
   6829 		    }
   6830 		    tmp->value = dictnsItem;
   6831 		    tmp->next = NULL;
   6832 		    if (wildc->nsSet == NULL)
   6833 			wildc->nsSet = tmp;
   6834 		    else if (lastNs != NULL)
   6835 			lastNs->next = tmp;
   6836 		    lastNs = tmp;
   6837 		}
   6838 
   6839 	    }
   6840 	    xmlFree(nsItem);
   6841 	    cur = end;
   6842 	} while (*cur != 0);
   6843     }
   6844     return (ret);
   6845 }
   6846 
   6847 static int
   6848 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
   6849 				 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
   6850 				 xmlNodePtr node,
   6851 				 int minOccurs,
   6852 				 int maxOccurs) {
   6853 
   6854     if ((maxOccurs == 0) && ( minOccurs == 0))
   6855 	return (0);
   6856     if (maxOccurs != UNBOUNDED) {
   6857 	/*
   6858 	* TODO: Maybe we should better not create the particle,
   6859 	* if min/max is invalid, since it could confuse the build of the
   6860 	* content model.
   6861 	*/
   6862 	/*
   6863 	* 3.9.6 Schema Component Constraint: Particle Correct
   6864 	*
   6865 	*/
   6866 	if (maxOccurs < 1) {
   6867 	    /*
   6868 	    * 2.2 {max occurs} must be greater than or equal to 1.
   6869 	    */
   6870 	    xmlSchemaPCustomAttrErr(ctxt,
   6871 		XML_SCHEMAP_P_PROPS_CORRECT_2_2,
   6872 		NULL, NULL,
   6873 		xmlSchemaGetPropNode(node, "maxOccurs"),
   6874 		"The value must be greater than or equal to 1");
   6875 	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
   6876 	} else if (minOccurs > maxOccurs) {
   6877 	    /*
   6878 	    * 2.1 {min occurs} must not be greater than {max occurs}.
   6879 	    */
   6880 	    xmlSchemaPCustomAttrErr(ctxt,
   6881 		XML_SCHEMAP_P_PROPS_CORRECT_2_1,
   6882 		NULL, NULL,
   6883 		xmlSchemaGetPropNode(node, "minOccurs"),
   6884 		"The value must not be greater than the value of 'maxOccurs'");
   6885 	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
   6886 	}
   6887     }
   6888     return (0);
   6889 }
   6890 
   6891 /**
   6892  * xmlSchemaParseAny:
   6893  * @ctxt:  a schema validation context
   6894  * @schema:  the schema being built
   6895  * @node:  a subtree containing XML Schema informations
   6896  *
   6897  * Parsea a XML schema <any> element. A particle and wildcard
   6898  * will be created (except if minOccurs==maxOccurs==0, in this case
   6899  * nothing will be created).
   6900  * *WARNING* this interface is highly subject to change
   6901  *
   6902  * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
   6903  */
   6904 static xmlSchemaParticlePtr
   6905 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6906                   xmlNodePtr node)
   6907 {
   6908     xmlSchemaParticlePtr particle;
   6909     xmlNodePtr child = NULL;
   6910     xmlSchemaWildcardPtr wild;
   6911     int min, max;
   6912     xmlAttrPtr attr;
   6913     xmlSchemaAnnotPtr annot = NULL;
   6914 
   6915     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   6916         return (NULL);
   6917     /*
   6918     * Check for illegal attributes.
   6919     */
   6920     attr = node->properties;
   6921     while (attr != NULL) {
   6922 	if (attr->ns == NULL) {
   6923 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   6924 		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
   6925 		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
   6926 	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
   6927 		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
   6928 		xmlSchemaPIllegalAttrErr(ctxt,
   6929 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6930 	    }
   6931 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   6932 	    xmlSchemaPIllegalAttrErr(ctxt,
   6933 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6934 	}
   6935 	attr = attr->next;
   6936     }
   6937     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   6938     /*
   6939     * minOccurs/maxOccurs.
   6940     */
   6941     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
   6942 	"(xs:nonNegativeInteger | unbounded)");
   6943     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
   6944 	"xs:nonNegativeInteger");
   6945     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
   6946     /*
   6947     * Create & parse the wildcard.
   6948     */
   6949     wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
   6950     if (wild == NULL)
   6951 	return (NULL);
   6952     xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
   6953     /*
   6954     * And now for the children...
   6955     */
   6956     child = node->children;
   6957     if (IS_SCHEMA(child, "annotation")) {
   6958         annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   6959         child = child->next;
   6960     }
   6961     if (child != NULL) {
   6962 	xmlSchemaPContentErr(ctxt,
   6963 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   6964 	    NULL, node, child,
   6965 	    NULL, "(annotation?)");
   6966     }
   6967     /*
   6968     * No component if minOccurs==maxOccurs==0.
   6969     */
   6970     if ((min == 0) && (max == 0)) {
   6971 	/* Don't free the wildcard, since it's already on the list. */
   6972 	return (NULL);
   6973     }
   6974     /*
   6975     * Create the particle.
   6976     */
   6977     particle = xmlSchemaAddParticle(ctxt, node, min, max);
   6978     if (particle == NULL)
   6979         return (NULL);
   6980     particle->annot = annot;
   6981     particle->children = (xmlSchemaTreeItemPtr) wild;
   6982 
   6983     return (particle);
   6984 }
   6985 
   6986 /**
   6987  * xmlSchemaParseNotation:
   6988  * @ctxt:  a schema validation context
   6989  * @schema:  the schema being built
   6990  * @node:  a subtree containing XML Schema informations
   6991  *
   6992  * parse a XML schema Notation declaration
   6993  *
   6994  * Returns the new structure or NULL in case of error
   6995  */
   6996 static xmlSchemaNotationPtr
   6997 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6998                        xmlNodePtr node)
   6999 {
   7000     const xmlChar *name;
   7001     xmlSchemaNotationPtr ret;
   7002     xmlNodePtr child = NULL;
   7003 
   7004     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   7005         return (NULL);
   7006     name = xmlSchemaGetProp(ctxt, node, "name");
   7007     if (name == NULL) {
   7008         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
   7009                        "Notation has no name\n", NULL, NULL);
   7010         return (NULL);
   7011     }
   7012     ret = xmlSchemaAddNotation(ctxt, schema, name,
   7013 	ctxt->targetNamespace, node);
   7014     if (ret == NULL)
   7015         return (NULL);
   7016     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   7017 
   7018     child = node->children;
   7019     if (IS_SCHEMA(child, "annotation")) {
   7020         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   7021         child = child->next;
   7022     }
   7023     if (child != NULL) {
   7024 	xmlSchemaPContentErr(ctxt,
   7025 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7026 	    NULL, node, child,
   7027 	    NULL, "(annotation?)");
   7028     }
   7029 
   7030     return (ret);
   7031 }
   7032 
   7033 /**
   7034  * xmlSchemaParseAnyAttribute:
   7035  * @ctxt:  a schema validation context
   7036  * @schema:  the schema being built
   7037  * @node:  a subtree containing XML Schema informations
   7038  *
   7039  * parse a XML schema AnyAttrribute declaration
   7040  * *WARNING* this interface is highly subject to change
   7041  *
   7042  * Returns a wildcard or NULL.
   7043  */
   7044 static xmlSchemaWildcardPtr
   7045 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
   7046                            xmlSchemaPtr schema, xmlNodePtr node)
   7047 {
   7048     xmlSchemaWildcardPtr ret;
   7049     xmlNodePtr child = NULL;
   7050     xmlAttrPtr attr;
   7051 
   7052     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   7053         return (NULL);
   7054 
   7055     ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
   7056 	node);
   7057     if (ret == NULL) {
   7058         return (NULL);
   7059     }
   7060     /*
   7061     * Check for illegal attributes.
   7062     */
   7063     attr = node->properties;
   7064     while (attr != NULL) {
   7065 	if (attr->ns == NULL) {
   7066 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   7067 	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
   7068 		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
   7069 		xmlSchemaPIllegalAttrErr(ctxt,
   7070 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7071 	    }
   7072 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7073 	    xmlSchemaPIllegalAttrErr(ctxt,
   7074 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7075 	}
   7076 	attr = attr->next;
   7077     }
   7078     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   7079     /*
   7080     * Parse the namespace list.
   7081     */
   7082     if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
   7083 	return (NULL);
   7084     /*
   7085     * And now for the children...
   7086     */
   7087     child = node->children;
   7088     if (IS_SCHEMA(child, "annotation")) {
   7089         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   7090         child = child->next;
   7091     }
   7092     if (child != NULL) {
   7093 	xmlSchemaPContentErr(ctxt,
   7094 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7095 	    NULL, node, child,
   7096 	    NULL, "(annotation?)");
   7097     }
   7098 
   7099     return (ret);
   7100 }
   7101 
   7102 
   7103 /**
   7104  * xmlSchemaParseAttribute:
   7105  * @ctxt:  a schema validation context
   7106  * @schema:  the schema being built
   7107  * @node:  a subtree containing XML Schema informations
   7108  *
   7109  * parse a XML schema Attrribute declaration
   7110  * *WARNING* this interface is highly subject to change
   7111  *
   7112  * Returns the attribute declaration.
   7113  */
   7114 static xmlSchemaBasicItemPtr
   7115 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
   7116 			     xmlSchemaPtr schema,
   7117 			     xmlNodePtr node,
   7118 			     xmlSchemaItemListPtr uses,
   7119 			     int parentType)
   7120 {
   7121     const xmlChar *attrValue, *name = NULL, *ns = NULL;
   7122     xmlSchemaAttributeUsePtr use = NULL;
   7123     xmlNodePtr child = NULL;
   7124     xmlAttrPtr attr;
   7125     const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
   7126     int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
   7127     int	nberrors, hasForm = 0, defValueType = 0;
   7128 
   7129 #define WXS_ATTR_DEF_VAL_DEFAULT 1
   7130 #define WXS_ATTR_DEF_VAL_FIXED 2
   7131 
   7132     /*
   7133      * 3.2.3 Constraints on XML Representations of Attribute Declarations
   7134      */
   7135 
   7136     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7137         return (NULL);
   7138     attr = xmlSchemaGetPropNode(node, "ref");
   7139     if (attr != NULL) {
   7140 	if (xmlSchemaPValAttrNodeQName(pctxt, schema,
   7141 	    NULL, attr, &tmpNs, &tmpName) != 0) {
   7142 	    return (NULL);
   7143 	}
   7144 	if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
   7145 	    return(NULL);
   7146 	isRef = 1;
   7147     }
   7148     nberrors = pctxt->nberrors;
   7149     /*
   7150     * Check for illegal attributes.
   7151     */
   7152     attr = node->properties;
   7153     while (attr != NULL) {
   7154 	if (attr->ns == NULL) {
   7155 	    if (isRef) {
   7156 		if (xmlStrEqual(attr->name, BAD_CAST "id")) {
   7157 		    xmlSchemaPValAttrNodeID(pctxt, attr);
   7158 		    goto attr_next;
   7159 		} else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
   7160 		    goto attr_next;
   7161 		}
   7162 	    } else {
   7163 		if (xmlStrEqual(attr->name, BAD_CAST "name")) {
   7164 		    goto attr_next;
   7165 		} else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
   7166 		    xmlSchemaPValAttrNodeID(pctxt, attr);
   7167 		    goto attr_next;
   7168 		} else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
   7169 		    xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
   7170 			attr, &tmpNs, &tmpName);
   7171 		    goto attr_next;
   7172 		} else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
   7173 		    /*
   7174 		    * Evaluate the target namespace
   7175 		    */
   7176 		    hasForm = 1;
   7177 		    attrValue = xmlSchemaGetNodeContent(pctxt,
   7178 			(xmlNodePtr) attr);
   7179 		    if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
   7180 			ns = pctxt->targetNamespace;
   7181 		    } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
   7182 		    {
   7183 			xmlSchemaPSimpleTypeErr(pctxt,
   7184 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   7185 			    NULL, (xmlNodePtr) attr,
   7186 			    NULL, "(qualified | unqualified)",
   7187 			    attrValue, NULL, NULL, NULL);
   7188 		    }
   7189 		    goto attr_next;
   7190 		}
   7191 	    }
   7192 	    if (xmlStrEqual(attr->name, BAD_CAST "use")) {
   7193 
   7194 		attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7195 		/* TODO: Maybe we need to normalize the value beforehand. */
   7196 		if (xmlStrEqual(attrValue, BAD_CAST "optional"))
   7197 		    occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
   7198 		else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
   7199 		    occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
   7200 		else if (xmlStrEqual(attrValue, BAD_CAST "required"))
   7201 		    occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
   7202 		else {
   7203 		    xmlSchemaPSimpleTypeErr(pctxt,
   7204 			XML_SCHEMAP_INVALID_ATTR_USE,
   7205 			NULL, (xmlNodePtr) attr,
   7206 			NULL, "(optional | prohibited | required)",
   7207 			attrValue, NULL, NULL, NULL);
   7208 		}
   7209 		goto attr_next;
   7210 	    } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
   7211 		/*
   7212 		* 3.2.3 : 1
   7213 		* default and fixed must not both be present.
   7214 		*/
   7215 		if (defValue) {
   7216 		    xmlSchemaPMutualExclAttrErr(pctxt,
   7217 			XML_SCHEMAP_SRC_ATTRIBUTE_1,
   7218 			NULL, attr, "default", "fixed");
   7219 		} else {
   7220 		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7221 		    defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
   7222 		}
   7223 		goto attr_next;
   7224 	    } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
   7225 		/*
   7226 		* 3.2.3 : 1
   7227 		* default and fixed must not both be present.
   7228 		*/
   7229 		if (defValue) {
   7230 		    xmlSchemaPMutualExclAttrErr(pctxt,
   7231 			XML_SCHEMAP_SRC_ATTRIBUTE_1,
   7232 			NULL, attr, "default", "fixed");
   7233 		} else {
   7234 		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7235 		    defValueType = WXS_ATTR_DEF_VAL_FIXED;
   7236 		}
   7237 		goto attr_next;
   7238 	    }
   7239 	} else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
   7240 	    goto attr_next;
   7241 
   7242 	xmlSchemaPIllegalAttrErr(pctxt,
   7243 	    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7244 
   7245 attr_next:
   7246 	attr = attr->next;
   7247     }
   7248     /*
   7249     * 3.2.3 : 2
   7250     * If default and use are both present, use must have
   7251     * the actual value optional.
   7252     */
   7253     if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
   7254 	(occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
   7255 	xmlSchemaPSimpleTypeErr(pctxt,
   7256 	    XML_SCHEMAP_SRC_ATTRIBUTE_2,
   7257 	    NULL, node, NULL,
   7258 	    "(optional | prohibited | required)", NULL,
   7259 	    "The value of the attribute 'use' must be 'optional' "
   7260 	    "if the attribute 'default' is present",
   7261 	    NULL, NULL);
   7262     }
   7263     /*
   7264     * We want correct attributes.
   7265     */
   7266     if (nberrors != pctxt->nberrors)
   7267 	return(NULL);
   7268     if (! isRef) {
   7269 	xmlSchemaAttributePtr attrDecl;
   7270 
   7271 	/* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
   7272 	if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
   7273 	    ns = pctxt->targetNamespace;
   7274 	/*
   7275 	* 3.2.6 Schema Component Constraint: xsi: Not Allowed
   7276 	* TODO: Move this to the component layer.
   7277 	*/
   7278 	if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
   7279 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   7280 		XML_SCHEMAP_NO_XSI,
   7281 		node, NULL,
   7282 		"The target namespace must not match '%s'",
   7283 		xmlSchemaInstanceNs, NULL);
   7284 	}
   7285 	attr = xmlSchemaGetPropNode(node, "name");
   7286 	if (attr == NULL) {
   7287 	    xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
   7288 		NULL, node, "name", NULL);
   7289 	    return (NULL);
   7290 	}
   7291 	if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
   7292 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   7293 	    return (NULL);
   7294 	}
   7295 	/*
   7296 	* 3.2.6 Schema Component Constraint: xmlns Not Allowed
   7297 	* TODO: Move this to the component layer.
   7298 	*/
   7299 	if (xmlStrEqual(name, BAD_CAST "xmlns")) {
   7300 	    xmlSchemaPSimpleTypeErr(pctxt,
   7301 		XML_SCHEMAP_NO_XMLNS,
   7302 		NULL, (xmlNodePtr) attr,
   7303 		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
   7304 		"The value of the attribute must not match 'xmlns'",
   7305 		NULL, NULL);
   7306 	    return (NULL);
   7307 	}
   7308 	if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
   7309 	    goto check_children;
   7310 	/*
   7311 	* Create the attribute use component.
   7312 	*/
   7313 	use = xmlSchemaAddAttributeUse(pctxt, node);
   7314 	if (use == NULL)
   7315 	    return(NULL);
   7316 	use->occurs = occurs;
   7317 	/*
   7318 	* Create the attribute declaration.
   7319 	*/
   7320 	attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
   7321 	if (attrDecl == NULL)
   7322 	    return (NULL);
   7323 	if (tmpName != NULL) {
   7324 	    attrDecl->typeName = tmpName;
   7325 	    attrDecl->typeNs = tmpNs;
   7326 	}
   7327 	use->attrDecl = attrDecl;
   7328 	/*
   7329 	* Value constraint.
   7330 	*/
   7331 	if (defValue != NULL) {
   7332 	    attrDecl->defValue = defValue;
   7333 	    if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
   7334 		attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
   7335 	}
   7336     } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
   7337 	xmlSchemaQNameRefPtr ref;
   7338 
   7339 	/*
   7340 	* Create the attribute use component.
   7341 	*/
   7342 	use = xmlSchemaAddAttributeUse(pctxt, node);
   7343 	if (use == NULL)
   7344 	    return(NULL);
   7345 	/*
   7346 	* We need to resolve the reference at later stage.
   7347 	*/
   7348 	WXS_ADD_PENDING(pctxt, use);
   7349 	use->occurs = occurs;
   7350 	/*
   7351 	* Create a QName reference to the attribute declaration.
   7352 	*/
   7353 	ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
   7354 	    tmpName, tmpNs);
   7355 	if (ref == NULL)
   7356 	    return(NULL);
   7357 	/*
   7358 	* Assign the reference. This will be substituted for the
   7359 	* referenced attribute declaration when the QName is resolved.
   7360 	*/
   7361 	use->attrDecl = WXS_ATTR_CAST ref;
   7362 	/*
   7363 	* Value constraint.
   7364 	*/
   7365 	if (defValue != NULL)
   7366 	    use->defValue = defValue;
   7367 	    if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
   7368 		use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
   7369     }
   7370 
   7371 check_children:
   7372     /*
   7373     * And now for the children...
   7374     */
   7375     child = node->children;
   7376     if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
   7377 	xmlSchemaAttributeUseProhibPtr prohib;
   7378 
   7379 	if (IS_SCHEMA(child, "annotation")) {
   7380 	    xmlSchemaParseAnnotation(pctxt, child, 0);
   7381 	    child = child->next;
   7382 	}
   7383 	if (child != NULL) {
   7384 	    xmlSchemaPContentErr(pctxt,
   7385 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7386 		NULL, node, child, NULL,
   7387 		"(annotation?)");
   7388 	}
   7389 	/*
   7390 	* Check for pointlessness of attribute prohibitions.
   7391 	*/
   7392 	if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
   7393 	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   7394 		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   7395 		node, NULL,
   7396 		"Skipping attribute use prohibition, since it is "
   7397 		"pointless inside an <attributeGroup>",
   7398 		NULL, NULL, NULL);
   7399 	    return(NULL);
   7400 	} else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
   7401 	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   7402 		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   7403 		node, NULL,
   7404 		"Skipping attribute use prohibition, since it is "
   7405 		"pointless when extending a type",
   7406 		NULL, NULL, NULL);
   7407 	    return(NULL);
   7408 	}
   7409 	if (! isRef) {
   7410 	    tmpName = name;
   7411 	    tmpNs = ns;
   7412 	}
   7413 	/*
   7414 	* Check for duplicate attribute prohibitions.
   7415 	*/
   7416 	if (uses) {
   7417 	    int i;
   7418 
   7419 	    for (i = 0; i < uses->nbItems; i++) {
   7420 		use = uses->items[i];
   7421 		if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
   7422 		    (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
   7423 		    (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
   7424 		{
   7425 		    xmlChar *str = NULL;
   7426 
   7427 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   7428 			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   7429 			node, NULL,
   7430 			"Skipping duplicate attribute use prohibition '%s'",
   7431 			xmlSchemaFormatQName(&str, tmpNs, tmpName),
   7432 			NULL, NULL);
   7433 		    FREE_AND_NULL(str)
   7434 		    return(NULL);
   7435 		}
   7436 	    }
   7437 	}
   7438 	/*
   7439 	* Create the attribute prohibition helper component.
   7440 	*/
   7441 	prohib = xmlSchemaAddAttributeUseProhib(pctxt);
   7442 	if (prohib == NULL)
   7443 	    return(NULL);
   7444 	prohib->node = node;
   7445 	prohib->name = tmpName;
   7446 	prohib->targetNamespace = tmpNs;
   7447 	if (isRef) {
   7448 	    /*
   7449 	    * We need at least to resolve to the attribute declaration.
   7450 	    */
   7451 	    WXS_ADD_PENDING(pctxt, prohib);
   7452 	}
   7453 	return(WXS_BASIC_CAST prohib);
   7454     } else {
   7455 	if (IS_SCHEMA(child, "annotation")) {
   7456 	    /*
   7457 	    * TODO: Should this go into the attr decl?
   7458 	    */
   7459 	    use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
   7460 	    child = child->next;
   7461 	}
   7462 	if (isRef) {
   7463 	    if (child != NULL) {
   7464 		if (IS_SCHEMA(child, "simpleType"))
   7465 		    /*
   7466 		    * 3.2.3 : 3.2
   7467 		    * If ref is present, then all of <simpleType>,
   7468 		    * form and type must be absent.
   7469 		    */
   7470 		    xmlSchemaPContentErr(pctxt,
   7471 			XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
   7472 			NULL, node, child, NULL,
   7473 			"(annotation?)");
   7474 		else
   7475 		    xmlSchemaPContentErr(pctxt,
   7476 			XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7477 			NULL, node, child, NULL,
   7478 			"(annotation?)");
   7479 	    }
   7480 	} else {
   7481 	    if (IS_SCHEMA(child, "simpleType")) {
   7482 		if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
   7483 		    /*
   7484 		    * 3.2.3 : 4
   7485 		    * type and <simpleType> must not both be present.
   7486 		    */
   7487 		    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
   7488 			NULL, node, child,
   7489 			"The attribute 'type' and the <simpleType> child "
   7490 			"are mutually exclusive", NULL);
   7491 		} else
   7492 		    WXS_ATTRUSE_TYPEDEF(use) =
   7493 			xmlSchemaParseSimpleType(pctxt, schema, child, 0);
   7494 		child = child->next;
   7495 	    }
   7496 	    if (child != NULL)
   7497 		xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7498 		NULL, node, child, NULL,
   7499 		"(annotation?, simpleType?)");
   7500 	}
   7501     }
   7502     return (WXS_BASIC_CAST use);
   7503 }
   7504 
   7505 
   7506 static xmlSchemaAttributePtr
   7507 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
   7508 			      xmlSchemaPtr schema,
   7509 			      xmlNodePtr node)
   7510 {
   7511     const xmlChar *attrValue;
   7512     xmlSchemaAttributePtr ret;
   7513     xmlNodePtr child = NULL;
   7514     xmlAttrPtr attr;
   7515 
   7516     /*
   7517      * Note that the w3c spec assumes the schema to be validated with schema
   7518      * for schemas beforehand.
   7519      *
   7520      * 3.2.3 Constraints on XML Representations of Attribute Declarations
   7521      */
   7522     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7523         return (NULL);
   7524     /*
   7525     * 3.2.3 : 3.1
   7526     * One of ref or name must be present, but not both
   7527     */
   7528     attr = xmlSchemaGetPropNode(node, "name");
   7529     if (attr == NULL) {
   7530 	xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
   7531 	    NULL, node, "name", NULL);
   7532 	return (NULL);
   7533     }
   7534     if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
   7535 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
   7536 	return (NULL);
   7537     }
   7538     /*
   7539     * 3.2.6 Schema Component Constraint: xmlns Not Allowed
   7540     * TODO: Move this to the component layer.
   7541     */
   7542     if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
   7543 	xmlSchemaPSimpleTypeErr(pctxt,
   7544 	    XML_SCHEMAP_NO_XMLNS,
   7545 	    NULL, (xmlNodePtr) attr,
   7546 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
   7547 	    "The value of the attribute must not match 'xmlns'",
   7548 	    NULL, NULL);
   7549 	return (NULL);
   7550     }
   7551     /*
   7552     * 3.2.6 Schema Component Constraint: xsi: Not Allowed
   7553     * TODO: Move this to the component layer.
   7554     *       Or better leave it here and add it to the component layer
   7555     *       if we have a schema construction API.
   7556     */
   7557     if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
   7558 	xmlSchemaCustomErr(ACTXT_CAST pctxt,
   7559 	    XML_SCHEMAP_NO_XSI, node, NULL,
   7560 	    "The target namespace must not match '%s'",
   7561 	    xmlSchemaInstanceNs, NULL);
   7562     }
   7563 
   7564     ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
   7565 	pctxt->targetNamespace, node, 1);
   7566     if (ret == NULL)
   7567 	return (NULL);
   7568     ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
   7569 
   7570     /*
   7571     * Check for illegal attributes.
   7572     */
   7573     attr = node->properties;
   7574     while (attr != NULL) {
   7575 	if (attr->ns == NULL) {
   7576 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   7577 		(!xmlStrEqual(attr->name, BAD_CAST "default")) &&
   7578 		(!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
   7579 		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   7580 		(!xmlStrEqual(attr->name, BAD_CAST "type")))
   7581 	    {
   7582 		xmlSchemaPIllegalAttrErr(pctxt,
   7583 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7584 	    }
   7585 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7586 	    xmlSchemaPIllegalAttrErr(pctxt,
   7587 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7588 	}
   7589 	attr = attr->next;
   7590     }
   7591     xmlSchemaPValAttrQName(pctxt, schema, NULL,
   7592 	node, "type", &ret->typeNs, &ret->typeName);
   7593 
   7594     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   7595     /*
   7596     * Attribute "fixed".
   7597     */
   7598     ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
   7599     if (ret->defValue != NULL)
   7600 	ret->flags |= XML_SCHEMAS_ATTR_FIXED;
   7601     /*
   7602     * Attribute "default".
   7603     */
   7604     attr = xmlSchemaGetPropNode(node, "default");
   7605     if (attr != NULL) {
   7606 	/*
   7607 	* 3.2.3 : 1
   7608 	* default and fixed must not both be present.
   7609 	*/
   7610 	if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
   7611 	    xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
   7612 		WXS_BASIC_CAST ret, attr, "default", "fixed");
   7613 	} else
   7614 	    ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7615     }
   7616     /*
   7617     * And now for the children...
   7618     */
   7619     child = node->children;
   7620     if (IS_SCHEMA(child, "annotation")) {
   7621         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
   7622         child = child->next;
   7623     }
   7624     if (IS_SCHEMA(child, "simpleType")) {
   7625 	if (ret->typeName != NULL) {
   7626 	    /*
   7627 	    * 3.2.3 : 4
   7628 	    * type and <simpleType> must not both be present.
   7629 	    */
   7630 	    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
   7631 		NULL, node, child,
   7632 		"The attribute 'type' and the <simpleType> child "
   7633 		"are mutually exclusive", NULL);
   7634 	} else
   7635 	    ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
   7636 	child = child->next;
   7637     }
   7638     if (child != NULL)
   7639 	xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7640 	    NULL, node, child, NULL,
   7641 	    "(annotation?, simpleType?)");
   7642 
   7643     return (ret);
   7644 }
   7645 
   7646 /**
   7647  * xmlSchemaParseAttributeGroupRef:
   7648  * @ctxt:  a schema validation context
   7649  * @schema:  the schema being built
   7650  * @node:  a subtree containing XML Schema informations
   7651  *
   7652  * Parse an attribute group definition reference.
   7653  * Note that a reference to an attribute group does not
   7654  * correspond to any component at all.
   7655  * *WARNING* this interface is highly subject to change
   7656  *
   7657  * Returns the attribute group or NULL in case of error.
   7658  */
   7659 static xmlSchemaQNameRefPtr
   7660 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
   7661 				xmlSchemaPtr schema,
   7662 				xmlNodePtr node)
   7663 {
   7664     xmlSchemaQNameRefPtr ret;
   7665     xmlNodePtr child = NULL;
   7666     xmlAttrPtr attr;
   7667     const xmlChar *refNs = NULL, *ref = NULL;
   7668 
   7669     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7670         return (NULL);
   7671 
   7672     attr = xmlSchemaGetPropNode(node, "ref");
   7673     if (attr == NULL) {
   7674 	xmlSchemaPMissingAttrErr(pctxt,
   7675 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   7676 	    NULL, node, "ref", NULL);
   7677 	return (NULL);
   7678     }
   7679     xmlSchemaPValAttrNodeQName(pctxt, schema,
   7680 	NULL, attr, &refNs, &ref);
   7681     if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
   7682 	return(NULL);
   7683 
   7684     /*
   7685     * Check for illegal attributes.
   7686     */
   7687     attr = node->properties;
   7688     while (attr != NULL) {
   7689 	if (attr->ns == NULL) {
   7690 	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
   7691 		(!xmlStrEqual(attr->name, BAD_CAST "id")))
   7692 	    {
   7693 		xmlSchemaPIllegalAttrErr(pctxt,
   7694 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7695 	    }
   7696 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7697 	    xmlSchemaPIllegalAttrErr(pctxt,
   7698 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7699 	}
   7700 	attr = attr->next;
   7701     }
   7702     /* Attribute ID */
   7703     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   7704 
   7705     /*
   7706     * And now for the children...
   7707     */
   7708     child = node->children;
   7709     if (IS_SCHEMA(child, "annotation")) {
   7710 	/*
   7711 	* TODO: We do not have a place to store the annotation, do we?
   7712 	*/
   7713         xmlSchemaParseAnnotation(pctxt, child, 0);
   7714         child = child->next;
   7715     }
   7716     if (child != NULL) {
   7717 	xmlSchemaPContentErr(pctxt,
   7718 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7719 	    NULL, node, child, NULL,
   7720 	    "(annotation?)");
   7721     }
   7722 
   7723     /*
   7724     * Handle attribute group redefinitions.
   7725     */
   7726     if (pctxt->isRedefine && pctxt->redef &&
   7727 	(pctxt->redef->item->type ==
   7728 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
   7729 	(ref == pctxt->redef->refName) &&
   7730 	(refNs == pctxt->redef->refTargetNs))
   7731     {
   7732 	/*
   7733 	* SPEC src-redefine:
   7734 	* (7.1) "If it has an <attributeGroup> among its contents
   7735 	* the `actual value` of whose ref [attribute] is the same
   7736 	* as the `actual value` of its own name attribute plus
   7737 	* target namespace, then it must have exactly one such group."
   7738 	*/
   7739 	if (pctxt->redefCounter != 0) {
   7740 	    xmlChar *str = NULL;
   7741 
   7742 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   7743 		XML_SCHEMAP_SRC_REDEFINE, node, NULL,
   7744 		"The redefining attribute group definition "
   7745 		"'%s' must not contain more than one "
   7746 		"reference to the redefined definition",
   7747 		xmlSchemaFormatQName(&str, refNs, ref), NULL);
   7748 	    FREE_AND_NULL(str);
   7749 	    return(NULL);
   7750 	}
   7751 	pctxt->redefCounter++;
   7752 	/*
   7753 	* URGENT TODO: How to ensure that the reference will not be
   7754 	* handled by the normal component resolution mechanism?
   7755 	*/
   7756 	ret = xmlSchemaNewQNameRef(pctxt,
   7757 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
   7758 	if (ret == NULL)
   7759 	    return(NULL);
   7760 	ret->node = node;
   7761 	pctxt->redef->reference = WXS_BASIC_CAST ret;
   7762     } else {
   7763 	/*
   7764 	* Create a QName-reference helper component. We will substitute this
   7765 	* component for the attribute uses of the referenced attribute group
   7766 	* definition.
   7767 	*/
   7768 	ret = xmlSchemaNewQNameRef(pctxt,
   7769 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
   7770 	if (ret == NULL)
   7771 	    return(NULL);
   7772 	ret->node = node;
   7773 	/* Add to pending items, to be able to resolve the reference. */
   7774 	WXS_ADD_PENDING(pctxt, ret);
   7775     }
   7776     return (ret);
   7777 }
   7778 
   7779 /**
   7780  * xmlSchemaParseAttributeGroupDefinition:
   7781  * @pctxt:  a schema validation context
   7782  * @schema:  the schema being built
   7783  * @node:  a subtree containing XML Schema informations
   7784  *
   7785  * parse a XML schema Attribute Group declaration
   7786  * *WARNING* this interface is highly subject to change
   7787  *
   7788  * Returns the attribute group definition or NULL in case of error.
   7789  */
   7790 static xmlSchemaAttributeGroupPtr
   7791 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
   7792 				       xmlSchemaPtr schema,
   7793 				       xmlNodePtr node)
   7794 {
   7795     const xmlChar *name;
   7796     xmlSchemaAttributeGroupPtr ret;
   7797     xmlNodePtr child = NULL;
   7798     xmlAttrPtr attr;
   7799     int hasRefs = 0;
   7800 
   7801     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7802         return (NULL);
   7803 
   7804     attr = xmlSchemaGetPropNode(node, "name");
   7805     if (attr == NULL) {
   7806 	xmlSchemaPMissingAttrErr(pctxt,
   7807 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   7808 	    NULL, node, "name", NULL);
   7809 	return (NULL);
   7810     }
   7811     /*
   7812     * The name is crucial, exit if invalid.
   7813     */
   7814     if (xmlSchemaPValAttrNode(pctxt,
   7815 	NULL, attr,
   7816 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   7817 	return (NULL);
   7818     }
   7819     ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
   7820 	name, pctxt->targetNamespace, node);
   7821     if (ret == NULL)
   7822 	return (NULL);
   7823     /*
   7824     * Check for illegal attributes.
   7825     */
   7826     attr = node->properties;
   7827     while (attr != NULL) {
   7828 	if (attr->ns == NULL) {
   7829 	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   7830 		(!xmlStrEqual(attr->name, BAD_CAST "id")))
   7831 	    {
   7832 		xmlSchemaPIllegalAttrErr(pctxt,
   7833 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7834 	    }
   7835 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7836 	    xmlSchemaPIllegalAttrErr(pctxt,
   7837 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7838 	}
   7839 	attr = attr->next;
   7840     }
   7841     /* Attribute ID */
   7842     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   7843     /*
   7844     * And now for the children...
   7845     */
   7846     child = node->children;
   7847     if (IS_SCHEMA(child, "annotation")) {
   7848         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
   7849         child = child->next;
   7850     }
   7851     /*
   7852     * Parse contained attribute decls/refs.
   7853     */
   7854     if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
   7855 	(xmlSchemaItemListPtr *) &(ret->attrUses),
   7856 	XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
   7857 	return(NULL);
   7858     if (hasRefs)
   7859 	ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
   7860     /*
   7861     * Parse the attribute wildcard.
   7862     */
   7863     if (IS_SCHEMA(child, "anyAttribute")) {
   7864 	ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
   7865 	    schema, child);
   7866 	child = child->next;
   7867     }
   7868     if (child != NULL) {
   7869 	xmlSchemaPContentErr(pctxt,
   7870 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7871 	    NULL, node, child, NULL,
   7872 	    "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
   7873     }
   7874     return (ret);
   7875 }
   7876 
   7877 /**
   7878  * xmlSchemaPValAttrFormDefault:
   7879  * @value:  the value
   7880  * @flags: the flags to be modified
   7881  * @flagQualified: the specific flag for "qualified"
   7882  *
   7883  * Returns 0 if the value is valid, 1 otherwise.
   7884  */
   7885 static int
   7886 xmlSchemaPValAttrFormDefault(const xmlChar *value,
   7887 			     int *flags,
   7888 			     int flagQualified)
   7889 {
   7890     if (xmlStrEqual(value, BAD_CAST "qualified")) {
   7891 	if  ((*flags & flagQualified) == 0)
   7892 	    *flags |= flagQualified;
   7893     } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
   7894 	return (1);
   7895 
   7896     return (0);
   7897 }
   7898 
   7899 /**
   7900  * xmlSchemaPValAttrBlockFinal:
   7901  * @value:  the value
   7902  * @flags: the flags to be modified
   7903  * @flagAll: the specific flag for "#all"
   7904  * @flagExtension: the specific flag for "extension"
   7905  * @flagRestriction: the specific flag for "restriction"
   7906  * @flagSubstitution: the specific flag for "substitution"
   7907  * @flagList: the specific flag for "list"
   7908  * @flagUnion: the specific flag for "union"
   7909  *
   7910  * Validates the value of the attribute "final" and "block". The value
   7911  * is converted into the specified flag values and returned in @flags.
   7912  *
   7913  * Returns 0 if the value is valid, 1 otherwise.
   7914  */
   7915 
   7916 static int
   7917 xmlSchemaPValAttrBlockFinal(const xmlChar *value,
   7918 			    int *flags,
   7919 			    int flagAll,
   7920 			    int flagExtension,
   7921 			    int flagRestriction,
   7922 			    int flagSubstitution,
   7923 			    int flagList,
   7924 			    int flagUnion)
   7925 {
   7926     int ret = 0;
   7927 
   7928     /*
   7929     * TODO: This does not check for dublicate entries.
   7930     */
   7931     if ((flags == NULL) || (value == NULL))
   7932 	return (-1);
   7933     if (value[0] == 0)
   7934 	return (0);
   7935     if (xmlStrEqual(value, BAD_CAST "#all")) {
   7936 	if (flagAll != -1)
   7937 	    *flags |= flagAll;
   7938 	else {
   7939 	    if (flagExtension != -1)
   7940 		*flags |= flagExtension;
   7941 	    if (flagRestriction != -1)
   7942 		*flags |= flagRestriction;
   7943 	    if (flagSubstitution != -1)
   7944 		*flags |= flagSubstitution;
   7945 	    if (flagList != -1)
   7946 		*flags |= flagList;
   7947 	    if (flagUnion != -1)
   7948 		*flags |= flagUnion;
   7949 	}
   7950     } else {
   7951 	const xmlChar *end, *cur = value;
   7952 	xmlChar *item;
   7953 
   7954 	do {
   7955 	    while (IS_BLANK_CH(*cur))
   7956 		cur++;
   7957 	    end = cur;
   7958 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   7959 		end++;
   7960 	    if (end == cur)
   7961 		break;
   7962 	    item = xmlStrndup(cur, end - cur);
   7963 	    if (xmlStrEqual(item, BAD_CAST "extension")) {
   7964 		if (flagExtension != -1) {
   7965 		    if ((*flags & flagExtension) == 0)
   7966 			*flags |= flagExtension;
   7967 		} else
   7968 		    ret = 1;
   7969 	    } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
   7970 		if (flagRestriction != -1) {
   7971 		    if ((*flags & flagRestriction) == 0)
   7972 			*flags |= flagRestriction;
   7973 		} else
   7974 		    ret = 1;
   7975 	    } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
   7976 		if (flagSubstitution != -1) {
   7977 		    if ((*flags & flagSubstitution) == 0)
   7978 			*flags |= flagSubstitution;
   7979 		} else
   7980 		    ret = 1;
   7981 	    } else if (xmlStrEqual(item, BAD_CAST "list")) {
   7982 		if (flagList != -1) {
   7983 		    if ((*flags & flagList) == 0)
   7984 			*flags |= flagList;
   7985 		} else
   7986 		    ret = 1;
   7987 	    } else if (xmlStrEqual(item, BAD_CAST "union")) {
   7988 		if (flagUnion != -1) {
   7989 		    if ((*flags & flagUnion) == 0)
   7990 			*flags |= flagUnion;
   7991 		} else
   7992 		    ret = 1;
   7993 	    } else
   7994 		ret = 1;
   7995 	    if (item != NULL)
   7996 		xmlFree(item);
   7997 	    cur = end;
   7998 	} while ((ret == 0) && (*cur != 0));
   7999     }
   8000 
   8001     return (ret);
   8002 }
   8003 
   8004 static int
   8005 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
   8006 			     xmlSchemaIDCPtr idc,
   8007 			     xmlSchemaIDCSelectPtr selector,
   8008 			     xmlAttrPtr attr,
   8009 			     int isField)
   8010 {
   8011     xmlNodePtr node;
   8012 
   8013     /*
   8014     * c-selector-xpath:
   8015     * Schema Component Constraint: Selector Value OK
   8016     *
   8017     * TODO: 1 The {selector} must be a valid XPath expression, as defined
   8018     * in [XPath].
   8019     */
   8020     if (selector == NULL) {
   8021 	xmlSchemaPErr(ctxt, idc->node,
   8022 	    XML_SCHEMAP_INTERNAL,
   8023 	    "Internal error: xmlSchemaCheckCSelectorXPath, "
   8024 	    "the selector is not specified.\n", NULL, NULL);
   8025 	return (-1);
   8026     }
   8027     if (attr == NULL)
   8028 	node = idc->node;
   8029     else
   8030 	node = (xmlNodePtr) attr;
   8031     if (selector->xpath == NULL) {
   8032 	xmlSchemaPCustomErr(ctxt,
   8033 	    /* TODO: Adjust error code. */
   8034 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8035 	    NULL, node,
   8036 	    "The XPath expression of the selector is not valid", NULL);
   8037 	return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
   8038     } else {
   8039 	const xmlChar **nsArray = NULL;
   8040 	xmlNsPtr *nsList = NULL;
   8041 	/*
   8042 	* Compile the XPath expression.
   8043 	*/
   8044 	/*
   8045 	* TODO: We need the array of in-scope namespaces for compilation.
   8046 	* TODO: Call xmlPatterncompile with different options for selector/
   8047 	* field.
   8048 	*/
   8049 	if (attr == NULL)
   8050 	    nsList = NULL;
   8051 	else
   8052 	    nsList = xmlGetNsList(attr->doc, attr->parent);
   8053 	/*
   8054 	* Build an array of prefixes and namespaces.
   8055 	*/
   8056 	if (nsList != NULL) {
   8057 	    int i, count = 0;
   8058 
   8059 	    for (i = 0; nsList[i] != NULL; i++)
   8060 		count++;
   8061 
   8062 	    nsArray = (const xmlChar **) xmlMalloc(
   8063 		(count * 2 + 1) * sizeof(const xmlChar *));
   8064 	    if (nsArray == NULL) {
   8065 		xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
   8066 		    NULL);
   8067 		xmlFree(nsList);
   8068 		return (-1);
   8069 	    }
   8070 	    for (i = 0; i < count; i++) {
   8071 		nsArray[2 * i] = nsList[i]->href;
   8072 		nsArray[2 * i + 1] = nsList[i]->prefix;
   8073 	    }
   8074 	    nsArray[count * 2] = NULL;
   8075 	    xmlFree(nsList);
   8076 	}
   8077 	/*
   8078 	* TODO: Differentiate between "selector" and "field".
   8079 	*/
   8080 	if (isField)
   8081 	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
   8082 		NULL, XML_PATTERN_XSFIELD, nsArray);
   8083 	else
   8084 	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
   8085 		NULL, XML_PATTERN_XSSEL, nsArray);
   8086 	if (nsArray != NULL)
   8087 	    xmlFree((xmlChar **) nsArray);
   8088 
   8089 	if (selector->xpathComp == NULL) {
   8090 	    xmlSchemaPCustomErr(ctxt,
   8091 		/* TODO: Adjust error code? */
   8092 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8093 		NULL, node,
   8094 		"The XPath expression '%s' could not be "
   8095 		"compiled", selector->xpath);
   8096 	    return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
   8097 	}
   8098     }
   8099     return (0);
   8100 }
   8101 
   8102 #define ADD_ANNOTATION(annot)   \
   8103     xmlSchemaAnnotPtr cur = item->annot; \
   8104     if (item->annot == NULL) {  \
   8105 	item->annot = annot;    \
   8106 	return (annot);         \
   8107     }                           \
   8108     cur = item->annot;          \
   8109     if (cur->next != NULL) {    \
   8110 	cur = cur->next;	\
   8111     }                           \
   8112     cur->next = annot;
   8113 
   8114 /**
   8115  * xmlSchemaAssignAnnotation:
   8116  * @item: the schema component
   8117  * @annot: the annotation
   8118  *
   8119  * Adds the annotation to the given schema component.
   8120  *
   8121  * Returns the given annotaion.
   8122  */
   8123 static xmlSchemaAnnotPtr
   8124 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
   8125 		       xmlSchemaAnnotPtr annot)
   8126 {
   8127     if ((annItem == NULL) || (annot == NULL))
   8128 	return (NULL);
   8129     switch (annItem->type) {
   8130 	case XML_SCHEMA_TYPE_ELEMENT: {
   8131 		xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
   8132 		ADD_ANNOTATION(annot)
   8133 	    }
   8134 	    break;
   8135 	case XML_SCHEMA_TYPE_ATTRIBUTE: {
   8136 		xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
   8137 		ADD_ANNOTATION(annot)
   8138 	    }
   8139 	    break;
   8140 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   8141 	case XML_SCHEMA_TYPE_ANY: {
   8142 		xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
   8143 		ADD_ANNOTATION(annot)
   8144 	    }
   8145 	    break;
   8146 	case XML_SCHEMA_TYPE_PARTICLE:
   8147 	case XML_SCHEMA_TYPE_IDC_KEY:
   8148 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   8149 	case XML_SCHEMA_TYPE_IDC_UNIQUE: {
   8150 		xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
   8151 		ADD_ANNOTATION(annot)
   8152 	    }
   8153 	    break;
   8154 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
   8155 		xmlSchemaAttributeGroupPtr item =
   8156 		    (xmlSchemaAttributeGroupPtr) annItem;
   8157 		ADD_ANNOTATION(annot)
   8158 	    }
   8159 	    break;
   8160 	case XML_SCHEMA_TYPE_NOTATION: {
   8161 		xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
   8162 		ADD_ANNOTATION(annot)
   8163 	    }
   8164 	    break;
   8165 	case XML_SCHEMA_FACET_MININCLUSIVE:
   8166 	case XML_SCHEMA_FACET_MINEXCLUSIVE:
   8167 	case XML_SCHEMA_FACET_MAXINCLUSIVE:
   8168 	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   8169 	case XML_SCHEMA_FACET_TOTALDIGITS:
   8170 	case XML_SCHEMA_FACET_FRACTIONDIGITS:
   8171 	case XML_SCHEMA_FACET_PATTERN:
   8172 	case XML_SCHEMA_FACET_ENUMERATION:
   8173 	case XML_SCHEMA_FACET_WHITESPACE:
   8174 	case XML_SCHEMA_FACET_LENGTH:
   8175 	case XML_SCHEMA_FACET_MAXLENGTH:
   8176 	case XML_SCHEMA_FACET_MINLENGTH: {
   8177 		xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
   8178 		ADD_ANNOTATION(annot)
   8179 	    }
   8180 	    break;
   8181 	case XML_SCHEMA_TYPE_SIMPLE:
   8182 	case XML_SCHEMA_TYPE_COMPLEX: {
   8183 		xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
   8184 		ADD_ANNOTATION(annot)
   8185 	    }
   8186 	    break;
   8187 	case XML_SCHEMA_TYPE_GROUP: {
   8188 		xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
   8189 		ADD_ANNOTATION(annot)
   8190 	    }
   8191 	    break;
   8192 	case XML_SCHEMA_TYPE_SEQUENCE:
   8193 	case XML_SCHEMA_TYPE_CHOICE:
   8194 	case XML_SCHEMA_TYPE_ALL: {
   8195 		xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
   8196 		ADD_ANNOTATION(annot)
   8197 	    }
   8198 	    break;
   8199 	default:
   8200 	     xmlSchemaPCustomErr(NULL,
   8201 		XML_SCHEMAP_INTERNAL,
   8202 		NULL, NULL,
   8203 		"Internal error: xmlSchemaAddAnnotation, "
   8204 		"The item is not a annotated schema component", NULL);
   8205 	     break;
   8206     }
   8207     return (annot);
   8208 }
   8209 
   8210 /**
   8211  * xmlSchemaParseIDCSelectorAndField:
   8212  * @ctxt:  a schema validation context
   8213  * @schema:  the schema being built
   8214  * @node:  a subtree containing XML Schema informations
   8215  *
   8216  * Parses a XML Schema identity-contraint definition's
   8217  * <selector> and <field> elements.
   8218  *
   8219  * Returns the parsed identity-constraint definition.
   8220  */
   8221 static xmlSchemaIDCSelectPtr
   8222 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
   8223 			  xmlSchemaIDCPtr idc,
   8224 			  xmlNodePtr node,
   8225 			  int isField)
   8226 {
   8227     xmlSchemaIDCSelectPtr item;
   8228     xmlNodePtr child = NULL;
   8229     xmlAttrPtr attr;
   8230 
   8231     /*
   8232     * Check for illegal attributes.
   8233     */
   8234     attr = node->properties;
   8235     while (attr != NULL) {
   8236 	if (attr->ns == NULL) {
   8237 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8238 		(!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
   8239 		xmlSchemaPIllegalAttrErr(ctxt,
   8240 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8241 	    }
   8242 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8243 	    xmlSchemaPIllegalAttrErr(ctxt,
   8244 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8245 	}
   8246 	attr = attr->next;
   8247     }
   8248     /*
   8249     * Create the item.
   8250     */
   8251     item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
   8252     if (item == NULL) {
   8253         xmlSchemaPErrMemory(ctxt,
   8254 	    "allocating a 'selector' of an identity-constraint definition",
   8255 	    NULL);
   8256         return (NULL);
   8257     }
   8258     memset(item, 0, sizeof(xmlSchemaIDCSelect));
   8259     /*
   8260     * Attribute "xpath" (mandatory).
   8261     */
   8262     attr = xmlSchemaGetPropNode(node, "xpath");
   8263     if (attr == NULL) {
   8264 	xmlSchemaPMissingAttrErr(ctxt,
   8265 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   8266 	    NULL, node,
   8267 	    "name", NULL);
   8268     } else {
   8269 	item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8270 	/*
   8271 	* URGENT TODO: "field"s have an other syntax than "selector"s.
   8272 	*/
   8273 
   8274 	if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
   8275 	    isField) == -1) {
   8276 	    xmlSchemaPErr(ctxt,
   8277 		(xmlNodePtr) attr,
   8278 		XML_SCHEMAP_INTERNAL,
   8279 		"Internal error: xmlSchemaParseIDCSelectorAndField, "
   8280 		"validating the XPath expression of a IDC selector.\n",
   8281 		NULL, NULL);
   8282 	}
   8283 
   8284     }
   8285     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8286     /*
   8287     * And now for the children...
   8288     */
   8289     child = node->children;
   8290     if (IS_SCHEMA(child, "annotation")) {
   8291 	/*
   8292 	* Add the annotation to the parent IDC.
   8293 	*/
   8294 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
   8295 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   8296 	child = child->next;
   8297     }
   8298     if (child != NULL) {
   8299 	xmlSchemaPContentErr(ctxt,
   8300 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8301 	    NULL, node, child,
   8302 	    NULL, "(annotation?)");
   8303     }
   8304 
   8305     return (item);
   8306 }
   8307 
   8308 /**
   8309  * xmlSchemaParseIDC:
   8310  * @ctxt:  a schema validation context
   8311  * @schema:  the schema being built
   8312  * @node:  a subtree containing XML Schema informations
   8313  *
   8314  * Parses a XML Schema identity-contraint definition.
   8315  *
   8316  * Returns the parsed identity-constraint definition.
   8317  */
   8318 static xmlSchemaIDCPtr
   8319 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
   8320 		  xmlSchemaPtr schema,
   8321 		  xmlNodePtr node,
   8322 		  xmlSchemaTypeType idcCategory,
   8323 		  const xmlChar *targetNamespace)
   8324 {
   8325     xmlSchemaIDCPtr item = NULL;
   8326     xmlNodePtr child = NULL;
   8327     xmlAttrPtr attr;
   8328     const xmlChar *name = NULL;
   8329     xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
   8330 
   8331     /*
   8332     * Check for illegal attributes.
   8333     */
   8334     attr = node->properties;
   8335     while (attr != NULL) {
   8336 	if (attr->ns == NULL) {
   8337 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8338 		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   8339 		((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
   8340 		 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
   8341 		xmlSchemaPIllegalAttrErr(ctxt,
   8342 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8343 	    }
   8344 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8345 	    xmlSchemaPIllegalAttrErr(ctxt,
   8346 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8347 	}
   8348 	attr = attr->next;
   8349     }
   8350     /*
   8351     * Attribute "name" (mandatory).
   8352     */
   8353     attr = xmlSchemaGetPropNode(node, "name");
   8354     if (attr == NULL) {
   8355 	xmlSchemaPMissingAttrErr(ctxt,
   8356 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   8357 	    NULL, node,
   8358 	    "name", NULL);
   8359 	return (NULL);
   8360     } else if (xmlSchemaPValAttrNode(ctxt,
   8361 	NULL, attr,
   8362 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   8363 	return (NULL);
   8364     }
   8365     /* Create the component. */
   8366     item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
   8367 	idcCategory, node);
   8368     if (item == NULL)
   8369 	return(NULL);
   8370 
   8371     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8372     if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
   8373 	/*
   8374 	* Attribute "refer" (mandatory).
   8375 	*/
   8376 	attr = xmlSchemaGetPropNode(node, "refer");
   8377 	if (attr == NULL) {
   8378 	    xmlSchemaPMissingAttrErr(ctxt,
   8379 		XML_SCHEMAP_S4S_ATTR_MISSING,
   8380 		NULL, node,
   8381 		"refer", NULL);
   8382 	} else {
   8383 	    /*
   8384 	    * Create a reference item.
   8385 	    */
   8386 	    item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
   8387 		NULL, NULL);
   8388 	    if (item->ref == NULL)
   8389 		return (NULL);
   8390 	    xmlSchemaPValAttrNodeQName(ctxt, schema,
   8391 		NULL, attr,
   8392 		&(item->ref->targetNamespace),
   8393 		&(item->ref->name));
   8394 	    xmlSchemaCheckReference(ctxt, schema, node, attr,
   8395 		item->ref->targetNamespace);
   8396 	}
   8397     }
   8398     /*
   8399     * And now for the children...
   8400     */
   8401     child = node->children;
   8402     if (IS_SCHEMA(child, "annotation")) {
   8403 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   8404 	child = child->next;
   8405     }
   8406     if (child == NULL) {
   8407 	xmlSchemaPContentErr(ctxt,
   8408 		XML_SCHEMAP_S4S_ELEM_MISSING,
   8409 		NULL, node, child,
   8410 		"A child element is missing",
   8411 		"(annotation?, (selector, field+))");
   8412     }
   8413     /*
   8414     * Child element <selector>.
   8415     */
   8416     if (IS_SCHEMA(child, "selector")) {
   8417 	item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
   8418 	    item, child, 0);
   8419 	child = child->next;
   8420 	/*
   8421 	* Child elements <field>.
   8422 	*/
   8423 	if (IS_SCHEMA(child, "field")) {
   8424 	    do {
   8425 		field = xmlSchemaParseIDCSelectorAndField(ctxt,
   8426 		    item, child, 1);
   8427 		if (field != NULL) {
   8428 		    field->index = item->nbFields;
   8429 		    item->nbFields++;
   8430 		    if (lastField != NULL)
   8431 			lastField->next = field;
   8432 		    else
   8433 			item->fields = field;
   8434 		    lastField = field;
   8435 		}
   8436 		child = child->next;
   8437 	    } while (IS_SCHEMA(child, "field"));
   8438 	} else {
   8439 	    xmlSchemaPContentErr(ctxt,
   8440 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8441 		NULL, node, child,
   8442 		NULL, "(annotation?, (selector, field+))");
   8443 	}
   8444     }
   8445     if (child != NULL) {
   8446 	xmlSchemaPContentErr(ctxt,
   8447 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8448 	    NULL, node, child,
   8449 	    NULL, "(annotation?, (selector, field+))");
   8450     }
   8451 
   8452     return (item);
   8453 }
   8454 
   8455 /**
   8456  * xmlSchemaParseElement:
   8457  * @ctxt:  a schema validation context
   8458  * @schema:  the schema being built
   8459  * @node:  a subtree containing XML Schema informations
   8460  * @topLevel: indicates if this is global declaration
   8461  *
   8462  * Parses a XML schema element declaration.
   8463  * *WARNING* this interface is highly subject to change
   8464  *
   8465  * Returns the element declaration or a particle; NULL in case
   8466  * of an error or if the particle has minOccurs==maxOccurs==0.
   8467  */
   8468 static xmlSchemaBasicItemPtr
   8469 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   8470                       xmlNodePtr node, int *isElemRef, int topLevel)
   8471 {
   8472     xmlSchemaElementPtr decl = NULL;
   8473     xmlSchemaParticlePtr particle = NULL;
   8474     xmlSchemaAnnotPtr annot = NULL;
   8475     xmlNodePtr child = NULL;
   8476     xmlAttrPtr attr, nameAttr;
   8477     int min, max, isRef = 0;
   8478     xmlChar *des = NULL;
   8479 
   8480     /* 3.3.3 Constraints on XML Representations of Element Declarations */
   8481     /* TODO: Complete implementation of 3.3.6 */
   8482 
   8483     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   8484         return (NULL);
   8485 
   8486     if (isElemRef != NULL)
   8487 	*isElemRef = 0;
   8488     /*
   8489     * If we get a "ref" attribute on a local <element> we will assume it's
   8490     * a reference - even if there's a "name" attribute; this seems to be more
   8491     * robust.
   8492     */
   8493     nameAttr = xmlSchemaGetPropNode(node, "name");
   8494     attr = xmlSchemaGetPropNode(node, "ref");
   8495     if ((topLevel) || (attr == NULL)) {
   8496 	if (nameAttr == NULL) {
   8497 	    xmlSchemaPMissingAttrErr(ctxt,
   8498 		XML_SCHEMAP_S4S_ATTR_MISSING,
   8499 		NULL, node, "name", NULL);
   8500 	    return (NULL);
   8501 	}
   8502     } else
   8503 	isRef = 1;
   8504 
   8505     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8506     child = node->children;
   8507     if (IS_SCHEMA(child, "annotation")) {
   8508 	annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   8509 	child = child->next;
   8510     }
   8511     /*
   8512     * Skip particle part if a global declaration.
   8513     */
   8514     if (topLevel)
   8515 	goto declaration_part;
   8516     /*
   8517     * The particle part ==================================================
   8518     */
   8519     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
   8520     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
   8521     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
   8522     particle = xmlSchemaAddParticle(ctxt, node, min, max);
   8523     if (particle == NULL)
   8524 	goto return_null;
   8525 
   8526     /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
   8527 
   8528     if (isRef) {
   8529 	const xmlChar *refNs = NULL, *ref = NULL;
   8530 	xmlSchemaQNameRefPtr refer = NULL;
   8531 	/*
   8532 	* The reference part =============================================
   8533 	*/
   8534 	if (isElemRef != NULL)
   8535 	    *isElemRef = 1;
   8536 
   8537 	xmlSchemaPValAttrNodeQName(ctxt, schema,
   8538 	    NULL, attr, &refNs, &ref);
   8539 	xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
   8540 	/*
   8541 	* SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
   8542 	*/
   8543 	if (nameAttr != NULL) {
   8544 	    xmlSchemaPMutualExclAttrErr(ctxt,
   8545 		XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
   8546 	}
   8547 	/*
   8548 	* Check for illegal attributes.
   8549 	*/
   8550 	attr = node->properties;
   8551 	while (attr != NULL) {
   8552 	    if (attr->ns == NULL) {
   8553 		if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
   8554 		    xmlStrEqual(attr->name, BAD_CAST "name") ||
   8555 		    xmlStrEqual(attr->name, BAD_CAST "id") ||
   8556 		    xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
   8557 		    xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
   8558 		{
   8559 		    attr = attr->next;
   8560 		    continue;
   8561 		} else {
   8562 		    /* SPEC (3.3.3 : 2.2) */
   8563 		    xmlSchemaPCustomAttrErr(ctxt,
   8564 			XML_SCHEMAP_SRC_ELEMENT_2_2,
   8565 			NULL, NULL, attr,
   8566 			"Only the attributes 'minOccurs', 'maxOccurs' and "
   8567 			"'id' are allowed in addition to 'ref'");
   8568 		    break;
   8569 		}
   8570 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8571 		xmlSchemaPIllegalAttrErr(ctxt,
   8572 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8573 	    }
   8574 	    attr = attr->next;
   8575 	}
   8576 	/*
   8577 	* No children except <annotation> expected.
   8578 	*/
   8579 	if (child != NULL) {
   8580 	    xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8581 		NULL, node, child, NULL, "(annotation?)");
   8582 	}
   8583 	if ((min == 0) && (max == 0))
   8584 	    goto return_null;
   8585 	/*
   8586 	* Create the reference item and attach it to the particle.
   8587 	*/
   8588 	refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
   8589 	    ref, refNs);
   8590 	if (refer == NULL)
   8591 	    goto return_null;
   8592 	particle->children = (xmlSchemaTreeItemPtr) refer;
   8593 	particle->annot = annot;
   8594 	/*
   8595 	* Add the particle to pending components, since the reference
   8596 	* need to be resolved.
   8597 	*/
   8598 	WXS_ADD_PENDING(ctxt, particle);
   8599 	return ((xmlSchemaBasicItemPtr) particle);
   8600     }
   8601     /*
   8602     * The declaration part ===============================================
   8603     */
   8604 declaration_part:
   8605     {
   8606 	const xmlChar *ns = NULL, *fixed, *name, *attrValue;
   8607 	xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
   8608 
   8609 	if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
   8610 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
   8611 	    goto return_null;
   8612 	/*
   8613 	* Evaluate the target namespace.
   8614 	*/
   8615 	if (topLevel) {
   8616 	    ns = ctxt->targetNamespace;
   8617 	} else {
   8618 	    attr = xmlSchemaGetPropNode(node, "form");
   8619 	    if (attr != NULL) {
   8620 		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8621 		if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
   8622 		    ns = ctxt->targetNamespace;
   8623 		} else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
   8624 		    xmlSchemaPSimpleTypeErr(ctxt,
   8625 			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8626 			NULL, (xmlNodePtr) attr,
   8627 			NULL, "(qualified | unqualified)",
   8628 			attrValue, NULL, NULL, NULL);
   8629 		}
   8630 	    } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
   8631 		ns = ctxt->targetNamespace;
   8632 	}
   8633 	decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
   8634 	if (decl == NULL) {
   8635 	    goto return_null;
   8636 	}
   8637 	/*
   8638 	* Check for illegal attributes.
   8639 	*/
   8640 	attr = node->properties;
   8641 	while (attr != NULL) {
   8642 	    if (attr->ns == NULL) {
   8643 		if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   8644 		    (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
   8645 		    (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8646 		    (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
   8647 		    (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
   8648 		    (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
   8649 		    (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
   8650 		{
   8651 		    if (topLevel == 0) {
   8652 			if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
   8653 			    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
   8654 			    (!xmlStrEqual(attr->name, BAD_CAST "form")))
   8655 			{
   8656 			    xmlSchemaPIllegalAttrErr(ctxt,
   8657 				XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8658 			}
   8659 		    } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
   8660 			(!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
   8661 			(!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
   8662 
   8663 			xmlSchemaPIllegalAttrErr(ctxt,
   8664 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8665 		    }
   8666 		}
   8667 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8668 
   8669 		xmlSchemaPIllegalAttrErr(ctxt,
   8670 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8671 	    }
   8672 	    attr = attr->next;
   8673 	}
   8674 	/*
   8675 	* Extract/validate attributes.
   8676 	*/
   8677 	if (topLevel) {
   8678 	    /*
   8679 	    * Process top attributes of global element declarations here.
   8680 	    */
   8681 	    decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
   8682 	    decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
   8683 	    xmlSchemaPValAttrQName(ctxt, schema,
   8684 		NULL, node, "substitutionGroup",
   8685 		&(decl->substGroupNs), &(decl->substGroup));
   8686 	    if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
   8687 		decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
   8688 	    /*
   8689 	    * Attribute "final".
   8690 	    */
   8691 	    attr = xmlSchemaGetPropNode(node, "final");
   8692 	    if (attr == NULL) {
   8693 		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
   8694 		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
   8695 		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   8696 		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
   8697 	    } else {
   8698 		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8699 		if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
   8700 		    -1,
   8701 		    XML_SCHEMAS_ELEM_FINAL_EXTENSION,
   8702 		    XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
   8703 		    xmlSchemaPSimpleTypeErr(ctxt,
   8704 			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8705 			NULL, (xmlNodePtr) attr,
   8706 			NULL, "(#all | List of (extension | restriction))",
   8707 			attrValue, NULL, NULL, NULL);
   8708 		}
   8709 	    }
   8710 	}
   8711 	/*
   8712 	* Attribute "block".
   8713 	*/
   8714 	attr = xmlSchemaGetPropNode(node, "block");
   8715 	if (attr == NULL) {
   8716 	    /*
   8717 	    * Apply default "block" values.
   8718 	    */
   8719 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
   8720 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
   8721 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
   8722 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
   8723 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
   8724 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
   8725 	} else {
   8726 	    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8727 	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
   8728 		-1,
   8729 		XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
   8730 		XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
   8731 		XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
   8732 		xmlSchemaPSimpleTypeErr(ctxt,
   8733 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8734 		    NULL, (xmlNodePtr) attr,
   8735 		    NULL, "(#all | List of (extension | "
   8736 		    "restriction | substitution))", attrValue,
   8737 		    NULL, NULL, NULL);
   8738 	    }
   8739 	}
   8740 	if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
   8741 	    decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
   8742 
   8743 	attr = xmlSchemaGetPropNode(node, "type");
   8744 	if (attr != NULL) {
   8745 	    xmlSchemaPValAttrNodeQName(ctxt, schema,
   8746 		NULL, attr,
   8747 		&(decl->namedTypeNs), &(decl->namedType));
   8748 	    xmlSchemaCheckReference(ctxt, schema, node,
   8749 		attr, decl->namedTypeNs);
   8750 	}
   8751 	decl->value = xmlSchemaGetProp(ctxt, node, "default");
   8752 	attr = xmlSchemaGetPropNode(node, "fixed");
   8753 	if (attr != NULL) {
   8754 	    fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8755 	    if (decl->value != NULL) {
   8756 		/*
   8757 		* 3.3.3 : 1
   8758 		* default and fixed must not both be present.
   8759 		*/
   8760 		xmlSchemaPMutualExclAttrErr(ctxt,
   8761 		    XML_SCHEMAP_SRC_ELEMENT_1,
   8762 		    NULL, attr, "default", "fixed");
   8763 	    } else {
   8764 		decl->flags |= XML_SCHEMAS_ELEM_FIXED;
   8765 		decl->value = fixed;
   8766 	    }
   8767 	}
   8768 	/*
   8769 	* And now for the children...
   8770 	*/
   8771 	if (IS_SCHEMA(child, "complexType")) {
   8772 	    /*
   8773 	    * 3.3.3 : 3
   8774 	    * "type" and either <simpleType> or <complexType> are mutually
   8775 	    * exclusive
   8776 	    */
   8777 	    if (decl->namedType != NULL) {
   8778 		xmlSchemaPContentErr(ctxt,
   8779 		    XML_SCHEMAP_SRC_ELEMENT_3,
   8780 		    NULL, node, child,
   8781 		    "The attribute 'type' and the <complexType> child are "
   8782 		    "mutually exclusive", NULL);
   8783 	    } else
   8784 		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
   8785 	    child = child->next;
   8786 	} else if (IS_SCHEMA(child, "simpleType")) {
   8787 	    /*
   8788 	    * 3.3.3 : 3
   8789 	    * "type" and either <simpleType> or <complexType> are
   8790 	    * mutually exclusive
   8791 	    */
   8792 	    if (decl->namedType != NULL) {
   8793 		xmlSchemaPContentErr(ctxt,
   8794 		    XML_SCHEMAP_SRC_ELEMENT_3,
   8795 		    NULL, node, child,
   8796 		    "The attribute 'type' and the <simpleType> child are "
   8797 		    "mutually exclusive", NULL);
   8798 	    } else
   8799 		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   8800 	    child = child->next;
   8801 	}
   8802 	while ((IS_SCHEMA(child, "unique")) ||
   8803 	    (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
   8804 	    if (IS_SCHEMA(child, "unique")) {
   8805 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
   8806 		    XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
   8807 	    } else if (IS_SCHEMA(child, "key")) {
   8808 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
   8809 		    XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
   8810 	    } else if (IS_SCHEMA(child, "keyref")) {
   8811 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
   8812 		    XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
   8813 	    }
   8814 	    if (lastIDC != NULL)
   8815 		lastIDC->next = curIDC;
   8816 	    else
   8817 		decl->idcs = (void *) curIDC;
   8818 	    lastIDC = curIDC;
   8819 	    child = child->next;
   8820 	}
   8821 	if (child != NULL) {
   8822 	    xmlSchemaPContentErr(ctxt,
   8823 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8824 		NULL, node, child,
   8825 		NULL, "(annotation?, ((simpleType | complexType)?, "
   8826 		"(unique | key | keyref)*))");
   8827 	}
   8828 	decl->annot = annot;
   8829     }
   8830     /*
   8831     * NOTE: Element Declaration Representation OK 4. will be checked at a
   8832     * different layer.
   8833     */
   8834     FREE_AND_NULL(des)
   8835     if (topLevel)
   8836 	return ((xmlSchemaBasicItemPtr) decl);
   8837     else {
   8838 	particle->children = (xmlSchemaTreeItemPtr) decl;
   8839 	return ((xmlSchemaBasicItemPtr) particle);
   8840     }
   8841 
   8842 return_null:
   8843     FREE_AND_NULL(des);
   8844     if (annot != NULL) {
   8845 	if (particle != NULL)
   8846 	    particle->annot = NULL;
   8847 	if (decl != NULL)
   8848 	    decl->annot = NULL;
   8849 	xmlSchemaFreeAnnot(annot);
   8850     }
   8851     return (NULL);
   8852 }
   8853 
   8854 /**
   8855  * xmlSchemaParseUnion:
   8856  * @ctxt:  a schema validation context
   8857  * @schema:  the schema being built
   8858  * @node:  a subtree containing XML Schema informations
   8859  *
   8860  * parse a XML schema Union definition
   8861  * *WARNING* this interface is highly subject to change
   8862  *
   8863  * Returns -1 in case of internal error, 0 in case of success and a positive
   8864  * error code otherwise.
   8865  */
   8866 static int
   8867 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   8868                     xmlNodePtr node)
   8869 {
   8870     xmlSchemaTypePtr type;
   8871     xmlNodePtr child = NULL;
   8872     xmlAttrPtr attr;
   8873     const xmlChar *cur = NULL;
   8874 
   8875     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   8876         return (-1);
   8877     /* Not a component, don't create it. */
   8878     type = ctxt->ctxtType;
   8879     /*
   8880     * Mark the simple type as being of variety "union".
   8881     */
   8882     type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
   8883     /*
   8884     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
   8885     * then the `simple ur-type definition`."
   8886     */
   8887     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
   8888     /*
   8889     * Check for illegal attributes.
   8890     */
   8891     attr = node->properties;
   8892     while (attr != NULL) {
   8893 	if (attr->ns == NULL) {
   8894 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8895 		(!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
   8896 		xmlSchemaPIllegalAttrErr(ctxt,
   8897 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8898 	    }
   8899 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8900 	    xmlSchemaPIllegalAttrErr(ctxt,
   8901 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8902 	}
   8903 	attr = attr->next;
   8904     }
   8905     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8906     /*
   8907     * Attribute "memberTypes". This is a list of QNames.
   8908     * TODO: Check the value to contain anything.
   8909     */
   8910     attr = xmlSchemaGetPropNode(node, "memberTypes");
   8911     if (attr != NULL) {
   8912 	const xmlChar *end;
   8913 	xmlChar *tmp;
   8914 	const xmlChar *localName, *nsName;
   8915 	xmlSchemaTypeLinkPtr link, lastLink = NULL;
   8916 	xmlSchemaQNameRefPtr ref;
   8917 
   8918 	cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8919 	type->base = cur;
   8920 	do {
   8921 	    while (IS_BLANK_CH(*cur))
   8922 		cur++;
   8923 	    end = cur;
   8924 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   8925 		end++;
   8926 	    if (end == cur)
   8927 		break;
   8928 	    tmp = xmlStrndup(cur, end - cur);
   8929 	    if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
   8930 		NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
   8931 		/*
   8932 		* Create the member type link.
   8933 		*/
   8934 		link = (xmlSchemaTypeLinkPtr)
   8935 		    xmlMalloc(sizeof(xmlSchemaTypeLink));
   8936 		if (link == NULL) {
   8937 		    xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
   8938 			"allocating a type link", NULL);
   8939 		    return (-1);
   8940 		}
   8941 		link->type = NULL;
   8942 		link->next = NULL;
   8943 		if (lastLink == NULL)
   8944 		    type->memberTypes = link;
   8945 		else
   8946 		    lastLink->next = link;
   8947 		lastLink = link;
   8948 		/*
   8949 		* Create a reference item.
   8950 		*/
   8951 		ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
   8952 		    localName, nsName);
   8953 		if (ref == NULL) {
   8954 		    FREE_AND_NULL(tmp)
   8955 		    return (-1);
   8956 		}
   8957 		/*
   8958 		* Assign the reference to the link, it will be resolved
   8959 		* later during fixup of the union simple type.
   8960 		*/
   8961 		link->type = (xmlSchemaTypePtr) ref;
   8962 	    }
   8963 	    FREE_AND_NULL(tmp)
   8964 	    cur = end;
   8965 	} while (*cur != 0);
   8966 
   8967     }
   8968     /*
   8969     * And now for the children...
   8970     */
   8971     child = node->children;
   8972     if (IS_SCHEMA(child, "annotation")) {
   8973 	/*
   8974 	* Add the annotation to the simple type ancestor.
   8975 	*/
   8976 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   8977 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   8978         child = child->next;
   8979     }
   8980     if (IS_SCHEMA(child, "simpleType")) {
   8981 	xmlSchemaTypePtr subtype, last = NULL;
   8982 
   8983 	/*
   8984 	* Anchor the member types in the "subtypes" field of the
   8985 	* simple type.
   8986 	*/
   8987 	while (IS_SCHEMA(child, "simpleType")) {
   8988 	    subtype = (xmlSchemaTypePtr)
   8989 		xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   8990 	    if (subtype != NULL) {
   8991 		if (last == NULL) {
   8992 		    type->subtypes = subtype;
   8993 		    last = subtype;
   8994 		} else {
   8995 		    last->next = subtype;
   8996 		    last = subtype;
   8997 		}
   8998 		last->next = NULL;
   8999 	    }
   9000 	    child = child->next;
   9001 	}
   9002     }
   9003     if (child != NULL) {
   9004 	xmlSchemaPContentErr(ctxt,
   9005 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9006 	    NULL, node, child, NULL, "(annotation?, simpleType*)");
   9007     }
   9008     if ((attr == NULL) && (type->subtypes == NULL)) {
   9009 	 /*
   9010 	* src-union-memberTypes-or-simpleTypes
   9011 	* Either the memberTypes [attribute] of the <union> element must
   9012 	* be non-empty or there must be at least one simpleType [child].
   9013 	*/
   9014 	xmlSchemaPCustomErr(ctxt,
   9015 	    XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
   9016 	    NULL, node,
   9017 	    "Either the attribute 'memberTypes' or "
   9018 	    "at least one <simpleType> child must be present", NULL);
   9019     }
   9020     return (0);
   9021 }
   9022 
   9023 /**
   9024  * xmlSchemaParseList:
   9025  * @ctxt:  a schema validation context
   9026  * @schema:  the schema being built
   9027  * @node:  a subtree containing XML Schema informations
   9028  *
   9029  * parse a XML schema List definition
   9030  * *WARNING* this interface is highly subject to change
   9031  *
   9032  * Returns -1 in case of error, 0 if the declaration is improper and
   9033  *         1 in case of success.
   9034  */
   9035 static xmlSchemaTypePtr
   9036 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   9037                    xmlNodePtr node)
   9038 {
   9039     xmlSchemaTypePtr type;
   9040     xmlNodePtr child = NULL;
   9041     xmlAttrPtr attr;
   9042 
   9043     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9044         return (NULL);
   9045     /* Not a component, don't create it. */
   9046     type = ctxt->ctxtType;
   9047     /*
   9048     * Mark the type as being of variety "list".
   9049     */
   9050     type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
   9051     /*
   9052     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
   9053     * then the `simple ur-type definition`."
   9054     */
   9055     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
   9056     /*
   9057     * Check for illegal attributes.
   9058     */
   9059     attr = node->properties;
   9060     while (attr != NULL) {
   9061 	if (attr->ns == NULL) {
   9062 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   9063 		(!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
   9064 		xmlSchemaPIllegalAttrErr(ctxt,
   9065 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9066 	    }
   9067 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9068 	    xmlSchemaPIllegalAttrErr(ctxt,
   9069 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9070 	}
   9071 	attr = attr->next;
   9072     }
   9073 
   9074     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9075 
   9076     /*
   9077     * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
   9078     * fields for holding the reference to the itemType.
   9079     *
   9080     * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
   9081     * the "ref" fields.
   9082     */
   9083     xmlSchemaPValAttrQName(ctxt, schema, NULL,
   9084 	node, "itemType", &(type->baseNs), &(type->base));
   9085     /*
   9086     * And now for the children...
   9087     */
   9088     child = node->children;
   9089     if (IS_SCHEMA(child, "annotation")) {
   9090 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   9091 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   9092         child = child->next;
   9093     }
   9094     if (IS_SCHEMA(child, "simpleType")) {
   9095 	/*
   9096 	* src-list-itemType-or-simpleType
   9097 	* Either the itemType [attribute] or the <simpleType> [child] of
   9098 	* the <list> element must be present, but not both.
   9099 	*/
   9100 	if (type->base != NULL) {
   9101 	    xmlSchemaPCustomErr(ctxt,
   9102 		XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   9103 		NULL, node,
   9104 		"The attribute 'itemType' and the <simpleType> child "
   9105 		"are mutually exclusive", NULL);
   9106 	} else {
   9107 	    type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   9108 	}
   9109         child = child->next;
   9110     } else if (type->base == NULL) {
   9111 	xmlSchemaPCustomErr(ctxt,
   9112 	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   9113 	    NULL, node,
   9114 	    "Either the attribute 'itemType' or the <simpleType> child "
   9115 	    "must be present", NULL);
   9116     }
   9117     if (child != NULL) {
   9118 	xmlSchemaPContentErr(ctxt,
   9119 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9120 	    NULL, node, child, NULL, "(annotation?, simpleType?)");
   9121     }
   9122     if ((type->base == NULL) &&
   9123 	(type->subtypes == NULL) &&
   9124 	(xmlSchemaGetPropNode(node, "itemType") == NULL)) {
   9125 	xmlSchemaPCustomErr(ctxt,
   9126 	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   9127 	    NULL, node,
   9128 	    "Either the attribute 'itemType' or the <simpleType> child "
   9129 	    "must be present", NULL);
   9130     }
   9131     return (NULL);
   9132 }
   9133 
   9134 /**
   9135  * xmlSchemaParseSimpleType:
   9136  * @ctxt:  a schema validation context
   9137  * @schema:  the schema being built
   9138  * @node:  a subtree containing XML Schema informations
   9139  *
   9140  * parse a XML schema Simple Type definition
   9141  * *WARNING* this interface is highly subject to change
   9142  *
   9143  * Returns -1 in case of error, 0 if the declaration is improper and
   9144  * 1 in case of success.
   9145  */
   9146 static xmlSchemaTypePtr
   9147 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   9148                          xmlNodePtr node, int topLevel)
   9149 {
   9150     xmlSchemaTypePtr type, oldCtxtType;
   9151     xmlNodePtr child = NULL;
   9152     const xmlChar *attrValue = NULL;
   9153     xmlAttrPtr attr;
   9154     int hasRestriction = 0;
   9155 
   9156     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9157         return (NULL);
   9158 
   9159     if (topLevel) {
   9160 	attr = xmlSchemaGetPropNode(node, "name");
   9161 	if (attr == NULL) {
   9162 	    xmlSchemaPMissingAttrErr(ctxt,
   9163 		XML_SCHEMAP_S4S_ATTR_MISSING,
   9164 		NULL, node,
   9165 		"name", NULL);
   9166 	    return (NULL);
   9167 	} else {
   9168 	    if (xmlSchemaPValAttrNode(ctxt,
   9169 		NULL, attr,
   9170 		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
   9171 		return (NULL);
   9172 	    /*
   9173 	    * Skip built-in types.
   9174 	    */
   9175 	    if (ctxt->isS4S) {
   9176 		xmlSchemaTypePtr biType;
   9177 
   9178 		if (ctxt->isRedefine) {
   9179 		    /*
   9180 		    * REDEFINE: Disallow redefinition of built-in-types.
   9181 		    * TODO: It seems that the spec does not say anything
   9182 		    * about this case.
   9183 		    */
   9184 		    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   9185 			NULL, node,
   9186 			"Redefinition of built-in simple types is not "
   9187 			"supported", NULL);
   9188 		    return(NULL);
   9189 		}
   9190 		biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
   9191 		if (biType != NULL)
   9192 		    return (biType);
   9193 	    }
   9194 	}
   9195     }
   9196     /*
   9197     * TargetNamespace:
   9198     * SPEC "The `actual value` of the targetNamespace [attribute]
   9199     * of the <schema> ancestor element information item if present,
   9200     * otherwise `absent`.
   9201     */
   9202     if (topLevel == 0) {
   9203 #ifdef ENABLE_NAMED_LOCALS
   9204         char buf[40];
   9205 #endif
   9206 	/*
   9207 	* Parse as local simple type definition.
   9208 	*/
   9209 #ifdef ENABLE_NAMED_LOCALS
   9210         snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
   9211 	type = xmlSchemaAddType(ctxt, schema,
   9212 	    XML_SCHEMA_TYPE_SIMPLE,
   9213 	    xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
   9214 	    ctxt->targetNamespace, node, 0);
   9215 #else
   9216 	type = xmlSchemaAddType(ctxt, schema,
   9217 	    XML_SCHEMA_TYPE_SIMPLE,
   9218 	    NULL, ctxt->targetNamespace, node, 0);
   9219 #endif
   9220 	if (type == NULL)
   9221 	    return (NULL);
   9222 	type->type = XML_SCHEMA_TYPE_SIMPLE;
   9223 	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   9224 	/*
   9225 	* Check for illegal attributes.
   9226 	*/
   9227 	attr = node->properties;
   9228 	while (attr != NULL) {
   9229 	    if (attr->ns == NULL) {
   9230 		if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
   9231 		    xmlSchemaPIllegalAttrErr(ctxt,
   9232 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9233 		}
   9234 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9235 		    xmlSchemaPIllegalAttrErr(ctxt,
   9236 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9237 	    }
   9238 	    attr = attr->next;
   9239 	}
   9240     } else {
   9241 	/*
   9242 	* Parse as global simple type definition.
   9243 	*
   9244 	* Note that attrValue is the value of the attribute "name" here.
   9245 	*/
   9246 	type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
   9247 	    attrValue, ctxt->targetNamespace, node, 1);
   9248 	if (type == NULL)
   9249 	    return (NULL);
   9250 	type->type = XML_SCHEMA_TYPE_SIMPLE;
   9251 	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   9252 	type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
   9253 	/*
   9254 	* Check for illegal attributes.
   9255 	*/
   9256 	attr = node->properties;
   9257 	while (attr != NULL) {
   9258 	    if (attr->ns == NULL) {
   9259 		if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   9260 		    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   9261 		    (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
   9262 		    xmlSchemaPIllegalAttrErr(ctxt,
   9263 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9264 		}
   9265 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9266 		xmlSchemaPIllegalAttrErr(ctxt,
   9267 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9268 	    }
   9269 	    attr = attr->next;
   9270 	}
   9271 	/*
   9272 	* Attribute "final".
   9273 	*/
   9274 	attr = xmlSchemaGetPropNode(node, "final");
   9275 	if (attr == NULL) {
   9276 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   9277 		type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
   9278 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
   9279 		type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
   9280 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
   9281 		type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
   9282 	} else {
   9283 	    attrValue = xmlSchemaGetProp(ctxt, node, "final");
   9284 	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
   9285 		-1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
   9286 		XML_SCHEMAS_TYPE_FINAL_LIST,
   9287 		XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
   9288 
   9289 		xmlSchemaPSimpleTypeErr(ctxt,
   9290 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   9291 		    WXS_BASIC_CAST type, (xmlNodePtr) attr,
   9292 		    NULL, "(#all | List of (list | union | restriction)",
   9293 		    attrValue, NULL, NULL, NULL);
   9294 	    }
   9295 	}
   9296     }
   9297     type->targetNamespace = ctxt->targetNamespace;
   9298     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9299     /*
   9300     * And now for the children...
   9301     */
   9302     oldCtxtType = ctxt->ctxtType;
   9303 
   9304     ctxt->ctxtType = type;
   9305 
   9306     child = node->children;
   9307     if (IS_SCHEMA(child, "annotation")) {
   9308         type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9309         child = child->next;
   9310     }
   9311     if (child == NULL) {
   9312 	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
   9313 	    NULL, node, child, NULL,
   9314 	    "(annotation?, (restriction | list | union))");
   9315     } else if (IS_SCHEMA(child, "restriction")) {
   9316         xmlSchemaParseRestriction(ctxt, schema, child,
   9317 	    XML_SCHEMA_TYPE_SIMPLE);
   9318 	hasRestriction = 1;
   9319         child = child->next;
   9320     } else if (IS_SCHEMA(child, "list")) {
   9321         xmlSchemaParseList(ctxt, schema, child);
   9322         child = child->next;
   9323     } else if (IS_SCHEMA(child, "union")) {
   9324         xmlSchemaParseUnion(ctxt, schema, child);
   9325         child = child->next;
   9326     }
   9327     if (child != NULL) {
   9328 	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9329 	    NULL, node, child, NULL,
   9330 	    "(annotation?, (restriction | list | union))");
   9331     }
   9332     /*
   9333     * REDEFINE: SPEC src-redefine (5)
   9334     * "Within the [children], each <simpleType> must have a
   9335     * <restriction> among its [children] ... the `actual value` of whose
   9336     * base [attribute] must be the same as the `actual value` of its own
   9337     * name attribute plus target namespace;"
   9338     */
   9339     if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
   9340 	xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   9341 	    NULL, node, "This is a redefinition, thus the "
   9342 	    "<simpleType> must have a <restriction> child", NULL);
   9343     }
   9344 
   9345     ctxt->ctxtType = oldCtxtType;
   9346     return (type);
   9347 }
   9348 
   9349 /**
   9350  * xmlSchemaParseModelGroupDefRef:
   9351  * @ctxt:  the parser context
   9352  * @schema: the schema being built
   9353  * @node:  the node
   9354  *
   9355  * Parses a reference to a model group definition.
   9356  *
   9357  * We will return a particle component with a qname-component or
   9358  * NULL in case of an error.
   9359  */
   9360 static xmlSchemaTreeItemPtr
   9361 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
   9362 			       xmlSchemaPtr schema,
   9363 			       xmlNodePtr node)
   9364 {
   9365     xmlSchemaParticlePtr item;
   9366     xmlNodePtr child = NULL;
   9367     xmlAttrPtr attr;
   9368     const xmlChar *ref = NULL, *refNs = NULL;
   9369     int min, max;
   9370 
   9371     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9372         return (NULL);
   9373 
   9374     attr = xmlSchemaGetPropNode(node, "ref");
   9375     if (attr == NULL) {
   9376 	xmlSchemaPMissingAttrErr(ctxt,
   9377 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   9378 	    NULL, node, "ref", NULL);
   9379 	return (NULL);
   9380     } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
   9381 	attr, &refNs, &ref) != 0) {
   9382 	return (NULL);
   9383     }
   9384     xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
   9385     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
   9386     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
   9387 	"(xs:nonNegativeInteger | unbounded)");
   9388     /*
   9389     * Check for illegal attributes.
   9390     */
   9391     attr = node->properties;
   9392     while (attr != NULL) {
   9393 	if (attr->ns == NULL) {
   9394 	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
   9395 		(!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   9396 		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
   9397 		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
   9398 		xmlSchemaPIllegalAttrErr(ctxt,
   9399 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9400 	    }
   9401 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9402 	    xmlSchemaPIllegalAttrErr(ctxt,
   9403 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9404 	}
   9405 	attr = attr->next;
   9406     }
   9407     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9408     item = xmlSchemaAddParticle(ctxt, node, min, max);
   9409     if (item == NULL)
   9410 	return (NULL);
   9411     /*
   9412     * Create a qname-reference and set as the term; it will be substituted
   9413     * for the model group after the reference has been resolved.
   9414     */
   9415     item->children = (xmlSchemaTreeItemPtr)
   9416 	xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
   9417     xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
   9418     /*
   9419     * And now for the children...
   9420     */
   9421     child = node->children;
   9422     /* TODO: Is annotation even allowed for a model group reference? */
   9423     if (IS_SCHEMA(child, "annotation")) {
   9424 	/*
   9425 	* TODO: What to do exactly with the annotation?
   9426 	*/
   9427 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9428 	child = child->next;
   9429     }
   9430     if (child != NULL) {
   9431 	xmlSchemaPContentErr(ctxt,
   9432 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9433 	    NULL, node, child, NULL,
   9434 	    "(annotation?)");
   9435     }
   9436     /*
   9437     * Corresponds to no component at all if minOccurs==maxOccurs==0.
   9438     */
   9439     if ((min == 0) && (max == 0))
   9440 	return (NULL);
   9441 
   9442     return ((xmlSchemaTreeItemPtr) item);
   9443 }
   9444 
   9445 /**
   9446  * xmlSchemaParseModelGroupDefinition:
   9447  * @ctxt:  a schema validation context
   9448  * @schema:  the schema being built
   9449  * @node:  a subtree containing XML Schema informations
   9450  *
   9451  * Parses a XML schema model group definition.
   9452  *
   9453  * Note that the contraint src-redefine (6.2) can't be applied until
   9454  * references have been resolved. So we will do this at the
   9455  * component fixup level.
   9456  *
   9457  * *WARNING* this interface is highly subject to change
   9458  *
   9459  * Returns -1 in case of error, 0 if the declaration is improper and
   9460  *         1 in case of success.
   9461  */
   9462 static xmlSchemaModelGroupDefPtr
   9463 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
   9464 				   xmlSchemaPtr schema,
   9465 				   xmlNodePtr node)
   9466 {
   9467     xmlSchemaModelGroupDefPtr item;
   9468     xmlNodePtr child = NULL;
   9469     xmlAttrPtr attr;
   9470     const xmlChar *name;
   9471 
   9472     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9473         return (NULL);
   9474 
   9475     attr = xmlSchemaGetPropNode(node, "name");
   9476     if (attr == NULL) {
   9477 	xmlSchemaPMissingAttrErr(ctxt,
   9478 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   9479 	    NULL, node,
   9480 	    "name", NULL);
   9481 	return (NULL);
   9482     } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
   9483 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   9484 	return (NULL);
   9485     }
   9486     item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
   9487 	ctxt->targetNamespace, node);
   9488     if (item == NULL)
   9489 	return (NULL);
   9490     /*
   9491     * Check for illegal attributes.
   9492     */
   9493     attr = node->properties;
   9494     while (attr != NULL) {
   9495 	if (attr->ns == NULL) {
   9496 	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   9497 		(!xmlStrEqual(attr->name, BAD_CAST "id"))) {
   9498 		xmlSchemaPIllegalAttrErr(ctxt,
   9499 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9500 	    }
   9501 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9502 	    xmlSchemaPIllegalAttrErr(ctxt,
   9503 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9504 	}
   9505 	attr = attr->next;
   9506     }
   9507     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9508     /*
   9509     * And now for the children...
   9510     */
   9511     child = node->children;
   9512     if (IS_SCHEMA(child, "annotation")) {
   9513 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9514 	child = child->next;
   9515     }
   9516     if (IS_SCHEMA(child, "all")) {
   9517 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
   9518 	    XML_SCHEMA_TYPE_ALL, 0);
   9519 	child = child->next;
   9520     } else if (IS_SCHEMA(child, "choice")) {
   9521 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
   9522 	    XML_SCHEMA_TYPE_CHOICE, 0);
   9523 	child = child->next;
   9524     } else if (IS_SCHEMA(child, "sequence")) {
   9525 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
   9526 	    XML_SCHEMA_TYPE_SEQUENCE, 0);
   9527 	child = child->next;
   9528     }
   9529 
   9530 
   9531 
   9532     if (child != NULL) {
   9533 	xmlSchemaPContentErr(ctxt,
   9534 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9535 	    NULL, node, child, NULL,
   9536 	    "(annotation?, (all | choice | sequence)?)");
   9537     }
   9538     return (item);
   9539 }
   9540 
   9541 /**
   9542  * xmlSchemaCleanupDoc:
   9543  * @ctxt:  a schema validation context
   9544  * @node:  the root of the document.
   9545  *
   9546  * removes unwanted nodes in a schemas document tree
   9547  */
   9548 static void
   9549 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
   9550 {
   9551     xmlNodePtr delete, cur;
   9552 
   9553     if ((ctxt == NULL) || (root == NULL)) return;
   9554 
   9555     /*
   9556      * Remove all the blank text nodes
   9557      */
   9558     delete = NULL;
   9559     cur = root;
   9560     while (cur != NULL) {
   9561         if (delete != NULL) {
   9562             xmlUnlinkNode(delete);
   9563             xmlFreeNode(delete);
   9564             delete = NULL;
   9565         }
   9566         if (cur->type == XML_TEXT_NODE) {
   9567             if (IS_BLANK_NODE(cur)) {
   9568                 if (xmlNodeGetSpacePreserve(cur) != 1) {
   9569                     delete = cur;
   9570                 }
   9571             }
   9572         } else if ((cur->type != XML_ELEMENT_NODE) &&
   9573                    (cur->type != XML_CDATA_SECTION_NODE)) {
   9574             delete = cur;
   9575             goto skip_children;
   9576         }
   9577 
   9578         /*
   9579          * Skip to next node
   9580          */
   9581         if (cur->children != NULL) {
   9582             if ((cur->children->type != XML_ENTITY_DECL) &&
   9583                 (cur->children->type != XML_ENTITY_REF_NODE) &&
   9584                 (cur->children->type != XML_ENTITY_NODE)) {
   9585                 cur = cur->children;
   9586                 continue;
   9587             }
   9588         }
   9589       skip_children:
   9590         if (cur->next != NULL) {
   9591             cur = cur->next;
   9592             continue;
   9593         }
   9594 
   9595         do {
   9596             cur = cur->parent;
   9597             if (cur == NULL)
   9598                 break;
   9599             if (cur == root) {
   9600                 cur = NULL;
   9601                 break;
   9602             }
   9603             if (cur->next != NULL) {
   9604                 cur = cur->next;
   9605                 break;
   9606             }
   9607         } while (cur != NULL);
   9608     }
   9609     if (delete != NULL) {
   9610         xmlUnlinkNode(delete);
   9611         xmlFreeNode(delete);
   9612         delete = NULL;
   9613     }
   9614 }
   9615 
   9616 
   9617 static void
   9618 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
   9619 {
   9620     if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
   9621 	schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
   9622 
   9623     if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
   9624 	schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
   9625 
   9626     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
   9627 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
   9628     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   9629 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
   9630     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
   9631 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
   9632     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
   9633 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
   9634 
   9635     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
   9636 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
   9637     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
   9638 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
   9639     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
   9640 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
   9641 }
   9642 
   9643 static int
   9644 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
   9645 			     xmlSchemaPtr schema,
   9646 			     xmlNodePtr node)
   9647 {
   9648     xmlAttrPtr attr;
   9649     const xmlChar *val;
   9650     int res = 0, oldErrs = ctxt->nberrors;
   9651 
   9652     /*
   9653     * Those flags should be moved to the parser context flags,
   9654     * since they are not visible at the component level. I.e.
   9655     * they are used if processing schema *documents* only.
   9656     */
   9657     res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9658     HFAILURE;
   9659 
   9660     /*
   9661     * Since the version is of type xs:token, we won't bother to
   9662     * check it.
   9663     */
   9664     /* REMOVED:
   9665     attr = xmlSchemaGetPropNode(node, "version");
   9666     if (attr != NULL) {
   9667 	res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
   9668 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
   9669 	HFAILURE;
   9670     }
   9671     */
   9672     attr = xmlSchemaGetPropNode(node, "targetNamespace");
   9673     if (attr != NULL) {
   9674 	res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
   9675 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
   9676 	HFAILURE;
   9677 	if (res != 0) {
   9678 	    ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   9679 	    goto exit;
   9680 	}
   9681     }
   9682     attr = xmlSchemaGetPropNode(node, "elementFormDefault");
   9683     if (attr != NULL) {
   9684 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9685 	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
   9686 	    XML_SCHEMAS_QUALIF_ELEM);
   9687 	HFAILURE;
   9688 	if (res != 0) {
   9689 	    xmlSchemaPSimpleTypeErr(ctxt,
   9690 		XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
   9691 		NULL, (xmlNodePtr) attr, NULL,
   9692 		"(qualified | unqualified)", val, NULL, NULL, NULL);
   9693 	}
   9694     }
   9695     attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
   9696     if (attr != NULL) {
   9697 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9698 	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
   9699 	    XML_SCHEMAS_QUALIF_ATTR);
   9700 	HFAILURE;
   9701 	if (res != 0) {
   9702 	    xmlSchemaPSimpleTypeErr(ctxt,
   9703 		XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
   9704 		NULL, (xmlNodePtr) attr, NULL,
   9705 		"(qualified | unqualified)", val, NULL, NULL, NULL);
   9706 	}
   9707     }
   9708     attr = xmlSchemaGetPropNode(node, "finalDefault");
   9709     if (attr != NULL) {
   9710 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9711 	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
   9712 	    XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
   9713 	    XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
   9714 	    -1,
   9715 	    XML_SCHEMAS_FINAL_DEFAULT_LIST,
   9716 	    XML_SCHEMAS_FINAL_DEFAULT_UNION);
   9717 	HFAILURE;
   9718 	if (res != 0) {
   9719 	    xmlSchemaPSimpleTypeErr(ctxt,
   9720 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   9721 		NULL, (xmlNodePtr) attr, NULL,
   9722 		"(#all | List of (extension | restriction | list | union))",
   9723 		val, NULL, NULL, NULL);
   9724 	}
   9725     }
   9726     attr = xmlSchemaGetPropNode(node, "blockDefault");
   9727     if (attr != NULL) {
   9728 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9729 	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
   9730 	    XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
   9731 	    XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
   9732 	    XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
   9733 	HFAILURE;
   9734 	if (res != 0) {
   9735 	    xmlSchemaPSimpleTypeErr(ctxt,
   9736 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   9737 		NULL, (xmlNodePtr) attr, NULL,
   9738 		"(#all | List of (extension | restriction | substitution))",
   9739 		val, NULL, NULL, NULL);
   9740 	}
   9741     }
   9742 
   9743 exit:
   9744     if (oldErrs != ctxt->nberrors)
   9745 	res = ctxt->err;
   9746     return(res);
   9747 exit_failure:
   9748     return(-1);
   9749 }
   9750 
   9751 /**
   9752  * xmlSchemaParseSchemaTopLevel:
   9753  * @ctxt:  a schema validation context
   9754  * @schema:  the schemas
   9755  * @nodes:  the list of top level nodes
   9756  *
   9757  * Returns the internal XML Schema structure built from the resource or
   9758  *         NULL in case of error
   9759  */
   9760 static int
   9761 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
   9762                              xmlSchemaPtr schema, xmlNodePtr nodes)
   9763 {
   9764     xmlNodePtr child;
   9765     xmlSchemaAnnotPtr annot;
   9766     int res = 0, oldErrs, tmpOldErrs;
   9767 
   9768     if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
   9769         return(-1);
   9770 
   9771     oldErrs = ctxt->nberrors;
   9772     child = nodes;
   9773     while ((IS_SCHEMA(child, "include")) ||
   9774 	   (IS_SCHEMA(child, "import")) ||
   9775 	   (IS_SCHEMA(child, "redefine")) ||
   9776 	   (IS_SCHEMA(child, "annotation"))) {
   9777 	if (IS_SCHEMA(child, "annotation")) {
   9778 	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9779 	    if (schema->annot == NULL)
   9780 		schema->annot = annot;
   9781 	    else
   9782 		xmlSchemaFreeAnnot(annot);
   9783 	} else if (IS_SCHEMA(child, "import")) {
   9784 	    tmpOldErrs = ctxt->nberrors;
   9785 	    res = xmlSchemaParseImport(ctxt, schema, child);
   9786 	    HFAILURE;
   9787 	    HSTOP(ctxt);
   9788 	    if (tmpOldErrs != ctxt->nberrors)
   9789 		goto exit;
   9790 	} else if (IS_SCHEMA(child, "include")) {
   9791 	    tmpOldErrs = ctxt->nberrors;
   9792 	    res = xmlSchemaParseInclude(ctxt, schema, child);
   9793 	    HFAILURE;
   9794 	    HSTOP(ctxt);
   9795 	    if (tmpOldErrs != ctxt->nberrors)
   9796 		goto exit;
   9797 	} else if (IS_SCHEMA(child, "redefine")) {
   9798 	    tmpOldErrs = ctxt->nberrors;
   9799 	    res = xmlSchemaParseRedefine(ctxt, schema, child);
   9800 	    HFAILURE;
   9801 	    HSTOP(ctxt);
   9802 	    if (tmpOldErrs != ctxt->nberrors)
   9803 		goto exit;
   9804 	}
   9805 	child = child->next;
   9806     }
   9807     /*
   9808     * URGENT TODO: Change the functions to return int results.
   9809     * We need especially to catch internal errors.
   9810     */
   9811     while (child != NULL) {
   9812 	if (IS_SCHEMA(child, "complexType")) {
   9813 	    xmlSchemaParseComplexType(ctxt, schema, child, 1);
   9814 	    child = child->next;
   9815 	} else if (IS_SCHEMA(child, "simpleType")) {
   9816 	    xmlSchemaParseSimpleType(ctxt, schema, child, 1);
   9817 	    child = child->next;
   9818 	} else if (IS_SCHEMA(child, "element")) {
   9819 	    xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
   9820 	    child = child->next;
   9821 	} else if (IS_SCHEMA(child, "attribute")) {
   9822 	    xmlSchemaParseGlobalAttribute(ctxt, schema, child);
   9823 	    child = child->next;
   9824 	} else if (IS_SCHEMA(child, "attributeGroup")) {
   9825 	    xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
   9826 	    child = child->next;
   9827 	} else if (IS_SCHEMA(child, "group")) {
   9828 	    xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
   9829 	    child = child->next;
   9830 	} else if (IS_SCHEMA(child, "notation")) {
   9831 	    xmlSchemaParseNotation(ctxt, schema, child);
   9832 	    child = child->next;
   9833 	} else {
   9834 	    xmlSchemaPContentErr(ctxt,
   9835 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9836 		NULL, child->parent, child,
   9837 		NULL, "((include | import | redefine | annotation)*, "
   9838 		"(((simpleType | complexType | group | attributeGroup) "
   9839 		"| element | attribute | notation), annotation*)*)");
   9840 	    child = child->next;
   9841 	}
   9842 	while (IS_SCHEMA(child, "annotation")) {
   9843 	    /*
   9844 	    * TODO: We should add all annotations.
   9845 	    */
   9846 	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9847 	    if (schema->annot == NULL)
   9848 		schema->annot = annot;
   9849 	    else
   9850 		xmlSchemaFreeAnnot(annot);
   9851 	    child = child->next;
   9852 	}
   9853     }
   9854 exit:
   9855     ctxt->ctxtType = NULL;
   9856     if (oldErrs != ctxt->nberrors)
   9857 	res = ctxt->err;
   9858     return(res);
   9859 exit_failure:
   9860     return(-1);
   9861 }
   9862 
   9863 static xmlSchemaSchemaRelationPtr
   9864 xmlSchemaSchemaRelationCreate(void)
   9865 {
   9866     xmlSchemaSchemaRelationPtr ret;
   9867 
   9868     ret = (xmlSchemaSchemaRelationPtr)
   9869 	xmlMalloc(sizeof(xmlSchemaSchemaRelation));
   9870     if (ret == NULL) {
   9871 	xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
   9872 	return(NULL);
   9873     }
   9874     memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
   9875     return(ret);
   9876 }
   9877 
   9878 #if 0
   9879 static void
   9880 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
   9881 {
   9882     xmlFree(rel);
   9883 }
   9884 #endif
   9885 
   9886 static void
   9887 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
   9888 {
   9889     xmlSchemaRedefPtr prev;
   9890 
   9891     while (redef != NULL) {
   9892 	prev = redef;
   9893 	redef = redef->next;
   9894 	xmlFree(prev);
   9895     }
   9896 }
   9897 
   9898 static void
   9899 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
   9900 {
   9901     /*
   9902     * After the construction context has been freed, there will be
   9903     * no schema graph available any more. Only the schema buckets
   9904     * will stay alive, which are put into the "schemasImports" and
   9905     * "includes" slots of the xmlSchema.
   9906     */
   9907     if (con->buckets != NULL)
   9908 	xmlSchemaItemListFree(con->buckets);
   9909     if (con->pending != NULL)
   9910 	xmlSchemaItemListFree(con->pending);
   9911     if (con->substGroups != NULL)
   9912 	xmlHashFree(con->substGroups,
   9913 	    (xmlHashDeallocator) xmlSchemaSubstGroupFree);
   9914     if (con->redefs != NULL)
   9915 	xmlSchemaRedefListFree(con->redefs);
   9916     if (con->dict != NULL)
   9917 	xmlDictFree(con->dict);
   9918     xmlFree(con);
   9919 }
   9920 
   9921 static xmlSchemaConstructionCtxtPtr
   9922 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
   9923 {
   9924     xmlSchemaConstructionCtxtPtr ret;
   9925 
   9926     ret = (xmlSchemaConstructionCtxtPtr)
   9927 	xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
   9928     if (ret == NULL) {
   9929         xmlSchemaPErrMemory(NULL,
   9930 	    "allocating schema construction context", NULL);
   9931         return (NULL);
   9932     }
   9933     memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
   9934 
   9935     ret->buckets = xmlSchemaItemListCreate();
   9936     if (ret->buckets == NULL) {
   9937 	xmlSchemaPErrMemory(NULL,
   9938 	    "allocating list of schema buckets", NULL);
   9939 	xmlFree(ret);
   9940         return (NULL);
   9941     }
   9942     ret->pending = xmlSchemaItemListCreate();
   9943     if (ret->pending == NULL) {
   9944 	xmlSchemaPErrMemory(NULL,
   9945 	    "allocating list of pending global components", NULL);
   9946 	xmlSchemaConstructionCtxtFree(ret);
   9947         return (NULL);
   9948     }
   9949     ret->dict = dict;
   9950     xmlDictReference(dict);
   9951     return(ret);
   9952 }
   9953 
   9954 static xmlSchemaParserCtxtPtr
   9955 xmlSchemaParserCtxtCreate(void)
   9956 {
   9957     xmlSchemaParserCtxtPtr ret;
   9958 
   9959     ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
   9960     if (ret == NULL) {
   9961         xmlSchemaPErrMemory(NULL, "allocating schema parser context",
   9962                             NULL);
   9963         return (NULL);
   9964     }
   9965     memset(ret, 0, sizeof(xmlSchemaParserCtxt));
   9966     ret->type = XML_SCHEMA_CTXT_PARSER;
   9967     ret->attrProhibs = xmlSchemaItemListCreate();
   9968     if (ret->attrProhibs == NULL) {
   9969 	xmlFree(ret);
   9970 	return(NULL);
   9971     }
   9972     return(ret);
   9973 }
   9974 
   9975 /**
   9976  * xmlSchemaNewParserCtxtUseDict:
   9977  * @URL:  the location of the schema
   9978  * @dict: the dictionary to be used
   9979  *
   9980  * Create an XML Schemas parse context for that file/resource expected
   9981  * to contain an XML Schemas file.
   9982  *
   9983  * Returns the parser context or NULL in case of error
   9984  */
   9985 static xmlSchemaParserCtxtPtr
   9986 xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
   9987 {
   9988     xmlSchemaParserCtxtPtr ret;
   9989 
   9990     ret = xmlSchemaParserCtxtCreate();
   9991     if (ret == NULL)
   9992         return (NULL);
   9993     ret->dict = dict;
   9994     xmlDictReference(dict);
   9995     if (URL != NULL)
   9996 	ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
   9997     return (ret);
   9998 }
   9999 
   10000 static int
   10001 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
   10002 {
   10003     if (vctxt->pctxt == NULL) {
   10004         if (vctxt->schema != NULL)
   10005 	    vctxt->pctxt =
   10006 		xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
   10007 	else
   10008 	    vctxt->pctxt = xmlSchemaNewParserCtxt("*");
   10009 	if (vctxt->pctxt == NULL) {
   10010 	    VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
   10011 		"failed to create a temp. parser context");
   10012 	    return (-1);
   10013 	}
   10014 	/* TODO: Pass user data. */
   10015 	xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
   10016 	    vctxt->warning, vctxt->errCtxt);
   10017 	xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
   10018 	    vctxt->errCtxt);
   10019     }
   10020     return (0);
   10021 }
   10022 
   10023 /**
   10024  * xmlSchemaGetSchemaBucket:
   10025  * @pctxt: the schema parser context
   10026  * @schemaLocation: the URI of the schema document
   10027  *
   10028  * Returns a schema bucket if it was already parsed.
   10029  *
   10030  * Returns a schema bucket if it was already parsed from
   10031  *         @schemaLocation, NULL otherwise.
   10032  */
   10033 static xmlSchemaBucketPtr
   10034 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
   10035 			    const xmlChar *schemaLocation)
   10036 {
   10037     xmlSchemaBucketPtr cur;
   10038     xmlSchemaItemListPtr list;
   10039 
   10040     list = pctxt->constructor->buckets;
   10041     if (list->nbItems == 0)
   10042 	return(NULL);
   10043     else {
   10044 	int i;
   10045 	for (i = 0; i < list->nbItems; i++) {
   10046 	    cur = (xmlSchemaBucketPtr) list->items[i];
   10047 	    /* Pointer comparison! */
   10048 	    if (cur->schemaLocation == schemaLocation)
   10049 		return(cur);
   10050 	}
   10051     }
   10052     return(NULL);
   10053 }
   10054 
   10055 static xmlSchemaBucketPtr
   10056 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
   10057 				     const xmlChar *schemaLocation,
   10058 				     const xmlChar *targetNamespace)
   10059 {
   10060     xmlSchemaBucketPtr cur;
   10061     xmlSchemaItemListPtr list;
   10062 
   10063     list = pctxt->constructor->buckets;
   10064     if (list->nbItems == 0)
   10065 	return(NULL);
   10066     else {
   10067 	int i;
   10068 	for (i = 0; i < list->nbItems; i++) {
   10069 	    cur = (xmlSchemaBucketPtr) list->items[i];
   10070 	    /* Pointer comparison! */
   10071 	    if ((cur->origTargetNamespace == NULL) &&
   10072 		(cur->schemaLocation == schemaLocation) &&
   10073 		(cur->targetNamespace == targetNamespace))
   10074 		return(cur);
   10075 	}
   10076     }
   10077     return(NULL);
   10078 }
   10079 
   10080 
   10081 #define IS_BAD_SCHEMA_DOC(b) \
   10082     (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
   10083 
   10084 static xmlSchemaBucketPtr
   10085 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
   10086 				 const xmlChar *targetNamespace,
   10087 				 int imported)
   10088 {
   10089     xmlSchemaBucketPtr cur;
   10090     xmlSchemaItemListPtr list;
   10091 
   10092     list = pctxt->constructor->buckets;
   10093     if (list->nbItems == 0)
   10094 	return(NULL);
   10095     else {
   10096 	int i;
   10097 	for (i = 0; i < list->nbItems; i++) {
   10098 	    cur = (xmlSchemaBucketPtr) list->items[i];
   10099 	    if ((! IS_BAD_SCHEMA_DOC(cur)) &&
   10100 		(cur->origTargetNamespace == targetNamespace) &&
   10101 		((imported && cur->imported) ||
   10102 		 ((!imported) && (!cur->imported))))
   10103 		return(cur);
   10104 	}
   10105     }
   10106     return(NULL);
   10107 }
   10108 
   10109 static int
   10110 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
   10111 		     xmlSchemaPtr schema,
   10112 		     xmlSchemaBucketPtr bucket)
   10113 {
   10114     int oldFlags;
   10115     xmlDocPtr oldDoc;
   10116     xmlNodePtr node;
   10117     int ret, oldErrs;
   10118     xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
   10119 
   10120     /*
   10121     * Save old values; reset the *main* schema.
   10122     * URGENT TODO: This is not good; move the per-document information
   10123     * to the parser. Get rid of passing the main schema to the
   10124     * parsing functions.
   10125     */
   10126     oldFlags = schema->flags;
   10127     oldDoc = schema->doc;
   10128     if (schema->flags != 0)
   10129 	xmlSchemaClearSchemaDefaults(schema);
   10130     schema->doc = bucket->doc;
   10131     pctxt->schema = schema;
   10132     /*
   10133     * Keep the current target namespace on the parser *not* on the
   10134     * main schema.
   10135     */
   10136     pctxt->targetNamespace = bucket->targetNamespace;
   10137     WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
   10138 
   10139     if ((bucket->targetNamespace != NULL) &&
   10140 	xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
   10141 	/*
   10142 	* We are parsing the schema for schemas!
   10143 	*/
   10144 	pctxt->isS4S = 1;
   10145     }
   10146     /* Mark it as parsed, even if parsing fails. */
   10147     bucket->parsed++;
   10148     /* Compile the schema doc. */
   10149     node = xmlDocGetRootElement(bucket->doc);
   10150     ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
   10151     if (ret != 0)
   10152 	goto exit;
   10153     /* An empty schema; just get out. */
   10154     if (node->children == NULL)
   10155 	goto exit;
   10156     oldErrs = pctxt->nberrors;
   10157     ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
   10158     if (ret != 0)
   10159 	goto exit;
   10160     /*
   10161     * TODO: Not nice, but I'm not 100% sure we will get always an error
   10162     * as a result of the obove functions; so better rely on pctxt->err
   10163     * as well.
   10164     */
   10165     if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
   10166 	ret = pctxt->err;
   10167 	goto exit;
   10168     }
   10169 
   10170 exit:
   10171     WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
   10172     /* Restore schema values. */
   10173     schema->doc = oldDoc;
   10174     schema->flags = oldFlags;
   10175     return(ret);
   10176 }
   10177 
   10178 static int
   10179 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
   10180 		     xmlSchemaPtr schema,
   10181 		     xmlSchemaBucketPtr bucket)
   10182 {
   10183     xmlSchemaParserCtxtPtr newpctxt;
   10184     int res = 0;
   10185 
   10186     if (bucket == NULL)
   10187 	return(0);
   10188     if (bucket->parsed) {
   10189 	PERROR_INT("xmlSchemaParseNewDoc",
   10190 	    "reparsing a schema doc");
   10191 	return(-1);
   10192     }
   10193     if (bucket->doc == NULL) {
   10194 	PERROR_INT("xmlSchemaParseNewDoc",
   10195 	    "parsing a schema doc, but there's no doc");
   10196 	return(-1);
   10197     }
   10198     if (pctxt->constructor == NULL) {
   10199 	PERROR_INT("xmlSchemaParseNewDoc",
   10200 	    "no constructor");
   10201 	return(-1);
   10202     }
   10203     /* Create and init the temporary parser context. */
   10204     newpctxt = xmlSchemaNewParserCtxtUseDict(
   10205 	(const char *) bucket->schemaLocation, pctxt->dict);
   10206     if (newpctxt == NULL)
   10207 	return(-1);
   10208     newpctxt->constructor = pctxt->constructor;
   10209     /*
   10210     * TODO: Can we avoid that the parser knows about the main schema?
   10211     * It would be better if he knows about the current schema bucket
   10212     * only.
   10213     */
   10214     newpctxt->schema = schema;
   10215     xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
   10216 	pctxt->errCtxt);
   10217     xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
   10218 	pctxt->errCtxt);
   10219     newpctxt->counter = pctxt->counter;
   10220 
   10221 
   10222     res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
   10223 
   10224     /* Channel back errors and cleanup the temporary parser context. */
   10225     if (res != 0)
   10226 	pctxt->err = res;
   10227     pctxt->nberrors += newpctxt->nberrors;
   10228     pctxt->counter = newpctxt->counter;
   10229     newpctxt->constructor = NULL;
   10230     /* Free the parser context. */
   10231     xmlSchemaFreeParserCtxt(newpctxt);
   10232     return(res);
   10233 }
   10234 
   10235 static void
   10236 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
   10237 				xmlSchemaSchemaRelationPtr rel)
   10238 {
   10239     xmlSchemaSchemaRelationPtr cur = bucket->relations;
   10240 
   10241     if (cur == NULL) {
   10242 	bucket->relations = rel;
   10243 	return;
   10244     }
   10245     while (cur->next != NULL)
   10246 	cur = cur->next;
   10247     cur->next = rel;
   10248 }
   10249 
   10250 
   10251 static const xmlChar *
   10252 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
   10253 			  xmlNodePtr ctxtNode)
   10254 {
   10255     /*
   10256     * Build an absolue location URI.
   10257     */
   10258     if (location != NULL) {
   10259 	if (ctxtNode == NULL)
   10260 	    return(location);
   10261 	else {
   10262 	    xmlChar *base, *URI;
   10263 	    const xmlChar *ret = NULL;
   10264 
   10265 	    base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
   10266 	    if (base == NULL) {
   10267 		URI = xmlBuildURI(location, ctxtNode->doc->URL);
   10268 	    } else {
   10269 		URI = xmlBuildURI(location, base);
   10270 		xmlFree(base);
   10271 	    }
   10272 	    if (URI != NULL) {
   10273 		ret = xmlDictLookup(dict, URI, -1);
   10274 		xmlFree(URI);
   10275 		return(ret);
   10276 	    }
   10277 	}
   10278     }
   10279     return(NULL);
   10280 }
   10281 
   10282 
   10283 
   10284 /**
   10285  * xmlSchemaAddSchemaDoc:
   10286  * @pctxt:  a schema validation context
   10287  * @schema:  the schema being built
   10288  * @node:  a subtree containing XML Schema informations
   10289  *
   10290  * Parse an included (and to-be-redefined) XML schema document.
   10291  *
   10292  * Returns 0 on success, a positive error code on errors and
   10293  *         -1 in case of an internal or API error.
   10294  */
   10295 
   10296 static int
   10297 xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
   10298 		int type, /* import or include or redefine */
   10299 		const xmlChar *schemaLocation,
   10300 		xmlDocPtr schemaDoc,
   10301 		const char *schemaBuffer,
   10302 		int schemaBufferLen,
   10303 		xmlNodePtr invokingNode,
   10304 		const xmlChar *sourceTargetNamespace,
   10305 		const xmlChar *importNamespace,
   10306 		xmlSchemaBucketPtr *bucket)
   10307 {
   10308     const xmlChar *targetNamespace = NULL;
   10309     xmlSchemaSchemaRelationPtr relation = NULL;
   10310     xmlDocPtr doc = NULL;
   10311     int res = 0, err = 0, located = 0, preserveDoc = 0;
   10312     xmlSchemaBucketPtr bkt = NULL;
   10313 
   10314     if (bucket != NULL)
   10315 	*bucket = NULL;
   10316 
   10317     switch (type) {
   10318 	case XML_SCHEMA_SCHEMA_IMPORT:
   10319 	case XML_SCHEMA_SCHEMA_MAIN:
   10320 	    err = XML_SCHEMAP_SRC_IMPORT;
   10321 	    break;
   10322 	case XML_SCHEMA_SCHEMA_INCLUDE:
   10323 	    err = XML_SCHEMAP_SRC_INCLUDE;
   10324 	    break;
   10325 	case XML_SCHEMA_SCHEMA_REDEFINE:
   10326 	    err = XML_SCHEMAP_SRC_REDEFINE;
   10327 	    break;
   10328     }
   10329 
   10330 
   10331     /* Special handling for the main schema:
   10332     * skip the location and relation logic and just parse the doc.
   10333     * We need just a bucket to be returned in this case.
   10334     */
   10335     if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
   10336 	goto doc_load;
   10337 
   10338     /* Note that we expect the location to be an absulute URI. */
   10339     if (schemaLocation != NULL) {
   10340 	bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
   10341 	if ((bkt != NULL) &&
   10342 	    (pctxt->constructor->bucket == bkt)) {
   10343 	    /* Report self-imports/inclusions/redefinitions. */
   10344 
   10345 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
   10346 		invokingNode, NULL,
   10347 		"The schema must not import/include/redefine itself",
   10348 		NULL, NULL);
   10349 	    goto exit;
   10350 	}
   10351     }
   10352     /*
   10353     * Create a relation for the graph of schemas.
   10354     */
   10355     relation = xmlSchemaSchemaRelationCreate();
   10356     if (relation == NULL)
   10357 	return(-1);
   10358     xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
   10359 	relation);
   10360     relation->type = type;
   10361 
   10362     /*
   10363     * Save the namespace import information.
   10364     */
   10365     if (WXS_IS_BUCKET_IMPMAIN(type)) {
   10366 	relation->importNamespace = importNamespace;
   10367 	if (schemaLocation == NULL) {
   10368 	    /*
   10369 	    * No location; this is just an import of the namespace.
   10370 	    * Note that we don't assign a bucket to the relation
   10371 	    * in this case.
   10372 	    */
   10373 	    goto exit;
   10374 	}
   10375 	targetNamespace = importNamespace;
   10376     }
   10377 
   10378     /* Did we already fetch the doc? */
   10379     if (bkt != NULL) {
   10380 	if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
   10381 	    /*
   10382 	    * We included/redefined and then try to import a schema,
   10383 	    * but the new location provided for import was different.
   10384 	    */
   10385 	    if (schemaLocation == NULL)
   10386 		schemaLocation = BAD_CAST "in_memory_buffer";
   10387 	    if (!xmlStrEqual(schemaLocation,
   10388 		bkt->schemaLocation)) {
   10389 		xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
   10390 		    invokingNode, NULL,
   10391 		    "The schema document '%s' cannot be imported, since "
   10392 		    "it was already included or redefined",
   10393 		    schemaLocation, NULL);
   10394 		goto exit;
   10395 	    }
   10396 	} else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
   10397 	    /*
   10398 	    * We imported and then try to include/redefine a schema,
   10399 	    * but the new location provided for the include/redefine
   10400 	    * was different.
   10401 	    */
   10402 	    if (schemaLocation == NULL)
   10403 		schemaLocation = BAD_CAST "in_memory_buffer";
   10404 	    if (!xmlStrEqual(schemaLocation,
   10405 		bkt->schemaLocation)) {
   10406 		xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
   10407 		    invokingNode, NULL,
   10408 		    "The schema document '%s' cannot be included or "
   10409 		    "redefined, since it was already imported",
   10410 		    schemaLocation, NULL);
   10411 		goto exit;
   10412 	    }
   10413 	}
   10414     }
   10415 
   10416     if (WXS_IS_BUCKET_IMPMAIN(type)) {
   10417 	/*
   10418 	* Given that the schemaLocation [attribute] is only a hint, it is open
   10419 	* to applications to ignore all but the first <import> for a given
   10420 	* namespace, regardless of the `actual value` of schemaLocation, but
   10421 	* such a strategy risks missing useful information when new
   10422 	* schemaLocations are offered.
   10423 	*
   10424 	* We will use the first <import> that comes with a location.
   10425 	* Further <import>s *with* a location, will result in an error.
   10426 	* TODO: Better would be to just report a warning here, but
   10427 	* we'll try it this way until someone complains.
   10428 	*
   10429 	* Schema Document Location Strategy:
   10430 	* 3 Based on the namespace name, identify an existing schema document,
   10431 	* either as a resource which is an XML document or a <schema> element
   10432 	* information item, in some local schema repository;
   10433 	* 5 Attempt to resolve the namespace name to locate such a resource.
   10434 	*
   10435 	* NOTE: (3) and (5) are not supported.
   10436 	*/
   10437 	if (bkt != NULL) {
   10438 	    relation->bucket = bkt;
   10439 	    goto exit;
   10440 	}
   10441 	bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
   10442 	    importNamespace, 1);
   10443 
   10444 	if (bkt != NULL) {
   10445 	    relation->bucket = bkt;
   10446 	    if (bkt->schemaLocation == NULL) {
   10447 		/* First given location of the schema; load the doc. */
   10448 		bkt->schemaLocation = schemaLocation;
   10449 	    } else {
   10450 		if (!xmlStrEqual(schemaLocation,
   10451 		    bkt->schemaLocation)) {
   10452 		    /*
   10453 		    * Additional location given; just skip it.
   10454 		    * URGENT TODO: We should report a warning here.
   10455 		    * res = XML_SCHEMAP_SRC_IMPORT;
   10456 		    */
   10457 		    if (schemaLocation == NULL)
   10458 			schemaLocation = BAD_CAST "in_memory_buffer";
   10459 
   10460 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   10461 			XML_SCHEMAP_WARN_SKIP_SCHEMA,
   10462 			invokingNode, NULL,
   10463 			"Skipping import of schema located at '%s' for the "
   10464 			"namespace '%s', since this namespace was already "
   10465 			"imported with the schema located at '%s'",
   10466 			schemaLocation, importNamespace, bkt->schemaLocation);
   10467 		}
   10468 		goto exit;
   10469 	    }
   10470 	}
   10471 	/*
   10472 	* No bucket + first location: load the doc and create a
   10473 	* bucket.
   10474 	*/
   10475     } else {
   10476 	/* <include> and <redefine> */
   10477 	if (bkt != NULL) {
   10478 
   10479 	    if ((bkt->origTargetNamespace == NULL) &&
   10480 		(bkt->targetNamespace != sourceTargetNamespace)) {
   10481 		xmlSchemaBucketPtr chamel;
   10482 
   10483 		/*
   10484 		* Chameleon include/redefine: skip loading only if it was
   10485 		* aleady build for the targetNamespace of the including
   10486 		* schema.
   10487 		*/
   10488 		/*
   10489 		* URGENT TODO: If the schema is a chameleon-include then copy
   10490 		* the components into the including schema and modify the
   10491 		* targetNamespace of those components, do nothing otherwise.
   10492 		* NOTE: This is currently worked-around by compiling the
   10493 		* chameleon for every destinct including targetNamespace; thus
   10494 		* not performant at the moment.
   10495 		* TODO: Check when the namespace in wildcards for chameleons
   10496 		* needs to be converted: before we built wildcard intersections
   10497 		* or after.
   10498 		*   Answer: after!
   10499 		*/
   10500 		chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
   10501 		    schemaLocation, sourceTargetNamespace);
   10502 		if (chamel != NULL) {
   10503 		    /* A fitting chameleon was already parsed; NOP. */
   10504 		    relation->bucket = chamel;
   10505 		    goto exit;
   10506 		}
   10507 		/*
   10508 		* We need to parse the chameleon again for a different
   10509 		* targetNamespace.
   10510 		* CHAMELEON TODO: Optimize this by only parsing the
   10511 		* chameleon once, and then copying the components to
   10512 		* the new targetNamespace.
   10513 		*/
   10514 		bkt = NULL;
   10515 	    } else {
   10516 		relation->bucket = bkt;
   10517 		goto exit;
   10518 	    }
   10519 	}
   10520     }
   10521     if ((bkt != NULL) && (bkt->doc != NULL)) {
   10522 	PERROR_INT("xmlSchemaAddSchemaDoc",
   10523 	    "trying to load a schema doc, but a doc is already "
   10524 	    "assigned to the schema bucket");
   10525 	goto exit_failure;
   10526     }
   10527 
   10528 doc_load:
   10529     /*
   10530     * Load the document.
   10531     */
   10532     if (schemaDoc != NULL) {
   10533 	doc = schemaDoc;
   10534 	/* Don' free this one, since it was provided by the caller. */
   10535 	preserveDoc = 1;
   10536 	/* TODO: Does the context or the doc hold the location? */
   10537 	if (schemaDoc->URL != NULL)
   10538 	    schemaLocation = xmlDictLookup(pctxt->dict,
   10539 		schemaDoc->URL, -1);
   10540         else
   10541 	    schemaLocation = BAD_CAST "in_memory_buffer";
   10542     } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
   10543 	xmlParserCtxtPtr parserCtxt;
   10544 
   10545 	parserCtxt = xmlNewParserCtxt();
   10546 	if (parserCtxt == NULL) {
   10547 	    xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
   10548 		"allocating a parser context", NULL);
   10549 	    goto exit_failure;
   10550 	}
   10551 	if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
   10552 	    /*
   10553 	    * TODO: Do we have to burden the schema parser dict with all
   10554 	    * the content of the schema doc?
   10555 	    */
   10556 	    xmlDictFree(parserCtxt->dict);
   10557 	    parserCtxt->dict = pctxt->dict;
   10558 	    xmlDictReference(parserCtxt->dict);
   10559 	}
   10560 	if (schemaLocation != NULL) {
   10561 	    /* Parse from file. */
   10562 	    doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
   10563 		NULL, SCHEMAS_PARSE_OPTIONS);
   10564 	} else if (schemaBuffer != NULL) {
   10565 	    /* Parse from memory buffer. */
   10566 	    doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
   10567 		NULL, NULL, SCHEMAS_PARSE_OPTIONS);
   10568 	    schemaLocation = BAD_CAST "in_memory_buffer";
   10569 	    if (doc != NULL)
   10570 		doc->URL = xmlStrdup(schemaLocation);
   10571 	}
   10572 	/*
   10573 	* For <import>:
   10574 	* 2.1 The referent is (a fragment of) a resource which is an
   10575 	* XML document (see clause 1.1), which in turn corresponds to
   10576 	* a <schema> element information item in a well-formed information
   10577 	* set, which in turn corresponds to a valid schema.
   10578 	* TODO: (2.1) fragments of XML documents are not supported.
   10579 	*
   10580 	* 2.2 The referent is a <schema> element information item in
   10581 	* a well-formed information set, which in turn corresponds
   10582 	* to a valid schema.
   10583 	* TODO: (2.2) is not supported.
   10584 	*/
   10585 	if (doc == NULL) {
   10586 	    xmlErrorPtr lerr;
   10587 	    lerr = xmlGetLastError();
   10588 	    /*
   10589 	    * Check if this a parser error, or if the document could
   10590 	    * just not be located.
   10591 	    * TODO: Try to find specific error codes to react only on
   10592 	    * localisation failures.
   10593 	    */
   10594 	    if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
   10595 		/*
   10596 		* We assume a parser error here.
   10597 		*/
   10598 		located = 1;
   10599 		/* TODO: Error code ?? */
   10600 		res = XML_SCHEMAP_SRC_IMPORT_2_1;
   10601 		xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
   10602 		    invokingNode, NULL,
   10603 		    "Failed to parse the XML resource '%s'",
   10604 		    schemaLocation, NULL);
   10605 	    }
   10606 	}
   10607 	xmlFreeParserCtxt(parserCtxt);
   10608 	if ((doc == NULL) && located)
   10609 	    goto exit_error;
   10610     } else {
   10611 	xmlSchemaPErr(pctxt, NULL,
   10612 	    XML_SCHEMAP_NOTHING_TO_PARSE,
   10613 	    "No information for parsing was provided with the "
   10614 	    "given schema parser context.\n",
   10615 	    NULL, NULL);
   10616 	goto exit_failure;
   10617     }
   10618     /*
   10619     * Preprocess the document.
   10620     */
   10621     if (doc != NULL) {
   10622 	xmlNodePtr docElem = NULL;
   10623 
   10624 	located = 1;
   10625 	docElem = xmlDocGetRootElement(doc);
   10626 	if (docElem == NULL) {
   10627 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
   10628 		invokingNode, NULL,
   10629 		"The document '%s' has no document element",
   10630 		schemaLocation, NULL);
   10631 	    goto exit_error;
   10632 	}
   10633 	/*
   10634 	* Remove all the blank text nodes.
   10635 	*/
   10636 	xmlSchemaCleanupDoc(pctxt, docElem);
   10637 	/*
   10638 	* Check the schema's top level element.
   10639 	*/
   10640 	if (!IS_SCHEMA(docElem, "schema")) {
   10641 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
   10642 		invokingNode, NULL,
   10643 		"The XML document '%s' is not a schema document",
   10644 		schemaLocation, NULL);
   10645 	    goto exit_error;
   10646 	}
   10647 	/*
   10648 	* Note that we don't apply a type check for the
   10649 	* targetNamespace value here.
   10650 	*/
   10651 	targetNamespace = xmlSchemaGetProp(pctxt, docElem,
   10652 	    "targetNamespace");
   10653     }
   10654 
   10655 /* after_doc_loading: */
   10656     if ((bkt == NULL) && located) {
   10657 	/* Only create a bucket if the schema was located. */
   10658         bkt = xmlSchemaBucketCreate(pctxt, type,
   10659 	    targetNamespace);
   10660 	if (bkt == NULL)
   10661 	    goto exit_failure;
   10662     }
   10663     if (bkt != NULL) {
   10664 	bkt->schemaLocation = schemaLocation;
   10665 	bkt->located = located;
   10666 	if (doc != NULL) {
   10667 	    bkt->doc = doc;
   10668 	    bkt->targetNamespace = targetNamespace;
   10669 	    bkt->origTargetNamespace = targetNamespace;
   10670 	    if (preserveDoc)
   10671 		bkt->preserveDoc = 1;
   10672 	}
   10673 	if (WXS_IS_BUCKET_IMPMAIN(type))
   10674 	    bkt->imported++;
   10675 	    /*
   10676 	    * Add it to the graph of schemas.
   10677 	    */
   10678 	if (relation != NULL)
   10679 	    relation->bucket = bkt;
   10680     }
   10681 
   10682 exit:
   10683     /*
   10684     * Return the bucket explicitely; this is needed for the
   10685     * main schema.
   10686     */
   10687     if (bucket != NULL)
   10688 	*bucket = bkt;
   10689     return (0);
   10690 
   10691 exit_error:
   10692     if ((doc != NULL) && (! preserveDoc)) {
   10693 	xmlFreeDoc(doc);
   10694 	if (bkt != NULL)
   10695 	    bkt->doc = NULL;
   10696     }
   10697     return(pctxt->err);
   10698 
   10699 exit_failure:
   10700     if ((doc != NULL) && (! preserveDoc)) {
   10701 	xmlFreeDoc(doc);
   10702 	if (bkt != NULL)
   10703 	    bkt->doc = NULL;
   10704     }
   10705     return (-1);
   10706 }
   10707 
   10708 /**
   10709  * xmlSchemaParseImport:
   10710  * @ctxt:  a schema validation context
   10711  * @schema:  the schema being built
   10712  * @node:  a subtree containing XML Schema informations
   10713  *
   10714  * parse a XML schema Import definition
   10715  * *WARNING* this interface is highly subject to change
   10716  *
   10717  * Returns 0 in case of success, a positive error code if
   10718  * not valid and -1 in case of an internal error.
   10719  */
   10720 static int
   10721 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
   10722                      xmlNodePtr node)
   10723 {
   10724     xmlNodePtr child;
   10725     const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
   10726     const xmlChar *thisTargetNamespace;
   10727     xmlAttrPtr attr;
   10728     int ret = 0;
   10729     xmlSchemaBucketPtr bucket = NULL;
   10730 
   10731     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   10732         return (-1);
   10733 
   10734     /*
   10735     * Check for illegal attributes.
   10736     */
   10737     attr = node->properties;
   10738     while (attr != NULL) {
   10739 	if (attr->ns == NULL) {
   10740 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   10741 		(!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
   10742 		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
   10743 		xmlSchemaPIllegalAttrErr(pctxt,
   10744 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10745 	    }
   10746 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   10747 	    xmlSchemaPIllegalAttrErr(pctxt,
   10748 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10749 	}
   10750 	attr = attr->next;
   10751     }
   10752     /*
   10753     * Extract and validate attributes.
   10754     */
   10755     if (xmlSchemaPValAttr(pctxt, NULL, node,
   10756 	"namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10757 	&namespaceName) != 0) {
   10758 	xmlSchemaPSimpleTypeErr(pctxt,
   10759 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   10760 	    NULL, node,
   10761 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10762 	    NULL, namespaceName, NULL, NULL, NULL);
   10763 	return (pctxt->err);
   10764     }
   10765 
   10766     if (xmlSchemaPValAttr(pctxt, NULL, node,
   10767 	"schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10768 	&schemaLocation) != 0) {
   10769 	xmlSchemaPSimpleTypeErr(pctxt,
   10770 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   10771 	    NULL, node,
   10772 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10773 	    NULL, schemaLocation, NULL, NULL, NULL);
   10774 	return (pctxt->err);
   10775     }
   10776     /*
   10777     * And now for the children...
   10778     */
   10779     child = node->children;
   10780     if (IS_SCHEMA(child, "annotation")) {
   10781         /*
   10782          * the annotation here is simply discarded ...
   10783 	 * TODO: really?
   10784          */
   10785         child = child->next;
   10786     }
   10787     if (child != NULL) {
   10788 	xmlSchemaPContentErr(pctxt,
   10789 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   10790 	    NULL, node, child, NULL,
   10791 	    "(annotation?)");
   10792     }
   10793     /*
   10794     * Apply additional constraints.
   10795     *
   10796     * Note that it is important to use the original @targetNamespace
   10797     * (or none at all), to rule out imports of schemas _with_ a
   10798     * @targetNamespace if the importing schema is a chameleon schema
   10799     * (with no @targetNamespace).
   10800     */
   10801     thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
   10802     if (namespaceName != NULL) {
   10803 	/*
   10804 	* 1.1 If the namespace [attribute] is present, then its `actual value`
   10805 	* must not match the `actual value` of the enclosing <schema>'s
   10806 	* targetNamespace [attribute].
   10807 	*/
   10808 	if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
   10809 	    xmlSchemaPCustomErr(pctxt,
   10810 		XML_SCHEMAP_SRC_IMPORT_1_1,
   10811 		NULL, node,
   10812 		"The value of the attribute 'namespace' must not match "
   10813 		"the target namespace '%s' of the importing schema",
   10814 		thisTargetNamespace);
   10815 	    return (pctxt->err);
   10816 	}
   10817     } else {
   10818 	/*
   10819 	* 1.2 If the namespace [attribute] is not present, then the enclosing
   10820 	* <schema> must have a targetNamespace [attribute].
   10821 	*/
   10822 	if (thisTargetNamespace == NULL) {
   10823 	    xmlSchemaPCustomErr(pctxt,
   10824 		XML_SCHEMAP_SRC_IMPORT_1_2,
   10825 		NULL, node,
   10826 		"The attribute 'namespace' must be existent if "
   10827 		"the importing schema has no target namespace",
   10828 		NULL);
   10829 	    return (pctxt->err);
   10830 	}
   10831     }
   10832     /*
   10833     * Locate and acquire the schema document.
   10834     */
   10835     if (schemaLocation != NULL)
   10836 	schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
   10837 	    schemaLocation, node);
   10838     ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
   10839 	schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
   10840 	namespaceName, &bucket);
   10841 
   10842     if (ret != 0)
   10843 	return(ret);
   10844 
   10845     /*
   10846     * For <import>: "It is *not* an error for the application
   10847     * schema reference strategy to fail."
   10848     * So just don't parse if no schema document was found.
   10849     * Note that we will get no bucket if the schema could not be
   10850     * located or if there was no schemaLocation.
   10851     */
   10852     if ((bucket == NULL) && (schemaLocation != NULL)) {
   10853 	xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   10854 	    XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
   10855 	    node, NULL,
   10856 	    "Failed to locate a schema at location '%s'. "
   10857 	    "Skipping the import", schemaLocation, NULL, NULL);
   10858     }
   10859 
   10860     if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
   10861 	ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
   10862     }
   10863 
   10864     return (ret);
   10865 }
   10866 
   10867 static int
   10868 xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
   10869 				     xmlSchemaPtr schema,
   10870 				     xmlNodePtr node,
   10871 				     xmlChar **schemaLocation,
   10872 				     int type)
   10873 {
   10874     xmlAttrPtr attr;
   10875 
   10876     if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
   10877 	(schemaLocation == NULL))
   10878         return (-1);
   10879 
   10880     *schemaLocation = NULL;
   10881     /*
   10882     * Check for illegal attributes.
   10883     * Applies for both <include> and <redefine>.
   10884     */
   10885     attr = node->properties;
   10886     while (attr != NULL) {
   10887 	if (attr->ns == NULL) {
   10888 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   10889 		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
   10890 		xmlSchemaPIllegalAttrErr(pctxt,
   10891 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10892 	    }
   10893 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   10894 	    xmlSchemaPIllegalAttrErr(pctxt,
   10895 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10896 	}
   10897 	attr = attr->next;
   10898     }
   10899     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   10900     /*
   10901     * Preliminary step, extract the URI-Reference and make an URI
   10902     * from the base.
   10903     */
   10904     /*
   10905     * Attribute "schemaLocation" is mandatory.
   10906     */
   10907     attr = xmlSchemaGetPropNode(node, "schemaLocation");
   10908     if (attr != NULL) {
   10909         xmlChar *base = NULL;
   10910         xmlChar *uri = NULL;
   10911 
   10912 	if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
   10913 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10914 	    (const xmlChar **) schemaLocation) != 0)
   10915 	    goto exit_error;
   10916 	base = xmlNodeGetBase(node->doc, node);
   10917 	if (base == NULL) {
   10918 	    uri = xmlBuildURI(*schemaLocation, node->doc->URL);
   10919 	} else {
   10920 	    uri = xmlBuildURI(*schemaLocation, base);
   10921 	    xmlFree(base);
   10922 	}
   10923 	if (uri == NULL) {
   10924 	    PERROR_INT("xmlSchemaParseIncludeOrRedefine",
   10925 		"could not build an URI from the schemaLocation")
   10926 	    goto exit_failure;
   10927 	}
   10928 	(*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
   10929 	xmlFree(uri);
   10930     } else {
   10931 	xmlSchemaPMissingAttrErr(pctxt,
   10932 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   10933 	    NULL, node, "schemaLocation", NULL);
   10934 	goto exit_error;
   10935     }
   10936     /*
   10937     * Report self-inclusion and self-redefinition.
   10938     */
   10939     if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
   10940 	if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
   10941 	    xmlSchemaPCustomErr(pctxt,
   10942 		XML_SCHEMAP_SRC_REDEFINE,
   10943 		NULL, node,
   10944 		"The schema document '%s' cannot redefine itself.",
   10945 		*schemaLocation);
   10946 	} else {
   10947 	    xmlSchemaPCustomErr(pctxt,
   10948 		XML_SCHEMAP_SRC_INCLUDE,
   10949 		NULL, node,
   10950 		"The schema document '%s' cannot include itself.",
   10951 		*schemaLocation);
   10952 	}
   10953 	goto exit_error;
   10954     }
   10955 
   10956     return(0);
   10957 exit_error:
   10958     return(pctxt->err);
   10959 exit_failure:
   10960     return(-1);
   10961 }
   10962 
   10963 static int
   10964 xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
   10965 				xmlSchemaPtr schema,
   10966 				xmlNodePtr node,
   10967 				int type)
   10968 {
   10969     xmlNodePtr child = NULL;
   10970     const xmlChar *schemaLocation = NULL;
   10971     int res = 0; /* hasRedefinitions = 0 */
   10972     int isChameleon = 0, wasChameleon = 0;
   10973     xmlSchemaBucketPtr bucket = NULL;
   10974 
   10975     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   10976         return (-1);
   10977 
   10978     /*
   10979     * Parse attributes. Note that the returned schemaLocation will
   10980     * be already converted to an absolute URI.
   10981     */
   10982     res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
   10983 	node, (xmlChar **) (&schemaLocation), type);
   10984     if (res != 0)
   10985 	return(res);
   10986     /*
   10987     * Load and add the schema document.
   10988     */
   10989     res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
   10990 	NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
   10991     if (res != 0)
   10992 	return(res);
   10993     /*
   10994     * If we get no schema bucket back, then this means that the schema
   10995     * document could not be located or was broken XML or was not
   10996     * a schema document.
   10997     */
   10998     if ((bucket == NULL) || (bucket->doc == NULL)) {
   10999 	if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
   11000 	    /*
   11001 	    * WARNING for <include>:
   11002 	    * We will raise an error if the schema cannot be located
   11003 	    * for inclusions, since the that was the feedback from the
   11004 	    * schema people. I.e. the following spec piece will *not* be
   11005 	    * satisfied:
   11006 	    * SPEC src-include: "It is not an error for the `actual value` of the
   11007 	    * schemaLocation [attribute] to fail to resolve it all, in which
   11008 	    * case no corresponding inclusion is performed.
   11009 	    * So do we need a warning report here?"
   11010 	    */
   11011 	    res = XML_SCHEMAP_SRC_INCLUDE;
   11012 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
   11013 		node, NULL,
   11014 		"Failed to load the document '%s' for inclusion",
   11015 		schemaLocation, NULL);
   11016 	} else {
   11017 	    /*
   11018 	    * NOTE: This was changed to raise an error even if no redefinitions
   11019 	    * are specified.
   11020 	    *
   11021 	    * SPEC src-redefine (1)
   11022 	    * "If there are any element information items among the [children]
   11023 	    * other than <annotation> then the `actual value` of the
   11024 	    * schemaLocation [attribute] must successfully resolve."
   11025 	    * TODO: Ask the WG if a the location has always to resolve
   11026 	    * here as well!
   11027 	    */
   11028 	    res = XML_SCHEMAP_SRC_REDEFINE;
   11029 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
   11030 		node, NULL,
   11031 		"Failed to load the document '%s' for redefinition",
   11032 		schemaLocation, NULL);
   11033 	}
   11034     } else {
   11035 	/*
   11036 	* Check targetNamespace sanity before parsing the new schema.
   11037 	* TODO: Note that we won't check further content if the
   11038 	* targetNamespace was bad.
   11039 	*/
   11040 	if (bucket->origTargetNamespace != NULL) {
   11041 	    /*
   11042 	    * SPEC src-include (2.1)
   11043 	    * "SII has a targetNamespace [attribute], and its `actual
   11044 	    * value` is identical to the `actual value` of the targetNamespace
   11045 	    * [attribute] of SII' (which must have such an [attribute])."
   11046 	    */
   11047 	    if (pctxt->targetNamespace == NULL) {
   11048 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   11049 		    XML_SCHEMAP_SRC_INCLUDE,
   11050 		    node, NULL,
   11051 		    "The target namespace of the included/redefined schema "
   11052 		    "'%s' has to be absent, since the including/redefining "
   11053 		    "schema has no target namespace",
   11054 		    schemaLocation, NULL);
   11055 		goto exit_error;
   11056 	    } else if (!xmlStrEqual(bucket->origTargetNamespace,
   11057 		pctxt->targetNamespace)) {
   11058 		/* TODO: Change error function. */
   11059 		xmlSchemaPCustomErrExt(pctxt,
   11060 		    XML_SCHEMAP_SRC_INCLUDE,
   11061 		    NULL, node,
   11062 		    "The target namespace '%s' of the included/redefined "
   11063 		    "schema '%s' differs from '%s' of the "
   11064 		    "including/redefining schema",
   11065 		    bucket->origTargetNamespace, schemaLocation,
   11066 		    pctxt->targetNamespace);
   11067 		goto exit_error;
   11068 	    }
   11069 	} else if (pctxt->targetNamespace != NULL) {
   11070 	    /*
   11071 	    * Chameleons: the original target namespace will
   11072 	    * differ from the resulting namespace.
   11073 	    */
   11074 	    isChameleon = 1;
   11075 	    if (bucket->parsed &&
   11076 		bucket->origTargetNamespace != NULL) {
   11077 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   11078 		    XML_SCHEMAP_SRC_INCLUDE,
   11079 		    node, NULL,
   11080 		    "The target namespace of the included/redefined schema "
   11081 		    "'%s' has to be absent or the same as the "
   11082 		    "including/redefining schema's target namespace",
   11083 		    schemaLocation, NULL);
   11084 		goto exit_error;
   11085 	    }
   11086 	    bucket->targetNamespace = pctxt->targetNamespace;
   11087 	}
   11088     }
   11089     /*
   11090     * Parse the schema.
   11091     */
   11092     if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
   11093 	if (isChameleon) {
   11094 	    /* TODO: Get rid of this flag on the schema itself. */
   11095 	    if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
   11096 		schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
   11097 	    } else
   11098 		wasChameleon = 1;
   11099 	}
   11100 	xmlSchemaParseNewDoc(pctxt, schema, bucket);
   11101 	/* Restore chameleon flag. */
   11102 	if (isChameleon && (!wasChameleon))
   11103 	    schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
   11104     }
   11105     /*
   11106     * And now for the children...
   11107     */
   11108     child = node->children;
   11109     if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
   11110 	/*
   11111 	* Parse (simpleType | complexType | group | attributeGroup))*
   11112 	*/
   11113 	pctxt->redefined = bucket;
   11114 	/*
   11115 	* How to proceed if the redefined schema was not located?
   11116 	*/
   11117 	pctxt->isRedefine = 1;
   11118 	while (IS_SCHEMA(child, "annotation") ||
   11119 	    IS_SCHEMA(child, "simpleType") ||
   11120 	    IS_SCHEMA(child, "complexType") ||
   11121 	    IS_SCHEMA(child, "group") ||
   11122 	    IS_SCHEMA(child, "attributeGroup")) {
   11123 	    if (IS_SCHEMA(child, "annotation")) {
   11124 		/*
   11125 		* TODO: discard or not?
   11126 		*/
   11127 	    } else if (IS_SCHEMA(child, "simpleType")) {
   11128 		xmlSchemaParseSimpleType(pctxt, schema, child, 1);
   11129 	    } else if (IS_SCHEMA(child, "complexType")) {
   11130 		xmlSchemaParseComplexType(pctxt, schema, child, 1);
   11131 		/* hasRedefinitions = 1; */
   11132 	    } else if (IS_SCHEMA(child, "group")) {
   11133 		/* hasRedefinitions = 1; */
   11134 		xmlSchemaParseModelGroupDefinition(pctxt,
   11135 		    schema, child);
   11136 	    } else if (IS_SCHEMA(child, "attributeGroup")) {
   11137 		/* hasRedefinitions = 1; */
   11138 		xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
   11139 		    child);
   11140 	    }
   11141 	    child = child->next;
   11142 	}
   11143 	pctxt->redefined = NULL;
   11144 	pctxt->isRedefine = 0;
   11145     } else {
   11146 	if (IS_SCHEMA(child, "annotation")) {
   11147 	    /*
   11148 	    * TODO: discard or not?
   11149 	    */
   11150 	    child = child->next;
   11151 	}
   11152     }
   11153     if (child != NULL) {
   11154 	res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
   11155 	if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
   11156 	    xmlSchemaPContentErr(pctxt, res,
   11157 		NULL, node, child, NULL,
   11158 		"(annotation | (simpleType | complexType | group | attributeGroup))*");
   11159 	} else {
   11160 	     xmlSchemaPContentErr(pctxt, res,
   11161 		NULL, node, child, NULL,
   11162 		"(annotation?)");
   11163 	}
   11164     }
   11165     return(res);
   11166 
   11167 exit_error:
   11168     return(pctxt->err);
   11169 }
   11170 
   11171 static int
   11172 xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
   11173                        xmlNodePtr node)
   11174 {
   11175     int res;
   11176 #ifndef ENABLE_REDEFINE
   11177     TODO
   11178     return(0);
   11179 #endif
   11180     res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
   11181 	XML_SCHEMA_SCHEMA_REDEFINE);
   11182     if (res != 0)
   11183 	return(res);
   11184     return(0);
   11185 }
   11186 
   11187 static int
   11188 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
   11189                        xmlNodePtr node)
   11190 {
   11191     int res;
   11192 
   11193     res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
   11194 	XML_SCHEMA_SCHEMA_INCLUDE);
   11195     if (res != 0)
   11196 	return(res);
   11197     return(0);
   11198 }
   11199 
   11200 /**
   11201  * xmlSchemaParseModelGroup:
   11202  * @ctxt:  a schema validation context
   11203  * @schema:  the schema being built
   11204  * @node:  a subtree containing XML Schema informations
   11205  * @type: the "compositor" type
   11206  * @particleNeeded: if a a model group with a particle
   11207  *
   11208  * parse a XML schema Sequence definition.
   11209  * Applies parts of:
   11210  *   Schema Representation Constraint:
   11211  *     Redefinition Constraints and Semantics (src-redefine)
   11212  *     (6.1), (6.1.1), (6.1.2)
   11213  *
   11214  *   Schema Component Constraint:
   11215  *     All Group Limited (cos-all-limited) (2)
   11216  *     TODO: Actually this should go to component-level checks,
   11217  *     but is done here due to performance. Move it to an other layer
   11218  *     is schema construction via an API is implemented.
   11219  *
   11220  * *WARNING* this interface is highly subject to change
   11221  *
   11222  * Returns -1 in case of error, 0 if the declaration is improper and
   11223  *         1 in case of success.
   11224  */
   11225 static xmlSchemaTreeItemPtr
   11226 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   11227 			 xmlNodePtr node, xmlSchemaTypeType type,
   11228 			 int withParticle)
   11229 {
   11230     xmlSchemaModelGroupPtr item;
   11231     xmlSchemaParticlePtr particle = NULL;
   11232     xmlNodePtr child = NULL;
   11233     xmlAttrPtr attr;
   11234     int min = 1, max = 1, isElemRef, hasRefs = 0;
   11235 
   11236     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   11237         return (NULL);
   11238     /*
   11239     * Create a model group with the given compositor.
   11240     */
   11241     item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
   11242     if (item == NULL)
   11243 	return (NULL);
   11244 
   11245     if (withParticle) {
   11246 	if (type == XML_SCHEMA_TYPE_ALL) {
   11247 	    min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
   11248 	    max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
   11249 	} else {
   11250 	    /* choice + sequence */
   11251 	    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
   11252 	    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
   11253 		"(xs:nonNegativeInteger | unbounded)");
   11254 	}
   11255 	xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
   11256 	/*
   11257 	* Create a particle
   11258 	*/
   11259 	particle = xmlSchemaAddParticle(ctxt, node, min, max);
   11260 	if (particle == NULL)
   11261 	    return (NULL);
   11262 	particle->children = (xmlSchemaTreeItemPtr) item;
   11263 	/*
   11264 	* Check for illegal attributes.
   11265 	*/
   11266 	attr = node->properties;
   11267 	while (attr != NULL) {
   11268 	    if (attr->ns == NULL) {
   11269 		if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   11270 		    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
   11271 		    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
   11272 		    xmlSchemaPIllegalAttrErr(ctxt,
   11273 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11274 		}
   11275 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11276 		xmlSchemaPIllegalAttrErr(ctxt,
   11277 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11278 	    }
   11279 	    attr = attr->next;
   11280 	}
   11281     } else {
   11282 	/*
   11283 	* Check for illegal attributes.
   11284 	*/
   11285 	attr = node->properties;
   11286 	while (attr != NULL) {
   11287 	    if (attr->ns == NULL) {
   11288 		if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
   11289 		    xmlSchemaPIllegalAttrErr(ctxt,
   11290 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11291 		}
   11292 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11293 		xmlSchemaPIllegalAttrErr(ctxt,
   11294 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11295 	    }
   11296 	    attr = attr->next;
   11297 	}
   11298     }
   11299 
   11300     /*
   11301     * Extract and validate attributes.
   11302     */
   11303     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   11304     /*
   11305     * And now for the children...
   11306     */
   11307     child = node->children;
   11308     if (IS_SCHEMA(child, "annotation")) {
   11309         item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   11310         child = child->next;
   11311     }
   11312     if (type == XML_SCHEMA_TYPE_ALL) {
   11313 	xmlSchemaParticlePtr part, last = NULL;
   11314 
   11315 	while (IS_SCHEMA(child, "element")) {
   11316 	    part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
   11317 		schema, child, &isElemRef, 0);
   11318 	    /*
   11319 	    * SPEC cos-all-limited (2)
   11320 	    * "The {max occurs} of all the particles in the {particles}
   11321 	    * of the ('all') group must be 0 or 1.
   11322 	    */
   11323 	    if (part != NULL) {
   11324 		if (isElemRef)
   11325 		    hasRefs++;
   11326 		if (part->minOccurs > 1) {
   11327 		    xmlSchemaPCustomErr(ctxt,
   11328 			XML_SCHEMAP_COS_ALL_LIMITED,
   11329 			NULL, child,
   11330 			"Invalid value for minOccurs (must be 0 or 1)",
   11331 			NULL);
   11332 		    /* Reset to 1. */
   11333 		    part->minOccurs = 1;
   11334 		}
   11335 		if (part->maxOccurs > 1) {
   11336 		    xmlSchemaPCustomErr(ctxt,
   11337 			XML_SCHEMAP_COS_ALL_LIMITED,
   11338 			NULL, child,
   11339 			"Invalid value for maxOccurs (must be 0 or 1)",
   11340 			NULL);
   11341 		    /* Reset to 1. */
   11342 		    part->maxOccurs = 1;
   11343 		}
   11344 		if (last == NULL)
   11345 		    item->children = (xmlSchemaTreeItemPtr) part;
   11346 		else
   11347 		    last->next = (xmlSchemaTreeItemPtr) part;
   11348 		last = part;
   11349 	    }
   11350 	    child = child->next;
   11351 	}
   11352 	if (child != NULL) {
   11353 	    xmlSchemaPContentErr(ctxt,
   11354 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11355 		NULL, node, child, NULL,
   11356 		"(annotation?, (annotation?, element*)");
   11357 	}
   11358     } else {
   11359 	/* choice + sequence */
   11360 	xmlSchemaTreeItemPtr part = NULL, last = NULL;
   11361 
   11362 	while ((IS_SCHEMA(child, "element")) ||
   11363 	    (IS_SCHEMA(child, "group")) ||
   11364 	    (IS_SCHEMA(child, "any")) ||
   11365 	    (IS_SCHEMA(child, "choice")) ||
   11366 	    (IS_SCHEMA(child, "sequence"))) {
   11367 
   11368 	    if (IS_SCHEMA(child, "element")) {
   11369 		part = (xmlSchemaTreeItemPtr)
   11370 		    xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
   11371 		if (part && isElemRef)
   11372 		    hasRefs++;
   11373 	    } else if (IS_SCHEMA(child, "group")) {
   11374 		part =
   11375 		    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
   11376 		if (part != NULL)
   11377 		    hasRefs++;
   11378 		/*
   11379 		* Handle redefinitions.
   11380 		*/
   11381 		if (ctxt->isRedefine && ctxt->redef &&
   11382 		    (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
   11383 		    part && part->children)
   11384 		{
   11385 		    if ((xmlSchemaGetQNameRefName(part->children) ==
   11386 			    ctxt->redef->refName) &&
   11387 			(xmlSchemaGetQNameRefTargetNs(part->children) ==
   11388 			    ctxt->redef->refTargetNs))
   11389 		    {
   11390 			/*
   11391 			* SPEC src-redefine:
   11392 			* (6.1) "If it has a <group> among its contents at
   11393 			* some level the `actual value` of whose ref
   11394 			* [attribute] is the same as the `actual value` of
   11395 			* its own name attribute plus target namespace, then
   11396 			* all of the following must be true:"
   11397 			* (6.1.1) "It must have exactly one such group."
   11398 			*/
   11399 			if (ctxt->redefCounter != 0) {
   11400 			    xmlChar *str = NULL;
   11401 
   11402 			    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   11403 				XML_SCHEMAP_SRC_REDEFINE, child, NULL,
   11404 				"The redefining model group definition "
   11405 				"'%s' must not contain more than one "
   11406 				"reference to the redefined definition",
   11407 				xmlSchemaFormatQName(&str,
   11408 				    ctxt->redef->refTargetNs,
   11409 				    ctxt->redef->refName),
   11410 				NULL);
   11411 			    FREE_AND_NULL(str)
   11412 			    part = NULL;
   11413 			} else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
   11414 			    ((WXS_PARTICLE(part))->maxOccurs != 1))
   11415 			{
   11416 			    xmlChar *str = NULL;
   11417 			    /*
   11418 			    * SPEC src-redefine:
   11419 			    * (6.1.2) "The `actual value` of both that
   11420 			    * group's minOccurs and maxOccurs [attribute]
   11421 			    * must be 1 (or `absent`).
   11422 			    */
   11423 			    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   11424 				XML_SCHEMAP_SRC_REDEFINE, child, NULL,
   11425 				"The redefining model group definition "
   11426 				"'%s' must not contain a reference to the "
   11427 				"redefined definition with a "
   11428 				"maxOccurs/minOccurs other than 1",
   11429 				xmlSchemaFormatQName(&str,
   11430 				    ctxt->redef->refTargetNs,
   11431 				    ctxt->redef->refName),
   11432 				NULL);
   11433 			    FREE_AND_NULL(str)
   11434 			    part = NULL;
   11435 			}
   11436 			ctxt->redef->reference = WXS_BASIC_CAST part;
   11437 			ctxt->redefCounter++;
   11438 		    }
   11439 		}
   11440 	    } else if (IS_SCHEMA(child, "any")) {
   11441 		part = (xmlSchemaTreeItemPtr)
   11442 		    xmlSchemaParseAny(ctxt, schema, child);
   11443 	    } else if (IS_SCHEMA(child, "choice")) {
   11444 		part = xmlSchemaParseModelGroup(ctxt, schema, child,
   11445 		    XML_SCHEMA_TYPE_CHOICE, 1);
   11446 	    } else if (IS_SCHEMA(child, "sequence")) {
   11447 		part = xmlSchemaParseModelGroup(ctxt, schema, child,
   11448 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
   11449 	    }
   11450 	    if (part != NULL) {
   11451 		if (last == NULL)
   11452 		    item->children = part;
   11453 		else
   11454 		    last->next = part;
   11455 		last = part;
   11456 	    }
   11457 	    child = child->next;
   11458 	}
   11459 	if (child != NULL) {
   11460 	    xmlSchemaPContentErr(ctxt,
   11461 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11462 		NULL, node, child, NULL,
   11463 		"(annotation?, (element | group | choice | sequence | any)*)");
   11464 	}
   11465     }
   11466     if ((max == 0) && (min == 0))
   11467 	return (NULL);
   11468     if (hasRefs) {
   11469 	/*
   11470 	* We need to resolve references.
   11471 	*/
   11472 	WXS_ADD_PENDING(ctxt, item);
   11473     }
   11474     if (withParticle)
   11475 	return ((xmlSchemaTreeItemPtr) particle);
   11476     else
   11477 	return ((xmlSchemaTreeItemPtr) item);
   11478 }
   11479 
   11480 /**
   11481  * xmlSchemaParseRestriction:
   11482  * @ctxt:  a schema validation context
   11483  * @schema:  the schema being built
   11484  * @node:  a subtree containing XML Schema informations
   11485  *
   11486  * parse a XML schema Restriction definition
   11487  * *WARNING* this interface is highly subject to change
   11488  *
   11489  * Returns the type definition or NULL in case of error
   11490  */
   11491 static xmlSchemaTypePtr
   11492 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   11493                           xmlNodePtr node, xmlSchemaTypeType parentType)
   11494 {
   11495     xmlSchemaTypePtr type;
   11496     xmlNodePtr child = NULL;
   11497     xmlAttrPtr attr;
   11498 
   11499     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   11500         return (NULL);
   11501     /* Not a component, don't create it. */
   11502     type = ctxt->ctxtType;
   11503     type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
   11504 
   11505     /*
   11506     * Check for illegal attributes.
   11507     */
   11508     attr = node->properties;
   11509     while (attr != NULL) {
   11510 	if (attr->ns == NULL) {
   11511 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   11512 		(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
   11513 		xmlSchemaPIllegalAttrErr(ctxt,
   11514 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11515 	    }
   11516 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11517 	    xmlSchemaPIllegalAttrErr(ctxt,
   11518 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11519 	}
   11520 	attr = attr->next;
   11521     }
   11522     /*
   11523     * Extract and validate attributes.
   11524     */
   11525     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   11526     /*
   11527     * Attribute
   11528     */
   11529     /*
   11530     * Extract the base type. The "base" attribute is mandatory if inside
   11531     * a complex type or if redefining.
   11532     *
   11533     * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
   11534     * among its [children]), the simple type definition which is
   11535     * the {content type} of the type definition `resolved` to by
   11536     * the `actual value` of the base [attribute]"
   11537     */
   11538     if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
   11539 	&(type->baseNs), &(type->base)) == 0)
   11540     {
   11541 	if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
   11542 	    xmlSchemaPMissingAttrErr(ctxt,
   11543 		XML_SCHEMAP_S4S_ATTR_MISSING,
   11544 		NULL, node, "base", NULL);
   11545 	} else if ((ctxt->isRedefine) &&
   11546 	    (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
   11547 	{
   11548 	    if (type->base == NULL) {
   11549 		xmlSchemaPMissingAttrErr(ctxt,
   11550 		    XML_SCHEMAP_S4S_ATTR_MISSING,
   11551 		    NULL, node, "base", NULL);
   11552 	    } else if ((! xmlStrEqual(type->base, type->name)) ||
   11553 		(! xmlStrEqual(type->baseNs, type->targetNamespace)))
   11554 	    {
   11555 		xmlChar *str1 = NULL, *str2 = NULL;
   11556 		/*
   11557 		* REDEFINE: SPEC src-redefine (5)
   11558 		* "Within the [children], each <simpleType> must have a
   11559 		* <restriction> among its [children] ... the `actual value` of
   11560 		* whose base [attribute] must be the same as the `actual value`
   11561 		* of its own name attribute plus target namespace;"
   11562 		*/
   11563 		xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   11564 		    NULL, node, "This is a redefinition, but the QName "
   11565 		    "value '%s' of the 'base' attribute does not match the "
   11566 		    "type's designation '%s'",
   11567 		    xmlSchemaFormatQName(&str1, type->baseNs, type->base),
   11568 		    xmlSchemaFormatQName(&str2, type->targetNamespace,
   11569 			type->name), NULL);
   11570 		FREE_AND_NULL(str1);
   11571 		FREE_AND_NULL(str2);
   11572 		/* Avoid confusion and erase the values. */
   11573 		type->base = NULL;
   11574 		type->baseNs = NULL;
   11575 	    }
   11576 	}
   11577     }
   11578     /*
   11579     * And now for the children...
   11580     */
   11581     child = node->children;
   11582     if (IS_SCHEMA(child, "annotation")) {
   11583 	/*
   11584 	* Add the annotation to the simple type ancestor.
   11585 	*/
   11586 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   11587 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   11588         child = child->next;
   11589     }
   11590     if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
   11591 	/*
   11592 	* Corresponds to <simpleType><restriction><simpleType>.
   11593 	*/
   11594 	if (IS_SCHEMA(child, "simpleType")) {
   11595 	    if (type->base != NULL) {
   11596 		/*
   11597 		* src-restriction-base-or-simpleType
   11598 		* Either the base [attribute] or the simpleType [child] of the
   11599 		* <restriction> element must be present, but not both.
   11600 		*/
   11601 		xmlSchemaPContentErr(ctxt,
   11602 		    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
   11603 		    NULL, node, child,
   11604 		    "The attribute 'base' and the <simpleType> child are "
   11605 		    "mutually exclusive", NULL);
   11606 	    } else {
   11607 		type->baseType = (xmlSchemaTypePtr)
   11608 		    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   11609 	    }
   11610 	    child = child->next;
   11611 	} else if (type->base == NULL) {
   11612 	    xmlSchemaPContentErr(ctxt,
   11613 		XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
   11614 		NULL, node, child,
   11615 		"Either the attribute 'base' or a <simpleType> child "
   11616 		"must be present", NULL);
   11617 	}
   11618     } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
   11619 	/*
   11620 	* Corresponds to <complexType><complexContent><restriction>...
   11621 	* followed by:
   11622 	*
   11623 	* Model groups <all>, <choice> and <sequence>.
   11624 	*/
   11625 	if (IS_SCHEMA(child, "all")) {
   11626 	    type->subtypes = (xmlSchemaTypePtr)
   11627 		xmlSchemaParseModelGroup(ctxt, schema, child,
   11628 		    XML_SCHEMA_TYPE_ALL, 1);
   11629 	    child = child->next;
   11630 	} else if (IS_SCHEMA(child, "choice")) {
   11631 	    type->subtypes = (xmlSchemaTypePtr)
   11632 		xmlSchemaParseModelGroup(ctxt,
   11633 		    schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
   11634 	    child = child->next;
   11635 	} else if (IS_SCHEMA(child, "sequence")) {
   11636 	    type->subtypes = (xmlSchemaTypePtr)
   11637 		xmlSchemaParseModelGroup(ctxt, schema, child,
   11638 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
   11639 	    child = child->next;
   11640 	/*
   11641 	* Model group reference <group>.
   11642 	*/
   11643 	} else if (IS_SCHEMA(child, "group")) {
   11644 	    type->subtypes = (xmlSchemaTypePtr)
   11645 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
   11646 	    /*
   11647 	    * Note that the reference will be resolved in
   11648 	    * xmlSchemaResolveTypeReferences();
   11649 	    */
   11650 	    child = child->next;
   11651 	}
   11652     } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
   11653 	/*
   11654 	* Corresponds to <complexType><simpleContent><restriction>...
   11655 	*
   11656 	* "1.1 the simple type definition corresponding to the <simpleType>
   11657 	* among the [children] of <restriction> if there is one;"
   11658 	*/
   11659 	if (IS_SCHEMA(child, "simpleType")) {
   11660 	    /*
   11661 	    * We will store the to-be-restricted simple type in
   11662 	    * type->contentTypeDef *temporarily*.
   11663 	    */
   11664 	    type->contentTypeDef = (xmlSchemaTypePtr)
   11665 		xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   11666 	    if ( type->contentTypeDef == NULL)
   11667 		return (NULL);
   11668 	    child = child->next;
   11669 	}
   11670     }
   11671 
   11672     if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
   11673 	(parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
   11674 	xmlSchemaFacetPtr facet, lastfacet = NULL;
   11675 	/*
   11676 	* Corresponds to <complexType><simpleContent><restriction>...
   11677 	* <simpleType><restriction>...
   11678 	*/
   11679 
   11680 	/*
   11681 	* Add the facets to the simple type ancestor.
   11682 	*/
   11683 	/*
   11684 	* TODO: Datatypes: 4.1.3 Constraints on XML Representation of
   11685 	* Simple Type Definition Schema Representation Constraint:
   11686 	* *Single Facet Value*
   11687 	*/
   11688 	while ((IS_SCHEMA(child, "minInclusive")) ||
   11689 	    (IS_SCHEMA(child, "minExclusive")) ||
   11690 	    (IS_SCHEMA(child, "maxInclusive")) ||
   11691 	    (IS_SCHEMA(child, "maxExclusive")) ||
   11692 	    (IS_SCHEMA(child, "totalDigits")) ||
   11693 	    (IS_SCHEMA(child, "fractionDigits")) ||
   11694 	    (IS_SCHEMA(child, "pattern")) ||
   11695 	    (IS_SCHEMA(child, "enumeration")) ||
   11696 	    (IS_SCHEMA(child, "whiteSpace")) ||
   11697 	    (IS_SCHEMA(child, "length")) ||
   11698 	    (IS_SCHEMA(child, "maxLength")) ||
   11699 	    (IS_SCHEMA(child, "minLength"))) {
   11700 	    facet = xmlSchemaParseFacet(ctxt, schema, child);
   11701 	    if (facet != NULL) {
   11702 		if (lastfacet == NULL)
   11703 		    type->facets = facet;
   11704 		else
   11705 		    lastfacet->next = facet;
   11706 		lastfacet = facet;
   11707 		lastfacet->next = NULL;
   11708 	    }
   11709 	    child = child->next;
   11710 	}
   11711 	/*
   11712 	* Create links for derivation and validation.
   11713 	*/
   11714 	if (type->facets != NULL) {
   11715 	    xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
   11716 
   11717 	    facet = type->facets;
   11718 	    do {
   11719 		facetLink = (xmlSchemaFacetLinkPtr)
   11720 		    xmlMalloc(sizeof(xmlSchemaFacetLink));
   11721 		if (facetLink == NULL) {
   11722 		    xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
   11723 		    xmlFree(facetLink);
   11724 		    return (NULL);
   11725 		}
   11726 		facetLink->facet = facet;
   11727 		facetLink->next = NULL;
   11728 		if (lastFacetLink == NULL)
   11729 		    type->facetSet = facetLink;
   11730 		else
   11731 		    lastFacetLink->next = facetLink;
   11732 		lastFacetLink = facetLink;
   11733 		facet = facet->next;
   11734 	    } while (facet != NULL);
   11735 	}
   11736     }
   11737     if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
   11738 	/*
   11739 	* Attribute uses/declarations.
   11740 	*/
   11741 	if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
   11742 	    (xmlSchemaItemListPtr *) &(type->attrUses),
   11743 	    XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
   11744 	    return(NULL);
   11745 	/*
   11746 	* Attribute wildcard.
   11747 	*/
   11748 	if (IS_SCHEMA(child, "anyAttribute")) {
   11749 	    type->attributeWildcard =
   11750 		xmlSchemaParseAnyAttribute(ctxt, schema, child);
   11751 	    child = child->next;
   11752 	}
   11753     }
   11754     if (child != NULL) {
   11755 	if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
   11756 	    xmlSchemaPContentErr(ctxt,
   11757 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11758 		NULL, node, child, NULL,
   11759 		"annotation?, (group | all | choice | sequence)?, "
   11760 		"((attribute | attributeGroup)*, anyAttribute?))");
   11761 	} else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
   11762 	     xmlSchemaPContentErr(ctxt,
   11763 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11764 		NULL, node, child, NULL,
   11765 		"(annotation?, (simpleType?, (minExclusive | minInclusive | "
   11766 		"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
   11767 		"length | minLength | maxLength | enumeration | whiteSpace | "
   11768 		"pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
   11769 	} else {
   11770 	    /* Simple type */
   11771 	    xmlSchemaPContentErr(ctxt,
   11772 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11773 		NULL, node, child, NULL,
   11774 		"(annotation?, (simpleType?, (minExclusive | minInclusive | "
   11775 		"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
   11776 		"length | minLength | maxLength | enumeration | whiteSpace | "
   11777 		"pattern)*))");
   11778 	}
   11779     }
   11780     return (NULL);
   11781 }
   11782 
   11783 /**
   11784  * xmlSchemaParseExtension:
   11785  * @ctxt:  a schema validation context
   11786  * @schema:  the schema being built
   11787  * @node:  a subtree containing XML Schema informations
   11788  *
   11789  * Parses an <extension>, which is found inside a
   11790  * <simpleContent> or <complexContent>.
   11791  * *WARNING* this interface is highly subject to change.
   11792  *
   11793  * TODO: Returns the type definition or NULL in case of error
   11794  */
   11795 static xmlSchemaTypePtr
   11796 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   11797                         xmlNodePtr node, xmlSchemaTypeType parentType)
   11798 {
   11799     xmlSchemaTypePtr type;
   11800     xmlNodePtr child = NULL;
   11801     xmlAttrPtr attr;
   11802 
   11803     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   11804         return (NULL);
   11805     /* Not a component, don't create it. */
   11806     type = ctxt->ctxtType;
   11807     type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
   11808 
   11809     /*
   11810     * Check for illegal attributes.
   11811     */
   11812     attr = node->properties;
   11813     while (attr != NULL) {
   11814 	if (attr->ns == NULL) {
   11815 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   11816 		(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
   11817 		xmlSchemaPIllegalAttrErr(ctxt,
   11818 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11819 	    }
   11820 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11821 	    xmlSchemaPIllegalAttrErr(ctxt,
   11822 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11823 	}
   11824 	attr = attr->next;
   11825     }
   11826 
   11827     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   11828 
   11829     /*
   11830     * Attribute "base" - mandatory.
   11831     */
   11832     if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
   11833 	"base", &(type->baseNs), &(type->base)) == 0) &&
   11834 	(type->base == NULL)) {
   11835 	xmlSchemaPMissingAttrErr(ctxt,
   11836 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   11837 	    NULL, node, "base", NULL);
   11838     }
   11839     /*
   11840     * And now for the children...
   11841     */
   11842     child = node->children;
   11843     if (IS_SCHEMA(child, "annotation")) {
   11844 	/*
   11845 	* Add the annotation to the type ancestor.
   11846 	*/
   11847 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   11848 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   11849         child = child->next;
   11850     }
   11851     if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
   11852 	/*
   11853 	* Corresponds to <complexType><complexContent><extension>... and:
   11854 	*
   11855 	* Model groups <all>, <choice>, <sequence> and <group>.
   11856 	*/
   11857 	if (IS_SCHEMA(child, "all")) {
   11858 	    type->subtypes = (xmlSchemaTypePtr)
   11859 		xmlSchemaParseModelGroup(ctxt, schema,
   11860 		    child, XML_SCHEMA_TYPE_ALL, 1);
   11861 	    child = child->next;
   11862 	} else if (IS_SCHEMA(child, "choice")) {
   11863 	    type->subtypes = (xmlSchemaTypePtr)
   11864 		xmlSchemaParseModelGroup(ctxt, schema,
   11865 		    child, XML_SCHEMA_TYPE_CHOICE, 1);
   11866 	    child = child->next;
   11867 	} else if (IS_SCHEMA(child, "sequence")) {
   11868 	    type->subtypes = (xmlSchemaTypePtr)
   11869 		xmlSchemaParseModelGroup(ctxt, schema,
   11870 		child, XML_SCHEMA_TYPE_SEQUENCE, 1);
   11871 	    child = child->next;
   11872 	} else if (IS_SCHEMA(child, "group")) {
   11873 	    type->subtypes = (xmlSchemaTypePtr)
   11874 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
   11875 	    /*
   11876 	    * Note that the reference will be resolved in
   11877 	    * xmlSchemaResolveTypeReferences();
   11878 	    */
   11879 	    child = child->next;
   11880 	}
   11881     }
   11882     if (child != NULL) {
   11883 	/*
   11884 	* Attribute uses/declarations.
   11885 	*/
   11886 	if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
   11887 	    (xmlSchemaItemListPtr *) &(type->attrUses),
   11888 	    XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
   11889 	    return(NULL);
   11890 	/*
   11891 	* Attribute wildcard.
   11892 	*/
   11893 	if (IS_SCHEMA(child, "anyAttribute")) {
   11894 	    ctxt->ctxtType->attributeWildcard =
   11895 		xmlSchemaParseAnyAttribute(ctxt, schema, child);
   11896 	    child = child->next;
   11897 	}
   11898     }
   11899     if (child != NULL) {
   11900 	if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
   11901 	    /* Complex content extension. */
   11902 	    xmlSchemaPContentErr(ctxt,
   11903 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11904 		NULL, node, child, NULL,
   11905 		"(annotation?, ((group | all | choice | sequence)?, "
   11906 		"((attribute | attributeGroup)*, anyAttribute?)))");
   11907 	} else {
   11908 	    /* Simple content extension. */
   11909 	    xmlSchemaPContentErr(ctxt,
   11910 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11911 		NULL, node, child, NULL,
   11912 		"(annotation?, ((attribute | attributeGroup)*, "
   11913 		"anyAttribute?))");
   11914 	}
   11915     }
   11916     return (NULL);
   11917 }
   11918 
   11919 /**
   11920  * xmlSchemaParseSimpleContent:
   11921  * @ctxt:  a schema validation context
   11922  * @schema:  the schema being built
   11923  * @node:  a subtree containing XML Schema informations
   11924  *
   11925  * parse a XML schema SimpleContent definition
   11926  * *WARNING* this interface is highly subject to change
   11927  *
   11928  * Returns the type definition or NULL in case of error
   11929  */
   11930 static int
   11931 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
   11932                             xmlSchemaPtr schema, xmlNodePtr node,
   11933 			    int *hasRestrictionOrExtension)
   11934 {
   11935     xmlSchemaTypePtr type;
   11936     xmlNodePtr child = NULL;
   11937     xmlAttrPtr attr;
   11938 
   11939     if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
   11940 	(hasRestrictionOrExtension == NULL))
   11941         return (-1);
   11942     *hasRestrictionOrExtension = 0;
   11943     /* Not a component, don't create it. */
   11944     type = ctxt->ctxtType;
   11945     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   11946     /*
   11947     * Check for illegal attributes.
   11948     */
   11949     attr = node->properties;
   11950     while (attr != NULL) {
   11951 	if (attr->ns == NULL) {
   11952 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
   11953 		xmlSchemaPIllegalAttrErr(ctxt,
   11954 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11955 	    }
   11956 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11957 	    xmlSchemaPIllegalAttrErr(ctxt,
   11958 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11959 	}
   11960 	attr = attr->next;
   11961     }
   11962 
   11963     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   11964 
   11965     /*
   11966     * And now for the children...
   11967     */
   11968     child = node->children;
   11969     if (IS_SCHEMA(child, "annotation")) {
   11970 	/*
   11971 	* Add the annotation to the complex type ancestor.
   11972 	*/
   11973 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   11974 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   11975         child = child->next;
   11976     }
   11977     if (child == NULL) {
   11978 	xmlSchemaPContentErr(ctxt,
   11979 	    XML_SCHEMAP_S4S_ELEM_MISSING,
   11980 	    NULL, node, NULL, NULL,
   11981 	    "(annotation?, (restriction | extension))");
   11982     }
   11983     if (child == NULL) {
   11984 	xmlSchemaPContentErr(ctxt,
   11985 	    XML_SCHEMAP_S4S_ELEM_MISSING,
   11986 	    NULL, node, NULL, NULL,
   11987 	    "(annotation?, (restriction | extension))");
   11988     }
   11989     if (IS_SCHEMA(child, "restriction")) {
   11990         xmlSchemaParseRestriction(ctxt, schema, child,
   11991 	    XML_SCHEMA_TYPE_SIMPLE_CONTENT);
   11992 	(*hasRestrictionOrExtension) = 1;
   11993         child = child->next;
   11994     } else if (IS_SCHEMA(child, "extension")) {
   11995         xmlSchemaParseExtension(ctxt, schema, child,
   11996 	    XML_SCHEMA_TYPE_SIMPLE_CONTENT);
   11997 	(*hasRestrictionOrExtension) = 1;
   11998         child = child->next;
   11999     }
   12000     if (child != NULL) {
   12001 	xmlSchemaPContentErr(ctxt,
   12002 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   12003 	    NULL, node, child, NULL,
   12004 	    "(annotation?, (restriction | extension))");
   12005     }
   12006     return (0);
   12007 }
   12008 
   12009 /**
   12010  * xmlSchemaParseComplexContent:
   12011  * @ctxt:  a schema validation context
   12012  * @schema:  the schema being built
   12013  * @node:  a subtree containing XML Schema informations
   12014  *
   12015  * parse a XML schema ComplexContent definition
   12016  * *WARNING* this interface is highly subject to change
   12017  *
   12018  * Returns the type definition or NULL in case of error
   12019  */
   12020 static int
   12021 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
   12022                              xmlSchemaPtr schema, xmlNodePtr node,
   12023 			     int *hasRestrictionOrExtension)
   12024 {
   12025     xmlSchemaTypePtr type;
   12026     xmlNodePtr child = NULL;
   12027     xmlAttrPtr attr;
   12028 
   12029     if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
   12030 	(hasRestrictionOrExtension == NULL))
   12031         return (-1);
   12032     *hasRestrictionOrExtension = 0;
   12033     /* Not a component, don't create it. */
   12034     type = ctxt->ctxtType;
   12035     /*
   12036     * Check for illegal attributes.
   12037     */
   12038     attr = node->properties;
   12039     while (attr != NULL) {
   12040 	if (attr->ns == NULL) {
   12041 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   12042 		(!xmlStrEqual(attr->name, BAD_CAST "mixed")))
   12043 	    {
   12044 		xmlSchemaPIllegalAttrErr(ctxt,
   12045 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12046 	    }
   12047 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   12048 	    xmlSchemaPIllegalAttrErr(ctxt,
   12049 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12050 	}
   12051 	attr = attr->next;
   12052     }
   12053 
   12054     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   12055 
   12056     /*
   12057     * Set the 'mixed' on the complex type ancestor.
   12058     */
   12059     if (xmlGetBooleanProp(ctxt, node, "mixed", 0))  {
   12060 	if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
   12061 	    type->flags |= XML_SCHEMAS_TYPE_MIXED;
   12062     }
   12063     child = node->children;
   12064     if (IS_SCHEMA(child, "annotation")) {
   12065 	/*
   12066 	* Add the annotation to the complex type ancestor.
   12067 	*/
   12068 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   12069 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   12070         child = child->next;
   12071     }
   12072     if (child == NULL) {
   12073 	xmlSchemaPContentErr(ctxt,
   12074 	    XML_SCHEMAP_S4S_ELEM_MISSING,
   12075 	    NULL, node, NULL,
   12076 	    NULL, "(annotation?, (restriction | extension))");
   12077     }
   12078     if (child == NULL) {
   12079 	xmlSchemaPContentErr(ctxt,
   12080 	    XML_SCHEMAP_S4S_ELEM_MISSING,
   12081 	    NULL, node, NULL,
   12082 	    NULL, "(annotation?, (restriction | extension))");
   12083     }
   12084     if (IS_SCHEMA(child, "restriction")) {
   12085         xmlSchemaParseRestriction(ctxt, schema, child,
   12086 	    XML_SCHEMA_TYPE_COMPLEX_CONTENT);
   12087 	(*hasRestrictionOrExtension) = 1;
   12088         child = child->next;
   12089     } else if (IS_SCHEMA(child, "extension")) {
   12090         xmlSchemaParseExtension(ctxt, schema, child,
   12091 	    XML_SCHEMA_TYPE_COMPLEX_CONTENT);
   12092 	(*hasRestrictionOrExtension) = 1;
   12093         child = child->next;
   12094     }
   12095     if (child != NULL) {
   12096 	xmlSchemaPContentErr(ctxt,
   12097 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   12098 	    NULL, node, child,
   12099 	    NULL, "(annotation?, (restriction | extension))");
   12100     }
   12101     return (0);
   12102 }
   12103 
   12104 /**
   12105  * xmlSchemaParseComplexType:
   12106  * @ctxt:  a schema validation context
   12107  * @schema:  the schema being built
   12108  * @node:  a subtree containing XML Schema informations
   12109  *
   12110  * parse a XML schema Complex Type definition
   12111  * *WARNING* this interface is highly subject to change
   12112  *
   12113  * Returns the type definition or NULL in case of error
   12114  */
   12115 static xmlSchemaTypePtr
   12116 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   12117                           xmlNodePtr node, int topLevel)
   12118 {
   12119     xmlSchemaTypePtr type, ctxtType;
   12120     xmlNodePtr child = NULL;
   12121     const xmlChar *name = NULL;
   12122     xmlAttrPtr attr;
   12123     const xmlChar *attrValue;
   12124 #ifdef ENABLE_NAMED_LOCALS
   12125     char buf[40];
   12126 #endif
   12127     int final = 0, block = 0, hasRestrictionOrExtension = 0;
   12128 
   12129 
   12130     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   12131         return (NULL);
   12132 
   12133     ctxtType = ctxt->ctxtType;
   12134 
   12135     if (topLevel) {
   12136 	attr = xmlSchemaGetPropNode(node, "name");
   12137 	if (attr == NULL) {
   12138 	    xmlSchemaPMissingAttrErr(ctxt,
   12139 		XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
   12140 	    return (NULL);
   12141 	} else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
   12142 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   12143 	    return (NULL);
   12144 	}
   12145     }
   12146 
   12147     if (topLevel == 0) {
   12148 	/*
   12149 	* Parse as local complex type definition.
   12150 	*/
   12151 #ifdef ENABLE_NAMED_LOCALS
   12152         snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
   12153 	type = xmlSchemaAddType(ctxt, schema,
   12154 	    XML_SCHEMA_TYPE_COMPLEX,
   12155 	    xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
   12156 	    ctxt->targetNamespace, node, 0);
   12157 #else
   12158 	type = xmlSchemaAddType(ctxt, schema,
   12159 	    XML_SCHEMA_TYPE_COMPLEX,
   12160 	    NULL, ctxt->targetNamespace, node, 0);
   12161 #endif
   12162 	if (type == NULL)
   12163 	    return (NULL);
   12164 	name = type->name;
   12165 	type->node = node;
   12166 	type->type = XML_SCHEMA_TYPE_COMPLEX;
   12167 	/*
   12168 	* TODO: We need the target namespace.
   12169 	*/
   12170     } else {
   12171 	/*
   12172 	* Parse as global complex type definition.
   12173 	*/
   12174 	type = xmlSchemaAddType(ctxt, schema,
   12175 	    XML_SCHEMA_TYPE_COMPLEX,
   12176 	    name, ctxt->targetNamespace, node, 1);
   12177 	if (type == NULL)
   12178 	    return (NULL);
   12179 	type->node = node;
   12180 	type->type = XML_SCHEMA_TYPE_COMPLEX;
   12181 	type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
   12182     }
   12183     type->targetNamespace = ctxt->targetNamespace;
   12184     /*
   12185     * Handle attributes.
   12186     */
   12187     attr = node->properties;
   12188     while (attr != NULL) {
   12189 	if (attr->ns == NULL) {
   12190 	    if (xmlStrEqual(attr->name, BAD_CAST "id")) {
   12191 		/*
   12192 		* Attribute "id".
   12193 		*/
   12194 		xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   12195 	    } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
   12196 		/*
   12197 		* Attribute "mixed".
   12198 		*/
   12199 		if (xmlSchemaPGetBoolNodeValue(ctxt,
   12200 			NULL, (xmlNodePtr) attr))
   12201 		    type->flags |= XML_SCHEMAS_TYPE_MIXED;
   12202 	    } else if (topLevel) {
   12203 		/*
   12204 		* Attributes of global complex type definitions.
   12205 		*/
   12206 		if (xmlStrEqual(attr->name, BAD_CAST "name")) {
   12207 		    /* Pass. */
   12208 		} else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
   12209 		    /*
   12210 		    * Attribute "abstract".
   12211 		    */
   12212 		    if (xmlSchemaPGetBoolNodeValue(ctxt,
   12213 			    NULL, (xmlNodePtr) attr))
   12214 			type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
   12215 		} else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
   12216 		    /*
   12217 		    * Attribute "final".
   12218 		    */
   12219 		    attrValue = xmlSchemaGetNodeContent(ctxt,
   12220 			(xmlNodePtr) attr);
   12221 		    if (xmlSchemaPValAttrBlockFinal(attrValue,
   12222 			&(type->flags),
   12223 			-1,
   12224 			XML_SCHEMAS_TYPE_FINAL_EXTENSION,
   12225 			XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
   12226 			-1, -1, -1) != 0)
   12227 		    {
   12228 			xmlSchemaPSimpleTypeErr(ctxt,
   12229 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   12230 			    NULL, (xmlNodePtr) attr, NULL,
   12231 			    "(#all | List of (extension | restriction))",
   12232 			    attrValue, NULL, NULL, NULL);
   12233 		    } else
   12234 			final = 1;
   12235 		} else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
   12236 		    /*
   12237 		    * Attribute "block".
   12238 		    */
   12239 		    attrValue = xmlSchemaGetNodeContent(ctxt,
   12240 			(xmlNodePtr) attr);
   12241 		    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
   12242 			-1,
   12243 			XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
   12244 			XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
   12245 			-1, -1, -1) != 0) {
   12246 			xmlSchemaPSimpleTypeErr(ctxt,
   12247 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   12248 			    NULL, (xmlNodePtr) attr, NULL,
   12249 			    "(#all | List of (extension | restriction)) ",
   12250 			    attrValue, NULL, NULL, NULL);
   12251 		    } else
   12252 			block = 1;
   12253 		} else {
   12254 			xmlSchemaPIllegalAttrErr(ctxt,
   12255 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12256 		}
   12257 	    } else {
   12258 		xmlSchemaPIllegalAttrErr(ctxt,
   12259 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12260 	    }
   12261 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   12262 	    xmlSchemaPIllegalAttrErr(ctxt,
   12263 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12264 	}
   12265 	attr = attr->next;
   12266     }
   12267     if (! block) {
   12268 	/*
   12269 	* Apply default "block" values.
   12270 	*/
   12271 	if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
   12272 	    type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
   12273 	if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
   12274 	    type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
   12275     }
   12276     if (! final) {
   12277 	/*
   12278 	* Apply default "block" values.
   12279 	*/
   12280 	if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   12281 	    type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
   12282 	if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
   12283 	    type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
   12284     }
   12285     /*
   12286     * And now for the children...
   12287     */
   12288     child = node->children;
   12289     if (IS_SCHEMA(child, "annotation")) {
   12290         type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   12291         child = child->next;
   12292     }
   12293     ctxt->ctxtType = type;
   12294     if (IS_SCHEMA(child, "simpleContent")) {
   12295 	/*
   12296 	* <complexType><simpleContent>...
   12297 	* 3.4.3 : 2.2
   12298 	* Specifying mixed='true' when the <simpleContent>
   12299 	* alternative is chosen has no effect
   12300 	*/
   12301 	if (type->flags & XML_SCHEMAS_TYPE_MIXED)
   12302 	    type->flags ^= XML_SCHEMAS_TYPE_MIXED;
   12303         xmlSchemaParseSimpleContent(ctxt, schema, child,
   12304 	    &hasRestrictionOrExtension);
   12305         child = child->next;
   12306     } else if (IS_SCHEMA(child, "complexContent")) {
   12307 	/*
   12308 	* <complexType><complexContent>...
   12309 	*/
   12310 	type->contentType = XML_SCHEMA_CONTENT_EMPTY;
   12311         xmlSchemaParseComplexContent(ctxt, schema, child,
   12312 	    &hasRestrictionOrExtension);
   12313         child = child->next;
   12314     } else {
   12315 	/*
   12316 	* E.g <complexType><sequence>... or <complexType><attribute>... etc.
   12317 	*
   12318 	* SPEC
   12319 	* "...the third alternative (neither <simpleContent> nor
   12320 	* <complexContent>) is chosen. This case is understood as shorthand
   12321 	* for complex content restricting the `ur-type definition`, and the
   12322 	* details of the mappings should be modified as necessary.
   12323 	*/
   12324 	type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
   12325 	type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
   12326 	/*
   12327 	* Parse model groups.
   12328 	*/
   12329         if (IS_SCHEMA(child, "all")) {
   12330             type->subtypes = (xmlSchemaTypePtr)
   12331 		xmlSchemaParseModelGroup(ctxt, schema, child,
   12332 		    XML_SCHEMA_TYPE_ALL, 1);
   12333             child = child->next;
   12334         } else if (IS_SCHEMA(child, "choice")) {
   12335             type->subtypes = (xmlSchemaTypePtr)
   12336 		xmlSchemaParseModelGroup(ctxt, schema, child,
   12337 		    XML_SCHEMA_TYPE_CHOICE, 1);
   12338             child = child->next;
   12339         } else if (IS_SCHEMA(child, "sequence")) {
   12340             type->subtypes = (xmlSchemaTypePtr)
   12341 		xmlSchemaParseModelGroup(ctxt, schema, child,
   12342 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
   12343             child = child->next;
   12344         } else if (IS_SCHEMA(child, "group")) {
   12345             type->subtypes = (xmlSchemaTypePtr)
   12346 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
   12347 	    /*
   12348 	    * Note that the reference will be resolved in
   12349 	    * xmlSchemaResolveTypeReferences();
   12350 	    */
   12351             child = child->next;
   12352         }
   12353 	/*
   12354 	* Parse attribute decls/refs.
   12355 	*/
   12356         if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
   12357 	    (xmlSchemaItemListPtr *) &(type->attrUses),
   12358 	    XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
   12359 	    return(NULL);
   12360 	/*
   12361 	* Parse attribute wildcard.
   12362 	*/
   12363 	if (IS_SCHEMA(child, "anyAttribute")) {
   12364 	    type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
   12365 	    child = child->next;
   12366 	}
   12367     }
   12368     if (child != NULL) {
   12369 	xmlSchemaPContentErr(ctxt,
   12370 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   12371 	    NULL, node, child,
   12372 	    NULL, "(annotation?, (simpleContent | complexContent | "
   12373 	    "((group | all | choice | sequence)?, ((attribute | "
   12374 	    "attributeGroup)*, anyAttribute?))))");
   12375     }
   12376     /*
   12377     * REDEFINE: SPEC src-redefine (5)
   12378     */
   12379     if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
   12380 	xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   12381 	    NULL, node, "This is a redefinition, thus the "
   12382 	    "<complexType> must have a <restriction> or <extension> "
   12383 	    "grand-child", NULL);
   12384     }
   12385     ctxt->ctxtType = ctxtType;
   12386     return (type);
   12387 }
   12388 
   12389 /************************************************************************
   12390  *									*
   12391  *			Validating using Schemas			*
   12392  *									*
   12393  ************************************************************************/
   12394 
   12395 /************************************************************************
   12396  *									*
   12397  *			Reading/Writing Schemas				*
   12398  *									*
   12399  ************************************************************************/
   12400 
   12401 #if 0 /* Will be enabled if it is clear what options are needed. */
   12402 /**
   12403  * xmlSchemaParserCtxtSetOptions:
   12404  * @ctxt:	a schema parser context
   12405  * @options: a combination of xmlSchemaParserOption
   12406  *
   12407  * Sets the options to be used during the parse.
   12408  *
   12409  * Returns 0 in case of success, -1 in case of an
   12410  * API error.
   12411  */
   12412 static int
   12413 xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
   12414 			      int options)
   12415 
   12416 {
   12417     int i;
   12418 
   12419     if (ctxt == NULL)
   12420 	return (-1);
   12421     /*
   12422     * WARNING: Change the start value if adding to the
   12423     * xmlSchemaParseOption.
   12424     */
   12425     for (i = 1; i < (int) sizeof(int) * 8; i++) {
   12426         if (options & 1<<i) {
   12427 	    return (-1);
   12428         }
   12429     }
   12430     ctxt->options = options;
   12431     return (0);
   12432 }
   12433 
   12434 /**
   12435  * xmlSchemaValidCtxtGetOptions:
   12436  * @ctxt: a schema parser context
   12437  *
   12438  * Returns the option combination of the parser context.
   12439  */
   12440 static int
   12441 xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
   12442 
   12443 {
   12444     if (ctxt == NULL)
   12445 	return (-1);
   12446     else
   12447 	return (ctxt->options);
   12448 }
   12449 #endif
   12450 
   12451 /**
   12452  * xmlSchemaNewParserCtxt:
   12453  * @URL:  the location of the schema
   12454  *
   12455  * Create an XML Schemas parse context for that file/resource expected
   12456  * to contain an XML Schemas file.
   12457  *
   12458  * Returns the parser context or NULL in case of error
   12459  */
   12460 xmlSchemaParserCtxtPtr
   12461 xmlSchemaNewParserCtxt(const char *URL)
   12462 {
   12463     xmlSchemaParserCtxtPtr ret;
   12464 
   12465     if (URL == NULL)
   12466         return (NULL);
   12467 
   12468     ret = xmlSchemaParserCtxtCreate();
   12469     if (ret == NULL)
   12470 	return(NULL);
   12471     ret->dict = xmlDictCreate();
   12472     ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
   12473     return (ret);
   12474 }
   12475 
   12476 /**
   12477  * xmlSchemaNewMemParserCtxt:
   12478  * @buffer:  a pointer to a char array containing the schemas
   12479  * @size:  the size of the array
   12480  *
   12481  * Create an XML Schemas parse context for that memory buffer expected
   12482  * to contain an XML Schemas file.
   12483  *
   12484  * Returns the parser context or NULL in case of error
   12485  */
   12486 xmlSchemaParserCtxtPtr
   12487 xmlSchemaNewMemParserCtxt(const char *buffer, int size)
   12488 {
   12489     xmlSchemaParserCtxtPtr ret;
   12490 
   12491     if ((buffer == NULL) || (size <= 0))
   12492         return (NULL);
   12493     ret = xmlSchemaParserCtxtCreate();
   12494     if (ret == NULL)
   12495 	return(NULL);
   12496     ret->buffer = buffer;
   12497     ret->size = size;
   12498     ret->dict = xmlDictCreate();
   12499     return (ret);
   12500 }
   12501 
   12502 /**
   12503  * xmlSchemaNewDocParserCtxt:
   12504  * @doc:  a preparsed document tree
   12505  *
   12506  * Create an XML Schemas parse context for that document.
   12507  * NB. The document may be modified during the parsing process.
   12508  *
   12509  * Returns the parser context or NULL in case of error
   12510  */
   12511 xmlSchemaParserCtxtPtr
   12512 xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
   12513 {
   12514     xmlSchemaParserCtxtPtr ret;
   12515 
   12516     if (doc == NULL)
   12517       return (NULL);
   12518     ret = xmlSchemaParserCtxtCreate();
   12519     if (ret == NULL)
   12520 	return(NULL);
   12521     ret->doc = doc;
   12522     ret->dict = xmlDictCreate();
   12523     /* The application has responsibility for the document */
   12524     ret->preserve = 1;
   12525 
   12526     return (ret);
   12527 }
   12528 
   12529 /**
   12530  * xmlSchemaFreeParserCtxt:
   12531  * @ctxt:  the schema parser context
   12532  *
   12533  * Free the resources associated to the schema parser context
   12534  */
   12535 void
   12536 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
   12537 {
   12538     if (ctxt == NULL)
   12539         return;
   12540     if (ctxt->doc != NULL && !ctxt->preserve)
   12541         xmlFreeDoc(ctxt->doc);
   12542     if (ctxt->vctxt != NULL) {
   12543 	xmlSchemaFreeValidCtxt(ctxt->vctxt);
   12544     }
   12545     if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
   12546 	xmlSchemaConstructionCtxtFree(ctxt->constructor);
   12547 	ctxt->constructor = NULL;
   12548 	ctxt->ownsConstructor = 0;
   12549     }
   12550     if (ctxt->attrProhibs != NULL)
   12551 	xmlSchemaItemListFree(ctxt->attrProhibs);
   12552     xmlDictFree(ctxt->dict);
   12553     xmlFree(ctxt);
   12554 }
   12555 
   12556 /************************************************************************
   12557  *									*
   12558  *			Building the content models			*
   12559  *									*
   12560  ************************************************************************/
   12561 
   12562 /**
   12563  * xmlSchemaBuildContentModelForSubstGroup:
   12564  *
   12565  * Returns 1 if nillable, 0 otherwise
   12566  */
   12567 static int
   12568 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
   12569 	xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
   12570 {
   12571     xmlAutomataStatePtr start, tmp;
   12572     xmlSchemaElementPtr elemDecl, member;
   12573     xmlSchemaSubstGroupPtr substGroup;
   12574     int i;
   12575     int ret = 0;
   12576 
   12577     elemDecl = (xmlSchemaElementPtr) particle->children;
   12578     /*
   12579     * Wrap the substitution group with a CHOICE.
   12580     */
   12581     start = pctxt->state;
   12582     if (end == NULL)
   12583 	end = xmlAutomataNewState(pctxt->am);
   12584     substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
   12585     if (substGroup == NULL) {
   12586 	xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
   12587 	    XML_SCHEMAP_INTERNAL,
   12588 	    "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
   12589 	    "declaration is marked having a subst. group but none "
   12590 	    "available.\n", elemDecl->name, NULL);
   12591 	return(0);
   12592     }
   12593     if (counter >= 0) {
   12594 	/*
   12595 	* NOTE that we put the declaration in, even if it's abstract.
   12596 	* However, an error will be raised during *validation* if an element
   12597 	* information item shall be validated against an abstract element
   12598 	* declaration.
   12599 	*/
   12600 	tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
   12601         xmlAutomataNewTransition2(pctxt->am, tmp, end,
   12602 	            elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12603 	/*
   12604 	* Add subst. group members.
   12605 	*/
   12606 	for (i = 0; i < substGroup->members->nbItems; i++) {
   12607 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
   12608             xmlAutomataNewTransition2(pctxt->am, tmp, end,
   12609 		               member->name, member->targetNamespace, member);
   12610 	}
   12611     } else if (particle->maxOccurs == 1) {
   12612 	/*
   12613 	* NOTE that we put the declaration in, even if it's abstract,
   12614 	*/
   12615 	xmlAutomataNewEpsilon(pctxt->am,
   12616 	    xmlAutomataNewTransition2(pctxt->am,
   12617 	    start, NULL,
   12618 	    elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
   12619 	/*
   12620 	* Add subst. group members.
   12621 	*/
   12622 	for (i = 0; i < substGroup->members->nbItems; i++) {
   12623 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
   12624 	    /*
   12625 	    * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
   12626 	    *  was incorrectly used instead of xmlAutomataNewTransition2()
   12627 	    *  (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
   12628 	    *  section in xmlSchemaBuildAContentModel() ).
   12629 	    * TODO: Check if xmlAutomataNewOnceTrans2() was instead
   12630 	    *  intended for the above "counter" section originally. I.e.,
   12631 	    *  check xs:all with subst-groups.
   12632 	    *
   12633 	    * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
   12634 	    *	               member->name, member->targetNamespace,
   12635 	    *		       1, 1, member);
   12636 	    */
   12637 	    tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
   12638 		member->name, member->targetNamespace, member);
   12639 	    xmlAutomataNewEpsilon(pctxt->am, tmp, end);
   12640 	}
   12641     } else {
   12642 	xmlAutomataStatePtr hop;
   12643 	int maxOccurs = particle->maxOccurs == UNBOUNDED ?
   12644 	    UNBOUNDED : particle->maxOccurs - 1;
   12645 	int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
   12646 
   12647 	counter =
   12648 	    xmlAutomataNewCounter(pctxt->am, minOccurs,
   12649 	    maxOccurs);
   12650 	hop = xmlAutomataNewState(pctxt->am);
   12651 
   12652 	xmlAutomataNewEpsilon(pctxt->am,
   12653 	    xmlAutomataNewTransition2(pctxt->am,
   12654 	    start, NULL,
   12655 	    elemDecl->name, elemDecl->targetNamespace, elemDecl),
   12656 	    hop);
   12657 	/*
   12658 	 * Add subst. group members.
   12659 	 */
   12660 	for (i = 0; i < substGroup->members->nbItems; i++) {
   12661 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
   12662 	    xmlAutomataNewEpsilon(pctxt->am,
   12663 		xmlAutomataNewTransition2(pctxt->am,
   12664 		start, NULL,
   12665 		member->name, member->targetNamespace, member),
   12666 		hop);
   12667 	}
   12668 	xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
   12669 	xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
   12670     }
   12671     if (particle->minOccurs == 0) {
   12672 	xmlAutomataNewEpsilon(pctxt->am, start, end);
   12673         ret = 1;
   12674     }
   12675     pctxt->state = end;
   12676     return(ret);
   12677 }
   12678 
   12679 /**
   12680  * xmlSchemaBuildContentModelForElement:
   12681  *
   12682  * Returns 1 if nillable, 0 otherwise
   12683  */
   12684 static int
   12685 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
   12686 				     xmlSchemaParticlePtr particle)
   12687 {
   12688     int ret = 0;
   12689 
   12690     if (((xmlSchemaElementPtr) particle->children)->flags &
   12691 	XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
   12692 	/*
   12693 	* Substitution groups.
   12694 	*/
   12695 	ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
   12696     } else {
   12697 	xmlSchemaElementPtr elemDecl;
   12698 	xmlAutomataStatePtr start;
   12699 
   12700 	elemDecl = (xmlSchemaElementPtr) particle->children;
   12701 
   12702 	if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
   12703 	    return(0);
   12704 	if (particle->maxOccurs == 1) {
   12705 	    start = ctxt->state;
   12706 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
   12707 		    elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12708 	} else if ((particle->maxOccurs >= UNBOUNDED) &&
   12709 	           (particle->minOccurs < 2)) {
   12710 	    /* Special case. */
   12711 	    start = ctxt->state;
   12712 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
   12713 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12714 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
   12715 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12716 	} else {
   12717 	    int counter;
   12718 	    int maxOccurs = particle->maxOccurs == UNBOUNDED ?
   12719 			    UNBOUNDED : particle->maxOccurs - 1;
   12720 	    int minOccurs = particle->minOccurs < 1 ?
   12721 			    0 : particle->minOccurs - 1;
   12722 
   12723 	    start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
   12724 	    counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
   12725 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
   12726 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12727 	    xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
   12728 	    ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
   12729 		NULL, counter);
   12730 	}
   12731 	if (particle->minOccurs == 0) {
   12732 	    xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
   12733             ret = 1;
   12734         }
   12735     }
   12736     return(ret);
   12737 }
   12738 
   12739 /**
   12740  * xmlSchemaBuildAContentModel:
   12741  * @ctxt:  the schema parser context
   12742  * @particle:  the particle component
   12743  * @name:  the complex type's name whose content is being built
   12744  *
   12745  * Create the automaton for the {content type} of a complex type.
   12746  *
   12747  * Returns 1 if the content is nillable, 0 otherwise
   12748  */
   12749 static int
   12750 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
   12751 			    xmlSchemaParticlePtr particle)
   12752 {
   12753     int ret = 0, tmp2;
   12754 
   12755     if (particle == NULL) {
   12756 	PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
   12757 	return(1);
   12758     }
   12759     if (particle->children == NULL) {
   12760 	/*
   12761 	* Just return in this case. A missing "term" of the particle
   12762 	* might arise due to an invalid "term" component.
   12763 	*/
   12764 	return(1);
   12765     }
   12766 
   12767     switch (particle->children->type) {
   12768 	case XML_SCHEMA_TYPE_ANY: {
   12769 	    xmlAutomataStatePtr start, end;
   12770 	    xmlSchemaWildcardPtr wild;
   12771 	    xmlSchemaWildcardNsPtr ns;
   12772 
   12773 	    wild = (xmlSchemaWildcardPtr) particle->children;
   12774 
   12775 	    start = pctxt->state;
   12776 	    end = xmlAutomataNewState(pctxt->am);
   12777 
   12778 	    if (particle->maxOccurs == 1) {
   12779 		if (wild->any == 1) {
   12780 		    /*
   12781 		    * We need to add both transitions:
   12782 		    *
   12783 		    * 1. the {"*", "*"} for elements in a namespace.
   12784 		    */
   12785 		    pctxt->state =
   12786 			xmlAutomataNewTransition2(pctxt->am,
   12787 			start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
   12788 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
   12789 		    /*
   12790 		    * 2. the {"*"} for elements in no namespace.
   12791 		    */
   12792 		    pctxt->state =
   12793 			xmlAutomataNewTransition2(pctxt->am,
   12794 			start, NULL, BAD_CAST "*", NULL, wild);
   12795 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
   12796 
   12797 		} else if (wild->nsSet != NULL) {
   12798 		    ns = wild->nsSet;
   12799 		    do {
   12800 			pctxt->state = start;
   12801 			pctxt->state = xmlAutomataNewTransition2(pctxt->am,
   12802 			    pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
   12803 			xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
   12804 			ns = ns->next;
   12805 		    } while (ns != NULL);
   12806 
   12807 		} else if (wild->negNsSet != NULL) {
   12808 		    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
   12809 			start, end, BAD_CAST "*", wild->negNsSet->value,
   12810 			wild);
   12811 		}
   12812 	    } else {
   12813 		int counter;
   12814 		xmlAutomataStatePtr hop;
   12815 		int maxOccurs =
   12816 		    particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
   12817                                            particle->maxOccurs - 1;
   12818 		int minOccurs =
   12819 		    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
   12820 
   12821 		counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
   12822 		hop = xmlAutomataNewState(pctxt->am);
   12823 		if (wild->any == 1) {
   12824 		    pctxt->state =
   12825 			xmlAutomataNewTransition2(pctxt->am,
   12826 			start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
   12827 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
   12828 		    pctxt->state =
   12829 			xmlAutomataNewTransition2(pctxt->am,
   12830 			start, NULL, BAD_CAST "*", NULL, wild);
   12831 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
   12832 		} else if (wild->nsSet != NULL) {
   12833 		    ns = wild->nsSet;
   12834 		    do {
   12835 			pctxt->state =
   12836 			    xmlAutomataNewTransition2(pctxt->am,
   12837 				start, NULL, BAD_CAST "*", ns->value, wild);
   12838 			xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
   12839 			ns = ns->next;
   12840 		    } while (ns != NULL);
   12841 
   12842 		} else if (wild->negNsSet != NULL) {
   12843 		    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
   12844 			start, hop, BAD_CAST "*", wild->negNsSet->value,
   12845 			wild);
   12846 		}
   12847 		xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
   12848 		xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
   12849 	    }
   12850 	    if (particle->minOccurs == 0) {
   12851 		xmlAutomataNewEpsilon(pctxt->am, start, end);
   12852                 ret = 1;
   12853 	    }
   12854 	    pctxt->state = end;
   12855             break;
   12856 	}
   12857         case XML_SCHEMA_TYPE_ELEMENT:
   12858 	    ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
   12859 	    break;
   12860         case XML_SCHEMA_TYPE_SEQUENCE:{
   12861             xmlSchemaTreeItemPtr sub;
   12862 
   12863             ret = 1;
   12864             /*
   12865              * If max and min occurances are default (1) then
   12866              * simply iterate over the particles of the <sequence>.
   12867              */
   12868             if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
   12869                 sub = particle->children->children;
   12870 
   12871                 while (sub != NULL) {
   12872                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12873                                         (xmlSchemaParticlePtr) sub);
   12874                     if (tmp2 != 1) ret = 0;
   12875                     sub = sub->next;
   12876                 }
   12877             } else {
   12878                 xmlAutomataStatePtr oldstate = pctxt->state;
   12879 
   12880                 if (particle->maxOccurs >= UNBOUNDED) {
   12881                     if (particle->minOccurs > 1) {
   12882                         xmlAutomataStatePtr tmp;
   12883                         int counter;
   12884 
   12885                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12886                             oldstate, NULL);
   12887                         oldstate = pctxt->state;
   12888 
   12889                         counter = xmlAutomataNewCounter(pctxt->am,
   12890                             particle->minOccurs - 1, UNBOUNDED);
   12891 
   12892                         sub = particle->children->children;
   12893                         while (sub != NULL) {
   12894                             tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12895                                             (xmlSchemaParticlePtr) sub);
   12896                             if (tmp2 != 1) ret = 0;
   12897                             sub = sub->next;
   12898                         }
   12899                         tmp = pctxt->state;
   12900                         xmlAutomataNewCountedTrans(pctxt->am, tmp,
   12901                                                    oldstate, counter);
   12902                         pctxt->state =
   12903                             xmlAutomataNewCounterTrans(pctxt->am, tmp,
   12904                                                        NULL, counter);
   12905                         if (ret == 1)
   12906                             xmlAutomataNewEpsilon(pctxt->am,
   12907                                                 oldstate, pctxt->state);
   12908 
   12909                     } else {
   12910                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12911                             oldstate, NULL);
   12912                         oldstate = pctxt->state;
   12913 
   12914                         sub = particle->children->children;
   12915                         while (sub != NULL) {
   12916                             tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12917                                         (xmlSchemaParticlePtr) sub);
   12918                             if (tmp2 != 1) ret = 0;
   12919                             sub = sub->next;
   12920                         }
   12921                         xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
   12922                                               oldstate);
   12923                         /*
   12924                          * epsilon needed to block previous trans from
   12925                          * being allowed to enter back from another
   12926                          * construct
   12927                          */
   12928                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12929                                             pctxt->state, NULL);
   12930                         if (particle->minOccurs == 0) {
   12931                             xmlAutomataNewEpsilon(pctxt->am,
   12932                                 oldstate, pctxt->state);
   12933                             ret = 1;
   12934                         }
   12935                     }
   12936                 } else if ((particle->maxOccurs > 1)
   12937                            || (particle->minOccurs > 1)) {
   12938                     xmlAutomataStatePtr tmp;
   12939                     int counter;
   12940 
   12941                     pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12942                         oldstate, NULL);
   12943                     oldstate = pctxt->state;
   12944 
   12945                     counter = xmlAutomataNewCounter(pctxt->am,
   12946                         particle->minOccurs - 1,
   12947                         particle->maxOccurs - 1);
   12948 
   12949                     sub = particle->children->children;
   12950                     while (sub != NULL) {
   12951                         tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12952                                         (xmlSchemaParticlePtr) sub);
   12953                         if (tmp2 != 1) ret = 0;
   12954                         sub = sub->next;
   12955                     }
   12956                     tmp = pctxt->state;
   12957                     xmlAutomataNewCountedTrans(pctxt->am,
   12958                         tmp, oldstate, counter);
   12959                     pctxt->state =
   12960                         xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
   12961                                                    counter);
   12962                     if ((particle->minOccurs == 0) || (ret == 1)) {
   12963                         xmlAutomataNewEpsilon(pctxt->am,
   12964                                             oldstate, pctxt->state);
   12965                         ret = 1;
   12966                     }
   12967                 } else {
   12968                     sub = particle->children->children;
   12969                     while (sub != NULL) {
   12970                         tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12971                                         (xmlSchemaParticlePtr) sub);
   12972                         if (tmp2 != 1) ret = 0;
   12973                         sub = sub->next;
   12974                     }
   12975 
   12976 		    /*
   12977 		     * epsilon needed to block previous trans from
   12978 		     * being allowed to enter back from another
   12979 		     * construct
   12980 		     */
   12981 		    pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12982 					pctxt->state, NULL);
   12983 
   12984                     if (particle->minOccurs == 0) {
   12985                         xmlAutomataNewEpsilon(pctxt->am, oldstate,
   12986                                               pctxt->state);
   12987                         ret = 1;
   12988                     }
   12989                 }
   12990             }
   12991             break;
   12992         }
   12993         case XML_SCHEMA_TYPE_CHOICE:{
   12994             xmlSchemaTreeItemPtr sub;
   12995             xmlAutomataStatePtr start, end;
   12996 
   12997             ret = 0;
   12998             start = pctxt->state;
   12999             end = xmlAutomataNewState(pctxt->am);
   13000 
   13001             /*
   13002              * iterate over the subtypes and remerge the end with an
   13003              * epsilon transition
   13004              */
   13005             if (particle->maxOccurs == 1) {
   13006                 sub = particle->children->children;
   13007                 while (sub != NULL) {
   13008                     pctxt->state = start;
   13009                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
   13010                                         (xmlSchemaParticlePtr) sub);
   13011                     if (tmp2 == 1) ret = 1;
   13012                     xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
   13013                     sub = sub->next;
   13014                 }
   13015             } else {
   13016                 int counter;
   13017                 xmlAutomataStatePtr hop, base;
   13018                 int maxOccurs = particle->maxOccurs == UNBOUNDED ?
   13019                     UNBOUNDED : particle->maxOccurs - 1;
   13020                 int minOccurs =
   13021                     particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
   13022 
   13023                 /*
   13024                  * use a counter to keep track of the number of transtions
   13025                  * which went through the choice.
   13026                  */
   13027                 counter =
   13028                     xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
   13029                 hop = xmlAutomataNewState(pctxt->am);
   13030                 base = xmlAutomataNewState(pctxt->am);
   13031 
   13032                 sub = particle->children->children;
   13033                 while (sub != NULL) {
   13034                     pctxt->state = base;
   13035                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
   13036                                         (xmlSchemaParticlePtr) sub);
   13037                     if (tmp2 == 1) ret = 1;
   13038                     xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
   13039                     sub = sub->next;
   13040                 }
   13041                 xmlAutomataNewEpsilon(pctxt->am, start, base);
   13042                 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
   13043                 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
   13044                 if (ret == 1)
   13045                     xmlAutomataNewEpsilon(pctxt->am, base, end);
   13046             }
   13047             if (particle->minOccurs == 0) {
   13048                 xmlAutomataNewEpsilon(pctxt->am, start, end);
   13049                 ret = 1;
   13050             }
   13051             pctxt->state = end;
   13052             break;
   13053         }
   13054         case XML_SCHEMA_TYPE_ALL:{
   13055             xmlAutomataStatePtr start, tmp;
   13056             xmlSchemaParticlePtr sub;
   13057             xmlSchemaElementPtr elemDecl;
   13058 
   13059             ret = 1;
   13060 
   13061             sub = (xmlSchemaParticlePtr) particle->children->children;
   13062             if (sub == NULL)
   13063                 break;
   13064 
   13065             ret = 0;
   13066 
   13067             start = pctxt->state;
   13068             tmp = xmlAutomataNewState(pctxt->am);
   13069             xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
   13070             pctxt->state = tmp;
   13071             while (sub != NULL) {
   13072                 pctxt->state = tmp;
   13073 
   13074                 elemDecl = (xmlSchemaElementPtr) sub->children;
   13075                 if (elemDecl == NULL) {
   13076                     PERROR_INT("xmlSchemaBuildAContentModel",
   13077                         "<element> particle has no term");
   13078                     return(ret);
   13079                 };
   13080                 /*
   13081                 * NOTE: The {max occurs} of all the particles in the
   13082                 * {particles} of the group must be 0 or 1; this is
   13083                 * already ensured during the parse of the content of
   13084                 * <all>.
   13085                 */
   13086                 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
   13087                     int counter;
   13088 
   13089                     /*
   13090                      * This is an abstract group, we need to share
   13091                      * the same counter for all the element transitions
   13092                      * derived from the group
   13093                      */
   13094                     counter = xmlAutomataNewCounter(pctxt->am,
   13095                                        sub->minOccurs, sub->maxOccurs);
   13096                     xmlSchemaBuildContentModelForSubstGroup(pctxt,
   13097                                        sub, counter, pctxt->state);
   13098                 } else {
   13099                     if ((sub->minOccurs == 1) &&
   13100                         (sub->maxOccurs == 1)) {
   13101                         xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
   13102                                                 pctxt->state,
   13103                                                 elemDecl->name,
   13104                                                 elemDecl->targetNamespace,
   13105                                                 1, 1, elemDecl);
   13106                     } else if ((sub->minOccurs == 0) &&
   13107                         (sub->maxOccurs == 1)) {
   13108 
   13109                         xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
   13110                                                  pctxt->state,
   13111                                                  elemDecl->name,
   13112                                                  elemDecl->targetNamespace,
   13113                                                  0,
   13114                                                  1,
   13115                                                  elemDecl);
   13116                     }
   13117                 }
   13118                 sub = (xmlSchemaParticlePtr) sub->next;
   13119             }
   13120             pctxt->state =
   13121                 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
   13122             if (particle->minOccurs == 0) {
   13123                 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
   13124                 ret = 1;
   13125             }
   13126             break;
   13127         }
   13128 	case XML_SCHEMA_TYPE_GROUP:
   13129 	    /*
   13130 	    * If we hit a model group definition, then this means that
   13131 	    * it was empty, thus was not substituted for the containing
   13132 	    * model group. Just do nothing in this case.
   13133 	    * TODO: But the group should be substituted and not occur at
   13134 	    * all in the content model at this point. Fix this.
   13135 	    */
   13136             ret = 1;
   13137 	    break;
   13138         default:
   13139 	    xmlSchemaInternalErr2(ACTXT_CAST pctxt,
   13140 		"xmlSchemaBuildAContentModel",
   13141 		"found unexpected term of type '%s' in content model",
   13142 		WXS_ITEM_TYPE_NAME(particle->children), NULL);
   13143             return(ret);
   13144     }
   13145     return(ret);
   13146 }
   13147 
   13148 /**
   13149  * xmlSchemaBuildContentModel:
   13150  * @ctxt:  the schema parser context
   13151  * @type:  the complex type definition
   13152  * @name:  the element name
   13153  *
   13154  * Builds the content model of the complex type.
   13155  */
   13156 static void
   13157 xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
   13158 			   xmlSchemaParserCtxtPtr ctxt)
   13159 {
   13160     if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
   13161 	(type->contModel != NULL) ||
   13162 	((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
   13163 	(type->contentType != XML_SCHEMA_CONTENT_MIXED)))
   13164 	return;
   13165 
   13166 #ifdef DEBUG_CONTENT
   13167     xmlGenericError(xmlGenericErrorContext,
   13168                     "Building content model for %s\n", name);
   13169 #endif
   13170     ctxt->am = NULL;
   13171     ctxt->am = xmlNewAutomata();
   13172     if (ctxt->am == NULL) {
   13173         xmlGenericError(xmlGenericErrorContext,
   13174 	    "Cannot create automata for complex type %s\n", type->name);
   13175         return;
   13176     }
   13177     ctxt->state = xmlAutomataGetInitState(ctxt->am);
   13178     /*
   13179     * Build the automaton.
   13180     */
   13181     xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
   13182     xmlAutomataSetFinalState(ctxt->am, ctxt->state);
   13183     type->contModel = xmlAutomataCompile(ctxt->am);
   13184     if (type->contModel == NULL) {
   13185         xmlSchemaPCustomErr(ctxt,
   13186 	    XML_SCHEMAP_INTERNAL,
   13187 	    WXS_BASIC_CAST type, type->node,
   13188 	    "Failed to compile the content model", NULL);
   13189     } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
   13190         xmlSchemaPCustomErr(ctxt,
   13191 	    XML_SCHEMAP_NOT_DETERMINISTIC,
   13192 	    /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
   13193 	    WXS_BASIC_CAST type, type->node,
   13194 	    "The content model is not determinist", NULL);
   13195     } else {
   13196 #ifdef DEBUG_CONTENT_REGEXP
   13197         xmlGenericError(xmlGenericErrorContext,
   13198                         "Content model of %s:\n", type->name);
   13199         xmlRegexpPrint(stderr, type->contModel);
   13200 #endif
   13201     }
   13202     ctxt->state = NULL;
   13203     xmlFreeAutomata(ctxt->am);
   13204     ctxt->am = NULL;
   13205 }
   13206 
   13207 /**
   13208  * xmlSchemaResolveElementReferences:
   13209  * @elem:  the schema element context
   13210  * @ctxt:  the schema parser context
   13211  *
   13212  * Resolves the references of an element declaration
   13213  * or particle, which has an element declaration as it's
   13214  * term.
   13215  */
   13216 static void
   13217 xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
   13218 				  xmlSchemaParserCtxtPtr ctxt)
   13219 {
   13220     if ((ctxt == NULL) || (elemDecl == NULL) ||
   13221 	((elemDecl != NULL) &&
   13222 	(elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
   13223         return;
   13224     elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
   13225 
   13226     if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
   13227 	xmlSchemaTypePtr type;
   13228 
   13229 	/* (type definition) ... otherwise the type definition `resolved`
   13230 	* to by the `actual value` of the type [attribute] ...
   13231 	*/
   13232 	type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
   13233 	    elemDecl->namedTypeNs);
   13234 	if (type == NULL) {
   13235 	    xmlSchemaPResCompAttrErr(ctxt,
   13236 		XML_SCHEMAP_SRC_RESOLVE,
   13237 		WXS_BASIC_CAST elemDecl, elemDecl->node,
   13238 		"type", elemDecl->namedType, elemDecl->namedTypeNs,
   13239 		XML_SCHEMA_TYPE_BASIC, "type definition");
   13240 	} else
   13241 	    elemDecl->subtypes = type;
   13242     }
   13243     if (elemDecl->substGroup != NULL) {
   13244 	xmlSchemaElementPtr substHead;
   13245 
   13246 	/*
   13247 	* FIXME TODO: Do we need a new field in _xmlSchemaElement for
   13248 	* substitutionGroup?
   13249 	*/
   13250 	substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
   13251 	    elemDecl->substGroupNs);
   13252 	if (substHead == NULL) {
   13253 	    xmlSchemaPResCompAttrErr(ctxt,
   13254 		XML_SCHEMAP_SRC_RESOLVE,
   13255 		WXS_BASIC_CAST elemDecl, NULL,
   13256 		"substitutionGroup", elemDecl->substGroup,
   13257 		elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
   13258 	} else {
   13259 	    xmlSchemaResolveElementReferences(substHead, ctxt);
   13260 	    /*
   13261 	    * Set the "substitution group affiliation".
   13262 	    * NOTE that now we use the "refDecl" field for this.
   13263 	    */
   13264 	    WXS_SUBST_HEAD(elemDecl) = substHead;
   13265 	    /*
   13266 	    * The type definitions is set to:
   13267 	    * SPEC "...the {type definition} of the element
   13268 	    * declaration `resolved` to by the `actual value`
   13269 	    * of the substitutionGroup [attribute], if present"
   13270 	    */
   13271 	    if (elemDecl->subtypes == NULL)
   13272 		elemDecl->subtypes = substHead->subtypes;
   13273 	}
   13274     }
   13275     /*
   13276     * SPEC "The definition of anyType serves as the default type definition
   13277     * for element declarations whose XML representation does not specify one."
   13278     */
   13279     if ((elemDecl->subtypes == NULL) &&
   13280 	(elemDecl->namedType == NULL) &&
   13281 	(elemDecl->substGroup == NULL))
   13282 	elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
   13283 }
   13284 
   13285 /**
   13286  * xmlSchemaResolveUnionMemberTypes:
   13287  * @ctxt:  the schema parser context
   13288  * @type:  the schema simple type definition
   13289  *
   13290  * Checks and builds the "member type definitions" property of the union
   13291  * simple type. This handles part (1), part (2) is done in
   13292  * xmlSchemaFinishMemberTypeDefinitionsProperty()
   13293  *
   13294  * Returns -1 in case of an internal error, 0 otherwise.
   13295  */
   13296 static int
   13297 xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
   13298 				 xmlSchemaTypePtr type)
   13299 {
   13300 
   13301     xmlSchemaTypeLinkPtr link, lastLink, newLink;
   13302     xmlSchemaTypePtr memberType;
   13303 
   13304     /*
   13305     * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
   13306     * define the explicit members as the type definitions `resolved`
   13307     * to by the items in the `actual value` of the memberTypes [attribute],
   13308     * if any, followed by the type definitions corresponding to the
   13309     * <simpleType>s among the [children] of <union>, if any."
   13310     */
   13311     /*
   13312     * Resolve references.
   13313     */
   13314     link = type->memberTypes;
   13315     lastLink = NULL;
   13316     while (link != NULL) {
   13317 	const xmlChar *name, *nsName;
   13318 
   13319 	name = ((xmlSchemaQNameRefPtr) link->type)->name;
   13320 	nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
   13321 
   13322 	memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
   13323 	if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
   13324 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
   13325 		WXS_BASIC_CAST type, type->node, "memberTypes",
   13326 		name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
   13327 	    /*
   13328 	    * Remove the member type link.
   13329 	    */
   13330 	    if (lastLink == NULL)
   13331 		type->memberTypes = link->next;
   13332 	    else
   13333 		lastLink->next = link->next;
   13334 	    newLink = link;
   13335 	    link = link->next;
   13336 	    xmlFree(newLink);
   13337 	} else {
   13338 	    link->type = memberType;
   13339 	    lastLink = link;
   13340 	    link = link->next;
   13341 	}
   13342     }
   13343     /*
   13344     * Add local simple types,
   13345     */
   13346     memberType = type->subtypes;
   13347     while (memberType != NULL) {
   13348 	link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
   13349 	if (link == NULL) {
   13350 	    xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
   13351 	    return (-1);
   13352 	}
   13353 	link->type = memberType;
   13354 	link->next = NULL;
   13355 	if (lastLink == NULL)
   13356 	    type->memberTypes = link;
   13357 	else
   13358 	    lastLink->next = link;
   13359 	lastLink = link;
   13360 	memberType = memberType->next;
   13361     }
   13362     return (0);
   13363 }
   13364 
   13365 /**
   13366  * xmlSchemaIsDerivedFromBuiltInType:
   13367  * @ctxt:  the schema parser context
   13368  * @type:  the type definition
   13369  * @valType: the value type
   13370  *
   13371  *
   13372  * Returns 1 if the type has the given value type, or
   13373  * is derived from such a type.
   13374  */
   13375 static int
   13376 xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
   13377 {
   13378     if (type == NULL)
   13379 	return (0);
   13380     if (WXS_IS_COMPLEX(type))
   13381 	return (0);
   13382     if (type->type == XML_SCHEMA_TYPE_BASIC) {
   13383 	if (type->builtInType == valType)
   13384 	    return(1);
   13385 	if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
   13386 	    (type->builtInType == XML_SCHEMAS_ANYTYPE))
   13387 	    return (0);
   13388 	return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
   13389     }
   13390     return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
   13391 }
   13392 
   13393 #if 0
   13394 /**
   13395  * xmlSchemaIsDerivedFromBuiltInType:
   13396  * @ctxt:  the schema parser context
   13397  * @type:  the type definition
   13398  * @valType: the value type
   13399  *
   13400  *
   13401  * Returns 1 if the type has the given value type, or
   13402  * is derived from such a type.
   13403  */
   13404 static int
   13405 xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
   13406 {
   13407     if (type == NULL)
   13408 	return (0);
   13409     if (WXS_IS_COMPLEX(type))
   13410 	return (0);
   13411     if (type->type == XML_SCHEMA_TYPE_BASIC) {
   13412 	if (type->builtInType == valType)
   13413 	    return(1);
   13414 	return (0);
   13415     } else
   13416 	return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
   13417 
   13418     return (0);
   13419 }
   13420 
   13421 static xmlSchemaTypePtr
   13422 xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
   13423 {
   13424     if (type == NULL)
   13425 	return (NULL);
   13426     if (WXS_IS_COMPLEX(type))
   13427 	return (NULL);
   13428     if (type->type == XML_SCHEMA_TYPE_BASIC)
   13429 	return(type);
   13430     return(xmlSchemaQueryBuiltInType(type->subtypes));
   13431 }
   13432 #endif
   13433 
   13434 /**
   13435  * xmlSchemaGetPrimitiveType:
   13436  * @type:  the simpleType definition
   13437  *
   13438  * Returns the primitive type of the given type or
   13439  * NULL in case of error.
   13440  */
   13441 static xmlSchemaTypePtr
   13442 xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
   13443 {
   13444 
   13445     while (type != NULL) {
   13446 	/*
   13447 	* Note that anySimpleType is actually not a primitive type
   13448 	* but we need that here.
   13449 	*/
   13450 	if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
   13451 	   (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
   13452 	    return (type);
   13453 	type = type->baseType;
   13454     }
   13455 
   13456     return (NULL);
   13457 }
   13458 
   13459 #if 0
   13460 /**
   13461  * xmlSchemaGetBuiltInTypeAncestor:
   13462  * @type:  the simpleType definition
   13463  *
   13464  * Returns the primitive type of the given type or
   13465  * NULL in case of error.
   13466  */
   13467 static xmlSchemaTypePtr
   13468 xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
   13469 {
   13470     if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
   13471 	return (0);
   13472     while (type != NULL) {
   13473 	if (type->type == XML_SCHEMA_TYPE_BASIC)
   13474 	    return (type);
   13475 	type = type->baseType;
   13476     }
   13477 
   13478     return (NULL);
   13479 }
   13480 #endif
   13481 
   13482 /**
   13483  * xmlSchemaCloneWildcardNsConstraints:
   13484  * @ctxt:  the schema parser context
   13485  * @dest:  the destination wildcard
   13486  * @source: the source wildcard
   13487  *
   13488  * Clones the namespace constraints of source
   13489  * and assignes them to dest.
   13490  * Returns -1 on internal error, 0 otherwise.
   13491  */
   13492 static int
   13493 xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
   13494 				    xmlSchemaWildcardPtr dest,
   13495 				    xmlSchemaWildcardPtr source)
   13496 {
   13497     xmlSchemaWildcardNsPtr cur, tmp, last;
   13498 
   13499     if ((source == NULL) || (dest == NULL))
   13500 	return(-1);
   13501     dest->any = source->any;
   13502     cur = source->nsSet;
   13503     last = NULL;
   13504     while (cur != NULL) {
   13505 	tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
   13506 	if (tmp == NULL)
   13507 	    return(-1);
   13508 	tmp->value = cur->value;
   13509 	if (last == NULL)
   13510 	    dest->nsSet = tmp;
   13511 	else
   13512 	    last->next = tmp;
   13513 	last = tmp;
   13514 	cur = cur->next;
   13515     }
   13516     if (dest->negNsSet != NULL)
   13517 	xmlSchemaFreeWildcardNsSet(dest->negNsSet);
   13518     if (source->negNsSet != NULL) {
   13519 	dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   13520 	if (dest->negNsSet == NULL)
   13521 	    return(-1);
   13522 	dest->negNsSet->value = source->negNsSet->value;
   13523     } else
   13524 	dest->negNsSet = NULL;
   13525     return(0);
   13526 }
   13527 
   13528 /**
   13529  * xmlSchemaUnionWildcards:
   13530  * @ctxt:  the schema parser context
   13531  * @completeWild:  the first wildcard
   13532  * @curWild: the second wildcard
   13533  *
   13534  * Unions the namespace constraints of the given wildcards.
   13535  * @completeWild will hold the resulting union.
   13536  * Returns a positive error code on failure, -1 in case of an
   13537  * internal error, 0 otherwise.
   13538  */
   13539 static int
   13540 xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
   13541 			    xmlSchemaWildcardPtr completeWild,
   13542 			    xmlSchemaWildcardPtr curWild)
   13543 {
   13544     xmlSchemaWildcardNsPtr cur, curB, tmp;
   13545 
   13546     /*
   13547     * 1 If O1 and O2 are the same value, then that value must be the
   13548     * value.
   13549     */
   13550     if ((completeWild->any == curWild->any) &&
   13551 	((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
   13552 	((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
   13553 
   13554 	if ((completeWild->negNsSet == NULL) ||
   13555 	    (completeWild->negNsSet->value == curWild->negNsSet->value)) {
   13556 
   13557 	    if (completeWild->nsSet != NULL) {
   13558 		int found = 0;
   13559 
   13560 		/*
   13561 		* Check equality of sets.
   13562 		*/
   13563 		cur = completeWild->nsSet;
   13564 		while (cur != NULL) {
   13565 		    found = 0;
   13566 		    curB = curWild->nsSet;
   13567 		    while (curB != NULL) {
   13568 			if (cur->value == curB->value) {
   13569 			    found = 1;
   13570 			    break;
   13571 			}
   13572 			curB = curB->next;
   13573 		    }
   13574 		    if (!found)
   13575 			break;
   13576 		    cur = cur->next;
   13577 		}
   13578 		if (found)
   13579 		    return(0);
   13580 	    } else
   13581 		return(0);
   13582 	}
   13583     }
   13584     /*
   13585     * 2 If either O1 or O2 is any, then any must be the value
   13586     */
   13587     if (completeWild->any != curWild->any) {
   13588 	if (completeWild->any == 0) {
   13589 	    completeWild->any = 1;
   13590 	    if (completeWild->nsSet != NULL) {
   13591 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13592 		completeWild->nsSet = NULL;
   13593 	    }
   13594 	    if (completeWild->negNsSet != NULL) {
   13595 		xmlFree(completeWild->negNsSet);
   13596 		completeWild->negNsSet = NULL;
   13597 	    }
   13598 	}
   13599 	return (0);
   13600     }
   13601     /*
   13602     * 3 If both O1 and O2 are sets of (namespace names or `absent`),
   13603     * then the union of those sets must be the value.
   13604     */
   13605     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
   13606 	int found;
   13607 	xmlSchemaWildcardNsPtr start;
   13608 
   13609 	cur = curWild->nsSet;
   13610 	start = completeWild->nsSet;
   13611 	while (cur != NULL) {
   13612 	    found = 0;
   13613 	    curB = start;
   13614 	    while (curB != NULL) {
   13615 		if (cur->value == curB->value) {
   13616 		    found = 1;
   13617 		    break;
   13618 		}
   13619 		curB = curB->next;
   13620 	    }
   13621 	    if (!found) {
   13622 		tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
   13623 		if (tmp == NULL)
   13624 		    return (-1);
   13625 		tmp->value = cur->value;
   13626 		tmp->next = completeWild->nsSet;
   13627 		completeWild->nsSet = tmp;
   13628 	    }
   13629 	    cur = cur->next;
   13630 	}
   13631 
   13632 	return(0);
   13633     }
   13634     /*
   13635     * 4 If the two are negations of different values (namespace names
   13636     * or `absent`), then a pair of not and `absent` must be the value.
   13637     */
   13638     if ((completeWild->negNsSet != NULL) &&
   13639 	(curWild->negNsSet != NULL) &&
   13640 	(completeWild->negNsSet->value != curWild->negNsSet->value)) {
   13641 	completeWild->negNsSet->value = NULL;
   13642 
   13643 	return(0);
   13644     }
   13645     /*
   13646      * 5.
   13647      */
   13648     if (((completeWild->negNsSet != NULL) &&
   13649 	(completeWild->negNsSet->value != NULL) &&
   13650 	(curWild->nsSet != NULL)) ||
   13651 	((curWild->negNsSet != NULL) &&
   13652 	(curWild->negNsSet->value != NULL) &&
   13653 	(completeWild->nsSet != NULL))) {
   13654 
   13655 	int nsFound, absentFound = 0;
   13656 
   13657 	if (completeWild->nsSet != NULL) {
   13658 	    cur = completeWild->nsSet;
   13659 	    curB = curWild->negNsSet;
   13660 	} else {
   13661 	    cur = curWild->nsSet;
   13662 	    curB = completeWild->negNsSet;
   13663 	}
   13664 	nsFound = 0;
   13665 	while (cur != NULL) {
   13666 	    if (cur->value == NULL)
   13667 		absentFound = 1;
   13668 	    else if (cur->value == curB->value)
   13669 		nsFound = 1;
   13670 	    if (nsFound && absentFound)
   13671 		break;
   13672 	    cur = cur->next;
   13673 	}
   13674 
   13675 	if (nsFound && absentFound) {
   13676 	    /*
   13677 	    * 5.1 If the set S includes both the negated namespace
   13678 	    * name and `absent`, then any must be the value.
   13679 	    */
   13680 	    completeWild->any = 1;
   13681 	    if (completeWild->nsSet != NULL) {
   13682 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13683 		completeWild->nsSet = NULL;
   13684 	    }
   13685 	    if (completeWild->negNsSet != NULL) {
   13686 		xmlFree(completeWild->negNsSet);
   13687 		completeWild->negNsSet = NULL;
   13688 	    }
   13689 	} else if (nsFound && (!absentFound)) {
   13690 	    /*
   13691 	    * 5.2 If the set S includes the negated namespace name
   13692 	    * but not `absent`, then a pair of not and `absent` must
   13693 	    * be the value.
   13694 	    */
   13695 	    if (completeWild->nsSet != NULL) {
   13696 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13697 		completeWild->nsSet = NULL;
   13698 	    }
   13699 	    if (completeWild->negNsSet == NULL) {
   13700 		completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   13701 		if (completeWild->negNsSet == NULL)
   13702 		    return (-1);
   13703 	    }
   13704 	    completeWild->negNsSet->value = NULL;
   13705 	} else if ((!nsFound) && absentFound) {
   13706 	    /*
   13707 	    * 5.3 If the set S includes `absent` but not the negated
   13708 	    * namespace name, then the union is not expressible.
   13709 	    */
   13710 	    xmlSchemaPErr(ctxt, completeWild->node,
   13711 		XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
   13712 		"The union of the wilcard is not expressible.\n",
   13713 		NULL, NULL);
   13714 	    return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
   13715 	} else if ((!nsFound) && (!absentFound)) {
   13716 	    /*
   13717 	    * 5.4 If the set S does not include either the negated namespace
   13718 	    * name or `absent`, then whichever of O1 or O2 is a pair of not
   13719 	    * and a namespace name must be the value.
   13720 	    */
   13721 	    if (completeWild->negNsSet == NULL) {
   13722 		if (completeWild->nsSet != NULL) {
   13723 		    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13724 		    completeWild->nsSet = NULL;
   13725 		}
   13726 		completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   13727 		if (completeWild->negNsSet == NULL)
   13728 		    return (-1);
   13729 		completeWild->negNsSet->value = curWild->negNsSet->value;
   13730 	    }
   13731 	}
   13732 	return (0);
   13733     }
   13734     /*
   13735      * 6.
   13736      */
   13737     if (((completeWild->negNsSet != NULL) &&
   13738 	(completeWild->negNsSet->value == NULL) &&
   13739 	(curWild->nsSet != NULL)) ||
   13740 	((curWild->negNsSet != NULL) &&
   13741 	(curWild->negNsSet->value == NULL) &&
   13742 	(completeWild->nsSet != NULL))) {
   13743 
   13744 	if (completeWild->nsSet != NULL) {
   13745 	    cur = completeWild->nsSet;
   13746 	} else {
   13747 	    cur = curWild->nsSet;
   13748 	}
   13749 	while (cur != NULL) {
   13750 	    if (cur->value == NULL) {
   13751 		/*
   13752 		* 6.1 If the set S includes `absent`, then any must be the
   13753 		* value.
   13754 		*/
   13755 		completeWild->any = 1;
   13756 		if (completeWild->nsSet != NULL) {
   13757 		    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13758 		    completeWild->nsSet = NULL;
   13759 		}
   13760 		if (completeWild->negNsSet != NULL) {
   13761 		    xmlFree(completeWild->negNsSet);
   13762 		    completeWild->negNsSet = NULL;
   13763 		}
   13764 		return (0);
   13765 	    }
   13766 	    cur = cur->next;
   13767 	}
   13768 	if (completeWild->negNsSet == NULL) {
   13769 	    /*
   13770 	    * 6.2 If the set S does not include `absent`, then a pair of not
   13771 	    * and `absent` must be the value.
   13772 	    */
   13773 	    if (completeWild->nsSet != NULL) {
   13774 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13775 		completeWild->nsSet = NULL;
   13776 	    }
   13777 	    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   13778 	    if (completeWild->negNsSet == NULL)
   13779 		return (-1);
   13780 	    completeWild->negNsSet->value = NULL;
   13781 	}
   13782 	return (0);
   13783     }
   13784     return (0);
   13785 
   13786 }
   13787 
   13788 /**
   13789  * xmlSchemaIntersectWildcards:
   13790  * @ctxt:  the schema parser context
   13791  * @completeWild:  the first wildcard
   13792  * @curWild: the second wildcard
   13793  *
   13794  * Intersects the namespace constraints of the given wildcards.
   13795  * @completeWild will hold the resulting intersection.
   13796  * Returns a positive error code on failure, -1 in case of an
   13797  * internal error, 0 otherwise.
   13798  */
   13799 static int
   13800 xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
   13801 			    xmlSchemaWildcardPtr completeWild,
   13802 			    xmlSchemaWildcardPtr curWild)
   13803 {
   13804     xmlSchemaWildcardNsPtr cur, curB, prev,  tmp;
   13805 
   13806     /*
   13807     * 1 If O1 and O2 are the same value, then that value must be the
   13808     * value.
   13809     */
   13810     if ((completeWild->any == curWild->any) &&
   13811 	((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
   13812 	((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
   13813 
   13814 	if ((completeWild->negNsSet == NULL) ||
   13815 	    (completeWild->negNsSet->value == curWild->negNsSet->value)) {
   13816 
   13817 	    if (completeWild->nsSet != NULL) {
   13818 		int found = 0;
   13819 
   13820 		/*
   13821 		* Check equality of sets.
   13822 		*/
   13823 		cur = completeWild->nsSet;
   13824 		while (cur != NULL) {
   13825 		    found = 0;
   13826 		    curB = curWild->nsSet;
   13827 		    while (curB != NULL) {
   13828 			if (cur->value == curB->value) {
   13829 			    found = 1;
   13830 			    break;
   13831 			}
   13832 			curB = curB->next;
   13833 		    }
   13834 		    if (!found)
   13835 			break;
   13836 		    cur = cur->next;
   13837 		}
   13838 		if (found)
   13839 		    return(0);
   13840 	    } else
   13841 		return(0);
   13842 	}
   13843     }
   13844     /*
   13845     * 2 If either O1 or O2 is any, then the other must be the value.
   13846     */
   13847     if ((completeWild->any != curWild->any) && (completeWild->any)) {
   13848 	if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
   13849 	    return(-1);
   13850 	return(0);
   13851     }
   13852     /*
   13853     * 3 If either O1 or O2 is a pair of not and a value (a namespace
   13854     * name or `absent`) and the other is a set of (namespace names or
   13855     * `absent`), then that set, minus the negated value if it was in
   13856     * the set, minus `absent` if it was in the set, must be the value.
   13857     */
   13858     if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
   13859 	((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
   13860 	const xmlChar *neg;
   13861 
   13862 	if (completeWild->nsSet == NULL) {
   13863 	    neg = completeWild->negNsSet->value;
   13864 	    if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
   13865 		return(-1);
   13866 	} else
   13867 	    neg = curWild->negNsSet->value;
   13868 	/*
   13869 	* Remove absent and negated.
   13870 	*/
   13871 	prev = NULL;
   13872 	cur = completeWild->nsSet;
   13873 	while (cur != NULL) {
   13874 	    if (cur->value == NULL) {
   13875 		if (prev == NULL)
   13876 		    completeWild->nsSet = cur->next;
   13877 		else
   13878 		    prev->next = cur->next;
   13879 		xmlFree(cur);
   13880 		break;
   13881 	    }
   13882 	    prev = cur;
   13883 	    cur = cur->next;
   13884 	}
   13885 	if (neg != NULL) {
   13886 	    prev = NULL;
   13887 	    cur = completeWild->nsSet;
   13888 	    while (cur != NULL) {
   13889 		if (cur->value == neg) {
   13890 		    if (prev == NULL)
   13891 			completeWild->nsSet = cur->next;
   13892 		    else
   13893 			prev->next = cur->next;
   13894 		    xmlFree(cur);
   13895 		    break;
   13896 		}
   13897 		prev = cur;
   13898 		cur = cur->next;
   13899 	    }
   13900 	}
   13901 
   13902 	return(0);
   13903     }
   13904     /*
   13905     * 4 If both O1 and O2 are sets of (namespace names or `absent`),
   13906     * then the intersection of those sets must be the value.
   13907     */
   13908     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
   13909 	int found;
   13910 
   13911 	cur = completeWild->nsSet;
   13912 	prev = NULL;
   13913 	while (cur != NULL) {
   13914 	    found = 0;
   13915 	    curB = curWild->nsSet;
   13916 	    while (curB != NULL) {
   13917 		if (cur->value == curB->value) {
   13918 		    found = 1;
   13919 		    break;
   13920 		}
   13921 		curB = curB->next;
   13922 	    }
   13923 	    if (!found) {
   13924 		if (prev == NULL)
   13925 		    completeWild->nsSet = cur->next;
   13926 		else
   13927 		    prev->next = cur->next;
   13928 		tmp = cur->next;
   13929 		xmlFree(cur);
   13930 		cur = tmp;
   13931 		continue;
   13932 	    }
   13933 	    prev = cur;
   13934 	    cur = cur->next;
   13935 	}
   13936 
   13937 	return(0);
   13938     }
   13939     /* 5 If the two are negations of different namespace names,
   13940     * then the intersection is not expressible
   13941     */
   13942     if ((completeWild->negNsSet != NULL) &&
   13943 	(curWild->negNsSet != NULL) &&
   13944 	(completeWild->negNsSet->value != curWild->negNsSet->value) &&
   13945 	(completeWild->negNsSet->value != NULL) &&
   13946 	(curWild->negNsSet->value != NULL)) {
   13947 
   13948 	xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
   13949 	    "The intersection of the wilcard is not expressible.\n",
   13950 	    NULL, NULL);
   13951 	return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
   13952     }
   13953     /*
   13954     * 6 If the one is a negation of a namespace name and the other
   13955     * is a negation of `absent`, then the one which is the negation
   13956     * of a namespace name must be the value.
   13957     */
   13958     if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
   13959 	(completeWild->negNsSet->value != curWild->negNsSet->value) &&
   13960 	(completeWild->negNsSet->value == NULL)) {
   13961 	completeWild->negNsSet->value =  curWild->negNsSet->value;
   13962     }
   13963     return(0);
   13964 }
   13965 
   13966 /**
   13967  * xmlSchemaIsWildcardNsConstraintSubset:
   13968  * @ctxt:  the schema parser context
   13969  * @sub:  the first wildcard
   13970  * @super: the second wildcard
   13971  *
   13972  * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
   13973  *
   13974  * Returns 0 if the namespace constraint of @sub is an intensional
   13975  * subset of @super, 1 otherwise.
   13976  */
   13977 static int
   13978 xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
   13979 			  xmlSchemaWildcardPtr super)
   13980 {
   13981     /*
   13982     * 1 super must be any.
   13983     */
   13984     if (super->any)
   13985 	return (0);
   13986     /*
   13987     * 2.1 sub must be a pair of not and a namespace name or `absent`.
   13988     * 2.2 super must be a pair of not and the same value.
   13989     */
   13990     if ((sub->negNsSet != NULL) &&
   13991 	(super->negNsSet != NULL) &&
   13992 	(sub->negNsSet->value == super->negNsSet->value))
   13993 	return (0);
   13994     /*
   13995     * 3.1 sub must be a set whose members are either namespace names or `absent`.
   13996     */
   13997     if (sub->nsSet != NULL) {
   13998 	/*
   13999 	* 3.2.1 super must be the same set or a superset thereof.
   14000 	*/
   14001 	if (super->nsSet != NULL) {
   14002 	    xmlSchemaWildcardNsPtr cur, curB;
   14003 	    int found = 0;
   14004 
   14005 	    cur = sub->nsSet;
   14006 	    while (cur != NULL) {
   14007 		found = 0;
   14008 		curB = super->nsSet;
   14009 		while (curB != NULL) {
   14010 		    if (cur->value == curB->value) {
   14011 			found = 1;
   14012 			break;
   14013 		    }
   14014 		    curB = curB->next;
   14015 		}
   14016 		if (!found)
   14017 		    return (1);
   14018 		cur = cur->next;
   14019 	    }
   14020 	    if (found)
   14021 		return (0);
   14022 	} else if (super->negNsSet != NULL) {
   14023 	    xmlSchemaWildcardNsPtr cur;
   14024 	    /*
   14025 	    * 3.2.2 super must be a pair of not and a namespace name or
   14026 	    * `absent` and that value must not be in sub's set.
   14027 	    */
   14028 	    cur = sub->nsSet;
   14029 	    while (cur != NULL) {
   14030 		if (cur->value == super->negNsSet->value)
   14031 		    return (1);
   14032 		cur = cur->next;
   14033 	    }
   14034 	    return (0);
   14035 	}
   14036     }
   14037     return (1);
   14038 }
   14039 
   14040 static int
   14041 xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
   14042 				     int *fixed,
   14043 				     const xmlChar **value,
   14044 				     xmlSchemaValPtr *val)
   14045 {
   14046     *fixed = 0;
   14047     *value = NULL;
   14048     if (val != 0)
   14049 	*val = NULL;
   14050 
   14051     if (attruse->defValue != NULL) {
   14052 	*value = attruse->defValue;
   14053 	if (val != NULL)
   14054 	    *val = attruse->defVal;
   14055 	if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
   14056 	    *fixed = 1;
   14057 	return(1);
   14058     } else if ((attruse->attrDecl != NULL) &&
   14059 	(attruse->attrDecl->defValue != NULL)) {
   14060 	*value = attruse->attrDecl->defValue;
   14061 	if (val != NULL)
   14062 	    *val = attruse->attrDecl->defVal;
   14063 	if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
   14064 	    *fixed = 1;
   14065 	return(1);
   14066     }
   14067     return(0);
   14068 }
   14069 /**
   14070  * xmlSchemaCheckCVCWildcardNamespace:
   14071  * @wild:  the wildcard
   14072  * @ns:  the namespace
   14073  *
   14074  * Validation Rule: Wildcard allows Namespace Name
   14075  * (cvc-wildcard-namespace)
   14076  *
   14077  * Returns 0 if the given namespace matches the wildcard,
   14078  * 1 otherwise and -1 on API errors.
   14079  */
   14080 static int
   14081 xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
   14082 				   const xmlChar* ns)
   14083 {
   14084     if (wild == NULL)
   14085 	return(-1);
   14086 
   14087     if (wild->any)
   14088 	return(0);
   14089     else if (wild->nsSet != NULL) {
   14090 	xmlSchemaWildcardNsPtr cur;
   14091 
   14092 	cur = wild->nsSet;
   14093 	while (cur != NULL) {
   14094 	    if (xmlStrEqual(cur->value, ns))
   14095 		return(0);
   14096 	    cur = cur->next;
   14097 	}
   14098     } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
   14099 	(!xmlStrEqual(wild->negNsSet->value, ns)))
   14100 	return(0);
   14101 
   14102     return(1);
   14103 }
   14104 
   14105 #define XML_SCHEMA_ACTION_DERIVE 0
   14106 #define XML_SCHEMA_ACTION_REDEFINE 1
   14107 
   14108 #define WXS_ACTION_STR(a) \
   14109 ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
   14110 
   14111 /*
   14112 * Schema Component Constraint:
   14113 *   Derivation Valid (Restriction, Complex)
   14114 *   derivation-ok-restriction (2) - (4)
   14115 *
   14116 * ATTENTION:
   14117 * In XML Schema 1.1 this will be:
   14118 * Validation Rule:
   14119 *     Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
   14120 *
   14121 */
   14122 static int
   14123 xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
   14124 				       int action,
   14125 				       xmlSchemaBasicItemPtr item,
   14126 				       xmlSchemaBasicItemPtr baseItem,
   14127 				       xmlSchemaItemListPtr uses,
   14128 				       xmlSchemaItemListPtr baseUses,
   14129 				       xmlSchemaWildcardPtr wild,
   14130 				       xmlSchemaWildcardPtr baseWild)
   14131 {
   14132     xmlSchemaAttributeUsePtr cur = NULL, bcur;
   14133     int i, j, found; /* err = 0; */
   14134     const xmlChar *bEffValue;
   14135     int effFixed;
   14136 
   14137     if (uses != NULL) {
   14138 	for (i = 0; i < uses->nbItems; i++) {
   14139 	    cur = uses->items[i];
   14140 	    found = 0;
   14141 	    if (baseUses == NULL)
   14142 		goto not_found;
   14143 	    for (j = 0; j < baseUses->nbItems; j++) {
   14144 		bcur = baseUses->items[j];
   14145 		if ((WXS_ATTRUSE_DECL_NAME(cur) ==
   14146 			WXS_ATTRUSE_DECL_NAME(bcur)) &&
   14147 		    (WXS_ATTRUSE_DECL_TNS(cur) ==
   14148 			WXS_ATTRUSE_DECL_TNS(bcur)))
   14149 		{
   14150 		    /*
   14151 		    * (2.1) "If there is an attribute use in the {attribute
   14152 		    * uses} of the {base type definition} (call this B) whose
   14153 		    * {attribute declaration} has the same {name} and {target
   14154 		    * namespace}, then  all of the following must be true:"
   14155 		    */
   14156 		    found = 1;
   14157 
   14158 		    if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
   14159 			(bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
   14160 		    {
   14161 			xmlChar *str = NULL;
   14162 			/*
   14163 			* (2.1.1) "one of the following must be true:"
   14164 			* (2.1.1.1) "B's {required} is false."
   14165 			* (2.1.1.2) "R's {required} is true."
   14166 			*/
   14167 			xmlSchemaPAttrUseErr4(pctxt,
   14168 			    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
   14169 			    WXS_ITEM_NODE(item), item, cur,
   14170 			    "The 'optional' attribute use is inconsistent "
   14171 			    "with the corresponding 'required' attribute use of "
   14172 			    "the %s %s",
   14173 			    WXS_ACTION_STR(action),
   14174 			    xmlSchemaGetComponentDesignation(&str, baseItem),
   14175 			    NULL, NULL);
   14176 			FREE_AND_NULL(str);
   14177 			/* err = pctxt->err; */
   14178 		    } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
   14179 			WXS_ATTRUSE_TYPEDEF(cur),
   14180 			WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
   14181 		    {
   14182 			xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
   14183 
   14184 			/*
   14185 			* SPEC (2.1.2) "R's {attribute declaration}'s
   14186 			* {type definition} must be validly derived from
   14187 			* B's {type definition} given the empty set as
   14188 			* defined in Type Derivation OK (Simple) ($3.14.6)."
   14189 			*/
   14190 			xmlSchemaPAttrUseErr4(pctxt,
   14191 			    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
   14192 			    WXS_ITEM_NODE(item), item, cur,
   14193 			    "The attribute declaration's %s "
   14194 			    "is not validly derived from "
   14195 			    "the corresponding %s of the "
   14196 			    "attribute declaration in the %s %s",
   14197 			    xmlSchemaGetComponentDesignation(&strA,
   14198 				WXS_ATTRUSE_TYPEDEF(cur)),
   14199 			    xmlSchemaGetComponentDesignation(&strB,
   14200 				WXS_ATTRUSE_TYPEDEF(bcur)),
   14201 			    WXS_ACTION_STR(action),
   14202 			    xmlSchemaGetComponentDesignation(&strC, baseItem));
   14203 			    /* xmlSchemaGetComponentDesignation(&str, baseItem), */
   14204 			FREE_AND_NULL(strA);
   14205 			FREE_AND_NULL(strB);
   14206 			FREE_AND_NULL(strC);
   14207 			/* err = pctxt->err; */
   14208 		    } else {
   14209 			/*
   14210 			* 2.1.3 [Definition:]  Let the effective value
   14211 			* constraint of an attribute use be its {value
   14212 			* constraint}, if present, otherwise its {attribute
   14213 			* declaration}'s {value constraint} .
   14214 			*/
   14215 			xmlSchemaGetEffectiveValueConstraint(bcur,
   14216 			    &effFixed, &bEffValue, NULL);
   14217 			/*
   14218 			* 2.1.3 ... one of the following must be true
   14219 			*
   14220 			* 2.1.3.1 B's `effective value constraint` is
   14221 			* `absent` or default.
   14222 			*/
   14223 			if ((bEffValue != NULL) &&
   14224 			    (effFixed == 1)) {
   14225 			    const xmlChar *rEffValue = NULL;
   14226 
   14227 			    xmlSchemaGetEffectiveValueConstraint(bcur,
   14228 				&effFixed, &rEffValue, NULL);
   14229 			    /*
   14230 			    * 2.1.3.2 R's `effective value constraint` is
   14231 			    * fixed with the same string as B's.
   14232 			    * MAYBE TODO: Compare the computed values.
   14233 			    *       Hmm, it says "same string" so
   14234 			    *       string-equality might really be sufficient.
   14235 			    */
   14236 			    if ((effFixed == 0) ||
   14237 				(! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
   14238 			    {
   14239 				xmlChar *str = NULL;
   14240 
   14241 				xmlSchemaPAttrUseErr4(pctxt,
   14242 				    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
   14243 				    WXS_ITEM_NODE(item), item, cur,
   14244 				    "The effective value constraint of the "
   14245 				    "attribute use is inconsistent with "
   14246 				    "its correspondent in the %s %s",
   14247 				    WXS_ACTION_STR(action),
   14248 				    xmlSchemaGetComponentDesignation(&str,
   14249 					baseItem),
   14250 				    NULL, NULL);
   14251 				FREE_AND_NULL(str);
   14252 				/* err = pctxt->err; */
   14253 			    }
   14254 			}
   14255 		    }
   14256 		    break;
   14257 		}
   14258 	    }
   14259 not_found:
   14260 	    if (!found) {
   14261 		/*
   14262 		* (2.2) "otherwise the {base type definition} must have an
   14263 		* {attribute wildcard} and the {target namespace} of the
   14264 		* R's {attribute declaration} must be `valid` with respect
   14265 		* to that wildcard, as defined in Wildcard allows Namespace
   14266 		* Name ($3.10.4)."
   14267 		*/
   14268 		if ((baseWild == NULL) ||
   14269 		    (xmlSchemaCheckCVCWildcardNamespace(baseWild,
   14270 		    (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
   14271 		{
   14272 		    xmlChar *str = NULL;
   14273 
   14274 		    xmlSchemaPAttrUseErr4(pctxt,
   14275 			XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
   14276 			WXS_ITEM_NODE(item), item, cur,
   14277 			"Neither a matching attribute use, "
   14278 			"nor a matching wildcard exists in the %s %s",
   14279 			WXS_ACTION_STR(action),
   14280 			xmlSchemaGetComponentDesignation(&str, baseItem),
   14281 			NULL, NULL);
   14282 		    FREE_AND_NULL(str);
   14283 		    /* err = pctxt->err; */
   14284 		}
   14285 	    }
   14286 	}
   14287     }
   14288     /*
   14289     * SPEC derivation-ok-restriction (3):
   14290     * (3) "For each attribute use in the {attribute uses} of the {base type
   14291     * definition} whose {required} is true, there must be an attribute
   14292     * use with an {attribute declaration} with the same {name} and
   14293     * {target namespace} as its {attribute declaration} in the {attribute
   14294     * uses} of the complex type definition itself whose {required} is true.
   14295     */
   14296     if (baseUses != NULL) {
   14297 	for (j = 0; j < baseUses->nbItems; j++) {
   14298 	    bcur = baseUses->items[j];
   14299 	    if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
   14300 		continue;
   14301 	    found = 0;
   14302 	    if (uses != NULL) {
   14303 		for (i = 0; i < uses->nbItems; i++) {
   14304 		    cur = uses->items[i];
   14305 		    if ((WXS_ATTRUSE_DECL_NAME(cur) ==
   14306 			WXS_ATTRUSE_DECL_NAME(bcur)) &&
   14307 			(WXS_ATTRUSE_DECL_TNS(cur) ==
   14308 			WXS_ATTRUSE_DECL_TNS(bcur))) {
   14309 			found = 1;
   14310 			break;
   14311 		    }
   14312 		}
   14313 	    }
   14314 	    if (!found) {
   14315 		xmlChar *strA = NULL, *strB = NULL;
   14316 
   14317 		xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   14318 		    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
   14319 		    NULL, item,
   14320 		    "A matching attribute use for the "
   14321 		    "'required' %s of the %s %s is missing",
   14322 		    xmlSchemaGetComponentDesignation(&strA, bcur),
   14323 		    WXS_ACTION_STR(action),
   14324 		    xmlSchemaGetComponentDesignation(&strB, baseItem),
   14325 		    NULL);
   14326 		FREE_AND_NULL(strA);
   14327 		FREE_AND_NULL(strB);
   14328 	    }
   14329 	}
   14330     }
   14331     /*
   14332     * derivation-ok-restriction (4)
   14333     */
   14334     if (wild != NULL) {
   14335 	/*
   14336 	* (4) "If there is an {attribute wildcard}, all of the
   14337 	* following must be true:"
   14338 	*/
   14339 	if (baseWild == NULL) {
   14340 	    xmlChar *str = NULL;
   14341 
   14342 	    /*
   14343 	    * (4.1) "The {base type definition} must also have one."
   14344 	    */
   14345 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   14346 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
   14347 		NULL, item,
   14348 		"The %s has an attribute wildcard, "
   14349 		"but the %s %s '%s' does not have one",
   14350 		WXS_ITEM_TYPE_NAME(item),
   14351 		WXS_ACTION_STR(action),
   14352 		WXS_ITEM_TYPE_NAME(baseItem),
   14353 		xmlSchemaGetComponentQName(&str, baseItem));
   14354 	    FREE_AND_NULL(str);
   14355 	    return(pctxt->err);
   14356 	} else if ((baseWild->any == 0) &&
   14357 		xmlSchemaCheckCOSNSSubset(wild, baseWild))
   14358 	{
   14359 	    xmlChar *str = NULL;
   14360 	    /*
   14361 	    * (4.2) "The complex type definition's {attribute wildcard}'s
   14362 	    * {namespace constraint} must be a subset of the {base type
   14363 	    * definition}'s {attribute wildcard}'s {namespace constraint},
   14364 	    * as defined by Wildcard Subset ($3.10.6)."
   14365 	    */
   14366 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   14367 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
   14368 		NULL, item,
   14369 		"The attribute wildcard is not a valid "
   14370 		"subset of the wildcard in the %s %s '%s'",
   14371 		WXS_ACTION_STR(action),
   14372 		WXS_ITEM_TYPE_NAME(baseItem),
   14373 		xmlSchemaGetComponentQName(&str, baseItem),
   14374 		NULL);
   14375 	    FREE_AND_NULL(str);
   14376 	    return(pctxt->err);
   14377 	}
   14378 	/* 4.3 Unless the {base type definition} is the `ur-type
   14379 	* definition`, the complex type definition's {attribute
   14380 	* wildcard}'s {process contents} must be identical to or
   14381 	* stronger than the {base type definition}'s {attribute
   14382 	* wildcard}'s {process contents}, where strict is stronger
   14383 	* than lax is stronger than skip.
   14384 	*/
   14385 	if ((! WXS_IS_ANYTYPE(baseItem)) &&
   14386 	    (wild->processContents < baseWild->processContents)) {
   14387 	    xmlChar *str = NULL;
   14388 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   14389 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
   14390 		NULL, baseItem,
   14391 		"The {process contents} of the attribute wildcard is "
   14392 		"weaker than the one in the %s %s '%s'",
   14393 		WXS_ACTION_STR(action),
   14394 		WXS_ITEM_TYPE_NAME(baseItem),
   14395 		xmlSchemaGetComponentQName(&str, baseItem),
   14396 		NULL);
   14397 	    FREE_AND_NULL(str)
   14398 		return(pctxt->err);
   14399 	}
   14400     }
   14401     return(0);
   14402 }
   14403 
   14404 
   14405 static int
   14406 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
   14407 				  xmlSchemaBasicItemPtr item,
   14408 				  xmlSchemaWildcardPtr *completeWild,
   14409 				  xmlSchemaItemListPtr list,
   14410 				  xmlSchemaItemListPtr prohibs);
   14411 /**
   14412  * xmlSchemaFixupTypeAttributeUses:
   14413  * @ctxt:  the schema parser context
   14414  * @type:  the complex type definition
   14415  *
   14416  *
   14417  * Builds the wildcard and the attribute uses on the given complex type.
   14418  * Returns -1 if an internal error occurs, 0 otherwise.
   14419  *
   14420  * ATTENTION TODO: Experimantally this uses pointer comparisons for
   14421  * strings, so recheck this if we start to hardcode some schemata, since
   14422  * they might not be in the same dict.
   14423  * NOTE: It is allowed to "extend" the xs:anyType type.
   14424  */
   14425 static int
   14426 xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
   14427 				  xmlSchemaTypePtr type)
   14428 {
   14429     xmlSchemaTypePtr baseType = NULL;
   14430     xmlSchemaAttributeUsePtr use;
   14431     xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
   14432 
   14433     if (type->baseType == NULL) {
   14434 	PERROR_INT("xmlSchemaFixupTypeAttributeUses",
   14435 	    "no base type");
   14436         return (-1);
   14437     }
   14438     baseType = type->baseType;
   14439     if (WXS_IS_TYPE_NOT_FIXED(baseType))
   14440 	if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
   14441 	    return(-1);
   14442 
   14443     uses = type->attrUses;
   14444     baseUses = baseType->attrUses;
   14445     /*
   14446     * Expand attribute group references. And build the 'complete'
   14447     * wildcard, i.e. intersect multiple wildcards.
   14448     * Move attribute prohibitions into a separate list.
   14449     */
   14450     if (uses != NULL) {
   14451 	if (WXS_IS_RESTRICTION(type)) {
   14452 	    /*
   14453 	    * This one will transfer all attr. prohibitions
   14454 	    * into pctxt->attrProhibs.
   14455 	    */
   14456 	    if (xmlSchemaExpandAttributeGroupRefs(pctxt,
   14457 		WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
   14458 		pctxt->attrProhibs) == -1)
   14459 	    {
   14460 		PERROR_INT("xmlSchemaFixupTypeAttributeUses",
   14461 		"failed to expand attributes");
   14462 	    }
   14463 	    if (pctxt->attrProhibs->nbItems != 0)
   14464 		prohibs = pctxt->attrProhibs;
   14465 	} else {
   14466 	    if (xmlSchemaExpandAttributeGroupRefs(pctxt,
   14467 		WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
   14468 		NULL) == -1)
   14469 	    {
   14470 		PERROR_INT("xmlSchemaFixupTypeAttributeUses",
   14471 		"failed to expand attributes");
   14472 	    }
   14473 	}
   14474     }
   14475     /*
   14476     * Inherit the attribute uses of the base type.
   14477     */
   14478     if (baseUses != NULL) {
   14479 	int i, j;
   14480 	xmlSchemaAttributeUseProhibPtr pro;
   14481 
   14482 	if (WXS_IS_RESTRICTION(type)) {
   14483 	    int usesCount;
   14484 	    xmlSchemaAttributeUsePtr tmp;
   14485 
   14486 	    if (uses != NULL)
   14487 		usesCount = uses->nbItems;
   14488 	    else
   14489 		usesCount = 0;
   14490 
   14491 	    /* Restriction. */
   14492 	    for (i = 0; i < baseUses->nbItems; i++) {
   14493 		use = baseUses->items[i];
   14494 		if (prohibs) {
   14495 		    /*
   14496 		    * Filter out prohibited uses.
   14497 		    */
   14498 		    for (j = 0; j < prohibs->nbItems; j++) {
   14499 			pro = prohibs->items[j];
   14500 			if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
   14501 			    (WXS_ATTRUSE_DECL_TNS(use) ==
   14502 				pro->targetNamespace))
   14503 			{
   14504 			    goto inherit_next;
   14505 			}
   14506 		    }
   14507 		}
   14508 		if (usesCount) {
   14509 		    /*
   14510 		    * Filter out existing uses.
   14511 		    */
   14512 		    for (j = 0; j < usesCount; j++) {
   14513 			tmp = uses->items[j];
   14514 			if ((WXS_ATTRUSE_DECL_NAME(use) ==
   14515 				WXS_ATTRUSE_DECL_NAME(tmp)) &&
   14516 			    (WXS_ATTRUSE_DECL_TNS(use) ==
   14517 				WXS_ATTRUSE_DECL_TNS(tmp)))
   14518 			{
   14519 			    goto inherit_next;
   14520 			}
   14521 		    }
   14522 		}
   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, 2, use);
   14530 inherit_next: {}
   14531 	    }
   14532 	} else {
   14533 	    /* Extension. */
   14534 	    for (i = 0; i < baseUses->nbItems; i++) {
   14535 		use = baseUses->items[i];
   14536 		if (uses == NULL) {
   14537 		    type->attrUses = xmlSchemaItemListCreate();
   14538 		    if (type->attrUses == NULL)
   14539 			goto exit_failure;
   14540 		    uses = type->attrUses;
   14541 		}
   14542 		xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
   14543 	    }
   14544 	}
   14545     }
   14546     /*
   14547     * Shrink attr. uses.
   14548     */
   14549     if (uses) {
   14550 	if (uses->nbItems == 0) {
   14551 	    xmlSchemaItemListFree(uses);
   14552 	    type->attrUses = NULL;
   14553 	}
   14554 	/*
   14555 	* TODO: We could shrink the size of the array
   14556 	* to fit the actual number of items.
   14557 	*/
   14558     }
   14559     /*
   14560     * Compute the complete wildcard.
   14561     */
   14562     if (WXS_IS_EXTENSION(type)) {
   14563 	if (baseType->attributeWildcard != NULL) {
   14564 	    /*
   14565 	    * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
   14566 	    * the appropriate case among the following:"
   14567 	    */
   14568 	    if (type->attributeWildcard != NULL) {
   14569 		/*
   14570 		* Union the complete wildcard with the base wildcard.
   14571 		* SPEC {attribute wildcard}
   14572 		* (3.2.2.1.2) "otherwise a wildcard whose {process contents}
   14573 		* and {annotation} are those of the `complete wildcard`,
   14574 		* and whose {namespace constraint} is the intensional union
   14575 		* of the {namespace constraint} of the `complete wildcard`
   14576 		* and of the `base wildcard`, as defined in Attribute
   14577 		* Wildcard Union ($3.10.6)."
   14578 		*/
   14579 		if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
   14580 		    baseType->attributeWildcard) == -1)
   14581 		    goto exit_failure;
   14582 	    } else {
   14583 		/*
   14584 		* (3.2.2.1.1) "If the `complete wildcard` is `absent`,
   14585 		* then the `base wildcard`."
   14586 		*/
   14587 		type->attributeWildcard = baseType->attributeWildcard;
   14588 	    }
   14589 	} else {
   14590 	    /*
   14591 	    * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
   14592 	    * `complete wildcard`"
   14593 	    * NOOP
   14594 	    */
   14595 	}
   14596     } else {
   14597 	/*
   14598 	* SPEC {attribute wildcard}
   14599 	* (3.1) "If the <restriction> alternative is chosen, then the
   14600 	* `complete wildcard`;"
   14601 	* NOOP
   14602 	*/
   14603     }
   14604 
   14605     return (0);
   14606 
   14607 exit_failure:
   14608     return(-1);
   14609 }
   14610 
   14611 /**
   14612  * xmlSchemaTypeFinalContains:
   14613  * @schema:  the schema
   14614  * @type:  the type definition
   14615  * @final: the final
   14616  *
   14617  * Evaluates if a type definition contains the given "final".
   14618  * This does take "finalDefault" into account as well.
   14619  *
   14620  * Returns 1 if the type does containt the given "final",
   14621  * 0 otherwise.
   14622  */
   14623 static int
   14624 xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
   14625 {
   14626     if (type == NULL)
   14627 	return (0);
   14628     if (type->flags & final)
   14629 	return (1);
   14630     else
   14631 	return (0);
   14632 }
   14633 
   14634 /**
   14635  * xmlSchemaGetUnionSimpleTypeMemberTypes:
   14636  * @type:  the Union Simple Type
   14637  *
   14638  * Returns a list of member types of @type if existing,
   14639  * returns NULL otherwise.
   14640  */
   14641 static xmlSchemaTypeLinkPtr
   14642 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
   14643 {
   14644     while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
   14645 	if (type->memberTypes != NULL)
   14646 	    return (type->memberTypes);
   14647 	else
   14648 	    type = type->baseType;
   14649     }
   14650     return (NULL);
   14651 }
   14652 
   14653 /**
   14654  * xmlSchemaGetParticleTotalRangeMin:
   14655  * @particle: the particle
   14656  *
   14657  * Schema Component Constraint: Effective Total Range
   14658  * (all and sequence) + (choice)
   14659  *
   14660  * Returns the minimun Effective Total Range.
   14661  */
   14662 static int
   14663 xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
   14664 {
   14665     if ((particle->children == NULL) ||
   14666 	(particle->minOccurs == 0))
   14667 	return (0);
   14668     if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
   14669 	int min = -1, cur;
   14670 	xmlSchemaParticlePtr part =
   14671 	    (xmlSchemaParticlePtr) particle->children->children;
   14672 
   14673 	if (part == NULL)
   14674 	    return (0);
   14675 	while (part != NULL) {
   14676 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
   14677 		(part->children->type == XML_SCHEMA_TYPE_ANY))
   14678 		cur = part->minOccurs;
   14679 	    else
   14680 		cur = xmlSchemaGetParticleTotalRangeMin(part);
   14681 	    if (cur == 0)
   14682 		return (0);
   14683 	    if ((min > cur) || (min == -1))
   14684 		min = cur;
   14685 	    part = (xmlSchemaParticlePtr) part->next;
   14686 	}
   14687 	return (particle->minOccurs * min);
   14688     } else {
   14689 	/* <all> and <sequence> */
   14690 	int sum = 0;
   14691 	xmlSchemaParticlePtr part =
   14692 	    (xmlSchemaParticlePtr) particle->children->children;
   14693 
   14694 	if (part == NULL)
   14695 	    return (0);
   14696 	do {
   14697 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
   14698 		(part->children->type == XML_SCHEMA_TYPE_ANY))
   14699 		sum += part->minOccurs;
   14700 	    else
   14701 		sum += xmlSchemaGetParticleTotalRangeMin(part);
   14702 	    part = (xmlSchemaParticlePtr) part->next;
   14703 	} while (part != NULL);
   14704 	return (particle->minOccurs * sum);
   14705     }
   14706 }
   14707 
   14708 #if 0
   14709 /**
   14710  * xmlSchemaGetParticleTotalRangeMax:
   14711  * @particle: the particle
   14712  *
   14713  * Schema Component Constraint: Effective Total Range
   14714  * (all and sequence) + (choice)
   14715  *
   14716  * Returns the maximum Effective Total Range.
   14717  */
   14718 static int
   14719 xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
   14720 {
   14721     if ((particle->children == NULL) ||
   14722 	(particle->children->children == NULL))
   14723 	return (0);
   14724     if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
   14725 	int max = -1, cur;
   14726 	xmlSchemaParticlePtr part =
   14727 	    (xmlSchemaParticlePtr) particle->children->children;
   14728 
   14729 	for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
   14730 	    if (part->children == NULL)
   14731 		continue;
   14732 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
   14733 		(part->children->type == XML_SCHEMA_TYPE_ANY))
   14734 		cur = part->maxOccurs;
   14735 	    else
   14736 		cur = xmlSchemaGetParticleTotalRangeMax(part);
   14737 	    if (cur == UNBOUNDED)
   14738 		return (UNBOUNDED);
   14739 	    if ((max < cur) || (max == -1))
   14740 		max = cur;
   14741 	}
   14742 	/* TODO: Handle overflows? */
   14743 	return (particle->maxOccurs * max);
   14744     } else {
   14745 	/* <all> and <sequence> */
   14746 	int sum = 0, cur;
   14747 	xmlSchemaParticlePtr part =
   14748 	    (xmlSchemaParticlePtr) particle->children->children;
   14749 
   14750 	for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
   14751 	    if (part->children == NULL)
   14752 		continue;
   14753 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
   14754 		(part->children->type == XML_SCHEMA_TYPE_ANY))
   14755 		cur = part->maxOccurs;
   14756 	    else
   14757 		cur = xmlSchemaGetParticleTotalRangeMax(part);
   14758 	    if (cur == UNBOUNDED)
   14759 		return (UNBOUNDED);
   14760 	    if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
   14761 		return (UNBOUNDED);
   14762 	    sum += cur;
   14763 	}
   14764 	/* TODO: Handle overflows? */
   14765 	return (particle->maxOccurs * sum);
   14766     }
   14767 }
   14768 #endif
   14769 
   14770 /**
   14771  * xmlSchemaIsParticleEmptiable:
   14772  * @particle: the particle
   14773  *
   14774  * Schema Component Constraint: Particle Emptiable
   14775  * Checks whether the given particle is emptiable.
   14776  *
   14777  * Returns 1 if emptiable, 0 otherwise.
   14778  */
   14779 static int
   14780 xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
   14781 {
   14782     /*
   14783     * SPEC (1) "Its {min occurs} is 0."
   14784     */
   14785     if ((particle == NULL) || (particle->minOccurs == 0) ||
   14786 	(particle->children == NULL))
   14787 	return (1);
   14788     /*
   14789     * SPEC (2) "Its {term} is a group and the minimum part of the
   14790     * effective total range of that group, [...] is 0."
   14791     */
   14792     if (WXS_IS_MODEL_GROUP(particle->children)) {
   14793 	if (xmlSchemaGetParticleTotalRangeMin(particle) == 0)
   14794 	    return (1);
   14795     }
   14796     return (0);
   14797 }
   14798 
   14799 /**
   14800  * xmlSchemaCheckCOSSTDerivedOK:
   14801  * @actxt: a context
   14802  * @type:  the derived simple type definition
   14803  * @baseType:  the base type definition
   14804  * @subset: the subset of ('restriction', ect.)
   14805  *
   14806  * Schema Component Constraint:
   14807  * Type Derivation OK (Simple) (cos-st-derived-OK)
   14808  *
   14809  * Checks wheter @type can be validly
   14810  * derived from @baseType.
   14811  *
   14812  * Returns 0 on success, an positive error code otherwise.
   14813  */
   14814 static int
   14815 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
   14816 			     xmlSchemaTypePtr type,
   14817 			     xmlSchemaTypePtr baseType,
   14818 			     int subset)
   14819 {
   14820     /*
   14821     * 1 They are the same type definition.
   14822     * TODO: The identy check might have to be more complex than this.
   14823     */
   14824     if (type == baseType)
   14825 	return (0);
   14826     /*
   14827     * 2.1 restriction is not in the subset, or in the {final}
   14828     * of its own {base type definition};
   14829     *
   14830     * NOTE that this will be used also via "xsi:type".
   14831     *
   14832     * TODO: Revise this, it looks strange. How can the "type"
   14833     * not be fixed or *in* fixing?
   14834     */
   14835     if (WXS_IS_TYPE_NOT_FIXED(type))
   14836 	if (xmlSchemaTypeFixup(type, actxt) == -1)
   14837 	    return(-1);
   14838     if (WXS_IS_TYPE_NOT_FIXED(baseType))
   14839 	if (xmlSchemaTypeFixup(baseType, actxt) == -1)
   14840 	    return(-1);
   14841     if ((subset & SUBSET_RESTRICTION) ||
   14842 	(xmlSchemaTypeFinalContains(type->baseType,
   14843 	    XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
   14844 	return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
   14845     }
   14846     /* 2.2 */
   14847     if (type->baseType == baseType) {
   14848 	/*
   14849 	* 2.2.1 D's `base type definition` is B.
   14850 	*/
   14851 	return (0);
   14852     }
   14853     /*
   14854     * 2.2.2 D's `base type definition` is not the `ur-type definition`
   14855     * and is validly derived from B given the subset, as defined by this
   14856     * constraint.
   14857     */
   14858     if ((! WXS_IS_ANYTYPE(type->baseType)) &&
   14859 	(xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
   14860 	    baseType, subset) == 0)) {
   14861 	return (0);
   14862     }
   14863     /*
   14864     * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
   14865     * definition`.
   14866     */
   14867     if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
   14868 	(WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
   14869 	return (0);
   14870     }
   14871     /*
   14872     * 2.2.4 B's {variety} is union and D is validly derived from a type
   14873     * definition in B's {member type definitions} given the subset, as
   14874     * defined by this constraint.
   14875     *
   14876     * NOTE: This seems not to involve built-in types, since there is no
   14877     * built-in Union Simple Type.
   14878     */
   14879     if (WXS_IS_UNION(baseType)) {
   14880 	xmlSchemaTypeLinkPtr cur;
   14881 
   14882 	cur = baseType->memberTypes;
   14883 	while (cur != NULL) {
   14884 	    if (WXS_IS_TYPE_NOT_FIXED(cur->type))
   14885 		if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
   14886 		    return(-1);
   14887 	    if (xmlSchemaCheckCOSSTDerivedOK(actxt,
   14888 		    type, cur->type, subset) == 0)
   14889 	    {
   14890 		/*
   14891 		* It just has to be validly derived from at least one
   14892 		* member-type.
   14893 		*/
   14894 		return (0);
   14895 	    }
   14896 	    cur = cur->next;
   14897 	}
   14898     }
   14899     return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
   14900 }
   14901 
   14902 /**
   14903  * xmlSchemaCheckTypeDefCircularInternal:
   14904  * @pctxt:  the schema parser context
   14905  * @ctxtType:  the type definition
   14906  * @ancestor: an ancestor of @ctxtType
   14907  *
   14908  * Checks st-props-correct (2) + ct-props-correct (3).
   14909  * Circular type definitions are not allowed.
   14910  *
   14911  * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
   14912  * circular, 0 otherwise.
   14913  */
   14914 static int
   14915 xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
   14916 			   xmlSchemaTypePtr ctxtType,
   14917 			   xmlSchemaTypePtr ancestor)
   14918 {
   14919     int ret;
   14920 
   14921     if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
   14922 	return (0);
   14923 
   14924     if (ctxtType == ancestor) {
   14925 	xmlSchemaPCustomErr(pctxt,
   14926 	    XML_SCHEMAP_ST_PROPS_CORRECT_2,
   14927 	    WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
   14928 	    "The definition is circular", NULL);
   14929 	return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
   14930     }
   14931     if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
   14932 	/*
   14933 	* Avoid inifinite recursion on circular types not yet checked.
   14934 	*/
   14935 	return (0);
   14936     }
   14937     ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
   14938     ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
   14939 	ancestor->baseType);
   14940     ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
   14941     return (ret);
   14942 }
   14943 
   14944 /**
   14945  * xmlSchemaCheckTypeDefCircular:
   14946  * @item:  the complex/simple type definition
   14947  * @ctxt:  the parser context
   14948  * @name:  the name
   14949  *
   14950  * Checks for circular type definitions.
   14951  */
   14952 static void
   14953 xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
   14954 			      xmlSchemaParserCtxtPtr ctxt)
   14955 {
   14956     if ((item == NULL) ||
   14957 	(item->type == XML_SCHEMA_TYPE_BASIC) ||
   14958 	(item->baseType == NULL))
   14959 	return;
   14960     xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
   14961 	item->baseType);
   14962 }
   14963 
   14964 /*
   14965 * Simple Type Definition Representation OK (src-simple-type) 4
   14966 *
   14967 * "4 Circular union type definition is disallowed. That is, if the
   14968 * <union> alternative is chosen, there must not be any entries in the
   14969 * memberTypes [attribute] at any depth which resolve to the component
   14970 * corresponding to the <simpleType>."
   14971 *
   14972 * Note that this should work on the *representation* of a component,
   14973 * thus assumes any union types in the member types not being yet
   14974 * substituted. At this stage we need the variety of the types
   14975 * to be already computed.
   14976 */
   14977 static int
   14978 xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
   14979 					xmlSchemaTypePtr ctxType,
   14980 					xmlSchemaTypeLinkPtr members)
   14981 {
   14982     xmlSchemaTypeLinkPtr member;
   14983     xmlSchemaTypePtr memberType;
   14984 
   14985     member = members;
   14986     while (member != NULL) {
   14987 	memberType = member->type;
   14988 	while ((memberType != NULL) &&
   14989 	    (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
   14990 	    if (memberType == ctxType) {
   14991 		xmlSchemaPCustomErr(pctxt,
   14992 		    XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
   14993 		    WXS_BASIC_CAST ctxType, NULL,
   14994 		    "The union type definition is circular", NULL);
   14995 		return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
   14996 	    }
   14997 	    if ((WXS_IS_UNION(memberType)) &&
   14998 		((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
   14999 	    {
   15000 		int res;
   15001 		memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
   15002 		res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
   15003 		    ctxType,
   15004 		    xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
   15005 		memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
   15006 		if (res != 0)
   15007 		    return(res);
   15008 	    }
   15009 	    memberType = memberType->baseType;
   15010 	}
   15011 	member = member->next;
   15012     }
   15013     return(0);
   15014 }
   15015 
   15016 static int
   15017 xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
   15018 				   xmlSchemaTypePtr type)
   15019 {
   15020     if (! WXS_IS_UNION(type))
   15021 	return(0);
   15022     return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
   15023 	type->memberTypes));
   15024 }
   15025 
   15026 /**
   15027  * xmlSchemaResolveTypeReferences:
   15028  * @item:  the complex/simple type definition
   15029  * @ctxt:  the parser context
   15030  * @name:  the name
   15031  *
   15032  * Resolvese type definition references
   15033  */
   15034 static void
   15035 xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
   15036 			 xmlSchemaParserCtxtPtr ctxt)
   15037 {
   15038     if (typeDef == NULL)
   15039 	return;
   15040 
   15041     /*
   15042     * Resolve the base type.
   15043     */
   15044     if (typeDef->baseType == NULL) {
   15045 	typeDef->baseType = xmlSchemaGetType(ctxt->schema,
   15046 	    typeDef->base, typeDef->baseNs);
   15047 	if (typeDef->baseType == NULL) {
   15048 	    xmlSchemaPResCompAttrErr(ctxt,
   15049 		XML_SCHEMAP_SRC_RESOLVE,
   15050 		WXS_BASIC_CAST typeDef, typeDef->node,
   15051 		"base", typeDef->base, typeDef->baseNs,
   15052 		XML_SCHEMA_TYPE_SIMPLE, NULL);
   15053 	    return;
   15054 	}
   15055     }
   15056     if (WXS_IS_SIMPLE(typeDef)) {
   15057 	if (WXS_IS_UNION(typeDef)) {
   15058 	    /*
   15059 	    * Resolve the memberTypes.
   15060 	    */
   15061 	    xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
   15062 	    return;
   15063 	} else if (WXS_IS_LIST(typeDef)) {
   15064 	    /*
   15065 	    * Resolve the itemType.
   15066 	    */
   15067 	    if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
   15068 
   15069 		typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
   15070 		    typeDef->base, typeDef->baseNs);
   15071 
   15072 		if ((typeDef->subtypes == NULL) ||
   15073 		    (! WXS_IS_SIMPLE(typeDef->subtypes)))
   15074 		{
   15075 		    typeDef->subtypes = NULL;
   15076 		    xmlSchemaPResCompAttrErr(ctxt,
   15077 			XML_SCHEMAP_SRC_RESOLVE,
   15078 			WXS_BASIC_CAST typeDef, typeDef->node,
   15079 			"itemType", typeDef->base, typeDef->baseNs,
   15080 			XML_SCHEMA_TYPE_SIMPLE, NULL);
   15081 		}
   15082 	    }
   15083 	    return;
   15084 	}
   15085     }
   15086     /*
   15087     * The ball of letters below means, that if we have a particle
   15088     * which has a QName-helper component as its {term}, we want
   15089     * to resolve it...
   15090     */
   15091     else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
   15092 	((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
   15093 	    XML_SCHEMA_TYPE_PARTICLE) &&
   15094 	(WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
   15095 	((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
   15096 	    XML_SCHEMA_EXTRA_QNAMEREF))
   15097     {
   15098 	xmlSchemaQNameRefPtr ref =
   15099 	    WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
   15100 	xmlSchemaModelGroupDefPtr groupDef;
   15101 
   15102 	/*
   15103 	* URGENT TODO: Test this.
   15104 	*/
   15105 	WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
   15106 	/*
   15107 	* Resolve the MG definition reference.
   15108 	*/
   15109 	groupDef =
   15110 	    WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
   15111 		ref->itemType, ref->name, ref->targetNamespace);
   15112 	if (groupDef == NULL) {
   15113 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
   15114 		NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
   15115 		"ref", ref->name, ref->targetNamespace, ref->itemType,
   15116 		NULL);
   15117 	    /* Remove the particle. */
   15118 	    WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
   15119 	} else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
   15120 	    /* Remove the particle. */
   15121 	    WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
   15122 	else {
   15123 	    /*
   15124 	    * Assign the MG definition's {model group} to the
   15125 	    * particle's {term}.
   15126 	    */
   15127 	    WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
   15128 
   15129 	    if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
   15130 		/*
   15131 		* SPEC cos-all-limited (1.2)
   15132 		* "1.2 the {term} property of a particle with
   15133 		* {max occurs}=1 which is part of a pair which constitutes
   15134 		* the {content type} of a complex type definition."
   15135 		*/
   15136 		if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
   15137 		    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   15138 			/* TODO: error code */
   15139 			XML_SCHEMAP_COS_ALL_LIMITED,
   15140 			WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
   15141 			"The particle's {max occurs} must be 1, since the "
   15142 			"reference resolves to an 'all' model group",
   15143 			NULL, NULL);
   15144 		}
   15145 	    }
   15146 	}
   15147     }
   15148 }
   15149 
   15150 
   15151 
   15152 /**
   15153  * xmlSchemaCheckSTPropsCorrect:
   15154  * @ctxt:  the schema parser context
   15155  * @type:  the simple type definition
   15156  *
   15157  * Checks st-props-correct.
   15158  *
   15159  * Returns 0 if the properties are correct,
   15160  * if not, a positive error code and -1 on internal
   15161  * errors.
   15162  */
   15163 static int
   15164 xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
   15165 			     xmlSchemaTypePtr type)
   15166 {
   15167     xmlSchemaTypePtr baseType = type->baseType;
   15168     xmlChar *str = NULL;
   15169 
   15170     /* STATE: error funcs converted. */
   15171     /*
   15172     * Schema Component Constraint: Simple Type Definition Properties Correct
   15173     *
   15174     * NOTE: This is somehow redundant, since we actually built a simple type
   15175     * to have all the needed information; this acts as an self test.
   15176     */
   15177     /* Base type: If the datatype has been `derived` by `restriction`
   15178     * then the Simple Type Definition component from which it is `derived`,
   15179     * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
   15180     */
   15181     if (baseType == NULL) {
   15182 	/*
   15183 	* TODO: Think about: "modulo the impact of Missing
   15184 	* Sub-components ($5.3)."
   15185 	*/
   15186 	xmlSchemaPCustomErr(ctxt,
   15187 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
   15188 	    WXS_BASIC_CAST type, NULL,
   15189 	    "No base type existent", NULL);
   15190 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
   15191 
   15192     }
   15193     if (! WXS_IS_SIMPLE(baseType)) {
   15194 	xmlSchemaPCustomErr(ctxt,
   15195 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
   15196 	    WXS_BASIC_CAST type, NULL,
   15197 	    "The base type '%s' is not a simple type",
   15198 	    xmlSchemaGetComponentQName(&str, baseType));
   15199 	FREE_AND_NULL(str)
   15200 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
   15201     }
   15202     if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
   15203 	(WXS_IS_RESTRICTION(type) == 0) &&
   15204 	((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
   15205          (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
   15206 	xmlSchemaPCustomErr(ctxt,
   15207 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
   15208 	    WXS_BASIC_CAST type, NULL,
   15209 	    "A type, derived by list or union, must have "
   15210 	    "the simple ur-type definition as base type, not '%s'",
   15211 	    xmlSchemaGetComponentQName(&str, baseType));
   15212 	FREE_AND_NULL(str)
   15213 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
   15214     }
   15215     /*
   15216     * Variety: One of {atomic, list, union}.
   15217     */
   15218     if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
   15219 	(! WXS_IS_LIST(type))) {
   15220 	xmlSchemaPCustomErr(ctxt,
   15221 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
   15222 	    WXS_BASIC_CAST type, NULL,
   15223 	    "The variety is absent", NULL);
   15224 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
   15225     }
   15226     /* TODO: Finish this. Hmm, is this finished? */
   15227 
   15228     /*
   15229     * 3 The {final} of the {base type definition} must not contain restriction.
   15230     */
   15231     if (xmlSchemaTypeFinalContains(baseType,
   15232 	XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
   15233 	xmlSchemaPCustomErr(ctxt,
   15234 	    XML_SCHEMAP_ST_PROPS_CORRECT_3,
   15235 	    WXS_BASIC_CAST type, NULL,
   15236 	    "The 'final' of its base type '%s' must not contain "
   15237 	    "'restriction'",
   15238 	    xmlSchemaGetComponentQName(&str, baseType));
   15239 	FREE_AND_NULL(str)
   15240 	return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
   15241     }
   15242 
   15243     /*
   15244     * 2 All simple type definitions must be derived ultimately from the `simple
   15245     * ur-type definition` (so circular definitions are disallowed). That is, it
   15246     * must be possible to reach a built-in primitive datatype or the `simple
   15247     * ur-type definition` by repeatedly following the {base type definition}.
   15248     *
   15249     * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
   15250     */
   15251     return (0);
   15252 }
   15253 
   15254 /**
   15255  * xmlSchemaCheckCOSSTRestricts:
   15256  * @ctxt:  the schema parser context
   15257  * @type:  the simple type definition
   15258  *
   15259  * Schema Component Constraint:
   15260  * Derivation Valid (Restriction, Simple) (cos-st-restricts)
   15261 
   15262  * Checks if the given @type (simpleType) is derived validly by restriction.
   15263  * STATUS:
   15264  *
   15265  * Returns -1 on internal errors, 0 if the type is validly derived,
   15266  * a positive error code otherwise.
   15267  */
   15268 static int
   15269 xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
   15270 			     xmlSchemaTypePtr type)
   15271 {
   15272     xmlChar *str = NULL;
   15273 
   15274     if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
   15275 	PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15276 	    "given type is not a user-derived simpleType");
   15277 	return (-1);
   15278     }
   15279 
   15280     if (WXS_IS_ATOMIC(type)) {
   15281 	xmlSchemaTypePtr primitive;
   15282 	/*
   15283 	* 1.1 The {base type definition} must be an atomic simple
   15284 	* type definition or a built-in primitive datatype.
   15285 	*/
   15286 	if (! WXS_IS_ATOMIC(type->baseType)) {
   15287 	    xmlSchemaPCustomErr(pctxt,
   15288 		XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
   15289 		WXS_BASIC_CAST type, NULL,
   15290 		"The base type '%s' is not an atomic simple type",
   15291 		xmlSchemaGetComponentQName(&str, type->baseType));
   15292 	    FREE_AND_NULL(str)
   15293 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
   15294 	}
   15295 	/* 1.2 The {final} of the {base type definition} must not contain
   15296 	* restriction.
   15297 	*/
   15298 	/* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
   15299 	if (xmlSchemaTypeFinalContains(type->baseType,
   15300 	    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
   15301 	    xmlSchemaPCustomErr(pctxt,
   15302 		XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
   15303 		WXS_BASIC_CAST type, NULL,
   15304 		"The final of its base type '%s' must not contain 'restriction'",
   15305 		xmlSchemaGetComponentQName(&str, type->baseType));
   15306 	    FREE_AND_NULL(str)
   15307 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
   15308 	}
   15309 
   15310 	/*
   15311 	* 1.3.1 DF must be an allowed constraining facet for the {primitive
   15312 	* type definition}, as specified in the appropriate subsection of 3.2
   15313 	* Primitive datatypes.
   15314 	*/
   15315 	if (type->facets != NULL) {
   15316 	    xmlSchemaFacetPtr facet;
   15317 	    int ok = 1;
   15318 
   15319 	    primitive = xmlSchemaGetPrimitiveType(type);
   15320 	    if (primitive == NULL) {
   15321 		PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15322 		    "failed to get primitive type");
   15323 		return (-1);
   15324 	    }
   15325 	    facet = type->facets;
   15326 	    do {
   15327 		if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
   15328 		    ok = 0;
   15329 		    xmlSchemaPIllegalFacetAtomicErr(pctxt,
   15330 			XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
   15331 			type, primitive, facet);
   15332 		}
   15333 		facet = facet->next;
   15334 	    } while (facet != NULL);
   15335 	    if (ok == 0)
   15336 		return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
   15337 	}
   15338 	/*
   15339 	* SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
   15340 	* of the {base type definition} (call this BF),then the DF's {value}
   15341 	* must be a valid restriction of BF's {value} as defined in
   15342 	* [XML Schemas: Datatypes]."
   15343 	*
   15344 	* NOTE (1.3.2) Facet derivation constraints are currently handled in
   15345 	* xmlSchemaDeriveAndValidateFacets()
   15346 	*/
   15347     } else if (WXS_IS_LIST(type)) {
   15348 	xmlSchemaTypePtr itemType = NULL;
   15349 
   15350 	itemType = type->subtypes;
   15351 	if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
   15352 	    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15353 		"failed to evaluate the item type");
   15354 	    return (-1);
   15355 	}
   15356 	if (WXS_IS_TYPE_NOT_FIXED(itemType))
   15357 	    xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
   15358 	/*
   15359 	* 2.1 The {item type definition} must have a {variety} of atomic or
   15360 	* union (in which case all the {member type definitions}
   15361 	* must be atomic).
   15362 	*/
   15363 	if ((! WXS_IS_ATOMIC(itemType)) &&
   15364 	    (! WXS_IS_UNION(itemType))) {
   15365 	    xmlSchemaPCustomErr(pctxt,
   15366 		XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
   15367 		WXS_BASIC_CAST type, NULL,
   15368 		"The item type '%s' does not have a variety of atomic or union",
   15369 		xmlSchemaGetComponentQName(&str, itemType));
   15370 	    FREE_AND_NULL(str)
   15371 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
   15372 	} else if (WXS_IS_UNION(itemType)) {
   15373 	    xmlSchemaTypeLinkPtr member;
   15374 
   15375 	    member = itemType->memberTypes;
   15376 	    while (member != NULL) {
   15377 		if (! WXS_IS_ATOMIC(member->type)) {
   15378 		    xmlSchemaPCustomErr(pctxt,
   15379 			XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
   15380 			WXS_BASIC_CAST type, NULL,
   15381 			"The item type is a union type, but the "
   15382 			"member type '%s' of this item type is not atomic",
   15383 			xmlSchemaGetComponentQName(&str, member->type));
   15384 		    FREE_AND_NULL(str)
   15385 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
   15386 		}
   15387 		member = member->next;
   15388 	    }
   15389 	}
   15390 
   15391 	if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
   15392 	    xmlSchemaFacetPtr facet;
   15393 	    /*
   15394 	    * This is the case if we have: <simpleType><list ..
   15395 	    */
   15396 	    /*
   15397 	    * 2.3.1
   15398 	    * 2.3.1.1 The {final} of the {item type definition} must not
   15399 	    * contain list.
   15400 	    */
   15401 	    if (xmlSchemaTypeFinalContains(itemType,
   15402 		XML_SCHEMAS_TYPE_FINAL_LIST)) {
   15403 		xmlSchemaPCustomErr(pctxt,
   15404 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
   15405 		    WXS_BASIC_CAST type, NULL,
   15406 		    "The final of its item type '%s' must not contain 'list'",
   15407 		    xmlSchemaGetComponentQName(&str, itemType));
   15408 		FREE_AND_NULL(str)
   15409 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
   15410 	    }
   15411 	    /*
   15412 	    * 2.3.1.2 The {facets} must only contain the whiteSpace
   15413 	    * facet component.
   15414 	    * OPTIMIZE TODO: the S4S already disallows any facet
   15415 	    * to be specified.
   15416 	    */
   15417 	    if (type->facets != NULL) {
   15418 		facet = type->facets;
   15419 		do {
   15420 		    if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
   15421 			xmlSchemaPIllegalFacetListUnionErr(pctxt,
   15422 			    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
   15423 			    type, facet);
   15424 			return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
   15425 		    }
   15426 		    facet = facet->next;
   15427 		} while (facet != NULL);
   15428 	    }
   15429 	    /*
   15430 	    * MAYBE TODO: (Hmm, not really) Datatypes states:
   15431 	    * A `list` datatype can be `derived` from an `atomic` datatype
   15432 	    * whose `lexical space` allows space (such as string or anyURI)or
   15433 	    * a `union` datatype any of whose {member type definitions}'s
   15434 	    * `lexical space` allows space.
   15435 	    */
   15436 	} else {
   15437 	    /*
   15438 	    * This is the case if we have: <simpleType><restriction ...
   15439 	    * I.e. the variety of "list" is inherited.
   15440 	    */
   15441 	    /*
   15442 	    * 2.3.2
   15443 	    * 2.3.2.1 The {base type definition} must have a {variety} of list.
   15444 	    */
   15445 	    if (! WXS_IS_LIST(type->baseType)) {
   15446 		xmlSchemaPCustomErr(pctxt,
   15447 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
   15448 		    WXS_BASIC_CAST type, NULL,
   15449 		    "The base type '%s' must be a list type",
   15450 		    xmlSchemaGetComponentQName(&str, type->baseType));
   15451 		FREE_AND_NULL(str)
   15452 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
   15453 	    }
   15454 	    /*
   15455 	    * 2.3.2.2 The {final} of the {base type definition} must not
   15456 	    * contain restriction.
   15457 	    */
   15458 	    if (xmlSchemaTypeFinalContains(type->baseType,
   15459 		XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
   15460 		xmlSchemaPCustomErr(pctxt,
   15461 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
   15462 		    WXS_BASIC_CAST type, NULL,
   15463 		    "The 'final' of the base type '%s' must not contain 'restriction'",
   15464 		    xmlSchemaGetComponentQName(&str, type->baseType));
   15465 		FREE_AND_NULL(str)
   15466 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
   15467 	    }
   15468 	    /*
   15469 	    * 2.3.2.3 The {item type definition} must be validly derived
   15470 	    * from the {base type definition}'s {item type definition} given
   15471 	    * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
   15472 	    */
   15473 	    {
   15474 		xmlSchemaTypePtr baseItemType;
   15475 
   15476 		baseItemType = type->baseType->subtypes;
   15477 		if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
   15478 		    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15479 			"failed to eval the item type of a base type");
   15480 		    return (-1);
   15481 		}
   15482 		if ((itemType != baseItemType) &&
   15483 		    (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
   15484 			baseItemType, 0) != 0)) {
   15485 		    xmlChar *strBIT = NULL, *strBT = NULL;
   15486 		    xmlSchemaPCustomErrExt(pctxt,
   15487 			XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
   15488 			WXS_BASIC_CAST type, NULL,
   15489 			"The item type '%s' is not validly derived from "
   15490 			"the item type '%s' of the base type '%s'",
   15491 			xmlSchemaGetComponentQName(&str, itemType),
   15492 			xmlSchemaGetComponentQName(&strBIT, baseItemType),
   15493 			xmlSchemaGetComponentQName(&strBT, type->baseType));
   15494 
   15495 		    FREE_AND_NULL(str)
   15496 		    FREE_AND_NULL(strBIT)
   15497 		    FREE_AND_NULL(strBT)
   15498 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
   15499 		}
   15500 	    }
   15501 
   15502 	    if (type->facets != NULL) {
   15503 		xmlSchemaFacetPtr facet;
   15504 		int ok = 1;
   15505 		/*
   15506 		* 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
   15507 		* and enumeration facet components are allowed among the {facets}.
   15508 		*/
   15509 		facet = type->facets;
   15510 		do {
   15511 		    switch (facet->type) {
   15512 			case XML_SCHEMA_FACET_LENGTH:
   15513 			case XML_SCHEMA_FACET_MINLENGTH:
   15514 			case XML_SCHEMA_FACET_MAXLENGTH:
   15515 			case XML_SCHEMA_FACET_WHITESPACE:
   15516 			    /*
   15517 			    * TODO: 2.5.1.2 List datatypes
   15518 			    * The value of `whiteSpace` is fixed to the value collapse.
   15519 			    */
   15520 			case XML_SCHEMA_FACET_PATTERN:
   15521 			case XML_SCHEMA_FACET_ENUMERATION:
   15522 			    break;
   15523 			default: {
   15524 			    xmlSchemaPIllegalFacetListUnionErr(pctxt,
   15525 				XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
   15526 				type, facet);
   15527 			    /*
   15528 			    * We could return, but it's nicer to report all
   15529 			    * invalid facets.
   15530 			    */
   15531 			    ok = 0;
   15532 			}
   15533 		    }
   15534 		    facet = facet->next;
   15535 		} while (facet != NULL);
   15536 		if (ok == 0)
   15537 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
   15538 		/*
   15539 		* SPEC (2.3.2.5) (same as 1.3.2)
   15540 		*
   15541 		* NOTE (2.3.2.5) This is currently done in
   15542 		* xmlSchemaDeriveAndValidateFacets()
   15543 		*/
   15544 	    }
   15545 	}
   15546     } else if (WXS_IS_UNION(type)) {
   15547 	/*
   15548 	* 3.1 The {member type definitions} must all have {variety} of
   15549 	* atomic or list.
   15550 	*/
   15551 	xmlSchemaTypeLinkPtr member;
   15552 
   15553 	member = type->memberTypes;
   15554 	while (member != NULL) {
   15555 	    if (WXS_IS_TYPE_NOT_FIXED(member->type))
   15556 		xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
   15557 
   15558 	    if ((! WXS_IS_ATOMIC(member->type)) &&
   15559 		(! WXS_IS_LIST(member->type))) {
   15560 		xmlSchemaPCustomErr(pctxt,
   15561 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
   15562 		    WXS_BASIC_CAST type, NULL,
   15563 		    "The member type '%s' is neither an atomic, nor a list type",
   15564 		    xmlSchemaGetComponentQName(&str, member->type));
   15565 		FREE_AND_NULL(str)
   15566 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
   15567 	    }
   15568 	    member = member->next;
   15569 	}
   15570 	/*
   15571 	* 3.3.1 If the {base type definition} is the `simple ur-type
   15572 	* definition`
   15573 	*/
   15574 	if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
   15575 	    /*
   15576 	    * 3.3.1.1 All of the {member type definitions} must have a
   15577 	    * {final} which does not contain union.
   15578 	    */
   15579 	    member = type->memberTypes;
   15580 	    while (member != NULL) {
   15581 		if (xmlSchemaTypeFinalContains(member->type,
   15582 		    XML_SCHEMAS_TYPE_FINAL_UNION)) {
   15583 		    xmlSchemaPCustomErr(pctxt,
   15584 			XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
   15585 			WXS_BASIC_CAST type, NULL,
   15586 			"The 'final' of member type '%s' contains 'union'",
   15587 			xmlSchemaGetComponentQName(&str, member->type));
   15588 		    FREE_AND_NULL(str)
   15589 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
   15590 		}
   15591 		member = member->next;
   15592 	    }
   15593 	    /*
   15594 	    * 3.3.1.2 The {facets} must be empty.
   15595 	    */
   15596 	    if (type->facetSet != NULL) {
   15597 		xmlSchemaPCustomErr(pctxt,
   15598 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
   15599 		    WXS_BASIC_CAST type, NULL,
   15600 		    "No facets allowed", NULL);
   15601 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
   15602 	    }
   15603 	} else {
   15604 	    /*
   15605 	    * 3.3.2.1 The {base type definition} must have a {variety} of union.
   15606 	    * I.e. the variety of "list" is inherited.
   15607 	    */
   15608 	    if (! WXS_IS_UNION(type->baseType)) {
   15609 		xmlSchemaPCustomErr(pctxt,
   15610 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
   15611 		    WXS_BASIC_CAST type, NULL,
   15612 		    "The base type '%s' is not a union type",
   15613 		    xmlSchemaGetComponentQName(&str, type->baseType));
   15614 		FREE_AND_NULL(str)
   15615 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
   15616 	    }
   15617 	    /*
   15618 	    * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
   15619 	    */
   15620 	    if (xmlSchemaTypeFinalContains(type->baseType,
   15621 		XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
   15622 		xmlSchemaPCustomErr(pctxt,
   15623 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
   15624 		    WXS_BASIC_CAST type, NULL,
   15625 		    "The 'final' of its base type '%s' must not contain 'restriction'",
   15626 		    xmlSchemaGetComponentQName(&str, type->baseType));
   15627 		FREE_AND_NULL(str)
   15628 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
   15629 	    }
   15630 	    /*
   15631 	    * 3.3.2.3 The {member type definitions}, in order, must be validly
   15632 	    * derived from the corresponding type definitions in the {base
   15633 	    * type definition}'s {member type definitions} given the empty set,
   15634 	    * as defined in Type Derivation OK (Simple) ($3.14.6).
   15635 	    */
   15636 	    {
   15637 		xmlSchemaTypeLinkPtr baseMember;
   15638 
   15639 		/*
   15640 		* OPTIMIZE: if the type is restricting, it has no local defined
   15641 		* member types and inherits the member types of the base type;
   15642 		* thus a check for equality can be skipped.
   15643 		*/
   15644 		/*
   15645 		* Even worse: I cannot see a scenario where a restricting
   15646 		* union simple type can have other member types as the member
   15647 		* types of it's base type. This check seems not necessary with
   15648 		* respect to the derivation process in libxml2.
   15649 		* But necessary if constructing types with an API.
   15650 		*/
   15651 		if (type->memberTypes != NULL) {
   15652 		    member = type->memberTypes;
   15653 		    baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
   15654 		    if ((member == NULL) && (baseMember != NULL)) {
   15655 			PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15656 			    "different number of member types in base");
   15657 		    }
   15658 		    while (member != NULL) {
   15659 			if (baseMember == NULL) {
   15660 			    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15661 			    "different number of member types in base");
   15662 			} else if ((member->type != baseMember->type) &&
   15663 			    (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
   15664 				member->type, baseMember->type, 0) != 0)) {
   15665 			    xmlChar *strBMT = NULL, *strBT = NULL;
   15666 
   15667 			    xmlSchemaPCustomErrExt(pctxt,
   15668 				XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
   15669 				WXS_BASIC_CAST type, NULL,
   15670 				"The member type %s is not validly "
   15671 				"derived from its corresponding member "
   15672 				"type %s of the base type %s",
   15673 				xmlSchemaGetComponentQName(&str, member->type),
   15674 				xmlSchemaGetComponentQName(&strBMT, baseMember->type),
   15675 				xmlSchemaGetComponentQName(&strBT, type->baseType));
   15676 			    FREE_AND_NULL(str)
   15677 			    FREE_AND_NULL(strBMT)
   15678 			    FREE_AND_NULL(strBT)
   15679 			    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
   15680 			}
   15681 			member = member->next;
   15682                         if (baseMember != NULL)
   15683                             baseMember = baseMember->next;
   15684 		    }
   15685 		}
   15686 	    }
   15687 	    /*
   15688 	    * 3.3.2.4 Only pattern and enumeration facet components are
   15689 	    * allowed among the {facets}.
   15690 	    */
   15691 	    if (type->facets != NULL) {
   15692 		xmlSchemaFacetPtr facet;
   15693 		int ok = 1;
   15694 
   15695 		facet = type->facets;
   15696 		do {
   15697 		    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
   15698 			(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
   15699 			xmlSchemaPIllegalFacetListUnionErr(pctxt,
   15700 				XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
   15701 				type, facet);
   15702 			ok = 0;
   15703 		    }
   15704 		    facet = facet->next;
   15705 		} while (facet != NULL);
   15706 		if (ok == 0)
   15707 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
   15708 
   15709 	    }
   15710 	    /*
   15711 	    * SPEC (3.3.2.5) (same as 1.3.2)
   15712 	    *
   15713 	    * NOTE (3.3.2.5) This is currently done in
   15714 	    * xmlSchemaDeriveAndValidateFacets()
   15715 	    */
   15716 	}
   15717     }
   15718 
   15719     return (0);
   15720 }
   15721 
   15722 /**
   15723  * xmlSchemaCheckSRCSimpleType:
   15724  * @ctxt:  the schema parser context
   15725  * @type:  the simple type definition
   15726  *
   15727  * Checks crc-simple-type constraints.
   15728  *
   15729  * Returns 0 if the constraints are satisfied,
   15730  * if not a positive error code and -1 on internal
   15731  * errors.
   15732  */
   15733 #if 0
   15734 static int
   15735 xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
   15736 			    xmlSchemaTypePtr type)
   15737 {
   15738     /*
   15739     * src-simple-type.1 The corresponding simple type definition, if any,
   15740     * must satisfy the conditions set out in Constraints on Simple Type
   15741     * Definition Schema Components ($3.14.6).
   15742     */
   15743     if (WXS_IS_RESTRICTION(type)) {
   15744 	/*
   15745 	* src-simple-type.2 "If the <restriction> alternative is chosen,
   15746 	* either it must have a base [attribute] or a <simpleType> among its
   15747 	* [children], but not both."
   15748 	* NOTE: This is checked in the parse function of <restriction>.
   15749 	*/
   15750 	/*
   15751 	*
   15752 	*/
   15753     } else if (WXS_IS_LIST(type)) {
   15754 	/* src-simple-type.3 "If the <list> alternative is chosen, either it must have
   15755 	* an itemType [attribute] or a <simpleType> among its [children],
   15756 	* but not both."
   15757 	*
   15758 	* NOTE: This is checked in the parse function of <list>.
   15759 	*/
   15760     } else if (WXS_IS_UNION(type)) {
   15761 	/*
   15762 	* src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
   15763 	*/
   15764     }
   15765     return (0);
   15766 }
   15767 #endif
   15768 
   15769 static int
   15770 xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
   15771 {
   15772    if (ctxt->vctxt == NULL) {
   15773 	ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
   15774 	if (ctxt->vctxt == NULL) {
   15775 	    xmlSchemaPErr(ctxt, NULL,
   15776 		XML_SCHEMAP_INTERNAL,
   15777 		"Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
   15778 		"failed to create a temp. validation context.\n",
   15779 		NULL, NULL);
   15780 	    return (-1);
   15781 	}
   15782 	/* TODO: Pass user data. */
   15783 	xmlSchemaSetValidErrors(ctxt->vctxt,
   15784 	    ctxt->error, ctxt->warning, ctxt->errCtxt);
   15785 	xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
   15786 	    ctxt->serror, ctxt->errCtxt);
   15787     }
   15788     return (0);
   15789 }
   15790 
   15791 static int
   15792 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
   15793 			     xmlNodePtr node,
   15794 			     xmlSchemaTypePtr type,
   15795 			     const xmlChar *value,
   15796 			     xmlSchemaValPtr *retVal,
   15797 			     int fireErrors,
   15798 			     int normalize,
   15799 			     int isNormalized);
   15800 
   15801 /**
   15802  * xmlSchemaParseCheckCOSValidDefault:
   15803  * @pctxt:  the schema parser context
   15804  * @type:  the simple type definition
   15805  * @value: the default value
   15806  * @node: an optional node (the holder of the value)
   15807  *
   15808  * Schema Component Constraint: Element Default Valid (Immediate)
   15809  * (cos-valid-default)
   15810  * This will be used by the parser only. For the validator there's
   15811  * an other version.
   15812  *
   15813  * Returns 0 if the constraints are satisfied,
   15814  * if not, a positive error code and -1 on internal
   15815  * errors.
   15816  */
   15817 static int
   15818 xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
   15819 				   xmlNodePtr node,
   15820 				   xmlSchemaTypePtr type,
   15821 				   const xmlChar *value,
   15822 				   xmlSchemaValPtr *val)
   15823 {
   15824     int ret = 0;
   15825 
   15826     /*
   15827     * cos-valid-default:
   15828     * Schema Component Constraint: Element Default Valid (Immediate)
   15829     * For a string to be a valid default with respect to a type
   15830     * definition the appropriate case among the following must be true:
   15831     */
   15832     if WXS_IS_COMPLEX(type) {
   15833 	/*
   15834 	* Complex type.
   15835 	*
   15836 	* SPEC (2.1) "its {content type} must be a simple type definition
   15837 	* or mixed."
   15838 	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
   15839 	* type}'s particle must be `emptiable` as defined by
   15840 	* Particle Emptiable ($3.9.6)."
   15841 	*/
   15842 	if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
   15843 	    ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
   15844 	    /* NOTE that this covers (2.2.2) as well. */
   15845 	    xmlSchemaPCustomErr(pctxt,
   15846 		XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
   15847 		WXS_BASIC_CAST type, type->node,
   15848 		"For a string to be a valid default, the type definition "
   15849 		"must be a simple type or a complex type with mixed content "
   15850 		"and a particle emptiable", NULL);
   15851 	    return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
   15852 	}
   15853     }
   15854     /*
   15855     * 1 If the type definition is a simple type definition, then the string
   15856     * must be `valid` with respect to that definition as defined by String
   15857     * Valid ($3.14.4).
   15858     *
   15859     * AND
   15860     *
   15861     * 2.2.1 If the {content type} is a simple type definition, then the
   15862     * string must be `valid` with respect to that simple type definition
   15863     * as defined by String Valid ($3.14.4).
   15864     */
   15865     if (WXS_IS_SIMPLE(type))
   15866 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
   15867 	    type, value, val, 1, 1, 0);
   15868     else if (WXS_HAS_SIMPLE_CONTENT(type))
   15869 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
   15870 	    type->contentTypeDef, value, val, 1, 1, 0);
   15871     else
   15872 	return (ret);
   15873 
   15874     if (ret < 0) {
   15875 	PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
   15876 	    "calling xmlSchemaVCheckCVCSimpleType()");
   15877     }
   15878 
   15879     return (ret);
   15880 }
   15881 
   15882 /**
   15883  * xmlSchemaCheckCTPropsCorrect:
   15884  * @ctxt:  the schema parser context
   15885  * @type:  the complex type definition
   15886  *
   15887  *.(4.6) Constraints on Complex Type Definition Schema Components
   15888  * Schema Component Constraint:
   15889  * Complex Type Definition Properties Correct (ct-props-correct)
   15890  * STATUS: (seems) complete
   15891  *
   15892  * Returns 0 if the constraints are satisfied, a positive
   15893  * error code if not and -1 if an internal error occured.
   15894  */
   15895 static int
   15896 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
   15897 			     xmlSchemaTypePtr type)
   15898 {
   15899     /*
   15900     * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
   15901     *
   15902     * SPEC (1) "The values of the properties of a complex type definition must
   15903     * be as described in the property tableau in The Complex Type Definition
   15904     * Schema Component ($3.4.1), modulo the impact of Missing
   15905     * Sub-components ($5.3)."
   15906     */
   15907     if ((type->baseType != NULL) &&
   15908 	(WXS_IS_SIMPLE(type->baseType)) &&
   15909 	(WXS_IS_EXTENSION(type) == 0)) {
   15910 	/*
   15911 	* SPEC (2) "If the {base type definition} is a simple type definition,
   15912 	* the {derivation method} must be extension."
   15913 	*/
   15914 	xmlSchemaCustomErr(ACTXT_CAST pctxt,
   15915 	    XML_SCHEMAP_SRC_CT_1,
   15916 	    NULL, WXS_BASIC_CAST type,
   15917 	    "If the base type is a simple type, the derivation method must be "
   15918 	    "'extension'", NULL, NULL);
   15919 	return (XML_SCHEMAP_SRC_CT_1);
   15920     }
   15921     /*
   15922     * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
   15923     * definition`. That is, it must be possible to reach the `ur-type
   15924     * definition` by repeatedly following the {base type definition}."
   15925     *
   15926     * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
   15927     */
   15928     /*
   15929     * NOTE that (4) and (5) need the following:
   15930     *   - attribute uses need to be already inherited (apply attr. prohibitions)
   15931     *   - attribute group references need to be expanded already
   15932     *   - simple types need to be typefixed already
   15933     */
   15934     if (type->attrUses &&
   15935 	(((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
   15936     {
   15937 	xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
   15938 	xmlSchemaAttributeUsePtr use, tmp;
   15939 	int i, j, hasId = 0;
   15940 
   15941 	for (i = uses->nbItems -1; i >= 0; i--) {
   15942 	    use = uses->items[i];
   15943 
   15944 	    /*
   15945 	    * SPEC ct-props-correct
   15946 	    * (4) "Two distinct attribute declarations in the
   15947 	    * {attribute uses} must not have identical {name}s and
   15948 	    * {target namespace}s."
   15949 	    */
   15950 	    if (i > 0) {
   15951 		for (j = i -1; j >= 0; j--) {
   15952 		    tmp = uses->items[j];
   15953 		    if ((WXS_ATTRUSE_DECL_NAME(use) ==
   15954 			WXS_ATTRUSE_DECL_NAME(tmp)) &&
   15955 			(WXS_ATTRUSE_DECL_TNS(use) ==
   15956 			WXS_ATTRUSE_DECL_TNS(tmp)))
   15957 		    {
   15958 			xmlChar *str = NULL;
   15959 
   15960 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   15961 			    XML_SCHEMAP_AG_PROPS_CORRECT,
   15962 			    NULL, WXS_BASIC_CAST type,
   15963 			    "Duplicate %s",
   15964 			    xmlSchemaGetComponentDesignation(&str, use),
   15965 			    NULL);
   15966 			FREE_AND_NULL(str);
   15967 			/*
   15968 			* Remove the duplicate.
   15969 			*/
   15970 			if (xmlSchemaItemListRemove(uses, i) == -1)
   15971 			    goto exit_failure;
   15972 			goto next_use;
   15973 		    }
   15974 		}
   15975 	    }
   15976 	    /*
   15977 	    * SPEC ct-props-correct
   15978 	    * (5) "Two distinct attribute declarations in the
   15979 	    * {attribute uses} must not have {type definition}s which
   15980 	    * are or are derived from ID."
   15981 	    */
   15982 	    if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
   15983 		if (xmlSchemaIsDerivedFromBuiltInType(
   15984 		    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
   15985 		{
   15986 		    if (hasId) {
   15987 			xmlChar *str = NULL;
   15988 
   15989 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   15990 			    XML_SCHEMAP_AG_PROPS_CORRECT,
   15991 			    NULL, WXS_BASIC_CAST type,
   15992 			    "There must not exist more than one attribute "
   15993 			    "declaration of type 'xs:ID' "
   15994 			    "(or derived from 'xs:ID'). The %s violates this "
   15995 			    "constraint",
   15996 			    xmlSchemaGetComponentDesignation(&str, use),
   15997 			    NULL);
   15998 			FREE_AND_NULL(str);
   15999 			if (xmlSchemaItemListRemove(uses, i) == -1)
   16000 			    goto exit_failure;
   16001 		    }
   16002 
   16003 		    hasId = 1;
   16004 		}
   16005 	    }
   16006 next_use: {}
   16007 	}
   16008     }
   16009     return (0);
   16010 exit_failure:
   16011     return(-1);
   16012 }
   16013 
   16014 static int
   16015 xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
   16016 		       xmlSchemaTypePtr typeB)
   16017 {
   16018     /*
   16019     * TODO: This should implement component-identity
   16020     * in the future.
   16021     */
   16022     if ((typeA == NULL) || (typeB == NULL))
   16023 	return (0);
   16024     return (typeA == typeB);
   16025 }
   16026 
   16027 /**
   16028  * xmlSchemaCheckCOSCTDerivedOK:
   16029  * @ctxt:  the schema parser context
   16030  * @type:  the to-be derived complex type definition
   16031  * @baseType:  the base complex type definition
   16032  * @set: the given set
   16033  *
   16034  * Schema Component Constraint:
   16035  * Type Derivation OK (Complex) (cos-ct-derived-ok)
   16036  *
   16037  * STATUS: completed
   16038  *
   16039  * Returns 0 if the constraints are satisfied, or 1
   16040  * if not.
   16041  */
   16042 static int
   16043 xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
   16044 			     xmlSchemaTypePtr type,
   16045 			     xmlSchemaTypePtr baseType,
   16046 			     int set)
   16047 {
   16048     int equal = xmlSchemaAreEqualTypes(type, baseType);
   16049     /* TODO: Error codes. */
   16050     /*
   16051     * SPEC "For a complex type definition (call it D, for derived)
   16052     * to be validly derived from a type definition (call this
   16053     * B, for base) given a subset of {extension, restriction}
   16054     * all of the following must be true:"
   16055     */
   16056     if (! equal) {
   16057 	/*
   16058 	* SPEC (1) "If B and D are not the same type definition, then the
   16059 	* {derivation method} of D must not be in the subset."
   16060 	*/
   16061 	if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
   16062 	    ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
   16063 	    return (1);
   16064     } else {
   16065 	/*
   16066 	* SPEC (2.1) "B and D must be the same type definition."
   16067 	*/
   16068 	return (0);
   16069     }
   16070     /*
   16071     * SPEC (2.2) "B must be D's {base type definition}."
   16072     */
   16073     if (type->baseType == baseType)
   16074 	return (0);
   16075     /*
   16076     * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
   16077     * definition`."
   16078     */
   16079     if (WXS_IS_ANYTYPE(type->baseType))
   16080 	return (1);
   16081 
   16082     if (WXS_IS_COMPLEX(type->baseType)) {
   16083 	/*
   16084 	* SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
   16085 	* must be validly derived from B given the subset as defined by this
   16086 	* constraint."
   16087 	*/
   16088 	return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
   16089 	    baseType, set));
   16090     } else {
   16091 	/*
   16092 	* SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
   16093 	* must be validly derived from B given the subset as defined in Type
   16094 	* Derivation OK (Simple) ($3.14.6).
   16095 	*/
   16096 	return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
   16097 	    baseType, set));
   16098     }
   16099 }
   16100 
   16101 /**
   16102  * xmlSchemaCheckCOSDerivedOK:
   16103  * @type:  the derived simple type definition
   16104  * @baseType:  the base type definition
   16105  *
   16106  * Calls:
   16107  * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
   16108  *
   16109  * Checks wheter @type can be validly derived from @baseType.
   16110  *
   16111  * Returns 0 on success, an positive error code otherwise.
   16112  */
   16113 static int
   16114 xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
   16115 			   xmlSchemaTypePtr type,
   16116 			   xmlSchemaTypePtr baseType,
   16117 			   int set)
   16118 {
   16119     if (WXS_IS_SIMPLE(type))
   16120 	return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
   16121     else
   16122 	return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
   16123 }
   16124 
   16125 /**
   16126  * xmlSchemaCheckCOSCTExtends:
   16127  * @ctxt:  the schema parser context
   16128  * @type:  the complex type definition
   16129  *
   16130  * (3.4.6) Constraints on Complex Type Definition Schema Components
   16131  * Schema Component Constraint:
   16132  * Derivation Valid (Extension) (cos-ct-extends)
   16133  *
   16134  * STATUS:
   16135  *   missing:
   16136  *     (1.5)
   16137  *     (1.4.3.2.2.2) "Particle Valid (Extension)"
   16138  *
   16139  * Returns 0 if the constraints are satisfied, a positive
   16140  * error code if not and -1 if an internal error occured.
   16141  */
   16142 static int
   16143 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
   16144 			   xmlSchemaTypePtr type)
   16145 {
   16146     xmlSchemaTypePtr base = type->baseType;
   16147     /*
   16148     * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
   16149     * temporarily only.
   16150     */
   16151     /*
   16152     * SPEC (1) "If the {base type definition} is a complex type definition,
   16153     * then all of the following must be true:"
   16154     */
   16155     if (WXS_IS_COMPLEX(base)) {
   16156 	/*
   16157 	* SPEC (1.1) "The {final} of the {base type definition} must not
   16158 	* contain extension."
   16159 	*/
   16160 	if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
   16161 	    xmlSchemaPCustomErr(ctxt,
   16162 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16163 		WXS_BASIC_CAST type, NULL,
   16164 		"The 'final' of the base type definition "
   16165 		"contains 'extension'", NULL);
   16166 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16167 	}
   16168 
   16169 	/*
   16170 	* ATTENTION: The constrains (1.2) and (1.3) are not applied,
   16171 	* since they are automatically satisfied through the
   16172 	* inheriting mechanism.
   16173 	* Note that even if redefining components, the inheriting mechanism
   16174 	* is used.
   16175 	*/
   16176 #if 0
   16177 	/*
   16178 	* SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
   16179 	* uses}
   16180 	* of the complex type definition itself, that is, for every attribute
   16181 	* use in the {attribute uses} of the {base type definition}, there
   16182 	* must be an attribute use in the {attribute uses} of the complex
   16183 	* type definition itself whose {attribute declaration} has the same
   16184 	* {name}, {target namespace} and {type definition} as its attribute
   16185 	* declaration"
   16186 	*/
   16187 	if (base->attrUses != NULL) {
   16188 	    int i, j, found;
   16189 	    xmlSchemaAttributeUsePtr use, buse;
   16190 
   16191 	    for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
   16192 		buse = (WXS_LIST_CAST base->attrUses)->items[i];
   16193 		found = 0;
   16194 		if (type->attrUses != NULL) {
   16195 		    use = (WXS_LIST_CAST type->attrUses)->items[j];
   16196 		    for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
   16197 		    {
   16198 			if ((WXS_ATTRUSE_DECL_NAME(use) ==
   16199 				WXS_ATTRUSE_DECL_NAME(buse)) &&
   16200 			    (WXS_ATTRUSE_DECL_TNS(use) ==
   16201 				WXS_ATTRUSE_DECL_TNS(buse)) &&
   16202 			    (WXS_ATTRUSE_TYPEDEF(use) ==
   16203 				WXS_ATTRUSE_TYPEDEF(buse))
   16204 			{
   16205 			    found = 1;
   16206 			    break;
   16207 			}
   16208 		    }
   16209 		}
   16210 		if (! found) {
   16211 		    xmlChar *str = NULL;
   16212 
   16213 		    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   16214 			XML_SCHEMAP_COS_CT_EXTENDS_1_2,
   16215 			NULL, WXS_BASIC_CAST type,
   16216 			/*
   16217 			* TODO: The report does not indicate that also the
   16218 			* type needs to be the same.
   16219 			*/
   16220 			"This type is missing a matching correspondent "
   16221 			"for its {base type}'s %s in its {attribute uses}",
   16222 			xmlSchemaGetComponentDesignation(&str,
   16223 			    buse->children),
   16224 			NULL);
   16225 		    FREE_AND_NULL(str)
   16226 		}
   16227 	    }
   16228 	}
   16229 	/*
   16230 	* SPEC (1.3) "If it has an {attribute wildcard}, the complex type
   16231 	* definition must also have one, and the base type definition's
   16232 	* {attribute  wildcard}'s {namespace constraint} must be a subset
   16233 	* of the complex  type definition's {attribute wildcard}'s {namespace
   16234 	* constraint}, as defined by Wildcard Subset ($3.10.6)."
   16235 	*/
   16236 
   16237 	/*
   16238 	* MAYBE TODO: Enable if ever needed. But this will be needed only
   16239 	* if created the type via a schema construction API.
   16240 	*/
   16241 	if (base->attributeWildcard != NULL) {
   16242 	    if (type->attributeWilcard == NULL) {
   16243 		xmlChar *str = NULL;
   16244 
   16245 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   16246 		    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
   16247 		    NULL, type,
   16248 		    "The base %s has an attribute wildcard, "
   16249 		    "but this type is missing an attribute wildcard",
   16250 		    xmlSchemaGetComponentDesignation(&str, base));
   16251 		FREE_AND_NULL(str)
   16252 
   16253 	    } else if (xmlSchemaCheckCOSNSSubset(
   16254 		base->attributeWildcard, type->attributeWildcard))
   16255 	    {
   16256 		xmlChar *str = NULL;
   16257 
   16258 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   16259 		    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
   16260 		    NULL, type,
   16261 		    "The attribute wildcard is not a valid "
   16262 		    "superset of the one in the base %s",
   16263 		    xmlSchemaGetComponentDesignation(&str, base));
   16264 		FREE_AND_NULL(str)
   16265 	    }
   16266 	}
   16267 #endif
   16268 	/*
   16269 	* SPEC (1.4) "One of the following must be true:"
   16270 	*/
   16271 	if ((type->contentTypeDef != NULL) &&
   16272 	    (type->contentTypeDef == base->contentTypeDef)) {
   16273 	    /*
   16274 	    * SPEC (1.4.1) "The {content type} of the {base type definition}
   16275 	    * and the {content type} of the complex type definition itself
   16276 	    * must be the same simple type definition"
   16277 	    * PASS
   16278 	    */
   16279 	} else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
   16280 	    (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
   16281 	    /*
   16282 	    * SPEC (1.4.2) "The {content type} of both the {base type
   16283 	    * definition} and the complex type definition itself must
   16284 	    * be empty."
   16285 	    * PASS
   16286 	    */
   16287 	} else {
   16288 	    /*
   16289 	    * SPEC (1.4.3) "All of the following must be true:"
   16290 	    */
   16291 	    if (type->subtypes == NULL) {
   16292 		/*
   16293 		* SPEC 1.4.3.1 The {content type} of the complex type
   16294 		* definition itself must specify a particle.
   16295 		*/
   16296 		xmlSchemaPCustomErr(ctxt,
   16297 		    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16298 		    WXS_BASIC_CAST type, NULL,
   16299 		    "The content type must specify a particle", NULL);
   16300 		return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16301 	    }
   16302 	    /*
   16303 	    * SPEC (1.4.3.2) "One of the following must be true:"
   16304 	    */
   16305 	    if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   16306 		/*
   16307 		* SPEC (1.4.3.2.1) "The {content type} of the {base type
   16308 		* definition} must be empty.
   16309 		* PASS
   16310 		*/
   16311 	    } else {
   16312 		/*
   16313 		* SPEC (1.4.3.2.2) "All of the following must be true:"
   16314 		*/
   16315 		if ((type->contentType != base->contentType) ||
   16316 		    ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
   16317 		    (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
   16318 		    /*
   16319 		    * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
   16320 		    * or both must be element-only."
   16321 		    */
   16322 		    xmlSchemaPCustomErr(ctxt,
   16323 			XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16324 			WXS_BASIC_CAST type, NULL,
   16325 			"The content type of both, the type and its base "
   16326 			"type, must either 'mixed' or 'element-only'", NULL);
   16327 		    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16328 		}
   16329 		/*
   16330 		* URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
   16331 		* complex type definition must be a `valid extension`
   16332 		* of the {base type definition}'s particle, as defined
   16333 		* in Particle Valid (Extension) ($3.9.6)."
   16334 		*
   16335 		* NOTE that we won't check "Particle Valid (Extension)",
   16336 		* since it is ensured by the derivation process in
   16337 		* xmlSchemaTypeFixup(). We need to implement this when heading
   16338 		* for a construction API
   16339 		* TODO: !! This is needed to be checked if redefining a type !!
   16340 		*/
   16341 	    }
   16342 	    /*
   16343 	    * URGENT TODO (1.5)
   16344 	    */
   16345 	}
   16346     } else {
   16347 	/*
   16348 	* SPEC (2) "If the {base type definition} is a simple type definition,
   16349 	* then all of the following must be true:"
   16350 	*/
   16351 	if (type->contentTypeDef != base) {
   16352 	    /*
   16353 	    * SPEC (2.1) "The {content type} must be the same simple type
   16354 	    * definition."
   16355 	    */
   16356 	    xmlSchemaPCustomErr(ctxt,
   16357 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16358 		WXS_BASIC_CAST type, NULL,
   16359 		"The content type must be the simple base type", NULL);
   16360 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16361 	}
   16362 	if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
   16363 	    /*
   16364 	    * SPEC (2.2) "The {final} of the {base type definition} must not
   16365 	    * contain extension"
   16366 	    * NOTE that this is the same as (1.1).
   16367 	    */
   16368 	    xmlSchemaPCustomErr(ctxt,
   16369 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16370 		WXS_BASIC_CAST type, NULL,
   16371 		"The 'final' of the base type definition "
   16372 		"contains 'extension'", NULL);
   16373 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16374 	}
   16375     }
   16376     return (0);
   16377 }
   16378 
   16379 /**
   16380  * xmlSchemaCheckDerivationOKRestriction:
   16381  * @ctxt:  the schema parser context
   16382  * @type:  the complex type definition
   16383  *
   16384  * (3.4.6) Constraints on Complex Type Definition Schema Components
   16385  * Schema Component Constraint:
   16386  * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
   16387  *
   16388  * STATUS:
   16389  *   missing:
   16390  *     (5.4.2) ???
   16391  *
   16392  * ATTENTION:
   16393  * In XML Schema 1.1 this will be:
   16394  * Validation Rule: Checking complex type subsumption
   16395  *
   16396  * Returns 0 if the constraints are satisfied, a positive
   16397  * error code if not and -1 if an internal error occured.
   16398  */
   16399 static int
   16400 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
   16401 				      xmlSchemaTypePtr type)
   16402 {
   16403     xmlSchemaTypePtr base;
   16404 
   16405     /*
   16406     * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
   16407     * temporarily only.
   16408     */
   16409     base = type->baseType;
   16410     if (! WXS_IS_COMPLEX(base)) {
   16411 	xmlSchemaCustomErr(ACTXT_CAST ctxt,
   16412 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16413 	    type->node, WXS_BASIC_CAST type,
   16414 	    "The base type must be a complex type", NULL, NULL);
   16415 	return(ctxt->err);
   16416     }
   16417     if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
   16418 	/*
   16419 	* SPEC (1) "The {base type definition} must be a complex type
   16420 	* definition whose {final} does not contain restriction."
   16421 	*/
   16422 	xmlSchemaCustomErr(ACTXT_CAST ctxt,
   16423 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16424 	    type->node, WXS_BASIC_CAST type,
   16425 	    "The 'final' of the base type definition "
   16426 	    "contains 'restriction'", NULL, NULL);
   16427 	return (ctxt->err);
   16428     }
   16429     /*
   16430     * SPEC (2), (3) and (4)
   16431     * Those are handled in a separate function, since the
   16432     * same constraints are needed for redefinition of
   16433     * attribute groups as well.
   16434     */
   16435     if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
   16436 	XML_SCHEMA_ACTION_DERIVE,
   16437 	WXS_BASIC_CAST type, WXS_BASIC_CAST base,
   16438 	type->attrUses, base->attrUses,
   16439 	type->attributeWildcard,
   16440 	base->attributeWildcard) == -1)
   16441     {
   16442 	return(-1);
   16443     }
   16444     /*
   16445     * SPEC (5) "One of the following must be true:"
   16446     */
   16447     if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
   16448 	/*
   16449 	* SPEC (5.1) "The {base type definition} must be the
   16450 	* `ur-type definition`."
   16451 	* PASS
   16452 	*/
   16453     } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
   16454 	    (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
   16455 	/*
   16456 	* SPEC (5.2.1) "The {content type} of the complex type definition
   16457 	* must be a simple type definition"
   16458 	*
   16459 	* SPEC (5.2.2) "One of the following must be true:"
   16460 	*/
   16461 	if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
   16462 	    (base->contentType == XML_SCHEMA_CONTENT_BASIC))
   16463 	{
   16464 	    int err;
   16465 	    /*
   16466 	    * SPEC (5.2.2.1) "The {content type} of the {base type
   16467 	    * definition} must be a simple type definition from which
   16468 	    * the {content type} is validly derived given the empty
   16469 	    * set as defined in Type Derivation OK (Simple) ($3.14.6)."
   16470 	    *
   16471 	    * ATTENTION TODO: This seems not needed if the type implicitely
   16472 	    * derived from the base type.
   16473 	    *
   16474 	    */
   16475 	    err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
   16476 		type->contentTypeDef, base->contentTypeDef, 0);
   16477 	    if (err != 0) {
   16478 		xmlChar *strA = NULL, *strB = NULL;
   16479 
   16480 		if (err == -1)
   16481 		    return(-1);
   16482 		xmlSchemaCustomErr(ACTXT_CAST ctxt,
   16483 		    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16484 		    NULL, WXS_BASIC_CAST type,
   16485 		    "The {content type} %s is not validly derived from the "
   16486 		    "base type's {content type} %s",
   16487 		    xmlSchemaGetComponentDesignation(&strA,
   16488 			type->contentTypeDef),
   16489 		    xmlSchemaGetComponentDesignation(&strB,
   16490 			base->contentTypeDef));
   16491 		FREE_AND_NULL(strA);
   16492 		FREE_AND_NULL(strB);
   16493 		return(ctxt->err);
   16494 	    }
   16495 	} else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
   16496 	    (xmlSchemaIsParticleEmptiable(
   16497 		(xmlSchemaParticlePtr) base->subtypes))) {
   16498 	    /*
   16499 	    * SPEC (5.2.2.2) "The {base type definition} must be mixed
   16500 	    * and have a particle which is `emptiable` as defined in
   16501 	    * Particle Emptiable ($3.9.6)."
   16502 	    * PASS
   16503 	    */
   16504 	} else {
   16505 	    xmlSchemaPCustomErr(ctxt,
   16506 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16507 		WXS_BASIC_CAST type, NULL,
   16508 		"The content type of the base type must be either "
   16509 		"a simple type or 'mixed' and an emptiable particle", NULL);
   16510 	    return (ctxt->err);
   16511 	}
   16512     } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   16513 	/*
   16514 	* SPEC (5.3.1) "The {content type} of the complex type itself must
   16515 	* be empty"
   16516 	*/
   16517 	if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   16518 	    /*
   16519 	    * SPEC (5.3.2.1) "The {content type} of the {base type
   16520 	    * definition} must also be empty."
   16521 	    * PASS
   16522 	    */
   16523 	} else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
   16524 	    (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
   16525 	    xmlSchemaIsParticleEmptiable(
   16526 		(xmlSchemaParticlePtr) base->subtypes)) {
   16527 	    /*
   16528 	    * SPEC (5.3.2.2) "The {content type} of the {base type
   16529 	    * definition} must be elementOnly or mixed and have a particle
   16530 	    * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
   16531 	    * PASS
   16532 	    */
   16533 	} else {
   16534 	    xmlSchemaPCustomErr(ctxt,
   16535 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16536 		WXS_BASIC_CAST type, NULL,
   16537 		"The content type of the base type must be either "
   16538 		"empty or 'mixed' (or 'elements-only') and an emptiable "
   16539 		"particle", NULL);
   16540 	    return (ctxt->err);
   16541 	}
   16542     } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
   16543 	WXS_HAS_MIXED_CONTENT(type)) {
   16544 	/*
   16545 	* SPEC (5.4.1.1) "The {content type} of the complex type definition
   16546 	* itself must be element-only"
   16547 	*/
   16548 	if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
   16549 	    /*
   16550 	    * SPEC (5.4.1.2) "The {content type} of the complex type
   16551 	    * definition itself and of the {base type definition} must be
   16552 	    * mixed"
   16553 	    */
   16554 	    xmlSchemaPCustomErr(ctxt,
   16555 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16556 		WXS_BASIC_CAST type, NULL,
   16557 		"If the content type is 'mixed', then the content type of the "
   16558 		"base type must also be 'mixed'", NULL);
   16559 	    return (ctxt->err);
   16560 	}
   16561 	/*
   16562 	* SPEC (5.4.2) "The particle of the complex type definition itself
   16563 	* must be a `valid restriction` of the particle of the {content
   16564 	* type} of the {base type definition} as defined in Particle Valid
   16565 	* (Restriction) ($3.9.6).
   16566 	*
   16567 	* URGENT TODO: (5.4.2)
   16568 	*/
   16569     } else {
   16570 	xmlSchemaPCustomErr(ctxt,
   16571 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16572 	    WXS_BASIC_CAST type, NULL,
   16573 	    "The type is not a valid restriction of its base type", NULL);
   16574 	return (ctxt->err);
   16575     }
   16576     return (0);
   16577 }
   16578 
   16579 /**
   16580  * xmlSchemaCheckCTComponent:
   16581  * @ctxt:  the schema parser context
   16582  * @type:  the complex type definition
   16583  *
   16584  * (3.4.6) Constraints on Complex Type Definition Schema Components
   16585  *
   16586  * Returns 0 if the constraints are satisfied, a positive
   16587  * error code if not and -1 if an internal error occured.
   16588  */
   16589 static int
   16590 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
   16591 			  xmlSchemaTypePtr type)
   16592 {
   16593     int ret;
   16594     /*
   16595     * Complex Type Definition Properties Correct
   16596     */
   16597     ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
   16598     if (ret != 0)
   16599 	return (ret);
   16600     if (WXS_IS_EXTENSION(type))
   16601 	ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
   16602     else
   16603 	ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
   16604     return (ret);
   16605 }
   16606 
   16607 /**
   16608  * xmlSchemaCheckSRCCT:
   16609  * @ctxt:  the schema parser context
   16610  * @type:  the complex type definition
   16611  *
   16612  * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
   16613  * Schema Representation Constraint:
   16614  * Complex Type Definition Representation OK (src-ct)
   16615  *
   16616  * Returns 0 if the constraints are satisfied, a positive
   16617  * error code if not and -1 if an internal error occured.
   16618  */
   16619 static int
   16620 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
   16621 		    xmlSchemaTypePtr type)
   16622 {
   16623     xmlSchemaTypePtr base;
   16624     int ret = 0;
   16625 
   16626     /*
   16627     * TODO: Adjust the error codes here, as I used
   16628     * XML_SCHEMAP_SRC_CT_1 only yet.
   16629     */
   16630     base = type->baseType;
   16631     if (! WXS_HAS_SIMPLE_CONTENT(type)) {
   16632 	/*
   16633 	* 1 If the <complexContent> alternative is chosen, the type definition
   16634 	* `resolved` to by the `actual value` of the base [attribute]
   16635 	* must be a complex type definition;
   16636 	*/
   16637 	if (! WXS_IS_COMPLEX(base)) {
   16638 	    xmlChar *str = NULL;
   16639 	    xmlSchemaPCustomErr(ctxt,
   16640 		XML_SCHEMAP_SRC_CT_1,
   16641 		WXS_BASIC_CAST type, type->node,
   16642 		"If using <complexContent>, the base type is expected to be "
   16643 		"a complex type. The base type '%s' is a simple type",
   16644 		xmlSchemaFormatQName(&str, base->targetNamespace,
   16645 		base->name));
   16646 	    FREE_AND_NULL(str)
   16647 	    return (XML_SCHEMAP_SRC_CT_1);
   16648 	}
   16649     } else {
   16650 	/*
   16651 	* SPEC
   16652 	* 2 If the <simpleContent> alternative is chosen, all of the
   16653 	* following must be true:
   16654 	* 2.1 The type definition `resolved` to by the `actual value` of the
   16655 	* base [attribute] must be one of the following:
   16656 	*/
   16657 	if (WXS_IS_SIMPLE(base)) {
   16658 	    if (WXS_IS_EXTENSION(type) == 0) {
   16659 		xmlChar *str = NULL;
   16660 		/*
   16661 		* 2.1.3 only if the <extension> alternative is also
   16662 		* chosen, a simple type definition.
   16663 		*/
   16664 		/* TODO: Change error code to ..._SRC_CT_2_1_3. */
   16665 		xmlSchemaPCustomErr(ctxt,
   16666 		    XML_SCHEMAP_SRC_CT_1,
   16667 		    WXS_BASIC_CAST type, NULL,
   16668 		    "If using <simpleContent> and <restriction>, the base "
   16669 		    "type must be a complex type. The base type '%s' is "
   16670 		    "a simple type",
   16671 		    xmlSchemaFormatQName(&str, base->targetNamespace,
   16672 			base->name));
   16673 		FREE_AND_NULL(str)
   16674 		return (XML_SCHEMAP_SRC_CT_1);
   16675 	    }
   16676 	} else {
   16677 	    /* Base type is a complex type. */
   16678 	    if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
   16679 		(base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
   16680 		/*
   16681 		* 2.1.1 a complex type definition whose {content type} is a
   16682 		* simple type definition;
   16683 		* PASS
   16684 		*/
   16685 		if (base->contentTypeDef == NULL) {
   16686 		    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
   16687 			WXS_BASIC_CAST type, NULL,
   16688 			"Internal error: xmlSchemaCheckSRCCT, "
   16689 			"'%s', base type has no content type",
   16690 			type->name);
   16691 		    return (-1);
   16692 		}
   16693 	    } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
   16694 		(WXS_IS_RESTRICTION(type))) {
   16695 
   16696 		/*
   16697 		* 2.1.2 only if the <restriction> alternative is also
   16698 		* chosen, a complex type definition whose {content type}
   16699 		* is mixed and a particle emptiable.
   16700 		*/
   16701 		if (! xmlSchemaIsParticleEmptiable(
   16702 		    (xmlSchemaParticlePtr) base->subtypes)) {
   16703 		    ret = XML_SCHEMAP_SRC_CT_1;
   16704 		} else
   16705 		    /*
   16706 		    * Attention: at this point the <simpleType> child is in
   16707 		    * ->contentTypeDef (put there during parsing).
   16708 		    */
   16709 		    if (type->contentTypeDef == NULL) {
   16710 		    xmlChar *str = NULL;
   16711 		    /*
   16712 		    * 2.2 If clause 2.1.2 above is satisfied, then there
   16713 		    * must be a <simpleType> among the [children] of
   16714 		    * <restriction>.
   16715 		    */
   16716 		    /* TODO: Change error code to ..._SRC_CT_2_2. */
   16717 		    xmlSchemaPCustomErr(ctxt,
   16718 			XML_SCHEMAP_SRC_CT_1,
   16719 			WXS_BASIC_CAST type, NULL,
   16720 			"A <simpleType> is expected among the children "
   16721 			"of <restriction>, if <simpleContent> is used and "
   16722 			"the base type '%s' is a complex type",
   16723 			xmlSchemaFormatQName(&str, base->targetNamespace,
   16724 			base->name));
   16725 		    FREE_AND_NULL(str)
   16726 		    return (XML_SCHEMAP_SRC_CT_1);
   16727 		}
   16728 	    } else {
   16729 		ret = XML_SCHEMAP_SRC_CT_1;
   16730 	    }
   16731 	}
   16732 	if (ret > 0) {
   16733 	    xmlChar *str = NULL;
   16734 	    if (WXS_IS_RESTRICTION(type)) {
   16735 		xmlSchemaPCustomErr(ctxt,
   16736 		    XML_SCHEMAP_SRC_CT_1,
   16737 		    WXS_BASIC_CAST type, NULL,
   16738 		    "If <simpleContent> and <restriction> is used, the "
   16739 		    "base type must be a simple type or a complex type with "
   16740 		    "mixed content and particle emptiable. The base type "
   16741 		    "'%s' is none of those",
   16742 		    xmlSchemaFormatQName(&str, base->targetNamespace,
   16743 		    base->name));
   16744 	    } else {
   16745 		xmlSchemaPCustomErr(ctxt,
   16746 		    XML_SCHEMAP_SRC_CT_1,
   16747 		    WXS_BASIC_CAST type, NULL,
   16748 		    "If <simpleContent> and <extension> is used, the "
   16749 		    "base type must be a simple type. The base type '%s' "
   16750 		    "is a complex type",
   16751 		    xmlSchemaFormatQName(&str, base->targetNamespace,
   16752 		    base->name));
   16753 	    }
   16754 	    FREE_AND_NULL(str)
   16755 	}
   16756     }
   16757     /*
   16758     * SPEC (3) "The corresponding complex type definition component must
   16759     * satisfy the conditions set out in Constraints on Complex Type
   16760     * Definition Schema Components ($3.4.6);"
   16761     * NOTE (3) will be done in xmlSchemaTypeFixup().
   16762     */
   16763     /*
   16764     * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
   16765     * above for {attribute wildcard} is satisfied, the intensional
   16766     * intersection must be expressible, as defined in Attribute Wildcard
   16767     * Intersection ($3.10.6).
   16768     * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
   16769     */
   16770     return (ret);
   16771 }
   16772 
   16773 #ifdef ENABLE_PARTICLE_RESTRICTION
   16774 /**
   16775  * xmlSchemaCheckParticleRangeOK:
   16776  * @ctxt:  the schema parser context
   16777  * @type:  the complex type definition
   16778  *
   16779  * (3.9.6) Constraints on Particle Schema Components
   16780  * Schema Component Constraint:
   16781  * Occurrence Range OK (range-ok)
   16782  *
   16783  * STATUS: complete
   16784  *
   16785  * Returns 0 if the constraints are satisfied, a positive
   16786  * error code if not and -1 if an internal error occured.
   16787  */
   16788 static int
   16789 xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
   16790 			      int bmin, int bmax)
   16791 {
   16792     if (rmin < bmin)
   16793 	return (1);
   16794     if ((bmax != UNBOUNDED) &&
   16795 	(rmax > bmax))
   16796 	return (1);
   16797     return (0);
   16798 }
   16799 
   16800 /**
   16801  * xmlSchemaCheckRCaseNameAndTypeOK:
   16802  * @ctxt:  the schema parser context
   16803  * @r: the restricting element declaration particle
   16804  * @b: the base element declaration particle
   16805  *
   16806  * (3.9.6) Constraints on Particle Schema Components
   16807  * Schema Component Constraint:
   16808  * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
   16809  * (rcase-NameAndTypeOK)
   16810  *
   16811  * STATUS:
   16812  *   MISSING (3.2.3)
   16813  *   CLARIFY: (3.2.2)
   16814  *
   16815  * Returns 0 if the constraints are satisfied, a positive
   16816  * error code if not and -1 if an internal error occured.
   16817  */
   16818 static int
   16819 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
   16820 				 xmlSchemaParticlePtr r,
   16821 				 xmlSchemaParticlePtr b)
   16822 {
   16823     xmlSchemaElementPtr elemR, elemB;
   16824 
   16825     /* TODO: Error codes (rcase-NameAndTypeOK). */
   16826     elemR = (xmlSchemaElementPtr) r->children;
   16827     elemB = (xmlSchemaElementPtr) b->children;
   16828     /*
   16829     * SPEC (1) "The declarations' {name}s and {target namespace}s are
   16830     * the same."
   16831     */
   16832     if ((elemR != elemB) &&
   16833 	((! xmlStrEqual(elemR->name, elemB->name)) ||
   16834 	(! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
   16835 	return (1);
   16836     /*
   16837     * SPEC (2) "R's occurrence range is a valid restriction of B's
   16838     * occurrence range as defined by Occurrence Range OK ($3.9.6)."
   16839     */
   16840     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
   16841 	    b->minOccurs, b->maxOccurs) != 0)
   16842 	return (1);
   16843     /*
   16844     * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
   16845     * {scope} are global."
   16846     */
   16847     if (elemR == elemB)
   16848 	return (0);
   16849     /*
   16850     * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
   16851     */
   16852     if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
   16853 	(elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
   16854 	 return (1);
   16855     /*
   16856     * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
   16857     * or is not fixed, or R's declaration's {value constraint} is fixed
   16858     * with the same value."
   16859     */
   16860     if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
   16861 	((elemR->value == NULL) ||
   16862 	 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
   16863 	 /* TODO: Equality of the initial value or normalized or canonical? */
   16864 	 (! xmlStrEqual(elemR->value, elemB->value))))
   16865 	 return (1);
   16866     /*
   16867     * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
   16868     * definitions} is a subset of B's declaration's {identity-constraint
   16869     * definitions}, if any."
   16870     */
   16871     if (elemB->idcs != NULL) {
   16872 	/* TODO */
   16873     }
   16874     /*
   16875     * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
   16876     * superset of B's declaration's {disallowed substitutions}."
   16877     */
   16878     if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
   16879 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
   16880 	((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
   16881 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
   16882 	((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
   16883 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
   16884 	 return (1);
   16885     /*
   16886     * SPEC (3.2.5) "R's {type definition} is validly derived given
   16887     * {extension, list, union} from B's {type definition}"
   16888     *
   16889     * BADSPEC TODO: What's the point of adding "list" and "union" to the
   16890     * set, if the corresponding constraints handle "restriction" and
   16891     * "extension" only?
   16892     *
   16893     */
   16894     {
   16895 	int set = 0;
   16896 
   16897 	set |= SUBSET_EXTENSION;
   16898 	set |= SUBSET_LIST;
   16899 	set |= SUBSET_UNION;
   16900 	if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
   16901 	    elemB->subtypes, set) != 0)
   16902 	    return (1);
   16903     }
   16904     return (0);
   16905 }
   16906 
   16907 /**
   16908  * xmlSchemaCheckRCaseNSCompat:
   16909  * @ctxt:  the schema parser context
   16910  * @r: the restricting element declaration particle
   16911  * @b: the base wildcard particle
   16912  *
   16913  * (3.9.6) Constraints on Particle Schema Components
   16914  * Schema Component Constraint:
   16915  * Particle Derivation OK (Elt:Any -- NSCompat)
   16916  * (rcase-NSCompat)
   16917  *
   16918  * STATUS: complete
   16919  *
   16920  * Returns 0 if the constraints are satisfied, a positive
   16921  * error code if not and -1 if an internal error occured.
   16922  */
   16923 static int
   16924 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
   16925 			    xmlSchemaParticlePtr r,
   16926 			    xmlSchemaParticlePtr b)
   16927 {
   16928     /* TODO:Error codes (rcase-NSCompat). */
   16929     /*
   16930     * SPEC "For an element declaration particle to be a `valid restriction`
   16931     * of a wildcard particle all of the following must be true:"
   16932     *
   16933     * SPEC (1) "The element declaration's {target namespace} is `valid`
   16934     * with respect to the wildcard's {namespace constraint} as defined by
   16935     * Wildcard allows Namespace Name ($3.10.4)."
   16936     */
   16937     if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
   16938 	((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
   16939 	return (1);
   16940     /*
   16941     * SPEC (2) "R's occurrence range is a valid restriction of B's
   16942     * occurrence range as defined by Occurrence Range OK ($3.9.6)."
   16943     */
   16944     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
   16945 	    b->minOccurs, b->maxOccurs) != 0)
   16946 	return (1);
   16947 
   16948     return (0);
   16949 }
   16950 
   16951 /**
   16952  * xmlSchemaCheckRCaseRecurseAsIfGroup:
   16953  * @ctxt:  the schema parser context
   16954  * @r: the restricting element declaration particle
   16955  * @b: the base model group particle
   16956  *
   16957  * (3.9.6) Constraints on Particle Schema Components
   16958  * Schema Component Constraint:
   16959  * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
   16960  * (rcase-RecurseAsIfGroup)
   16961  *
   16962  * STATUS: TODO
   16963  *
   16964  * Returns 0 if the constraints are satisfied, a positive
   16965  * error code if not and -1 if an internal error occured.
   16966  */
   16967 static int
   16968 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
   16969 				    xmlSchemaParticlePtr r,
   16970 				    xmlSchemaParticlePtr b)
   16971 {
   16972     /* TODO: Error codes (rcase-RecurseAsIfGroup). */
   16973     TODO
   16974     return (0);
   16975 }
   16976 
   16977 /**
   16978  * xmlSchemaCheckRCaseNSSubset:
   16979  * @ctxt:  the schema parser context
   16980  * @r: the restricting wildcard particle
   16981  * @b: the base wildcard particle
   16982  *
   16983  * (3.9.6) Constraints on Particle Schema Components
   16984  * Schema Component Constraint:
   16985  * Particle Derivation OK (Any:Any -- NSSubset)
   16986  * (rcase-NSSubset)
   16987  *
   16988  * STATUS: complete
   16989  *
   16990  * Returns 0 if the constraints are satisfied, a positive
   16991  * error code if not and -1 if an internal error occured.
   16992  */
   16993 static int
   16994 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
   16995 				    xmlSchemaParticlePtr r,
   16996 				    xmlSchemaParticlePtr b,
   16997 				    int isAnyTypeBase)
   16998 {
   16999     /* TODO: Error codes (rcase-NSSubset). */
   17000     /*
   17001     * SPEC (1) "R's occurrence range is a valid restriction of B's
   17002     * occurrence range as defined by Occurrence Range OK ($3.9.6)."
   17003     */
   17004     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
   17005 	    b->minOccurs, b->maxOccurs))
   17006 	return (1);
   17007     /*
   17008     * SPEC (2) "R's {namespace constraint} must be an intensional subset
   17009     * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
   17010     */
   17011     if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
   17012 	(xmlSchemaWildcardPtr) b->children))
   17013 	return (1);
   17014     /*
   17015     * SPEC (3) "Unless B is the content model wildcard of the `ur-type
   17016     * definition`, R's {process contents} must be identical to or stronger
   17017     * than B's {process contents}, where strict is stronger than lax is
   17018     * stronger than skip."
   17019     */
   17020     if (! isAnyTypeBase) {
   17021 	if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
   17022 	    ((xmlSchemaWildcardPtr) b->children)->processContents)
   17023 	    return (1);
   17024     }
   17025 
   17026     return (0);
   17027 }
   17028 
   17029 /**
   17030  * xmlSchemaCheckCOSParticleRestrict:
   17031  * @ctxt:  the schema parser context
   17032  * @type:  the complex type definition
   17033  *
   17034  * (3.9.6) Constraints on Particle Schema Components
   17035  * Schema Component Constraint:
   17036  * Particle Valid (Restriction) (cos-particle-restrict)
   17037  *
   17038  * STATUS: TODO
   17039  *
   17040  * Returns 0 if the constraints are satisfied, a positive
   17041  * error code if not and -1 if an internal error occured.
   17042  */
   17043 static int
   17044 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
   17045 				  xmlSchemaParticlePtr r,
   17046 				  xmlSchemaParticlePtr b)
   17047 {
   17048     int ret = 0;
   17049 
   17050     /*part = WXS_TYPE_PARTICLE(type);
   17051     basePart = WXS_TYPE_PARTICLE(base);
   17052     */
   17053 
   17054     TODO
   17055 
   17056     /*
   17057     * SPEC (1) "They are the same particle."
   17058     */
   17059     if (r == b)
   17060 	return (0);
   17061 
   17062 
   17063     return (0);
   17064 }
   17065 
   17066 #if 0
   17067 /**
   17068  * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
   17069  * @ctxt:  the schema parser context
   17070  * @r: the model group particle
   17071  * @b: the base wildcard particle
   17072  *
   17073  * (3.9.6) Constraints on Particle Schema Components
   17074  * Schema Component Constraint:
   17075  * Particle Derivation OK (All/Choice/Sequence:Any --
   17076  *                         NSRecurseCheckCardinality)
   17077  * (rcase-NSRecurseCheckCardinality)
   17078  *
   17079  * STATUS: TODO: subst-groups
   17080  *
   17081  * Returns 0 if the constraints are satisfied, a positive
   17082  * error code if not and -1 if an internal error occured.
   17083  */
   17084 static int
   17085 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
   17086 					     xmlSchemaParticlePtr r,
   17087 					     xmlSchemaParticlePtr b)
   17088 {
   17089     xmlSchemaParticlePtr part;
   17090     /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
   17091     if ((r->children == NULL) || (r->children->children == NULL))
   17092 	return (-1);
   17093     /*
   17094     * SPEC "For a group particle to be a `valid restriction` of a
   17095     * wildcard particle..."
   17096     *
   17097     * SPEC (1) "Every member of the {particles} of the group is a `valid
   17098     * restriction` of the wildcard as defined by
   17099     * Particle Valid (Restriction) ($3.9.6)."
   17100     */
   17101     part = (xmlSchemaParticlePtr) r->children->children;
   17102     do {
   17103 	if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
   17104 	    return (1);
   17105 	part = (xmlSchemaParticlePtr) part->next;
   17106     } while (part != NULL);
   17107     /*
   17108     * SPEC (2) "The effective total range of the group [...] is a
   17109     * valid restriction of B's occurrence range as defined by
   17110     * Occurrence Range OK ($3.9.6)."
   17111     */
   17112     if (xmlSchemaCheckParticleRangeOK(
   17113 	    xmlSchemaGetParticleTotalRangeMin(r),
   17114 	    xmlSchemaGetParticleTotalRangeMax(r),
   17115 	    b->minOccurs, b->maxOccurs) != 0)
   17116 	return (1);
   17117     return (0);
   17118 }
   17119 #endif
   17120 
   17121 /**
   17122  * xmlSchemaCheckRCaseRecurse:
   17123  * @ctxt:  the schema parser context
   17124  * @r: the <all> or <sequence> model group particle
   17125  * @b: the base <all> or <sequence> model group particle
   17126  *
   17127  * (3.9.6) Constraints on Particle Schema Components
   17128  * Schema Component Constraint:
   17129  * Particle Derivation OK (All:All,Sequence:Sequence --
   17130                            Recurse)
   17131  * (rcase-Recurse)
   17132  *
   17133  * STATUS:  ?
   17134  * TODO: subst-groups
   17135  *
   17136  * Returns 0 if the constraints are satisfied, a positive
   17137  * error code if not and -1 if an internal error occured.
   17138  */
   17139 static int
   17140 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
   17141 			   xmlSchemaParticlePtr r,
   17142 			   xmlSchemaParticlePtr b)
   17143 {
   17144     /* xmlSchemaParticlePtr part; */
   17145     /* TODO: Error codes (rcase-Recurse). */
   17146     if ((r->children == NULL) || (b->children == NULL) ||
   17147 	(r->children->type != b->children->type))
   17148 	return (-1);
   17149     /*
   17150     * SPEC "For an all or sequence group particle to be a `valid
   17151     * restriction` of another group particle with the same {compositor}..."
   17152     *
   17153     * SPEC (1) "R's occurrence range is a valid restriction of B's
   17154     * occurrence range as defined by Occurrence Range OK ($3.9.6)."
   17155     */
   17156     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
   17157 	    b->minOccurs, b->maxOccurs))
   17158 	return (1);
   17159 
   17160 
   17161     return (0);
   17162 }
   17163 
   17164 #endif
   17165 
   17166 #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
   17167     xmlSchemaPCustomErrExt(pctxt,      \
   17168 	XML_SCHEMAP_INVALID_FACET_VALUE, \
   17169 	WXS_BASIC_CAST fac1, fac1->node, \
   17170 	"It is an error for both '%s' and '%s' to be specified on the "\
   17171 	"same type definition", \
   17172 	BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
   17173 	BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
   17174 
   17175 #define FACET_RESTR_ERR(fac1, msg) \
   17176     xmlSchemaPCustomErr(pctxt,      \
   17177 	XML_SCHEMAP_INVALID_FACET_VALUE, \
   17178 	WXS_BASIC_CAST fac1, fac1->node, \
   17179 	msg, NULL);
   17180 
   17181 #define FACET_RESTR_FIXED_ERR(fac) \
   17182     xmlSchemaPCustomErr(pctxt, \
   17183 	XML_SCHEMAP_INVALID_FACET_VALUE, \
   17184 	WXS_BASIC_CAST fac, fac->node, \
   17185 	"The base type's facet is 'fixed', thus the value must not " \
   17186 	"differ", NULL);
   17187 
   17188 static void
   17189 xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
   17190 			xmlSchemaFacetPtr facet1,
   17191 			xmlSchemaFacetPtr facet2,
   17192 			int lessGreater,
   17193 			int orEqual,
   17194 			int ofBase)
   17195 {
   17196     xmlChar *msg = NULL;
   17197 
   17198     msg = xmlStrdup(BAD_CAST "'");
   17199     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
   17200     msg = xmlStrcat(msg, BAD_CAST "' has to be");
   17201     if (lessGreater == 0)
   17202 	msg = xmlStrcat(msg, BAD_CAST " equal to");
   17203     if (lessGreater == 1)
   17204 	msg = xmlStrcat(msg, BAD_CAST " greater than");
   17205     else
   17206 	msg = xmlStrcat(msg, BAD_CAST " less than");
   17207 
   17208     if (orEqual)
   17209 	msg = xmlStrcat(msg, BAD_CAST " or equal to");
   17210     msg = xmlStrcat(msg, BAD_CAST " '");
   17211     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
   17212     if (ofBase)
   17213 	msg = xmlStrcat(msg, BAD_CAST "' of the base type");
   17214     else
   17215 	msg = xmlStrcat(msg, BAD_CAST "'");
   17216 
   17217     xmlSchemaPCustomErr(pctxt,
   17218 	XML_SCHEMAP_INVALID_FACET_VALUE,
   17219 	WXS_BASIC_CAST facet1, NULL,
   17220 	(const char *) msg, NULL);
   17221 
   17222     if (msg != NULL)
   17223 	xmlFree(msg);
   17224 }
   17225 
   17226 /*
   17227 * xmlSchemaDeriveAndValidateFacets:
   17228 *
   17229 * Schema Component Constraint: Simple Type Restriction (Facets)
   17230 * (st-restrict-facets)
   17231 */
   17232 static int
   17233 xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
   17234 				 xmlSchemaTypePtr type)
   17235 {
   17236     xmlSchemaTypePtr base = type->baseType;
   17237     xmlSchemaFacetLinkPtr link, cur, last = NULL;
   17238     xmlSchemaFacetPtr facet, bfacet,
   17239 	flength = NULL, ftotdig = NULL, ffracdig = NULL,
   17240 	fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
   17241 	fmininc = NULL, fmaxinc = NULL,
   17242 	fminexc = NULL, fmaxexc = NULL,
   17243 	bflength = NULL, bftotdig = NULL, bffracdig = NULL,
   17244 	bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
   17245 	bfmininc = NULL, bfmaxinc = NULL,
   17246 	bfminexc = NULL, bfmaxexc = NULL;
   17247     int res; /* err = 0, fixedErr; */
   17248 
   17249     /*
   17250     * SPEC st-restrict-facets 1:
   17251     * "The {variety} of R is the same as that of B."
   17252     */
   17253     /*
   17254     * SPEC st-restrict-facets 2:
   17255     * "If {variety} is atomic, the {primitive type definition}
   17256     * of R is the same as that of B."
   17257     *
   17258     * NOTE: we leave 1 & 2 out for now, since this will be
   17259     * satisfied by the derivation process.
   17260     * CONSTRUCTION TODO: Maybe needed if using a construction API.
   17261     */
   17262     /*
   17263     * SPEC st-restrict-facets 3:
   17264     * "The {facets} of R are the union of S and the {facets}
   17265     * of B, eliminating duplicates. To eliminate duplicates,
   17266     * when a facet of the same kind occurs in both S and the
   17267     * {facets} of B, the one in the {facets} of B is not
   17268     * included, with the exception of enumeration and pattern
   17269     * facets, for which multiple occurrences with distinct values
   17270     * are allowed."
   17271     */
   17272 
   17273     if ((type->facetSet == NULL) && (base->facetSet == NULL))
   17274 	return (0);
   17275 
   17276     last = type->facetSet;
   17277     if (last != NULL)
   17278 	while (last->next != NULL)
   17279 	    last = last->next;
   17280 
   17281     for (cur = type->facetSet; cur != NULL; cur = cur->next) {
   17282 	facet = cur->facet;
   17283 	switch (facet->type) {
   17284 	    case XML_SCHEMA_FACET_LENGTH:
   17285 		flength = facet; break;
   17286 	    case XML_SCHEMA_FACET_MINLENGTH:
   17287 		fminlen = facet; break;
   17288 	    case XML_SCHEMA_FACET_MININCLUSIVE:
   17289 		fmininc = facet; break;
   17290 	    case XML_SCHEMA_FACET_MINEXCLUSIVE:
   17291 		fminexc = facet; break;
   17292 	    case XML_SCHEMA_FACET_MAXLENGTH:
   17293 		fmaxlen = facet; break;
   17294 	    case XML_SCHEMA_FACET_MAXINCLUSIVE:
   17295 		fmaxinc = facet; break;
   17296 	    case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   17297 		fmaxexc = facet; break;
   17298 	    case XML_SCHEMA_FACET_TOTALDIGITS:
   17299 		ftotdig = facet; break;
   17300 	    case XML_SCHEMA_FACET_FRACTIONDIGITS:
   17301 		ffracdig = facet; break;
   17302 	    default:
   17303 		break;
   17304 	}
   17305     }
   17306     for (cur = base->facetSet; cur != NULL; cur = cur->next) {
   17307 	facet = cur->facet;
   17308 	switch (facet->type) {
   17309 	    case XML_SCHEMA_FACET_LENGTH:
   17310 		bflength = facet; break;
   17311 	    case XML_SCHEMA_FACET_MINLENGTH:
   17312 		bfminlen = facet; break;
   17313 	    case XML_SCHEMA_FACET_MININCLUSIVE:
   17314 		bfmininc = facet; break;
   17315 	    case XML_SCHEMA_FACET_MINEXCLUSIVE:
   17316 		bfminexc = facet; break;
   17317 	    case XML_SCHEMA_FACET_MAXLENGTH:
   17318 		bfmaxlen = facet; break;
   17319 	    case XML_SCHEMA_FACET_MAXINCLUSIVE:
   17320 		bfmaxinc = facet; break;
   17321 	    case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   17322 		bfmaxexc = facet; break;
   17323 	    case XML_SCHEMA_FACET_TOTALDIGITS:
   17324 		bftotdig = facet; break;
   17325 	    case XML_SCHEMA_FACET_FRACTIONDIGITS:
   17326 		bffracdig = facet; break;
   17327 	    default:
   17328 		break;
   17329 	}
   17330     }
   17331     /*
   17332     * length and minLength or maxLength (2.2) + (3.2)
   17333     */
   17334     if (flength && (fminlen || fmaxlen)) {
   17335 	FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
   17336 	    "either of 'minLength' or 'maxLength' to be specified on "
   17337 	    "the same type definition")
   17338     }
   17339     /*
   17340     * Mutual exclusions in the same derivation step.
   17341     */
   17342     if ((fmaxinc) && (fmaxexc)) {
   17343 	/*
   17344 	* SCC "maxInclusive and maxExclusive"
   17345 	*/
   17346 	FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
   17347     }
   17348     if ((fmininc) && (fminexc)) {
   17349 	/*
   17350 	* SCC "minInclusive and minExclusive"
   17351 	*/
   17352 	FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
   17353     }
   17354 
   17355     if (flength && bflength) {
   17356 	/*
   17357 	* SCC "length valid restriction"
   17358 	* The values have to be equal.
   17359 	*/
   17360 	res = xmlSchemaCompareValues(flength->val, bflength->val);
   17361 	if (res == -2)
   17362 	    goto internal_error;
   17363 	if (res != 0)
   17364 	    xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
   17365 	if ((res != 0) && (bflength->fixed)) {
   17366 	    FACET_RESTR_FIXED_ERR(flength)
   17367 	}
   17368 
   17369     }
   17370     if (fminlen && bfminlen) {
   17371 	/*
   17372 	* SCC "minLength valid restriction"
   17373 	* minLength >= BASE minLength
   17374 	*/
   17375 	res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
   17376 	if (res == -2)
   17377 	    goto internal_error;
   17378 	if (res == -1)
   17379 	    xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
   17380 	if ((res != 0) && (bfminlen->fixed)) {
   17381 	    FACET_RESTR_FIXED_ERR(fminlen)
   17382 	}
   17383     }
   17384     if (fmaxlen && bfmaxlen) {
   17385 	/*
   17386 	* SCC "maxLength valid restriction"
   17387 	* maxLength <= BASE minLength
   17388 	*/
   17389 	res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
   17390 	if (res == -2)
   17391 	    goto internal_error;
   17392 	if (res == 1)
   17393 	    xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
   17394 	if ((res != 0) && (bfmaxlen->fixed)) {
   17395 	    FACET_RESTR_FIXED_ERR(fmaxlen)
   17396 	}
   17397     }
   17398     /*
   17399     * SCC "length and minLength or maxLength"
   17400     */
   17401     if (! flength)
   17402 	flength = bflength;
   17403     if (flength) {
   17404 	if (! fminlen)
   17405 	    fminlen = bfminlen;
   17406 	if (fminlen) {
   17407 	    /* (1.1) length >= minLength */
   17408 	    res = xmlSchemaCompareValues(flength->val, fminlen->val);
   17409 	    if (res == -2)
   17410 		goto internal_error;
   17411 	    if (res == -1)
   17412 		xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
   17413 	}
   17414 	if (! fmaxlen)
   17415 	    fmaxlen = bfmaxlen;
   17416 	if (fmaxlen) {
   17417 	    /* (2.1) length <= maxLength */
   17418 	    res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
   17419 	    if (res == -2)
   17420 		goto internal_error;
   17421 	    if (res == 1)
   17422 		xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
   17423 	}
   17424     }
   17425     if (fmaxinc) {
   17426 	/*
   17427 	* "maxInclusive"
   17428 	*/
   17429 	if (fmininc) {
   17430 	    /* SCC "maxInclusive >= minInclusive" */
   17431 	    res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
   17432 	    if (res == -2)
   17433 		goto internal_error;
   17434 	    if (res == -1) {
   17435 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
   17436 	    }
   17437 	}
   17438 	/*
   17439 	* SCC "maxInclusive valid restriction"
   17440 	*/
   17441 	if (bfmaxinc) {
   17442 	    /* maxInclusive <= BASE maxInclusive */
   17443 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
   17444 	    if (res == -2)
   17445 		goto internal_error;
   17446 	    if (res == 1)
   17447 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
   17448 	    if ((res != 0) && (bfmaxinc->fixed)) {
   17449 		FACET_RESTR_FIXED_ERR(fmaxinc)
   17450 	    }
   17451 	}
   17452 	if (bfmaxexc) {
   17453 	    /* maxInclusive < BASE maxExclusive */
   17454 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
   17455 	    if (res == -2)
   17456 		goto internal_error;
   17457 	    if (res != -1) {
   17458 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
   17459 	    }
   17460 	}
   17461 	if (bfmininc) {
   17462 	    /* maxInclusive >= BASE minInclusive */
   17463 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
   17464 	    if (res == -2)
   17465 		goto internal_error;
   17466 	    if (res == -1) {
   17467 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
   17468 	    }
   17469 	}
   17470 	if (bfminexc) {
   17471 	    /* maxInclusive > BASE minExclusive */
   17472 	    res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
   17473 	    if (res == -2)
   17474 		goto internal_error;
   17475 	    if (res != 1) {
   17476 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
   17477 	    }
   17478 	}
   17479     }
   17480     if (fmaxexc) {
   17481 	/*
   17482 	* "maxExclusive >= minExclusive"
   17483 	*/
   17484 	if (fminexc) {
   17485 	    res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
   17486 	    if (res == -2)
   17487 		goto internal_error;
   17488 	    if (res == -1) {
   17489 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
   17490 	    }
   17491 	}
   17492 	/*
   17493 	* "maxExclusive valid restriction"
   17494 	*/
   17495 	if (bfmaxexc) {
   17496 	    /* maxExclusive <= BASE maxExclusive */
   17497 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
   17498 	    if (res == -2)
   17499 		goto internal_error;
   17500 	    if (res == 1) {
   17501 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
   17502 	    }
   17503 	    if ((res != 0) && (bfmaxexc->fixed)) {
   17504 		FACET_RESTR_FIXED_ERR(fmaxexc)
   17505 	    }
   17506 	}
   17507 	if (bfmaxinc) {
   17508 	    /* maxExclusive <= BASE maxInclusive */
   17509 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
   17510 	    if (res == -2)
   17511 		goto internal_error;
   17512 	    if (res == 1) {
   17513 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
   17514 	    }
   17515 	}
   17516 	if (bfmininc) {
   17517 	    /* maxExclusive > BASE minInclusive */
   17518 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
   17519 	    if (res == -2)
   17520 		goto internal_error;
   17521 	    if (res != 1) {
   17522 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
   17523 	    }
   17524 	}
   17525 	if (bfminexc) {
   17526 	    /* maxExclusive > BASE minExclusive */
   17527 	    res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
   17528 	    if (res == -2)
   17529 		goto internal_error;
   17530 	    if (res != 1) {
   17531 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
   17532 	    }
   17533 	}
   17534     }
   17535     if (fminexc) {
   17536 	/*
   17537 	* "minExclusive < maxInclusive"
   17538 	*/
   17539 	if (fmaxinc) {
   17540 	    res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
   17541 	    if (res == -2)
   17542 		goto internal_error;
   17543 	    if (res != -1) {
   17544 		xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
   17545 	    }
   17546 	}
   17547 	/*
   17548 	* "minExclusive valid restriction"
   17549 	*/
   17550 	if (bfminexc) {
   17551 	    /* minExclusive >= BASE minExclusive */
   17552 	    res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
   17553 	    if (res == -2)
   17554 		goto internal_error;
   17555 	    if (res == -1) {
   17556 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
   17557 	    }
   17558 	    if ((res != 0) && (bfminexc->fixed)) {
   17559 		FACET_RESTR_FIXED_ERR(fminexc)
   17560 	    }
   17561 	}
   17562 	if (bfmaxinc) {
   17563 	    /* minExclusive <= BASE maxInclusive */
   17564 	    res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
   17565 	    if (res == -2)
   17566 		goto internal_error;
   17567 	    if (res == 1) {
   17568 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
   17569 	    }
   17570 	}
   17571 	if (bfmininc) {
   17572 	    /* minExclusive >= BASE minInclusive */
   17573 	    res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
   17574 	    if (res == -2)
   17575 		goto internal_error;
   17576 	    if (res == -1) {
   17577 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
   17578 	    }
   17579 	}
   17580 	if (bfmaxexc) {
   17581 	    /* minExclusive < BASE maxExclusive */
   17582 	    res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
   17583 	    if (res == -2)
   17584 		goto internal_error;
   17585 	    if (res != -1) {
   17586 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
   17587 	    }
   17588 	}
   17589     }
   17590     if (fmininc) {
   17591 	/*
   17592 	* "minInclusive < maxExclusive"
   17593 	*/
   17594 	if (fmaxexc) {
   17595 	    res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
   17596 	    if (res == -2)
   17597 		goto internal_error;
   17598 	    if (res != -1) {
   17599 		xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
   17600 	    }
   17601 	}
   17602 	/*
   17603 	* "minExclusive valid restriction"
   17604 	*/
   17605 	if (bfmininc) {
   17606 	    /* minInclusive >= BASE minInclusive */
   17607 	    res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
   17608 	    if (res == -2)
   17609 		goto internal_error;
   17610 	    if (res == -1) {
   17611 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
   17612 	    }
   17613 	    if ((res != 0) && (bfmininc->fixed)) {
   17614 		FACET_RESTR_FIXED_ERR(fmininc)
   17615 	    }
   17616 	}
   17617 	if (bfmaxinc) {
   17618 	    /* minInclusive <= BASE maxInclusive */
   17619 	    res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
   17620 	    if (res == -2)
   17621 		goto internal_error;
   17622 	    if (res == 1) {
   17623 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
   17624 	    }
   17625 	}
   17626 	if (bfminexc) {
   17627 	    /* minInclusive > BASE minExclusive */
   17628 	    res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
   17629 	    if (res == -2)
   17630 		goto internal_error;
   17631 	    if (res != 1)
   17632 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
   17633 	}
   17634 	if (bfmaxexc) {
   17635 	    /* minInclusive < BASE maxExclusive */
   17636 	    res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
   17637 	    if (res == -2)
   17638 		goto internal_error;
   17639 	    if (res != -1)
   17640 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
   17641 	}
   17642     }
   17643     if (ftotdig && bftotdig) {
   17644 	/*
   17645 	* SCC " totalDigits valid restriction"
   17646 	* totalDigits <= BASE totalDigits
   17647 	*/
   17648 	res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
   17649 	if (res == -2)
   17650 	    goto internal_error;
   17651 	if (res == 1)
   17652 	    xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
   17653 	    -1, 1, 1);
   17654 	if ((res != 0) && (bftotdig->fixed)) {
   17655 	    FACET_RESTR_FIXED_ERR(ftotdig)
   17656 	}
   17657     }
   17658     if (ffracdig && bffracdig) {
   17659 	/*
   17660 	* SCC  "fractionDigits valid restriction"
   17661 	* fractionDigits <= BASE fractionDigits
   17662 	*/
   17663 	res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
   17664 	if (res == -2)
   17665 	    goto internal_error;
   17666 	if (res == 1)
   17667 	    xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
   17668 	    -1, 1, 1);
   17669 	if ((res != 0) && (bffracdig->fixed)) {
   17670 	    FACET_RESTR_FIXED_ERR(ffracdig)
   17671 	}
   17672     }
   17673     /*
   17674     * SCC "fractionDigits less than or equal to totalDigits"
   17675     */
   17676     if (! ftotdig)
   17677 	ftotdig = bftotdig;
   17678     if (! ffracdig)
   17679 	ffracdig = bffracdig;
   17680     if (ftotdig && ffracdig) {
   17681 	res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
   17682 	if (res == -2)
   17683 	    goto internal_error;
   17684 	if (res == 1)
   17685 	    xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
   17686 		-1, 1, 0);
   17687     }
   17688     /*
   17689     * *Enumerations* won' be added here, since only the first set
   17690     * of enumerations in the ancestor-or-self axis is used
   17691     * for validation, plus we need to use the base type of those
   17692     * enumerations for whitespace.
   17693     *
   17694     * *Patterns*: won't be add here, since they are ORed at
   17695     * type level and ANDed at ancestor level. This will
   17696     * happed during validation by walking the base axis
   17697     * of the type.
   17698     */
   17699     for (cur = base->facetSet; cur != NULL; cur = cur->next) {
   17700 	bfacet = cur->facet;
   17701 	/*
   17702 	* Special handling of enumerations and patterns.
   17703 	* TODO: hmm, they should not appear in the set, so remove this.
   17704 	*/
   17705 	if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
   17706 	    (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
   17707 	    continue;
   17708 	/*
   17709 	* Search for a duplicate facet in the current type.
   17710 	*/
   17711 	link = type->facetSet;
   17712 	/* err = 0; */
   17713 	/* fixedErr = 0; */
   17714 	while (link != NULL) {
   17715 	    facet = link->facet;
   17716 	    if (facet->type == bfacet->type) {
   17717 		switch (facet->type) {
   17718 		    case XML_SCHEMA_FACET_WHITESPACE:
   17719 			/*
   17720 			* The whitespace must be stronger.
   17721 			*/
   17722 			if (facet->whitespace < bfacet->whitespace) {
   17723 			    FACET_RESTR_ERR(facet,
   17724 				"The 'whitespace' value has to be equal to "
   17725 				"or stronger than the 'whitespace' value of "
   17726 				"the base type")
   17727 			}
   17728 			if ((bfacet->fixed) &&
   17729 			    (facet->whitespace != bfacet->whitespace)) {
   17730 			    FACET_RESTR_FIXED_ERR(facet)
   17731 			}
   17732 			break;
   17733 		    default:
   17734 			break;
   17735 		}
   17736 		/* Duplicate found. */
   17737 		break;
   17738 	    }
   17739 	    link = link->next;
   17740 	}
   17741 	/*
   17742 	* If no duplicate was found: add the base types's facet
   17743 	* to the set.
   17744 	*/
   17745 	if (link == NULL) {
   17746 	    link = (xmlSchemaFacetLinkPtr)
   17747 		xmlMalloc(sizeof(xmlSchemaFacetLink));
   17748 	    if (link == NULL) {
   17749 		xmlSchemaPErrMemory(pctxt,
   17750 		    "deriving facets, creating a facet link", NULL);
   17751 		return (-1);
   17752 	    }
   17753 	    link->facet = cur->facet;
   17754 	    link->next = NULL;
   17755 	    if (last == NULL)
   17756 		type->facetSet = link;
   17757 	    else
   17758 		last->next = link;
   17759 	    last = link;
   17760 	}
   17761 
   17762     }
   17763 
   17764     return (0);
   17765 internal_error:
   17766     PERROR_INT("xmlSchemaDeriveAndValidateFacets",
   17767 	"an error occured");
   17768     return (-1);
   17769 }
   17770 
   17771 static int
   17772 xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
   17773 					     xmlSchemaTypePtr type)
   17774 {
   17775     xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
   17776     /*
   17777     * The actual value is then formed by replacing any union type
   17778     * definition in the `explicit members` with the members of their
   17779     * {member type definitions}, in order.
   17780     *
   17781     * TODO: There's a bug entry at
   17782     * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
   17783     * which indicates that we'll keep the union types the future.
   17784     */
   17785     link = type->memberTypes;
   17786     while (link != NULL) {
   17787 
   17788 	if (WXS_IS_TYPE_NOT_FIXED(link->type))
   17789 	    xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
   17790 
   17791 	if (WXS_IS_UNION(link->type)) {
   17792 	    subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
   17793 	    if (subLink != NULL) {
   17794 		link->type = subLink->type;
   17795 		if (subLink->next != NULL) {
   17796 		    lastLink = link->next;
   17797 		    subLink = subLink->next;
   17798 		    prevLink = link;
   17799 		    while (subLink != NULL) {
   17800 			newLink = (xmlSchemaTypeLinkPtr)
   17801 			    xmlMalloc(sizeof(xmlSchemaTypeLink));
   17802 			if (newLink == NULL) {
   17803 			    xmlSchemaPErrMemory(pctxt, "allocating a type link",
   17804 				NULL);
   17805 			    return (-1);
   17806 			}
   17807 			newLink->type = subLink->type;
   17808 			prevLink->next = newLink;
   17809 			prevLink = newLink;
   17810 			newLink->next = lastLink;
   17811 
   17812 			subLink = subLink->next;
   17813 		    }
   17814 		}
   17815 	    }
   17816 	}
   17817 	link = link->next;
   17818     }
   17819     return (0);
   17820 }
   17821 
   17822 static void
   17823 xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
   17824 {
   17825     int has = 0, needVal = 0, normVal = 0;
   17826 
   17827     has	= (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
   17828     if (has) {
   17829 	needVal = (type->baseType->flags &
   17830 	    XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
   17831 	normVal = (type->baseType->flags &
   17832 	    XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
   17833     }
   17834     if (type->facets != NULL) {
   17835 	xmlSchemaFacetPtr fac;
   17836 
   17837 	for (fac = type->facets; fac != NULL; fac = fac->next) {
   17838 	    switch (fac->type) {
   17839 		case XML_SCHEMA_FACET_WHITESPACE:
   17840 		    break;
   17841 		case XML_SCHEMA_FACET_PATTERN:
   17842 		    normVal = 1;
   17843 		    has = 1;
   17844 		    break;
   17845 		case XML_SCHEMA_FACET_ENUMERATION:
   17846 		    needVal = 1;
   17847 		    normVal = 1;
   17848 		    has = 1;
   17849 		    break;
   17850 		default:
   17851 		    has = 1;
   17852 		    break;
   17853 	    }
   17854 	}
   17855     }
   17856     if (normVal)
   17857 	type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
   17858     if (needVal)
   17859 	type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
   17860     if (has)
   17861 	type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
   17862 
   17863     if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
   17864 	xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
   17865 	/*
   17866 	* OPTIMIZE VAL TODO: Some facets need a computed value.
   17867 	*/
   17868 	if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
   17869 	    (prim->builtInType != XML_SCHEMAS_STRING)) {
   17870 	    type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
   17871 	}
   17872     }
   17873 }
   17874 
   17875 static int
   17876 xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
   17877 {
   17878 
   17879 
   17880     /*
   17881     * Evaluate the whitespace-facet value.
   17882     */
   17883     if (WXS_IS_LIST(type)) {
   17884 	type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
   17885 	return (0);
   17886     } else if (WXS_IS_UNION(type))
   17887 	return (0);
   17888 
   17889     if (type->facetSet != NULL) {
   17890 	xmlSchemaFacetLinkPtr lin;
   17891 
   17892 	for (lin = type->facetSet; lin != NULL; lin = lin->next) {
   17893 	    if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
   17894 		switch (lin->facet->whitespace) {
   17895 		case XML_SCHEMAS_FACET_PRESERVE:
   17896 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
   17897 		    break;
   17898 		case XML_SCHEMAS_FACET_REPLACE:
   17899 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
   17900 		    break;
   17901 		case XML_SCHEMAS_FACET_COLLAPSE:
   17902 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
   17903 		    break;
   17904 		default:
   17905 		    return (-1);
   17906 		}
   17907 		return (0);
   17908 	    }
   17909 	}
   17910     }
   17911     /*
   17912     * For all `atomic` datatypes other than string (and types `derived`
   17913     * by `restriction` from it) the value of whiteSpace is fixed to
   17914     * collapse
   17915     */
   17916     {
   17917 	xmlSchemaTypePtr anc;
   17918 
   17919 	for (anc = type->baseType; anc != NULL &&
   17920 		anc->builtInType != XML_SCHEMAS_ANYTYPE;
   17921 		anc = anc->baseType) {
   17922 
   17923 	    if (anc->type == XML_SCHEMA_TYPE_BASIC) {
   17924 		if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
   17925 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
   17926 
   17927 		} else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
   17928 		    (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
   17929 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
   17930 
   17931 		} else
   17932 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
   17933 		break;
   17934 	    }
   17935 	}
   17936     }
   17937     return (0);
   17938 }
   17939 
   17940 static int
   17941 xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
   17942 			  xmlSchemaTypePtr type)
   17943 {
   17944     if (type->type != XML_SCHEMA_TYPE_SIMPLE)
   17945 	return(0);
   17946     if (! WXS_IS_TYPE_NOT_FIXED_1(type))
   17947 	return(0);
   17948     type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
   17949 
   17950     if (WXS_IS_LIST(type)) {
   17951 	/*
   17952 	* Corresponds to <simpleType><list>...
   17953 	*/
   17954 	if (type->subtypes == NULL) {
   17955 	    /*
   17956 	    * This one is really needed, so get out.
   17957 	    */
   17958 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
   17959 		"list type has no item-type assigned");
   17960 	    return(-1);
   17961 	}
   17962     } else if (WXS_IS_UNION(type)) {
   17963 	/*
   17964 	* Corresponds to <simpleType><union>...
   17965 	*/
   17966 	if (type->memberTypes == NULL) {
   17967 	    /*
   17968 	    * This one is really needed, so get out.
   17969 	    */
   17970 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
   17971 		"union type has no member-types assigned");
   17972 	    return(-1);
   17973 	}
   17974     } else {
   17975 	/*
   17976 	* Corresponds to <simpleType><restriction>...
   17977 	*/
   17978 	if (type->baseType == NULL) {
   17979 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
   17980 		"type has no base-type assigned");
   17981 	    return(-1);
   17982 	}
   17983 	if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
   17984 	    if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
   17985 		return(-1);
   17986 	/*
   17987 	* Variety
   17988 	* If the <restriction> alternative is chosen, then the
   17989 	* {variety} of the {base type definition}.
   17990 	*/
   17991 	if (WXS_IS_ATOMIC(type->baseType))
   17992 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
   17993 	else if (WXS_IS_LIST(type->baseType)) {
   17994 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
   17995 	    /*
   17996 	    * Inherit the itemType.
   17997 	    */
   17998 	    type->subtypes = type->baseType->subtypes;
   17999 	} else if (WXS_IS_UNION(type->baseType)) {
   18000 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
   18001 	    /*
   18002 	    * NOTE that we won't assign the memberTypes of the base,
   18003 	    * since this will make trouble when freeing them; we will
   18004 	    * use a lookup function to access them instead.
   18005 	    */
   18006 	}
   18007     }
   18008     return(0);
   18009 }
   18010 
   18011 #ifdef DEBUG_TYPE
   18012 static void
   18013 xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
   18014 		       xmlSchemaTypePtr type)
   18015 {
   18016     if (type->node != NULL) {
   18017         xmlGenericError(xmlGenericErrorContext,
   18018                         "Type of %s : %s:%d :", name,
   18019                         type->node->doc->URL,
   18020                         xmlGetLineNo(type->node));
   18021     } else {
   18022         xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
   18023     }
   18024     if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
   18025 	switch (type->contentType) {
   18026 	    case XML_SCHEMA_CONTENT_SIMPLE:
   18027 		xmlGenericError(xmlGenericErrorContext, "simple\n");
   18028 		break;
   18029 	    case XML_SCHEMA_CONTENT_ELEMENTS:
   18030 		xmlGenericError(xmlGenericErrorContext, "elements\n");
   18031 		break;
   18032 	    case XML_SCHEMA_CONTENT_UNKNOWN:
   18033 		xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
   18034 		break;
   18035 	    case XML_SCHEMA_CONTENT_EMPTY:
   18036 		xmlGenericError(xmlGenericErrorContext, "empty\n");
   18037 		break;
   18038 	    case XML_SCHEMA_CONTENT_MIXED:
   18039 		if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
   18040 		    type->subtypes))
   18041 		    xmlGenericError(xmlGenericErrorContext,
   18042 			"mixed as emptiable particle\n");
   18043 		else
   18044 		    xmlGenericError(xmlGenericErrorContext, "mixed\n");
   18045 		break;
   18046 		/* Removed, since not used. */
   18047 		/*
   18048 		case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
   18049 		xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
   18050 		break;
   18051 		*/
   18052 	    case XML_SCHEMA_CONTENT_BASIC:
   18053 		xmlGenericError(xmlGenericErrorContext, "basic\n");
   18054 		break;
   18055 	    default:
   18056 		xmlGenericError(xmlGenericErrorContext,
   18057 		    "not registered !!!\n");
   18058 		break;
   18059 	}
   18060     }
   18061 }
   18062 #endif
   18063 
   18064 /*
   18065 * 3.14.6 Constraints on Simple Type Definition Schema Components
   18066 */
   18067 static int
   18068 xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
   18069 				 xmlSchemaTypePtr type)
   18070 {
   18071     int res, olderrs = pctxt->nberrors;
   18072 
   18073     if (type->type != XML_SCHEMA_TYPE_SIMPLE)
   18074 	return(-1);
   18075 
   18076     if (! WXS_IS_TYPE_NOT_FIXED(type))
   18077 	return(0);
   18078 
   18079     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
   18080     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   18081 
   18082     if (type->baseType == NULL) {
   18083 	PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
   18084 	    "missing baseType");
   18085 	goto exit_failure;
   18086     }
   18087     if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
   18088 	xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
   18089     /*
   18090     * If a member type of a union is a union itself, we need to substitute
   18091     * that member type for its member types.
   18092     * NOTE that this might change in WXS 1.1; i.e. we will keep the union
   18093     * types in WXS 1.1.
   18094     */
   18095     if ((type->memberTypes != NULL) &&
   18096 	(xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
   18097 	return(-1);
   18098     /*
   18099     * SPEC src-simple-type 1
   18100     * "The corresponding simple type definition, if any, must satisfy
   18101     * the conditions set out in Constraints on Simple Type Definition
   18102     * Schema Components ($3.14.6)."
   18103     */
   18104     /*
   18105     * Schema Component Constraint: Simple Type Definition Properties Correct
   18106     * (st-props-correct)
   18107     */
   18108     res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
   18109     HFAILURE HERROR
   18110     /*
   18111     * Schema Component Constraint: Derivation Valid (Restriction, Simple)
   18112     * (cos-st-restricts)
   18113     */
   18114     res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
   18115     HFAILURE HERROR
   18116     /*
   18117     * TODO: Removed the error report, since it got annoying to get an
   18118     * extra error report, if anything failed until now.
   18119     * Enable this if needed.
   18120     *
   18121     * xmlSchemaPErr(ctxt, type->node,
   18122     *    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   18123     *    "Simple type '%s' does not satisfy the constraints "
   18124     *    "on simple type definitions.\n",
   18125     *    type->name, NULL);
   18126     */
   18127     /*
   18128     * Schema Component Constraint: Simple Type Restriction (Facets)
   18129     * (st-restrict-facets)
   18130     */
   18131     res = xmlSchemaCheckFacetValues(type, pctxt);
   18132     HFAILURE HERROR
   18133     if ((type->facetSet != NULL) ||
   18134 	(type->baseType->facetSet != NULL)) {
   18135 	res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
   18136 	HFAILURE HERROR
   18137     }
   18138     /*
   18139     * Whitespace value.
   18140     */
   18141     res = xmlSchemaTypeFixupWhitespace(type);
   18142     HFAILURE HERROR
   18143     xmlSchemaTypeFixupOptimFacets(type);
   18144 
   18145 exit_error:
   18146 #ifdef DEBUG_TYPE
   18147     xmlSchemaDebugFixedType(pctxt, type);
   18148 #endif
   18149     if (olderrs != pctxt->nberrors)
   18150 	return(pctxt->err);
   18151     return(0);
   18152 
   18153 exit_failure:
   18154 #ifdef DEBUG_TYPE
   18155     xmlSchemaDebugFixedType(pctxt, type);
   18156 #endif
   18157     return(-1);
   18158 }
   18159 
   18160 static int
   18161 xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
   18162 			  xmlSchemaTypePtr type)
   18163 {
   18164     int res = 0, olderrs = pctxt->nberrors;
   18165     xmlSchemaTypePtr baseType = type->baseType;
   18166 
   18167     if (! WXS_IS_TYPE_NOT_FIXED(type))
   18168 	return(0);
   18169     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
   18170     if (baseType == NULL) {
   18171 	PERROR_INT("xmlSchemaFixupComplexType",
   18172 	    "missing baseType");
   18173 	goto exit_failure;
   18174     }
   18175     /*
   18176     * Fixup the base type.
   18177     */
   18178     if (WXS_IS_TYPE_NOT_FIXED(baseType))
   18179 	xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
   18180     if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
   18181 	/*
   18182 	* Skip fixup if the base type is invalid.
   18183 	* TODO: Generate a warning!
   18184 	*/
   18185 	return(0);
   18186     }
   18187     /*
   18188     * This basically checks if the base type can be derived.
   18189     */
   18190     res = xmlSchemaCheckSRCCT(pctxt, type);
   18191     HFAILURE HERROR
   18192     /*
   18193     * Fixup the content type.
   18194     */
   18195     if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
   18196 	/*
   18197 	* Corresponds to <complexType><simpleContent>...
   18198 	*/
   18199 	if ((WXS_IS_COMPLEX(baseType)) &&
   18200 	    (baseType->contentTypeDef != NULL) &&
   18201 	    (WXS_IS_RESTRICTION(type))) {
   18202 	    xmlSchemaTypePtr contentBase, content;
   18203 #ifdef ENABLE_NAMED_LOCALS
   18204 	    char buf[30];
   18205 	    const xmlChar *tmpname;
   18206 #endif
   18207 	    /*
   18208 	    * SPEC (1) If <restriction> + base type is <complexType>,
   18209 	    * "whose own {content type} is a simple type..."
   18210 	    */
   18211 	    if (type->contentTypeDef != NULL) {
   18212 		/*
   18213 		* SPEC (1.1) "the simple type definition corresponding to the
   18214 		* <simpleType> among the [children] of <restriction> if there
   18215 		* is one;"
   18216 		* Note that this "<simpleType> among the [children]" was put
   18217 		* into ->contentTypeDef during parsing.
   18218 		*/
   18219 		contentBase = type->contentTypeDef;
   18220 		type->contentTypeDef = NULL;
   18221 	    } else {
   18222 		/*
   18223 		* (1.2) "...otherwise (<restriction> has no <simpleType>
   18224 		* among its [children]), the simple type definition which
   18225 		* is the {content type} of the ... base type."
   18226 		*/
   18227 		contentBase = baseType->contentTypeDef;
   18228 	    }
   18229 	    /*
   18230 	    * SPEC
   18231 	    * "... a simple type definition which restricts the simple
   18232 	    * type definition identified in clause 1.1 or clause 1.2
   18233 	    * with a set of facet components"
   18234 	    *
   18235 	    * Create the anonymous simple type, which will be the content
   18236 	    * type of the complex type.
   18237 	    */
   18238 #ifdef ENABLE_NAMED_LOCALS
   18239 	    snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
   18240 	    tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
   18241 	    content = xmlSchemaAddType(pctxt, pctxt->schema,
   18242 		XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
   18243 		type->node, 0);
   18244 #else
   18245 	    content = xmlSchemaAddType(pctxt, pctxt->schema,
   18246 		XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
   18247 		type->node, 0);
   18248 #endif
   18249 	    if (content == NULL)
   18250 		goto exit_failure;
   18251 	    /*
   18252 	    * We will use the same node as for the <complexType>
   18253 	    * to have it somehow anchored in the schema doc.
   18254 	    */
   18255 	    content->type = XML_SCHEMA_TYPE_SIMPLE;
   18256 	    content->baseType = contentBase;
   18257 	    /*
   18258 	    * Move the facets, previously anchored on the
   18259 	    * complexType during parsing.
   18260 	    */
   18261 	    content->facets = type->facets;
   18262 	    type->facets = NULL;
   18263 	    content->facetSet = type->facetSet;
   18264 	    type->facetSet = NULL;
   18265 
   18266 	    type->contentTypeDef = content;
   18267 	    if (WXS_IS_TYPE_NOT_FIXED(contentBase))
   18268 		xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
   18269 	    /*
   18270 	    * Fixup the newly created type. We don't need to check
   18271 	    * for circularity here.
   18272 	    */
   18273 	    res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
   18274 	    HFAILURE HERROR
   18275 	    res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
   18276 	    HFAILURE HERROR
   18277 
   18278 	} else if ((WXS_IS_COMPLEX(baseType)) &&
   18279 	    (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
   18280 	    (WXS_IS_RESTRICTION(type))) {
   18281 	    /*
   18282 	    * SPEC (2) If <restriction> + base is a mixed <complexType> with
   18283 	    * an emptiable particle, then a simple type definition which
   18284 	    * restricts the <restriction>'s <simpleType> child.
   18285 	    */
   18286 	    if ((type->contentTypeDef == NULL) ||
   18287 		(type->contentTypeDef->baseType == NULL)) {
   18288 		/*
   18289 		* TODO: Check if this ever happens.
   18290 		*/
   18291 		xmlSchemaPCustomErr(pctxt,
   18292 		    XML_SCHEMAP_INTERNAL,
   18293 		    WXS_BASIC_CAST type, NULL,
   18294 		    "Internal error: xmlSchemaTypeFixup, "
   18295 		    "complex type '%s': the <simpleContent><restriction> "
   18296 		    "is missing a <simpleType> child, but was not catched "
   18297 		    "by xmlSchemaCheckSRCCT()", type->name);
   18298 		goto exit_failure;
   18299 	    }
   18300 	} else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
   18301 	    /*
   18302 	    * SPEC (3) If <extension> + base is <complexType> with
   18303 	    * <simpleType> content, "...then the {content type} of that
   18304 	    * complex type definition"
   18305 	    */
   18306 	    if (baseType->contentTypeDef == NULL) {
   18307 		/*
   18308 		* TODO: Check if this ever happens. xmlSchemaCheckSRCCT
   18309 		* should have catched this already.
   18310 		*/
   18311 		xmlSchemaPCustomErr(pctxt,
   18312 		    XML_SCHEMAP_INTERNAL,
   18313 		    WXS_BASIC_CAST type, NULL,
   18314 		    "Internal error: xmlSchemaTypeFixup, "
   18315 		    "complex type '%s': the <extension>ed base type is "
   18316 		    "a complex type with no simple content type",
   18317 		    type->name);
   18318 		goto exit_failure;
   18319 	    }
   18320 	    type->contentTypeDef = baseType->contentTypeDef;
   18321 	} else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
   18322 	    /*
   18323 	    * SPEC (4) <extension> + base is <simpleType>
   18324 	    * "... then that simple type definition"
   18325 	    */
   18326 	    type->contentTypeDef = baseType;
   18327 	} else {
   18328 	    /*
   18329 	    * TODO: Check if this ever happens.
   18330 	    */
   18331 	    xmlSchemaPCustomErr(pctxt,
   18332 		XML_SCHEMAP_INTERNAL,
   18333 		WXS_BASIC_CAST type, NULL,
   18334 		"Internal error: xmlSchemaTypeFixup, "
   18335 		"complex type '%s' with <simpleContent>: unhandled "
   18336 		"derivation case", type->name);
   18337 	    goto exit_failure;
   18338 	}
   18339     } else {
   18340 	int dummySequence = 0;
   18341 	xmlSchemaParticlePtr particle =
   18342 	    (xmlSchemaParticlePtr) type->subtypes;
   18343 	/*
   18344 	* Corresponds to <complexType><complexContent>...
   18345 	*
   18346 	* NOTE that the effective mixed was already set during parsing of
   18347 	* <complexType> and <complexContent>; its flag value is
   18348 	* XML_SCHEMAS_TYPE_MIXED.
   18349 	*
   18350 	* Compute the "effective content":
   18351 	* (2.1.1) + (2.1.2) + (2.1.3)
   18352 	*/
   18353 	if ((particle == NULL) ||
   18354 	    ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
   18355 	    ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
   18356 	    (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
   18357 	    ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
   18358 	    (particle->minOccurs == 0))) &&
   18359 	    ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
   18360 	    if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
   18361 		/*
   18362 		* SPEC (2.1.4) "If the `effective mixed` is true, then
   18363 		* a particle whose properties are as follows:..."
   18364 		*
   18365 		* Empty sequence model group with
   18366 		* minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
   18367 		* NOTE that we sill assign it the <complexType> node to
   18368 		* somehow anchor it in the doc.
   18369 		*/
   18370 		if ((particle == NULL) ||
   18371 		    (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
   18372 		    /*
   18373 		    * Create the particle.
   18374 		    */
   18375 		    particle = xmlSchemaAddParticle(pctxt,
   18376 			type->node, 1, 1);
   18377 		    if (particle == NULL)
   18378 			goto exit_failure;
   18379 		    /*
   18380 		    * Create the model group.
   18381 		    */ /* URGENT TODO: avoid adding to pending items. */
   18382 		    particle->children = (xmlSchemaTreeItemPtr)
   18383 			xmlSchemaAddModelGroup(pctxt, pctxt->schema,
   18384 			XML_SCHEMA_TYPE_SEQUENCE, type->node);
   18385 		    if (particle->children == NULL)
   18386 			goto exit_failure;
   18387 
   18388 		    type->subtypes = (xmlSchemaTypePtr) particle;
   18389 		}
   18390 		dummySequence = 1;
   18391 		type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
   18392 	    } else {
   18393 		/*
   18394 		* SPEC (2.1.5) "otherwise empty"
   18395 		*/
   18396 		type->contentType = XML_SCHEMA_CONTENT_EMPTY;
   18397 	    }
   18398 	} else {
   18399 	    /*
   18400 	    * SPEC (2.2) "otherwise the particle corresponding to the
   18401 	    * <all>, <choice>, <group> or <sequence> among the
   18402 	    * [children]."
   18403 	    */
   18404 	    type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
   18405 	}
   18406 	/*
   18407 	* Compute the "content type".
   18408 	*/
   18409 	if (WXS_IS_RESTRICTION(type)) {
   18410 	    /*
   18411 	    * SPEC (3.1) "If <restriction>..."
   18412 	    * (3.1.1) + (3.1.2) */
   18413 	    if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
   18414 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
   18415 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
   18416 	    }
   18417 	} else {
   18418 	    /*
   18419 	    * SPEC (3.2) "If <extension>..."
   18420 	    */
   18421 	    if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   18422 		/*
   18423 		* SPEC (3.2.1)
   18424 		* "If the `effective content` is empty, then the
   18425 		*  {content type} of the [...] base ..."
   18426 		*/
   18427 		type->contentType = baseType->contentType;
   18428 		type->subtypes = baseType->subtypes;
   18429 		/*
   18430 		* Fixes bug #347316:
   18431 		* This is the case when the base type has a simple
   18432 		* type definition as content.
   18433 		*/
   18434 		type->contentTypeDef = baseType->contentTypeDef;
   18435 		/*
   18436 		* NOTE that the effective mixed is ignored here.
   18437 		*/
   18438 	    } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   18439 		/*
   18440 		* SPEC (3.2.2)
   18441 		*/
   18442 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
   18443 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
   18444 	    } else {
   18445 		/*
   18446 		* SPEC (3.2.3)
   18447 		*/
   18448 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
   18449 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
   18450 		    /*
   18451 		    * "A model group whose {compositor} is sequence and whose
   18452 		    * {particles} are..."
   18453 		    */
   18454 		if ((WXS_TYPE_PARTICLE(type) != NULL) &&
   18455 		    (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
   18456 		    ((WXS_TYPE_PARTICLE_TERM(type))->type ==
   18457 			XML_SCHEMA_TYPE_ALL))
   18458 		{
   18459 		    /*
   18460 		    * SPEC cos-all-limited (1)
   18461 		    */
   18462 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18463 			/* TODO: error code */
   18464 			XML_SCHEMAP_COS_ALL_LIMITED,
   18465 			WXS_ITEM_NODE(type), NULL,
   18466 			"The type has an 'all' model group in its "
   18467 			"{content type} and thus cannot be derived from "
   18468 			"a non-empty type, since this would produce a "
   18469 			"'sequence' model group containing the 'all' "
   18470 			"model group; 'all' model groups are not "
   18471 			"allowed to appear inside other model groups",
   18472 			NULL, NULL);
   18473 
   18474 		} else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
   18475 		    (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
   18476 		    ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
   18477 			XML_SCHEMA_TYPE_ALL))
   18478 		{
   18479 		    /*
   18480 		    * SPEC cos-all-limited (1)
   18481 		    */
   18482 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18483 			/* TODO: error code */
   18484 			XML_SCHEMAP_COS_ALL_LIMITED,
   18485 			WXS_ITEM_NODE(type), NULL,
   18486 			"A type cannot be derived by extension from a type "
   18487 			"which has an 'all' model group in its "
   18488 			"{content type}, since this would produce a "
   18489 			"'sequence' model group containing the 'all' "
   18490 			"model group; 'all' model groups are not "
   18491 			"allowed to appear inside other model groups",
   18492 			NULL, NULL);
   18493 
   18494 		} else if (! dummySequence) {
   18495 		    xmlSchemaTreeItemPtr effectiveContent =
   18496 			(xmlSchemaTreeItemPtr) type->subtypes;
   18497 		    /*
   18498 		    * Create the particle.
   18499 		    */
   18500 		    particle = xmlSchemaAddParticle(pctxt,
   18501 			type->node, 1, 1);
   18502 		    if (particle == NULL)
   18503 			goto exit_failure;
   18504 		    /*
   18505 		    * Create the "sequence" model group.
   18506 		    */
   18507 		    particle->children = (xmlSchemaTreeItemPtr)
   18508 			xmlSchemaAddModelGroup(pctxt, pctxt->schema,
   18509 			XML_SCHEMA_TYPE_SEQUENCE, type->node);
   18510 		    if (particle->children == NULL)
   18511 			goto exit_failure;
   18512 		    WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
   18513 		    /*
   18514 		    * SPEC "the particle of the {content type} of
   18515 		    * the ... base ..."
   18516 		    * Create a duplicate of the base type's particle
   18517 		    * and assign its "term" to it.
   18518 		    */
   18519 		    particle->children->children =
   18520 			(xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
   18521 			type->node,
   18522 			((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
   18523 			((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
   18524 		    if (particle->children->children == NULL)
   18525 			goto exit_failure;
   18526 		    particle = (xmlSchemaParticlePtr)
   18527 			particle->children->children;
   18528 		    particle->children =
   18529 			((xmlSchemaParticlePtr) baseType->subtypes)->children;
   18530 		    /*
   18531 		    * SPEC "followed by the `effective content`."
   18532 		    */
   18533 		    particle->next = effectiveContent;
   18534 		    /*
   18535 		    * This all will result in:
   18536 		    * new-particle
   18537 		    *   --> new-sequence(
   18538 		    *         new-particle
   18539 		    *           --> base-model,
   18540 		    *         this-particle
   18541 		    *	        --> this-model
   18542 		    *	    )
   18543 		    */
   18544 		} else {
   18545 		    /*
   18546 		    * This is the case when there is already an empty
   18547 		    * <sequence> with minOccurs==maxOccurs==1.
   18548 		    * Just add the base types's content type.
   18549 		    * NOTE that, although we miss to add an intermediate
   18550 		    * <sequence>, this should produce no difference to
   18551 		    * neither the regex compilation of the content model,
   18552 		    * nor to the complex type contraints.
   18553 		    */
   18554 		    particle->children->children =
   18555 			(xmlSchemaTreeItemPtr) baseType->subtypes;
   18556 		}
   18557 	    }
   18558 	}
   18559     }
   18560     /*
   18561     * Now fixup attribute uses:
   18562     *   - expand attr. group references
   18563     *     - intersect attribute wildcards
   18564     *   - inherit attribute uses of the base type
   18565     *   - inherit or union attr. wildcards if extending
   18566     *   - apply attr. use prohibitions if restricting
   18567     */
   18568     res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
   18569     HFAILURE HERROR
   18570     /*
   18571     * Apply the complex type component constraints; this will not
   18572     * check attributes, since this is done in
   18573     * xmlSchemaFixupTypeAttributeUses().
   18574     */
   18575     res = xmlSchemaCheckCTComponent(pctxt, type);
   18576     HFAILURE HERROR
   18577 
   18578 #ifdef DEBUG_TYPE
   18579     xmlSchemaDebugFixedType(pctxt, type);
   18580 #endif
   18581     if (olderrs != pctxt->nberrors)
   18582 	return(pctxt->err);
   18583     else
   18584 	return(0);
   18585 
   18586 exit_error:
   18587     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
   18588 #ifdef DEBUG_TYPE
   18589     xmlSchemaDebugFixedType(pctxt, type);
   18590 #endif
   18591     return(pctxt->err);
   18592 
   18593 exit_failure:
   18594     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
   18595 #ifdef DEBUG_TYPE
   18596     xmlSchemaDebugFixedType(pctxt, type);
   18597 #endif
   18598     return(-1);
   18599 }
   18600 
   18601 
   18602 /**
   18603  * xmlSchemaTypeFixup:
   18604  * @typeDecl:  the schema type definition
   18605  * @ctxt:  the schema parser context
   18606  *
   18607  * Fixes the content model of the type.
   18608  * URGENT TODO: We need an int result!
   18609  */
   18610 static int
   18611 xmlSchemaTypeFixup(xmlSchemaTypePtr type,
   18612                    xmlSchemaAbstractCtxtPtr actxt)
   18613 {
   18614     if (type == NULL)
   18615         return(0);
   18616     if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
   18617 	AERROR_INT("xmlSchemaTypeFixup",
   18618 	    "this function needs a parser context");
   18619 	return(-1);
   18620     }
   18621     if (! WXS_IS_TYPE_NOT_FIXED(type))
   18622 	return(0);
   18623     if (type->type == XML_SCHEMA_TYPE_COMPLEX)
   18624 	return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
   18625     else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
   18626 	return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
   18627     return(0);
   18628 }
   18629 
   18630 /**
   18631  * xmlSchemaCheckFacet:
   18632  * @facet:  the facet
   18633  * @typeDecl:  the schema type definition
   18634  * @pctxt:  the schema parser context or NULL
   18635  * @name: the optional name of the type
   18636  *
   18637  * Checks and computes the values of facets.
   18638  *
   18639  * Returns 0 if valid, a positive error code if not valid and
   18640  *         -1 in case of an internal or API error.
   18641  */
   18642 int
   18643 xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
   18644                     xmlSchemaTypePtr typeDecl,
   18645                     xmlSchemaParserCtxtPtr pctxt,
   18646 		    const xmlChar * name ATTRIBUTE_UNUSED)
   18647 {
   18648     int ret = 0, ctxtGiven;
   18649 
   18650     if ((facet == NULL) || (typeDecl == NULL))
   18651         return(-1);
   18652     /*
   18653     * TODO: will the parser context be given if used from
   18654     * the relaxNG module?
   18655     */
   18656     if (pctxt == NULL)
   18657 	ctxtGiven = 0;
   18658     else
   18659 	ctxtGiven = 1;
   18660 
   18661     switch (facet->type) {
   18662         case XML_SCHEMA_FACET_MININCLUSIVE:
   18663         case XML_SCHEMA_FACET_MINEXCLUSIVE:
   18664         case XML_SCHEMA_FACET_MAXINCLUSIVE:
   18665         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   18666 	case XML_SCHEMA_FACET_ENUMERATION: {
   18667                 /*
   18668                  * Okay we need to validate the value
   18669                  * at that point.
   18670                  */
   18671 		xmlSchemaTypePtr base;
   18672 
   18673 		/* 4.3.5.5 Constraints on enumeration Schema Components
   18674 		* Schema Component Constraint: enumeration valid restriction
   18675 		* It is an `error` if any member of {value} is not in the
   18676 		* `value space` of {base type definition}.
   18677 		*
   18678 		* minInclusive, maxInclusive, minExclusive, maxExclusive:
   18679 		* The value `must` be in the
   18680 		* `value space` of the `base type`.
   18681 		*/
   18682 		/*
   18683 		* This function is intended to deliver a compiled value
   18684 		* on the facet. In this implementation of XML Schemata the
   18685 		* type holding a facet, won't be a built-in type.
   18686 		* Thus to ensure that other API
   18687 		* calls (relaxng) do work, if the given type is a built-in
   18688 		* type, we will assume that the given built-in type *is
   18689 		* already* the base type.
   18690 		*/
   18691 		if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
   18692 		    base = typeDecl->baseType;
   18693 		    if (base == NULL) {
   18694 			PERROR_INT("xmlSchemaCheckFacet",
   18695 			    "a type user derived type has no base type");
   18696 			return (-1);
   18697 		    }
   18698 		} else
   18699 		    base = typeDecl;
   18700 
   18701 		if (! ctxtGiven) {
   18702 		    /*
   18703 		    * A context is needed if called from RelaxNG.
   18704 		    */
   18705 		    pctxt = xmlSchemaNewParserCtxt("*");
   18706 		    if (pctxt == NULL)
   18707 			return (-1);
   18708 		}
   18709 		/*
   18710 		* NOTE: This call does not check the content nodes,
   18711 		* since they are not available:
   18712 		* facet->node is just the node holding the facet
   18713 		* definition, *not* the attribute holding the *value*
   18714 		* of the facet.
   18715 		*/
   18716 		ret = xmlSchemaVCheckCVCSimpleType(
   18717 		    ACTXT_CAST pctxt, facet->node, base,
   18718 		    facet->value, &(facet->val), 1, 1, 0);
   18719                 if (ret != 0) {
   18720 		    if (ret < 0) {
   18721 			/* No error message for RelaxNG. */
   18722 			if (ctxtGiven) {
   18723 			    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18724 				XML_SCHEMAP_INTERNAL, facet->node, NULL,
   18725 				"Internal error: xmlSchemaCheckFacet, "
   18726 				"failed to validate the value '%s' of the "
   18727 				"facet '%s' against the base type",
   18728 				facet->value, xmlSchemaFacetTypeToString(facet->type));
   18729 			}
   18730 			goto internal_error;
   18731 		    }
   18732 		    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
   18733 		    /* No error message for RelaxNG. */
   18734 		    if (ctxtGiven) {
   18735 			xmlChar *str = NULL;
   18736 
   18737 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18738 			    ret, facet->node, WXS_BASIC_CAST facet,
   18739 			    "The value '%s' of the facet does not validate "
   18740 			    "against the base type '%s'",
   18741 			    facet->value,
   18742 			    xmlSchemaFormatQName(&str,
   18743 				base->targetNamespace, base->name));
   18744 			FREE_AND_NULL(str);
   18745 		    }
   18746 		    goto exit;
   18747                 } else if (facet->val == NULL) {
   18748 		    if (ctxtGiven) {
   18749 			PERROR_INT("xmlSchemaCheckFacet",
   18750 			    "value was not computed");
   18751 		    }
   18752 		    TODO
   18753 		}
   18754                 break;
   18755             }
   18756         case XML_SCHEMA_FACET_PATTERN:
   18757             facet->regexp = xmlRegexpCompile(facet->value);
   18758             if (facet->regexp == NULL) {
   18759 		ret = XML_SCHEMAP_REGEXP_INVALID;
   18760 		/* No error message for RelaxNG. */
   18761 		if (ctxtGiven) {
   18762 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18763 			ret, facet->node, WXS_BASIC_CAST typeDecl,
   18764 			"The value '%s' of the facet 'pattern' is not a "
   18765 			"valid regular expression",
   18766 			facet->value, NULL);
   18767 		}
   18768             }
   18769             break;
   18770         case XML_SCHEMA_FACET_TOTALDIGITS:
   18771         case XML_SCHEMA_FACET_FRACTIONDIGITS:
   18772         case XML_SCHEMA_FACET_LENGTH:
   18773         case XML_SCHEMA_FACET_MAXLENGTH:
   18774         case XML_SCHEMA_FACET_MINLENGTH:
   18775 
   18776 	    if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
   18777 		ret = xmlSchemaValidatePredefinedType(
   18778 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
   18779 		    facet->value, &(facet->val));
   18780 	    } else {
   18781 		ret = xmlSchemaValidatePredefinedType(
   18782 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
   18783 		    facet->value, &(facet->val));
   18784 	    }
   18785 	    if (ret != 0) {
   18786 		if (ret < 0) {
   18787 		    /* No error message for RelaxNG. */
   18788 		    if (ctxtGiven) {
   18789 			PERROR_INT("xmlSchemaCheckFacet",
   18790 			    "validating facet value");
   18791 		    }
   18792 		    goto internal_error;
   18793 		}
   18794 		ret = XML_SCHEMAP_INVALID_FACET_VALUE;
   18795 		/* No error message for RelaxNG. */
   18796 		if (ctxtGiven) {
   18797 		    /* error code */
   18798 		    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   18799 			ret, facet->node, WXS_BASIC_CAST typeDecl,
   18800 			"The value '%s' of the facet '%s' is not a valid '%s'",
   18801 			facet->value,
   18802 			xmlSchemaFacetTypeToString(facet->type),
   18803 			(facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
   18804 			    BAD_CAST "nonNegativeInteger" :
   18805 			    BAD_CAST "positiveInteger",
   18806 			NULL);
   18807 		}
   18808 	    }
   18809 	    break;
   18810 
   18811         case XML_SCHEMA_FACET_WHITESPACE:{
   18812                 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
   18813                     facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
   18814                 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
   18815                     facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
   18816                 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
   18817                     facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
   18818                 } else {
   18819 		    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
   18820                     /* No error message for RelaxNG. */
   18821 		    if (ctxtGiven) {
   18822 			/* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
   18823 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18824 			    ret, facet->node, WXS_BASIC_CAST typeDecl,
   18825 			    "The value '%s' of the facet 'whitespace' is not "
   18826 			    "valid", facet->value, NULL);
   18827                     }
   18828                 }
   18829             }
   18830         default:
   18831             break;
   18832     }
   18833 exit:
   18834     if ((! ctxtGiven) && (pctxt != NULL))
   18835 	xmlSchemaFreeParserCtxt(pctxt);
   18836     return (ret);
   18837 internal_error:
   18838     if ((! ctxtGiven) && (pctxt != NULL))
   18839 	xmlSchemaFreeParserCtxt(pctxt);
   18840     return (-1);
   18841 }
   18842 
   18843 /**
   18844  * xmlSchemaCheckFacetValues:
   18845  * @typeDecl:  the schema type definition
   18846  * @ctxt:  the schema parser context
   18847  *
   18848  * Checks the default values types, especially for facets
   18849  */
   18850 static int
   18851 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
   18852 			  xmlSchemaParserCtxtPtr pctxt)
   18853 {
   18854     int res, olderrs = pctxt->nberrors;
   18855     const xmlChar *name = typeDecl->name;
   18856     /*
   18857     * NOTE: It is intended to use the facets list, instead
   18858     * of facetSet.
   18859     */
   18860     if (typeDecl->facets != NULL) {
   18861 	xmlSchemaFacetPtr facet = typeDecl->facets;
   18862 
   18863 	/*
   18864 	* Temporarily assign the "schema" to the validation context
   18865 	* of the parser context. This is needed for NOTATION validation.
   18866 	*/
   18867 	if (pctxt->vctxt == NULL) {
   18868 	    if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
   18869 		return(-1);
   18870 	}
   18871 	pctxt->vctxt->schema = pctxt->schema;
   18872 	while (facet != NULL) {
   18873 	    res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
   18874 	    HFAILURE
   18875 	    facet = facet->next;
   18876 	}
   18877 	pctxt->vctxt->schema = NULL;
   18878     }
   18879     if (olderrs != pctxt->nberrors)
   18880 	return(pctxt->err);
   18881     return(0);
   18882 exit_failure:
   18883     return(-1);
   18884 }
   18885 
   18886 /**
   18887  * xmlSchemaGetCircModelGrDefRef:
   18888  * @ctxtMGroup: the searched model group
   18889  * @selfMGroup: the second searched model group
   18890  * @particle: the first particle
   18891  *
   18892  * This one is intended to be used by
   18893  * xmlSchemaCheckGroupDefCircular only.
   18894  *
   18895  * Returns the particle with the circular model group definition reference,
   18896  * otherwise NULL.
   18897  */
   18898 static xmlSchemaTreeItemPtr
   18899 xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
   18900 			      xmlSchemaTreeItemPtr particle)
   18901 {
   18902     xmlSchemaTreeItemPtr circ = NULL;
   18903     xmlSchemaTreeItemPtr term;
   18904     xmlSchemaModelGroupDefPtr gdef;
   18905 
   18906     for (; particle != NULL; particle = particle->next) {
   18907 	term = particle->children;
   18908 	if (term == NULL)
   18909 	    continue;
   18910 	switch (term->type) {
   18911 	    case XML_SCHEMA_TYPE_GROUP:
   18912 		gdef = (xmlSchemaModelGroupDefPtr) term;
   18913 		if (gdef == groupDef)
   18914 		    return (particle);
   18915 		/*
   18916 		* Mark this model group definition to avoid infinite
   18917 		* recursion on circular references not yet examined.
   18918 		*/
   18919 		if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
   18920 		    continue;
   18921 		if (gdef->children != NULL) {
   18922 		    gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
   18923 		    circ = xmlSchemaGetCircModelGrDefRef(groupDef,
   18924 			gdef->children->children);
   18925 		    gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
   18926 		    if (circ != NULL)
   18927 			return (circ);
   18928 		}
   18929 		break;
   18930 	    case XML_SCHEMA_TYPE_SEQUENCE:
   18931 	    case XML_SCHEMA_TYPE_CHOICE:
   18932 	    case XML_SCHEMA_TYPE_ALL:
   18933 		circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
   18934 		if (circ != NULL)
   18935 		    return (circ);
   18936 		break;
   18937 	    default:
   18938 		break;
   18939 	}
   18940     }
   18941     return (NULL);
   18942 }
   18943 
   18944 /**
   18945  * xmlSchemaCheckGroupDefCircular:
   18946  * @item:  the model group definition
   18947  * @ctxt:  the parser context
   18948  * @name:  the name
   18949  *
   18950  * Checks for circular references to model group definitions.
   18951  */
   18952 static void
   18953 xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
   18954 			       xmlSchemaParserCtxtPtr ctxt)
   18955 {
   18956     /*
   18957     * Schema Component Constraint: Model Group Correct
   18958     * 2 Circular groups are disallowed. That is, within the {particles}
   18959     * of a group there must not be at any depth a particle whose {term}
   18960     * is the group itself.
   18961     */
   18962     if ((item == NULL) ||
   18963 	(item->type != XML_SCHEMA_TYPE_GROUP) ||
   18964 	(item->children == NULL))
   18965 	return;
   18966     {
   18967 	xmlSchemaTreeItemPtr circ;
   18968 
   18969 	circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
   18970 	if (circ != NULL) {
   18971 	    xmlChar *str = NULL;
   18972 	    /*
   18973 	    * TODO: The error report is not adequate: this constraint
   18974 	    * is defined for model groups but not definitions, but since
   18975 	    * there cannot be any circular model groups without a model group
   18976 	    * definition (if not using a construction API), we check those
   18977 	    * defintions only.
   18978 	    */
   18979 	    xmlSchemaPCustomErr(ctxt,
   18980 		XML_SCHEMAP_MG_PROPS_CORRECT_2,
   18981 		NULL, WXS_ITEM_NODE(circ),
   18982 		"Circular reference to the model group definition '%s' "
   18983 		"defined", xmlSchemaFormatQName(&str,
   18984 		    item->targetNamespace, item->name));
   18985 	    FREE_AND_NULL(str)
   18986 	    /*
   18987 	    * NOTE: We will cut the reference to avoid further
   18988 	    * confusion of the processor. This is a fatal error.
   18989 	    */
   18990 	    circ->children = NULL;
   18991 	}
   18992     }
   18993 }
   18994 
   18995 /**
   18996  * xmlSchemaModelGroupToModelGroupDefFixup:
   18997  * @ctxt:  the parser context
   18998  * @mg:  the model group
   18999  *
   19000  * Assigns the model group of model group definitions to the "term"
   19001  * of the referencing particle.
   19002  * In xmlSchemaResolveModelGroupParticleReferences the model group
   19003  * definitions were assigned to the "term", since needed for the
   19004  * circularity check.
   19005  *
   19006  * Schema Component Constraint:
   19007  *     All Group Limited (cos-all-limited) (1.2)
   19008  */
   19009 static void
   19010 xmlSchemaModelGroupToModelGroupDefFixup(
   19011     xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
   19012     xmlSchemaModelGroupPtr mg)
   19013 {
   19014     xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
   19015 
   19016     while (particle != NULL) {
   19017 	if ((WXS_PARTICLE_TERM(particle) == NULL) ||
   19018 	    ((WXS_PARTICLE_TERM(particle))->type !=
   19019 		XML_SCHEMA_TYPE_GROUP))
   19020 	{
   19021 	    particle = WXS_PTC_CAST particle->next;
   19022 	    continue;
   19023 	}
   19024 	if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
   19025 	    /*
   19026 	    * TODO: Remove the particle.
   19027 	    */
   19028 	    WXS_PARTICLE_TERM(particle) = NULL;
   19029 	    particle = WXS_PTC_CAST particle->next;
   19030 	    continue;
   19031 	}
   19032 	/*
   19033 	* Assign the model group to the {term} of the particle.
   19034 	*/
   19035 	WXS_PARTICLE_TERM(particle) =
   19036 	    WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
   19037 
   19038 	particle = WXS_PTC_CAST particle->next;
   19039     }
   19040 }
   19041 
   19042 /**
   19043  * xmlSchemaCheckAttrGroupCircularRecur:
   19044  * @ctxtGr: the searched attribute group
   19045  * @attr: the current attribute list to be processed
   19046  *
   19047  * This one is intended to be used by
   19048  * xmlSchemaCheckAttrGroupCircular only.
   19049  *
   19050  * Returns the circular attribute grou reference, otherwise NULL.
   19051  */
   19052 static xmlSchemaQNameRefPtr
   19053 xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
   19054 				     xmlSchemaItemListPtr list)
   19055 {
   19056     xmlSchemaAttributeGroupPtr gr;
   19057     xmlSchemaQNameRefPtr ref, circ;
   19058     int i;
   19059     /*
   19060     * We will search for an attribute group reference which
   19061     * references the context attribute group.
   19062     */
   19063     for (i = 0; i < list->nbItems; i++) {
   19064 	ref = list->items[i];
   19065 	if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
   19066 	    (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
   19067 	    (ref->item != NULL))
   19068 	{
   19069 	    gr = WXS_ATTR_GROUP_CAST ref->item;
   19070 	    if (gr == ctxtGr)
   19071 		return(ref);
   19072 	    if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
   19073 		continue;
   19074 	    /*
   19075 	    * Mark as visited to avoid infinite recursion on
   19076 	    * circular references not yet examined.
   19077 	    */
   19078 	    if ((gr->attrUses) &&
   19079 		(gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
   19080 	    {
   19081 		gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
   19082 		circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
   19083 		    (xmlSchemaItemListPtr) gr->attrUses);
   19084 		gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
   19085 		if (circ != NULL)
   19086 		    return (circ);
   19087 	    }
   19088 
   19089 	}
   19090     }
   19091     return (NULL);
   19092 }
   19093 
   19094 /**
   19095  * xmlSchemaCheckAttrGroupCircular:
   19096  * attrGr:  the attribute group definition
   19097  * @ctxt:  the parser context
   19098  * @name:  the name
   19099  *
   19100  * Checks for circular references of attribute groups.
   19101  */
   19102 static int
   19103 xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
   19104 				xmlSchemaParserCtxtPtr ctxt)
   19105 {
   19106     /*
   19107     * Schema Representation Constraint:
   19108     * Attribute Group Definition Representation OK
   19109     * 3 Circular group reference is disallowed outside <redefine>.
   19110     * That is, unless this element information item's parent is
   19111     * <redefine>, then among the [children], if any, there must
   19112     * not be an <attributeGroup> with ref [attribute] which resolves
   19113     * to the component corresponding to this <attributeGroup>. Indirect
   19114     * circularity is also ruled out. That is, when QName resolution
   19115     * (Schema Document) ($3.15.3) is applied to a `QName` arising from
   19116     * any <attributeGroup>s with a ref [attribute] among the [children],
   19117     * it must not be the case that a `QName` is encountered at any depth
   19118     * which resolves to the component corresponding to this <attributeGroup>.
   19119     */
   19120     if (attrGr->attrUses == NULL)
   19121 	return(0);
   19122     else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
   19123 	return(0);
   19124     else {
   19125 	xmlSchemaQNameRefPtr circ;
   19126 
   19127 	circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
   19128 	    (xmlSchemaItemListPtr) attrGr->attrUses);
   19129 	if (circ != NULL) {
   19130 	    xmlChar *str = NULL;
   19131 	    /*
   19132 	    * TODO: Report the referenced attr group as QName.
   19133 	    */
   19134 	    xmlSchemaPCustomErr(ctxt,
   19135 		XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
   19136 		NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
   19137 		"Circular reference to the attribute group '%s' "
   19138 		"defined", xmlSchemaGetComponentQName(&str, attrGr));
   19139 	    FREE_AND_NULL(str);
   19140 	    /*
   19141 	    * NOTE: We will cut the reference to avoid further
   19142 	    * confusion of the processor.
   19143 	    * BADSPEC TODO: The spec should define how to process in this case.
   19144 	    */
   19145 	    circ->item = NULL;
   19146 	    return(ctxt->err);
   19147 	}
   19148     }
   19149     return(0);
   19150 }
   19151 
   19152 static int
   19153 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
   19154 				  xmlSchemaAttributeGroupPtr attrGr);
   19155 
   19156 /**
   19157  * xmlSchemaExpandAttributeGroupRefs:
   19158  * @pctxt: the parser context
   19159  * @node: the node of the component holding the attribute uses
   19160  * @completeWild: the intersected wildcard to be returned
   19161  * @list: the attribute uses
   19162  *
   19163  * Substitutes contained attribute group references
   19164  * for their attribute uses. Wilcards are intersected.
   19165  * Attribute use prohibitions are removed from the list
   19166  * and returned via the @prohibs list.
   19167  * Pointlessness of attr. prohibs, if a matching attr. decl
   19168  * is existent a well, are checked.
   19169  */
   19170 static int
   19171 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
   19172 				  xmlSchemaBasicItemPtr item,
   19173 				  xmlSchemaWildcardPtr *completeWild,
   19174 				  xmlSchemaItemListPtr list,
   19175 				  xmlSchemaItemListPtr prohibs)
   19176 {
   19177     xmlSchemaAttributeGroupPtr gr;
   19178     xmlSchemaAttributeUsePtr use;
   19179     xmlSchemaItemListPtr sublist;
   19180     int i, j;
   19181     int created = (*completeWild == NULL) ? 0 : 1;
   19182 
   19183     if (prohibs)
   19184 	prohibs->nbItems = 0;
   19185 
   19186     for (i = 0; i < list->nbItems; i++) {
   19187 	use = list->items[i];
   19188 
   19189 	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
   19190 	    if (prohibs == NULL) {
   19191 		PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
   19192 		    "unexpected attr prohibition found");
   19193 		return(-1);
   19194 	    }
   19195 	    /*
   19196 	    * Remove from attribute uses.
   19197 	    */
   19198 	    if (xmlSchemaItemListRemove(list, i) == -1)
   19199 		return(-1);
   19200 	    i--;
   19201 	    /*
   19202 	    * Note that duplicate prohibitions were already
   19203 	    * handled at parsing time.
   19204 	    */
   19205 	    /*
   19206 	    * Add to list of prohibitions.
   19207 	    */
   19208 	    xmlSchemaItemListAddSize(prohibs, 2, use);
   19209 	    continue;
   19210 	}
   19211 	if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
   19212 	    ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
   19213 	{
   19214 	    if ((WXS_QNAME_CAST use)->item == NULL)
   19215 		return(-1);
   19216 	    gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
   19217 	    /*
   19218 	    * Expand the referenced attr. group.
   19219 	    * TODO: remove this, this is done in a previous step, so
   19220 	    * already done here.
   19221 	    */
   19222 	    if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
   19223 		if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
   19224 		    return(-1);
   19225 	    }
   19226 	    /*
   19227 	    * Build the 'complete' wildcard; i.e. intersect multiple
   19228 	    * wildcards.
   19229 	    */
   19230 	    if (gr->attributeWildcard != NULL) {
   19231 		if (*completeWild == NULL) {
   19232 		    *completeWild = gr->attributeWildcard;
   19233 		} else {
   19234 		    if (! created) {
   19235 			xmlSchemaWildcardPtr tmpWild;
   19236 
   19237 			 /*
   19238 			* Copy the first encountered wildcard as context,
   19239 			* except for the annotation.
   19240 			*
   19241 			* Although the complete wildcard might not correspond
   19242 			* to any node in the schema, we will anchor it on
   19243 			* the node of the owner component.
   19244 			*/
   19245 			tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
   19246 			    XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
   19247 			    WXS_ITEM_NODE(item));
   19248 			if (tmpWild == NULL)
   19249 			    return(-1);
   19250 			if (xmlSchemaCloneWildcardNsConstraints(pctxt,
   19251 			    tmpWild, *completeWild) == -1)
   19252 			    return (-1);
   19253 			tmpWild->processContents = (*completeWild)->processContents;
   19254 			*completeWild = tmpWild;
   19255 			created = 1;
   19256 		    }
   19257 
   19258 		    if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
   19259 			gr->attributeWildcard) == -1)
   19260 			return(-1);
   19261 		}
   19262 	    }
   19263 	    /*
   19264 	    * Just remove the reference if the referenced group does not
   19265 	    * contain any attribute uses.
   19266 	    */
   19267 	    sublist = ((xmlSchemaItemListPtr) gr->attrUses);
   19268 	    if ((sublist == NULL) || sublist->nbItems == 0) {
   19269 		if (xmlSchemaItemListRemove(list, i) == -1)
   19270 		    return(-1);
   19271 		i--;
   19272 		continue;
   19273 	    }
   19274 	    /*
   19275 	    * Add the attribute uses.
   19276 	    */
   19277 	    list->items[i] = sublist->items[0];
   19278 	    if (sublist->nbItems != 1) {
   19279 		for (j = 1; j < sublist->nbItems; j++) {
   19280 		    i++;
   19281 		    if (xmlSchemaItemListInsert(list,
   19282 			    sublist->items[j], i) == -1)
   19283 			return(-1);
   19284 		}
   19285 	    }
   19286 	}
   19287 
   19288     }
   19289     /*
   19290     * Handle pointless prohibitions of declared attributes.
   19291     */
   19292     if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
   19293 	xmlSchemaAttributeUseProhibPtr prohib;
   19294 
   19295 	for (i = prohibs->nbItems -1; i >= 0; i--) {
   19296 	    prohib = prohibs->items[i];
   19297 	    for (j = 0; j < list->nbItems; j++) {
   19298 		use = list->items[j];
   19299 
   19300 		if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
   19301 		    (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
   19302 		{
   19303 		    xmlChar *str = NULL;
   19304 
   19305 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   19306 			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   19307 			prohib->node, NULL,
   19308 			"Skipping pointless attribute use prohibition "
   19309 			"'%s', since a corresponding attribute use "
   19310 			"exists already in the type definition",
   19311 			xmlSchemaFormatQName(&str,
   19312 			    prohib->targetNamespace, prohib->name),
   19313 			NULL, NULL);
   19314 		    FREE_AND_NULL(str);
   19315 		    /*
   19316 		    * Remove the prohibition.
   19317 		    */
   19318 		    if (xmlSchemaItemListRemove(prohibs, i) == -1)
   19319 			return(-1);
   19320 		    break;
   19321 		}
   19322 	    }
   19323 	}
   19324     }
   19325     return(0);
   19326 }
   19327 
   19328 /**
   19329  * xmlSchemaAttributeGroupExpandRefs:
   19330  * @pctxt:  the parser context
   19331  * @attrGr:  the attribute group definition
   19332  *
   19333  * Computation of:
   19334  * {attribute uses} property
   19335  * {attribute wildcard} property
   19336  *
   19337  * Substitutes contained attribute group references
   19338  * for their attribute uses. Wilcards are intersected.
   19339  */
   19340 static int
   19341 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
   19342 				  xmlSchemaAttributeGroupPtr attrGr)
   19343 {
   19344     if ((attrGr->attrUses == NULL) ||
   19345 	(attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
   19346 	return(0);
   19347 
   19348     attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
   19349     if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
   19350 	&(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
   19351 	return(-1);
   19352     return(0);
   19353 }
   19354 
   19355 /**
   19356  * xmlSchemaAttributeGroupExpandRefs:
   19357  * @pctxt:  the parser context
   19358  * @attrGr:  the attribute group definition
   19359  *
   19360  * Substitutes contained attribute group references
   19361  * for their attribute uses. Wilcards are intersected.
   19362  *
   19363  * Schema Component Constraint:
   19364  *    Attribute Group Definition Properties Correct (ag-props-correct)
   19365  */
   19366 static int
   19367 xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
   19368 				  xmlSchemaAttributeGroupPtr attrGr)
   19369 {
   19370     /*
   19371     * SPEC ag-props-correct
   19372     * (1) "The values of the properties of an attribute group definition
   19373     * must be as described in the property tableau in The Attribute
   19374     * Group Definition Schema Component ($3.6.1), modulo the impact of
   19375     * Missing Sub-components ($5.3);"
   19376     */
   19377 
   19378     if ((attrGr->attrUses != NULL) &&
   19379 	(WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
   19380     {
   19381 	xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
   19382 	xmlSchemaAttributeUsePtr use, tmp;
   19383 	int i, j, hasId = 0;
   19384 
   19385 	for (i = uses->nbItems -1; i >= 0; i--) {
   19386 	    use = uses->items[i];
   19387 	    /*
   19388 	    * SPEC ag-props-correct
   19389 	    * (2) "Two distinct members of the {attribute uses} must not have
   19390 	    * {attribute declaration}s both of whose {name}s match and whose
   19391 	    * {target namespace}s are identical."
   19392 	    */
   19393 	    if (i > 0) {
   19394 		for (j = i -1; j >= 0; j--) {
   19395 		    tmp = uses->items[j];
   19396 		    if ((WXS_ATTRUSE_DECL_NAME(use) ==
   19397 			WXS_ATTRUSE_DECL_NAME(tmp)) &&
   19398 			(WXS_ATTRUSE_DECL_TNS(use) ==
   19399 			WXS_ATTRUSE_DECL_TNS(tmp)))
   19400 		    {
   19401 			xmlChar *str = NULL;
   19402 
   19403 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19404 			    XML_SCHEMAP_AG_PROPS_CORRECT,
   19405 			    attrGr->node, WXS_BASIC_CAST attrGr,
   19406 			    "Duplicate %s",
   19407 			    xmlSchemaGetComponentDesignation(&str, use),
   19408 			    NULL);
   19409 			FREE_AND_NULL(str);
   19410 			/*
   19411 			* Remove the duplicate.
   19412 			*/
   19413 			if (xmlSchemaItemListRemove(uses, i) == -1)
   19414 			    return(-1);
   19415 			goto next_use;
   19416 		    }
   19417 		}
   19418 	    }
   19419 	    /*
   19420 	    * SPEC ag-props-correct
   19421 	    * (3) "Two distinct members of the {attribute uses} must not have
   19422 	    * {attribute declaration}s both of whose {type definition}s are or
   19423 	    * are derived from ID."
   19424 	    * TODO: Does 'derived' include member-types of unions?
   19425 	    */
   19426 	    if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
   19427 		if (xmlSchemaIsDerivedFromBuiltInType(
   19428 		    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
   19429 		{
   19430 		    if (hasId) {
   19431 			xmlChar *str = NULL;
   19432 
   19433 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19434 			    XML_SCHEMAP_AG_PROPS_CORRECT,
   19435 			    attrGr->node, WXS_BASIC_CAST attrGr,
   19436 			    "There must not exist more than one attribute "
   19437 			    "declaration of type 'xs:ID' "
   19438 			    "(or derived from 'xs:ID'). The %s violates this "
   19439 			    "constraint",
   19440 			    xmlSchemaGetComponentDesignation(&str, use),
   19441 			    NULL);
   19442 			FREE_AND_NULL(str);
   19443 			if (xmlSchemaItemListRemove(uses, i) == -1)
   19444 			    return(-1);
   19445 		    }
   19446 		    hasId = 1;
   19447 		}
   19448 	    }
   19449 next_use: {}
   19450 	}
   19451     }
   19452     return(0);
   19453 }
   19454 
   19455 /**
   19456  * xmlSchemaResolveAttrGroupReferences:
   19457  * @attrgrpDecl:  the schema attribute definition
   19458  * @ctxt:  the schema parser context
   19459  * @name:  the attribute name
   19460  *
   19461  * Resolves references to attribute group definitions.
   19462  */
   19463 static int
   19464 xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
   19465 				    xmlSchemaParserCtxtPtr ctxt)
   19466 {
   19467     xmlSchemaAttributeGroupPtr group;
   19468 
   19469     if (ref->item != NULL)
   19470         return(0);
   19471     group = xmlSchemaGetAttributeGroup(ctxt->schema,
   19472 	ref->name,
   19473 	ref->targetNamespace);
   19474     if (group == NULL) {
   19475 	xmlSchemaPResCompAttrErr(ctxt,
   19476 	    XML_SCHEMAP_SRC_RESOLVE,
   19477 	    NULL, ref->node,
   19478 	    "ref", ref->name, ref->targetNamespace,
   19479 	    ref->itemType, NULL);
   19480 	return(ctxt->err);
   19481     }
   19482     ref->item = WXS_BASIC_CAST group;
   19483     return(0);
   19484 }
   19485 
   19486 /**
   19487  * xmlSchemaCheckAttrPropsCorrect:
   19488  * @item:  an schema attribute declaration/use
   19489  * @ctxt:  a schema parser context
   19490  * @name:  the name of the attribute
   19491  *
   19492  *
   19493  * Schema Component Constraint:
   19494  *    Attribute Declaration Properties Correct (a-props-correct)
   19495  *
   19496  * Validates the value constraints of an attribute declaration/use.
   19497  * NOTE that this needs the simle type definitions to be already
   19498  *   builded and checked.
   19499  */
   19500 static int
   19501 xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
   19502 			       xmlSchemaAttributePtr attr)
   19503 {
   19504 
   19505     /*
   19506     * SPEC a-props-correct (1)
   19507     * "The values of the properties of an attribute declaration must
   19508     * be as described in the property tableau in The Attribute
   19509     * Declaration Schema Component ($3.2.1), modulo the impact of
   19510     * Missing Sub-components ($5.3)."
   19511     */
   19512 
   19513     if (WXS_ATTR_TYPEDEF(attr) == NULL)
   19514 	return(0);
   19515 
   19516     if (attr->defValue != NULL) {
   19517 	int ret;
   19518 
   19519 	/*
   19520 	* SPEC a-props-correct (3)
   19521 	* "If the {type definition} is or is derived from ID then there
   19522 	* must not be a {value constraint}."
   19523 	*/
   19524 	if (xmlSchemaIsDerivedFromBuiltInType(
   19525 	    WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
   19526 	{
   19527 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19528 		XML_SCHEMAP_A_PROPS_CORRECT_3,
   19529 		NULL, WXS_BASIC_CAST attr,
   19530 		"Value constraints are not allowed if the type definition "
   19531 		"is or is derived from xs:ID",
   19532 		NULL, NULL);
   19533 	    return(pctxt->err);
   19534 	}
   19535 	/*
   19536 	* SPEC a-props-correct (2)
   19537 	* "if there is a {value constraint}, the canonical lexical
   19538 	* representation of its value must be `valid` with respect
   19539 	* to the {type definition} as defined in String Valid ($3.14.4)."
   19540 	* TODO: Don't care about the *canonical* stuff here, this requirement
   19541 	* will be removed in WXS 1.1 anyway.
   19542 	*/
   19543 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
   19544 	    attr->node, WXS_ATTR_TYPEDEF(attr),
   19545 	    attr->defValue, &(attr->defVal),
   19546 	    1, 1, 0);
   19547 	if (ret != 0) {
   19548 	    if (ret < 0) {
   19549 		PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
   19550 		    "calling xmlSchemaVCheckCVCSimpleType()");
   19551 		return(-1);
   19552 	    }
   19553 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19554 		XML_SCHEMAP_A_PROPS_CORRECT_2,
   19555 		NULL, WXS_BASIC_CAST attr,
   19556 		"The value of the value constraint is not valid",
   19557 		NULL, NULL);
   19558 	    return(pctxt->err);
   19559 	}
   19560     }
   19561 
   19562     return(0);
   19563 }
   19564 
   19565 static xmlSchemaElementPtr
   19566 xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
   19567 				 xmlSchemaElementPtr ancestor)
   19568 {
   19569     xmlSchemaElementPtr ret;
   19570 
   19571     if (WXS_SUBST_HEAD(ancestor) == NULL)
   19572 	return (NULL);
   19573     if (WXS_SUBST_HEAD(ancestor) == elemDecl)
   19574 	return (ancestor);
   19575 
   19576     if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
   19577 	return (NULL);
   19578     WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
   19579     ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
   19580 	WXS_SUBST_HEAD(ancestor));
   19581     WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
   19582 
   19583     return (ret);
   19584 }
   19585 
   19586 /**
   19587  * xmlSchemaCheckElemPropsCorrect:
   19588  * @ctxt:  a schema parser context
   19589  * @decl: the element declaration
   19590  * @name:  the name of the attribute
   19591  *
   19592  * Schema Component Constraint:
   19593  * Element Declaration Properties Correct (e-props-correct)
   19594  *
   19595  * STATUS:
   19596  *   missing: (6)
   19597  */
   19598 static int
   19599 xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
   19600 			       xmlSchemaElementPtr elemDecl)
   19601 {
   19602     int ret = 0;
   19603     xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
   19604     /*
   19605     * SPEC (1) "The values of the properties of an element declaration
   19606     * must be as described in the property tableau in The Element
   19607     * Declaration Schema Component ($3.3.1), modulo the impact of Missing
   19608     * Sub-components ($5.3)."
   19609     */
   19610     if (WXS_SUBST_HEAD(elemDecl) != NULL) {
   19611 	xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
   19612 
   19613 	xmlSchemaCheckElementDeclComponent(head, pctxt);
   19614 	/*
   19615 	* SPEC (3) "If there is a non-`absent` {substitution group
   19616 	* affiliation}, then {scope} must be global."
   19617 	*/
   19618 	if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
   19619 	    xmlSchemaPCustomErr(pctxt,
   19620 		XML_SCHEMAP_E_PROPS_CORRECT_3,
   19621 		WXS_BASIC_CAST elemDecl, NULL,
   19622 		"Only global element declarations can have a "
   19623 		"substitution group affiliation", NULL);
   19624 	    ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
   19625 	}
   19626 	/*
   19627 	* TODO: SPEC (6) "Circular substitution groups are disallowed.
   19628 	* That is, it must not be possible to return to an element declaration
   19629 	* by repeatedly following the {substitution group affiliation}
   19630 	* property."
   19631 	*/
   19632 	if (head == elemDecl)
   19633 	    circ = head;
   19634 	else if (WXS_SUBST_HEAD(head) != NULL)
   19635 	    circ = xmlSchemaCheckSubstGroupCircular(head, head);
   19636 	else
   19637 	    circ = NULL;
   19638 	if (circ != NULL) {
   19639 	    xmlChar *strA = NULL, *strB = NULL;
   19640 
   19641 	    xmlSchemaPCustomErrExt(pctxt,
   19642 		XML_SCHEMAP_E_PROPS_CORRECT_6,
   19643 		WXS_BASIC_CAST circ, NULL,
   19644 		"The element declaration '%s' defines a circular "
   19645 		"substitution group to element declaration '%s'",
   19646 		xmlSchemaGetComponentQName(&strA, circ),
   19647 		xmlSchemaGetComponentQName(&strB, head),
   19648 		NULL);
   19649 	    FREE_AND_NULL(strA)
   19650 	    FREE_AND_NULL(strB)
   19651 	    ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
   19652 	}
   19653 	/*
   19654 	* SPEC (4) "If there is a {substitution group affiliation},
   19655 	* the {type definition}
   19656 	* of the element declaration must be validly derived from the {type
   19657 	* definition} of the {substitution group affiliation}, given the value
   19658 	* of the {substitution group exclusions} of the {substitution group
   19659 	* affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
   19660 	* (if the {type definition} is complex) or as defined in
   19661 	* Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
   19662 	* simple)."
   19663 	*
   19664 	* NOTE: {substitution group exclusions} means the values of the
   19665 	* attribute "final".
   19666 	*/
   19667 
   19668 	if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
   19669 	    int set = 0;
   19670 
   19671 	    if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
   19672 		set |= SUBSET_EXTENSION;
   19673 	    if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
   19674 		set |= SUBSET_RESTRICTION;
   19675 
   19676 	    if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
   19677 		WXS_ELEM_TYPEDEF(head), set) != 0) {
   19678 		xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
   19679 
   19680 		ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
   19681 		xmlSchemaPCustomErrExt(pctxt,
   19682 		    XML_SCHEMAP_E_PROPS_CORRECT_4,
   19683 		    WXS_BASIC_CAST elemDecl, NULL,
   19684 		    "The type definition '%s' was "
   19685 		    "either rejected by the substitution group "
   19686 		    "affiliation '%s', or not validly derived from its type "
   19687 		    "definition '%s'",
   19688 		    xmlSchemaGetComponentQName(&strA, typeDef),
   19689 		    xmlSchemaGetComponentQName(&strB, head),
   19690 		    xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
   19691 		FREE_AND_NULL(strA)
   19692 		FREE_AND_NULL(strB)
   19693 		FREE_AND_NULL(strC)
   19694 	    }
   19695 	}
   19696     }
   19697     /*
   19698     * SPEC (5) "If the {type definition} or {type definition}'s
   19699     * {content type}
   19700     * is or is derived from ID then there must not be a {value constraint}.
   19701     * Note: The use of ID as a type definition for elements goes beyond
   19702     * XML 1.0, and should be avoided if backwards compatibility is desired"
   19703     */
   19704     if ((elemDecl->value != NULL) &&
   19705 	((WXS_IS_SIMPLE(typeDef) &&
   19706 	  xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
   19707 	 (WXS_IS_COMPLEX(typeDef) &&
   19708 	  WXS_HAS_SIMPLE_CONTENT(typeDef) &&
   19709 	  xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
   19710 	    XML_SCHEMAS_ID)))) {
   19711 
   19712 	ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
   19713 	xmlSchemaPCustomErr(pctxt,
   19714 	    XML_SCHEMAP_E_PROPS_CORRECT_5,
   19715 	    WXS_BASIC_CAST elemDecl, NULL,
   19716 	    "The type definition (or type definition's content type) is or "
   19717 	    "is derived from ID; value constraints are not allowed in "
   19718 	    "conjunction with such a type definition", NULL);
   19719     } else if (elemDecl->value != NULL) {
   19720 	int vcret;
   19721 	xmlNodePtr node = NULL;
   19722 
   19723 	/*
   19724 	* SPEC (2) "If there is a {value constraint}, the canonical lexical
   19725 	* representation of its value must be `valid` with respect to the
   19726 	* {type definition} as defined in Element Default Valid (Immediate)
   19727 	* ($3.3.6)."
   19728 	*/
   19729 	if (typeDef == NULL) {
   19730 	    xmlSchemaPErr(pctxt, elemDecl->node,
   19731 		XML_SCHEMAP_INTERNAL,
   19732 		"Internal error: xmlSchemaCheckElemPropsCorrect, "
   19733 		"type is missing... skipping validation of "
   19734 		"the value constraint", NULL, NULL);
   19735 	    return (-1);
   19736 	}
   19737 	if (elemDecl->node != NULL) {
   19738 	    if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
   19739 		node = (xmlNodePtr) xmlHasProp(elemDecl->node,
   19740 		    BAD_CAST "fixed");
   19741 	    else
   19742 		node = (xmlNodePtr) xmlHasProp(elemDecl->node,
   19743 		    BAD_CAST "default");
   19744 	}
   19745 	vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
   19746 	    typeDef, elemDecl->value, &(elemDecl->defVal));
   19747 	if (vcret != 0) {
   19748 	    if (vcret < 0) {
   19749 		PERROR_INT("xmlSchemaElemCheckValConstr",
   19750 		    "failed to validate the value constraint of an "
   19751 		    "element declaration");
   19752 		return (-1);
   19753 	    }
   19754 	    return (vcret);
   19755 	}
   19756     }
   19757 
   19758     return (ret);
   19759 }
   19760 
   19761 /**
   19762  * xmlSchemaCheckElemSubstGroup:
   19763  * @ctxt:  a schema parser context
   19764  * @decl: the element declaration
   19765  * @name:  the name of the attribute
   19766  *
   19767  * Schema Component Constraint:
   19768  * Substitution Group (cos-equiv-class)
   19769  *
   19770  * In Libxml2 the subst. groups will be precomputed, in terms of that
   19771  * a list will be built for each subst. group head, holding all direct
   19772  * referents to this head.
   19773  * NOTE that this function needs:
   19774  *   1. circular subst. groups to be checked beforehand
   19775  *   2. the declaration's type to be derived from the head's type
   19776  *
   19777  * STATUS:
   19778  *
   19779  */
   19780 static void
   19781 xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
   19782 			     xmlSchemaElementPtr elemDecl)
   19783 {
   19784     if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
   19785 	/* SPEC (1) "Its {abstract} is false." */
   19786 	(elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
   19787 	return;
   19788     {
   19789 	xmlSchemaElementPtr head;
   19790 	xmlSchemaTypePtr headType, type;
   19791 	int set, methSet;
   19792 	/*
   19793 	* SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
   19794 	* {disallowed substitutions} as the blocking constraint, as defined in
   19795 	* Substitution Group OK (Transitive) ($3.3.6)."
   19796 	*/
   19797 	for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
   19798 	    head = WXS_SUBST_HEAD(head)) {
   19799 	    set = 0;
   19800 	    methSet = 0;
   19801 	    /*
   19802 	    * The blocking constraints.
   19803 	    */
   19804 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
   19805 		continue;
   19806 	    headType = head->subtypes;
   19807 	    type = elemDecl->subtypes;
   19808 	    if (headType == type)
   19809 		goto add_member;
   19810 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
   19811 		set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
   19812 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
   19813 		set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
   19814 	    /*
   19815 	    * SPEC: Substitution Group OK (Transitive) (2.3)
   19816 	    * "The set of all {derivation method}s involved in the
   19817 	    * derivation of D's {type definition} from C's {type definition}
   19818 	    * does not intersect with the union of the blocking constraint,
   19819 	    * C's {prohibited substitutions} (if C is complex, otherwise the
   19820 	    * empty set) and the {prohibited substitutions} (respectively the
   19821 	    * empty set) of any intermediate {type definition}s in the
   19822 	    * derivation of D's {type definition} from C's {type definition}."
   19823 	    */
   19824 	    /*
   19825 	    * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
   19826 	    * subst.head axis, the methSet does not need to be computed for
   19827 	    * the full depth over and over.
   19828 	    */
   19829 	    /*
   19830 	    * The set of all {derivation method}s involved in the derivation
   19831 	    */
   19832 	    while ((type != NULL) && (type != headType)) {
   19833 		if ((WXS_IS_EXTENSION(type)) &&
   19834 		    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
   19835 		    methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
   19836 
   19837 		if (WXS_IS_RESTRICTION(type) &&
   19838 		    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
   19839 		    methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
   19840 
   19841 		type = type->baseType;
   19842 	    }
   19843 	    /*
   19844 	    * The {prohibited substitutions} of all intermediate types +
   19845 	    * the head's type.
   19846 	    */
   19847 	    type = elemDecl->subtypes->baseType;
   19848 	    while (type != NULL) {
   19849 		if (WXS_IS_COMPLEX(type)) {
   19850 		    if ((type->flags &
   19851 			    XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
   19852 			((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
   19853 		    set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
   19854 		    if ((type->flags &
   19855 			    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
   19856 			((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
   19857 		    set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
   19858 		} else
   19859 		    break;
   19860 		if (type == headType)
   19861 		    break;
   19862 		type = type->baseType;
   19863 	    }
   19864 	    if ((set != 0) &&
   19865 		(((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
   19866 		(methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
   19867 		((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
   19868 		(methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
   19869 		continue;
   19870 	    }
   19871 add_member:
   19872 	    xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
   19873 	    if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
   19874 		head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
   19875 	}
   19876     }
   19877 }
   19878 
   19879 #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
   19880 /**
   19881  * xmlSchemaCheckElementDeclComponent
   19882  * @pctxt: the schema parser context
   19883  * @ctxtComponent: the context component (an element declaration)
   19884  * @ctxtParticle: the first particle of the context component
   19885  * @searchParticle: the element declaration particle to be analysed
   19886  *
   19887  * Schema Component Constraint: Element Declarations Consistent
   19888  */
   19889 static int
   19890 xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
   19891 				    xmlSchemaBasicItemPtr ctxtComponent,
   19892 				    xmlSchemaParticlePtr ctxtParticle,
   19893 				    xmlSchemaParticlePtr searchParticle,
   19894 				    xmlSchemaParticlePtr curParticle,
   19895 				    int search)
   19896 {
   19897     return(0);
   19898 
   19899     int ret = 0;
   19900     xmlSchemaParticlePtr cur = curParticle;
   19901     if (curParticle == NULL) {
   19902 	return(0);
   19903     }
   19904     if (WXS_PARTICLE_TERM(curParticle) == NULL) {
   19905 	/*
   19906 	* Just return in this case. A missing "term" of the particle
   19907 	* might arise due to an invalid "term" component.
   19908 	*/
   19909 	return(0);
   19910     }
   19911     while (cur != NULL) {
   19912 	switch (WXS_PARTICLE_TERM(cur)->type) {
   19913 	    case XML_SCHEMA_TYPE_ANY:
   19914 		break;
   19915 	    case XML_SCHEMA_TYPE_ELEMENT:
   19916 		if (search == 0) {
   19917 		    ret = xmlSchemaCheckElementDeclConsistent(pctxt,
   19918 			ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
   19919 		    if (ret != 0)
   19920 			return(ret);
   19921 		} else {
   19922 		    xmlSchemaElementPtr elem =
   19923 			WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
   19924 		    /*
   19925 		    * SPEC Element Declarations Consistent:
   19926 		    * "If the {particles} contains, either directly,
   19927 		    * indirectly (that is, within the {particles} of a
   19928 		    * contained model group, recursively) or `implicitly`
   19929 		    * two or more element declaration particles with
   19930 		    * the same {name} and {target namespace}, then
   19931 		    * all their type definitions must be the same
   19932 		    * top-level definition [...]"
   19933 		    */
   19934 		    if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
   19935 			    WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
   19936 			xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
   19937 			    WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
   19938 		    {
   19939 			xmlChar *strA = NULL, *strB = NULL;
   19940 
   19941 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19942 			    /* TODO: error code */
   19943 			    XML_SCHEMAP_COS_NONAMBIG,
   19944 			    WXS_ITEM_NODE(cur), NULL,
   19945 			    "In the content model of %s, there are multiple "
   19946 			    "element declarations for '%s' with different "
   19947 			    "type definitions",
   19948 			    xmlSchemaGetComponentDesignation(&strA,
   19949 				ctxtComponent),
   19950 			    xmlSchemaFormatQName(&strB,
   19951 				WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
   19952 				WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
   19953 			FREE_AND_NULL(strA);
   19954 			FREE_AND_NULL(strB);
   19955 			return(XML_SCHEMAP_COS_NONAMBIG);
   19956 		    }
   19957 		}
   19958 		break;
   19959 	    case XML_SCHEMA_TYPE_SEQUENCE: {
   19960 		break;
   19961 		}
   19962 	    case XML_SCHEMA_TYPE_CHOICE:{
   19963 		/*
   19964 		xmlSchemaTreeItemPtr sub;
   19965 
   19966 		sub = WXS_PARTICLE_TERM(particle)->children;  (xmlSchemaParticlePtr)
   19967 		while (sub != NULL) {
   19968 		    ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
   19969 			ctxtParticle, ctxtElem);
   19970 		    if (ret != 0)
   19971 			return(ret);
   19972 		    sub = sub->next;
   19973 		}
   19974 		*/
   19975 		break;
   19976 		}
   19977 	    case XML_SCHEMA_TYPE_ALL:
   19978 		break;
   19979 	    case XML_SCHEMA_TYPE_GROUP:
   19980 		break;
   19981 	    default:
   19982 		xmlSchemaInternalErr2(ACTXT_CAST pctxt,
   19983 		    "xmlSchemaCheckElementDeclConsistent",
   19984 		    "found unexpected term of type '%s' in content model",
   19985 		    WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
   19986 		return(-1);
   19987 	}
   19988 	cur = (xmlSchemaParticlePtr) cur->next;
   19989     }
   19990 
   19991 exit:
   19992     return(ret);
   19993 }
   19994 #endif
   19995 
   19996 /**
   19997  * xmlSchemaCheckElementDeclComponent
   19998  * @item:  an schema element declaration/particle
   19999  * @ctxt:  a schema parser context
   20000  * @name:  the name of the attribute
   20001  *
   20002  * Validates the value constraints of an element declaration.
   20003  * Adds substitution group members.
   20004  */
   20005 static void
   20006 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
   20007 				   xmlSchemaParserCtxtPtr ctxt)
   20008 {
   20009     if (elemDecl == NULL)
   20010 	return;
   20011     if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
   20012 	return;
   20013     elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
   20014     if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
   20015 	/*
   20016 	* Adds substitution group members.
   20017 	*/
   20018 	xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
   20019     }
   20020 }
   20021 
   20022 /**
   20023  * xmlSchemaResolveModelGroupParticleReferences:
   20024  * @particle:  a particle component
   20025  * @ctxt:  a parser context
   20026  *
   20027  * Resolves references of a model group's {particles} to
   20028  * model group definitions and to element declarations.
   20029  */
   20030 static void
   20031 xmlSchemaResolveModelGroupParticleReferences(
   20032     xmlSchemaParserCtxtPtr ctxt,
   20033     xmlSchemaModelGroupPtr mg)
   20034 {
   20035     xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
   20036     xmlSchemaQNameRefPtr ref;
   20037     xmlSchemaBasicItemPtr refItem;
   20038 
   20039     /*
   20040     * URGENT TODO: Test this.
   20041     */
   20042     while (particle != NULL) {
   20043 	if ((WXS_PARTICLE_TERM(particle) == NULL) ||
   20044 	    ((WXS_PARTICLE_TERM(particle))->type !=
   20045 		XML_SCHEMA_EXTRA_QNAMEREF))
   20046 	{
   20047 	    goto next_particle;
   20048 	}
   20049 	ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
   20050 	/*
   20051 	* Resolve the reference.
   20052 	* NULL the {term} by default.
   20053 	*/
   20054 	particle->children = NULL;
   20055 
   20056 	refItem = xmlSchemaGetNamedComponent(ctxt->schema,
   20057 	    ref->itemType, ref->name, ref->targetNamespace);
   20058 	if (refItem == NULL) {
   20059 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
   20060 		NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
   20061 		ref->targetNamespace, ref->itemType, NULL);
   20062 	    /* TODO: remove the particle. */
   20063 	    goto next_particle;
   20064 	}
   20065 	if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
   20066 	    if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
   20067 		/* TODO: remove the particle. */
   20068 		goto next_particle;
   20069 	    /*
   20070 	    * NOTE that we will assign the model group definition
   20071 	    * itself to the "term" of the particle. This will ease
   20072 	    * the check for circular model group definitions. After
   20073 	    * that the "term" will be assigned the model group of the
   20074 	    * model group definition.
   20075 	    */
   20076 	    if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
   20077 		    XML_SCHEMA_TYPE_ALL) {
   20078 		/*
   20079 		* SPEC cos-all-limited (1)
   20080 		* SPEC cos-all-limited (1.2)
   20081 		* "It appears only as the value of one or both of the
   20082 		* following properties:"
   20083 		* (1.1) "the {model group} property of a model group
   20084 		*        definition."
   20085 		* (1.2) "the {term} property of a particle [... of] the "
   20086 		* {content type} of a complex type definition."
   20087 		*/
   20088 		xmlSchemaCustomErr(ACTXT_CAST ctxt,
   20089 		    /* TODO: error code */
   20090 		    XML_SCHEMAP_COS_ALL_LIMITED,
   20091 		    WXS_ITEM_NODE(particle), NULL,
   20092 		    "A model group definition is referenced, but "
   20093 		    "it contains an 'all' model group, which "
   20094 		    "cannot be contained by model groups",
   20095 		    NULL, NULL);
   20096 		/* TODO: remove the particle. */
   20097 		goto next_particle;
   20098 	    }
   20099 	    particle->children = (xmlSchemaTreeItemPtr) refItem;
   20100 	} else {
   20101 	    /*
   20102 	    * TODO: Are referenced element declarations the only
   20103 	    * other components we expect here?
   20104 	    */
   20105 	    particle->children = (xmlSchemaTreeItemPtr) refItem;
   20106 	}
   20107 next_particle:
   20108 	particle = WXS_PTC_CAST particle->next;
   20109     }
   20110 }
   20111 
   20112 static int
   20113 xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
   20114 		       xmlSchemaValPtr y)
   20115 {
   20116     xmlSchemaTypePtr tx, ty, ptx, pty;
   20117     int ret;
   20118 
   20119     while (x != NULL) {
   20120 	/* Same types. */
   20121 	tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
   20122 	ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
   20123 	ptx = xmlSchemaGetPrimitiveType(tx);
   20124 	pty = xmlSchemaGetPrimitiveType(ty);
   20125 	/*
   20126 	* (1) if a datatype T' is `derived` by `restriction` from an
   20127 	* atomic datatype T then the `value space` of T' is a subset of
   20128 	* the `value space` of T. */
   20129 	/*
   20130 	* (2) if datatypes T' and T'' are `derived` by `restriction`
   20131 	* from a common atomic ancestor T then the `value space`s of T'
   20132 	* and T'' may overlap.
   20133 	*/
   20134 	if (ptx != pty)
   20135 	    return(0);
   20136 	/*
   20137 	* We assume computed values to be normalized, so do a fast
   20138 	* string comparison for string based types.
   20139 	*/
   20140 	if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
   20141 	    WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
   20142 	    if (! xmlStrEqual(
   20143 		xmlSchemaValueGetAsString(x),
   20144 		xmlSchemaValueGetAsString(y)))
   20145 		return (0);
   20146 	} else {
   20147 	    ret = xmlSchemaCompareValuesWhtsp(
   20148 		x, XML_SCHEMA_WHITESPACE_PRESERVE,
   20149 		y, XML_SCHEMA_WHITESPACE_PRESERVE);
   20150 	    if (ret == -2)
   20151 		return(-1);
   20152 	    if (ret != 0)
   20153 		return(0);
   20154 	}
   20155 	/*
   20156 	* Lists.
   20157 	*/
   20158 	x = xmlSchemaValueGetNext(x);
   20159 	if (x != NULL) {
   20160 	    y = xmlSchemaValueGetNext(y);
   20161 	    if (y == NULL)
   20162 		return (0);
   20163 	} else if (xmlSchemaValueGetNext(y) != NULL)
   20164 	    return (0);
   20165 	else
   20166 	    return (1);
   20167     }
   20168     return (0);
   20169 }
   20170 
   20171 /**
   20172  * xmlSchemaResolveAttrUseReferences:
   20173  * @item:  an attribute use
   20174  * @ctxt:  a parser context
   20175  *
   20176  * Resolves the referenced attribute declaration.
   20177  */
   20178 static int
   20179 xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
   20180 				  xmlSchemaParserCtxtPtr ctxt)
   20181 {
   20182     if ((ctxt == NULL) || (ause == NULL))
   20183 	return(-1);
   20184     if ((ause->attrDecl == NULL) ||
   20185 	(ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
   20186 	return(0);
   20187 
   20188     {
   20189 	xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
   20190 
   20191 	/*
   20192 	* TODO: Evaluate, what errors could occur if the declaration is not
   20193 	* found.
   20194 	*/
   20195 	ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
   20196 	    ref->name, ref->targetNamespace);
   20197         if (ause->attrDecl == NULL) {
   20198 	    xmlSchemaPResCompAttrErr(ctxt,
   20199 		XML_SCHEMAP_SRC_RESOLVE,
   20200 		WXS_BASIC_CAST ause, ause->node,
   20201 		"ref", ref->name, ref->targetNamespace,
   20202 		XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
   20203             return(ctxt->err);;
   20204         }
   20205     }
   20206     return(0);
   20207 }
   20208 
   20209 /**
   20210  * xmlSchemaCheckAttrUsePropsCorrect:
   20211  * @ctxt:  a parser context
   20212  * @use:  an attribute use
   20213  *
   20214  * Schema Component Constraint:
   20215  * Attribute Use Correct (au-props-correct)
   20216  *
   20217  */
   20218 static int
   20219 xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
   20220 			     xmlSchemaAttributeUsePtr use)
   20221 {
   20222     if ((ctxt == NULL) || (use == NULL))
   20223 	return(-1);
   20224     if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
   20225 	((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
   20226 	return(0);
   20227 
   20228     /*
   20229     * SPEC au-props-correct (1)
   20230     * "The values of the properties of an attribute use must be as
   20231     * described in the property tableau in The Attribute Use Schema
   20232     * Component ($3.5.1), modulo the impact of Missing
   20233     * Sub-components ($5.3)."
   20234     */
   20235 
   20236     if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
   20237 	((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
   20238         ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
   20239     {
   20240 	xmlSchemaPCustomErr(ctxt,
   20241 	    XML_SCHEMAP_AU_PROPS_CORRECT_2,
   20242 	    WXS_BASIC_CAST use, NULL,
   20243 	    "The attribute declaration has a 'fixed' value constraint "
   20244 	    ", thus the attribute use must also have a 'fixed' value "
   20245 	    "constraint",
   20246 	    NULL);
   20247 	return(ctxt->err);
   20248     }
   20249     /*
   20250     * Compute and check the value constraint's value.
   20251     */
   20252     if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
   20253 	int ret;
   20254 	/*
   20255 	* TODO: The spec seems to be missing a check of the
   20256 	* value constraint of the attribute use. We will do it here.
   20257 	*/
   20258 	/*
   20259 	* SPEC a-props-correct (3)
   20260 	*/
   20261 	if (xmlSchemaIsDerivedFromBuiltInType(
   20262 	    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
   20263 	{
   20264 	    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   20265 		XML_SCHEMAP_AU_PROPS_CORRECT,
   20266 		NULL, WXS_BASIC_CAST use,
   20267 		"Value constraints are not allowed if the type definition "
   20268 		"is or is derived from xs:ID",
   20269 		NULL, NULL);
   20270 	    return(ctxt->err);
   20271 	}
   20272 
   20273 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
   20274 	    use->node, WXS_ATTRUSE_TYPEDEF(use),
   20275 	    use->defValue, &(use->defVal),
   20276 	    1, 1, 0);
   20277 	if (ret != 0) {
   20278 	    if (ret < 0) {
   20279 		PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
   20280 		    "calling xmlSchemaVCheckCVCSimpleType()");
   20281 		return(-1);
   20282 	    }
   20283 	    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   20284 		XML_SCHEMAP_AU_PROPS_CORRECT,
   20285 		NULL, WXS_BASIC_CAST use,
   20286 		"The value of the value constraint is not valid",
   20287 		NULL, NULL);
   20288 	    return(ctxt->err);
   20289 	}
   20290     }
   20291     /*
   20292     * SPEC au-props-correct (2)
   20293     * "If the {attribute declaration} has a fixed
   20294     * {value constraint}, then if the attribute use itself has a
   20295     * {value constraint}, it must also be fixed and its value must match
   20296     * that of the {attribute declaration}'s {value constraint}."
   20297     */
   20298     if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
   20299 	(((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
   20300     {
   20301 	if (! xmlSchemaAreValuesEqual(use->defVal,
   20302 		(WXS_ATTRUSE_DECL(use))->defVal))
   20303 	{
   20304 	    xmlSchemaPCustomErr(ctxt,
   20305 		XML_SCHEMAP_AU_PROPS_CORRECT_2,
   20306 		WXS_BASIC_CAST use, NULL,
   20307 		"The 'fixed' value constraint of the attribute use "
   20308 		"must match the attribute declaration's value "
   20309 		"constraint '%s'",
   20310 		(WXS_ATTRUSE_DECL(use))->defValue);
   20311 	}
   20312 	return(ctxt->err);
   20313     }
   20314     return(0);
   20315 }
   20316 
   20317 
   20318 
   20319 
   20320 /**
   20321  * xmlSchemaResolveAttrTypeReferences:
   20322  * @item:  an attribute declaration
   20323  * @ctxt:  a parser context
   20324  *
   20325  * Resolves the referenced type definition component.
   20326  */
   20327 static int
   20328 xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
   20329 				   xmlSchemaParserCtxtPtr ctxt)
   20330 {
   20331     /*
   20332     * The simple type definition corresponding to the <simpleType> element
   20333     * information item in the [children], if present, otherwise the simple
   20334     * type definition `resolved` to by the `actual value` of the type
   20335     * [attribute], if present, otherwise the `simple ur-type definition`.
   20336     */
   20337     if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
   20338 	return(0);
   20339     item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
   20340     if (item->subtypes != NULL)
   20341         return(0);
   20342     if (item->typeName != NULL) {
   20343         xmlSchemaTypePtr type;
   20344 
   20345 	type = xmlSchemaGetType(ctxt->schema, item->typeName,
   20346 	    item->typeNs);
   20347 	if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
   20348 	    xmlSchemaPResCompAttrErr(ctxt,
   20349 		XML_SCHEMAP_SRC_RESOLVE,
   20350 		WXS_BASIC_CAST item, item->node,
   20351 		"type", item->typeName, item->typeNs,
   20352 		XML_SCHEMA_TYPE_SIMPLE, NULL);
   20353 	    return(ctxt->err);
   20354 	} else
   20355 	    item->subtypes = type;
   20356 
   20357     } else {
   20358 	/*
   20359 	* The type defaults to the xs:anySimpleType.
   20360 	*/
   20361 	item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
   20362     }
   20363     return(0);
   20364 }
   20365 
   20366 /**
   20367  * xmlSchemaResolveIDCKeyReferences:
   20368  * @idc:  the identity-constraint definition
   20369  * @ctxt:  the schema parser context
   20370  * @name:  the attribute name
   20371  *
   20372  * Resolve keyRef references to key/unique IDCs.
   20373  * Schema Component Constraint:
   20374  *   Identity-constraint Definition Properties Correct (c-props-correct)
   20375  */
   20376 static int
   20377 xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
   20378 			  xmlSchemaParserCtxtPtr pctxt)
   20379 {
   20380     if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
   20381         return(0);
   20382     if (idc->ref->name != NULL) {
   20383 	idc->ref->item = (xmlSchemaBasicItemPtr)
   20384 	    xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
   20385 		idc->ref->targetNamespace);
   20386         if (idc->ref->item == NULL) {
   20387 	    /*
   20388 	    * TODO: It is actually not an error to fail to resolve
   20389 	    * at this stage. BUT we need to be that strict!
   20390 	    */
   20391 	    xmlSchemaPResCompAttrErr(pctxt,
   20392 		XML_SCHEMAP_SRC_RESOLVE,
   20393 		WXS_BASIC_CAST idc, idc->node,
   20394 		"refer", idc->ref->name,
   20395 		idc->ref->targetNamespace,
   20396 		XML_SCHEMA_TYPE_IDC_KEY, NULL);
   20397             return(pctxt->err);
   20398 	} else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
   20399 	    /*
   20400 	    * SPEC c-props-correct (1)
   20401 	    */
   20402 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20403 		XML_SCHEMAP_C_PROPS_CORRECT,
   20404 		NULL, WXS_BASIC_CAST idc,
   20405 		"The keyref references a keyref",
   20406 		NULL, NULL);
   20407 	    idc->ref->item = NULL;
   20408 	    return(pctxt->err);
   20409 	} else {
   20410 	    if (idc->nbFields !=
   20411 		((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
   20412 		xmlChar *str = NULL;
   20413 		xmlSchemaIDCPtr refer;
   20414 
   20415 		refer = (xmlSchemaIDCPtr) idc->ref->item;
   20416 		/*
   20417 		* SPEC c-props-correct(2)
   20418 		* "If the {identity-constraint category} is keyref,
   20419 		* the cardinality of the {fields} must equal that of
   20420 		* the {fields} of the {referenced key}.
   20421 		*/
   20422 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20423 		    XML_SCHEMAP_C_PROPS_CORRECT,
   20424 		    NULL, WXS_BASIC_CAST idc,
   20425 		    "The cardinality of the keyref differs from the "
   20426 		    "cardinality of the referenced key/unique '%s'",
   20427 		    xmlSchemaFormatQName(&str, refer->targetNamespace,
   20428 			refer->name),
   20429 		    NULL);
   20430 		FREE_AND_NULL(str)
   20431 		return(pctxt->err);
   20432 	    }
   20433 	}
   20434     }
   20435     return(0);
   20436 }
   20437 
   20438 static int
   20439 xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
   20440 				       xmlSchemaParserCtxtPtr pctxt)
   20441 {
   20442     if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
   20443 	prohib->targetNamespace) == NULL) {
   20444 
   20445 	xmlSchemaPResCompAttrErr(pctxt,
   20446 	    XML_SCHEMAP_SRC_RESOLVE,
   20447 	    NULL, prohib->node,
   20448 	    "ref", prohib->name, prohib->targetNamespace,
   20449 	    XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
   20450 	return(XML_SCHEMAP_SRC_RESOLVE);
   20451     }
   20452     return(0);
   20453 }
   20454 
   20455 #define WXS_REDEFINED_TYPE(c) \
   20456 (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
   20457 
   20458 #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
   20459 (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
   20460 
   20461 #define WXS_REDEFINED_ATTR_GROUP(c) \
   20462 (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
   20463 
   20464 static int
   20465 xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
   20466 {
   20467     int err = 0;
   20468     xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
   20469     xmlSchemaBasicItemPtr prev, item;
   20470     int wasRedefined;
   20471 
   20472     if (redef == NULL)
   20473 	return(0);
   20474 
   20475     do {
   20476 	item = redef->item;
   20477 	/*
   20478 	* First try to locate the redefined component in the
   20479 	* schema graph starting with the redefined schema.
   20480 	* NOTE: According to this schema bug entry:
   20481 	*   http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
   20482 	*   it's not clear if the referenced component needs to originate
   20483 	*   from the <redefine>d schema _document_ or the schema; the latter
   20484 	*   would include all imported and included sub-schemas of the
   20485 	*   <redefine>d schema. Currenlty we latter approach is used.
   20486 	*   SUPPLEMENT: It seems that the WG moves towards the latter
   20487 	*   approach, so we are doing it right.
   20488 	*
   20489 	*/
   20490 	prev = xmlSchemaFindRedefCompInGraph(
   20491 	    redef->targetBucket, item->type,
   20492 	    redef->refName, redef->refTargetNs);
   20493 	if (prev == NULL) {
   20494 	    xmlChar *str = NULL;
   20495 	    xmlNodePtr node;
   20496 
   20497 	    /*
   20498 	    * SPEC src-redefine:
   20499 	    * (6.2.1) "The `actual value` of its own name attribute plus
   20500 	    * target namespace must successfully `resolve` to a model
   20501 	    * group definition in I."
   20502 	    * (7.2.1) "The `actual value` of its own name attribute plus
   20503 	    * target namespace must successfully `resolve` to an attribute
   20504 	    * group definition in I."
   20505 
   20506 	    *
   20507 	    * Note that, if we are redefining with the use of references
   20508 	    * to components, the spec assumes the src-resolve to be used;
   20509 	    * but this won't assure that we search only *inside* the
   20510 	    * redefined schema.
   20511 	    */
   20512 	    if (redef->reference)
   20513 		node = WXS_ITEM_NODE(redef->reference);
   20514 	    else
   20515 		node = WXS_ITEM_NODE(item);
   20516 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20517 		/*
   20518 		* TODO: error code.
   20519 		* Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
   20520 		* reference kind.
   20521 		*/
   20522 		XML_SCHEMAP_SRC_REDEFINE, node, NULL,
   20523 		"The %s '%s' to be redefined could not be found in "
   20524 		"the redefined schema",
   20525 		WXS_ITEM_TYPE_NAME(item),
   20526 		xmlSchemaFormatQName(&str, redef->refTargetNs,
   20527 		    redef->refName));
   20528 	    FREE_AND_NULL(str);
   20529 	    err = pctxt->err;
   20530 	    redef = redef->next;
   20531 	    continue;
   20532 	}
   20533 	/*
   20534 	* TODO: Obtaining and setting the redefinition state is really
   20535 	* clumsy.
   20536 	*/
   20537 	wasRedefined = 0;
   20538 	switch (item->type) {
   20539 	    case XML_SCHEMA_TYPE_COMPLEX:
   20540 	    case XML_SCHEMA_TYPE_SIMPLE:
   20541 		if ((WXS_TYPE_CAST prev)->flags &
   20542 		    XML_SCHEMAS_TYPE_REDEFINED)
   20543 		{
   20544 		    wasRedefined = 1;
   20545 		    break;
   20546 		}
   20547 		/* Mark it as redefined. */
   20548 		(WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
   20549 		/*
   20550 		* Assign the redefined type to the
   20551 		* base type of the redefining type.
   20552 		* TODO: How
   20553 		*/
   20554 		((xmlSchemaTypePtr) item)->baseType =
   20555 		    (xmlSchemaTypePtr) prev;
   20556 		break;
   20557 	    case XML_SCHEMA_TYPE_GROUP:
   20558 		if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
   20559 		    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
   20560 		{
   20561 		    wasRedefined = 1;
   20562 		    break;
   20563 		}
   20564 		/* Mark it as redefined. */
   20565 		(WXS_MODEL_GROUPDEF_CAST prev)->flags |=
   20566 		    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
   20567 		if (redef->reference != NULL) {
   20568 		    /*
   20569 		    * Overwrite the QName-reference with the
   20570 		    * referenced model group def.
   20571 		    */
   20572 		    (WXS_PTC_CAST redef->reference)->children =
   20573 			WXS_TREE_CAST prev;
   20574 		}
   20575 		redef->target = prev;
   20576 		break;
   20577 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   20578 		if ((WXS_ATTR_GROUP_CAST prev)->flags &
   20579 		    XML_SCHEMAS_ATTRGROUP_REDEFINED)
   20580 		{
   20581 		    wasRedefined = 1;
   20582 		    break;
   20583 		}
   20584 		(WXS_ATTR_GROUP_CAST prev)->flags |=
   20585 		    XML_SCHEMAS_ATTRGROUP_REDEFINED;
   20586 		if (redef->reference != NULL) {
   20587 		    /*
   20588 		    * Assign the redefined attribute group to the
   20589 		    * QName-reference component.
   20590 		    * This is the easy case, since we will just
   20591 		    * expand the redefined group.
   20592 		    */
   20593 		    (WXS_QNAME_CAST redef->reference)->item = prev;
   20594 		    redef->target = NULL;
   20595 		} else {
   20596 		    /*
   20597 		    * This is the complicated case: we need
   20598 		    * to apply src-redefine (7.2.2) at a later
   20599 		    * stage, i.e. when attribute group references
   20600 		    * have beed expanded and simple types have
   20601 		    * beed fixed.
   20602 		    */
   20603 		    redef->target = prev;
   20604 		}
   20605 		break;
   20606 	    default:
   20607 		PERROR_INT("xmlSchemaResolveRedefReferences",
   20608 		    "Unexpected redefined component type");
   20609 		return(-1);
   20610 	}
   20611 	if (wasRedefined) {
   20612 	    xmlChar *str = NULL;
   20613 	    xmlNodePtr node;
   20614 
   20615 	    if (redef->reference)
   20616 		node = WXS_ITEM_NODE(redef->reference);
   20617 	    else
   20618 		node = WXS_ITEM_NODE(redef->item);
   20619 
   20620 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20621 		/* TODO: error code. */
   20622 		XML_SCHEMAP_SRC_REDEFINE,
   20623 		node, NULL,
   20624 		"The referenced %s was already redefined. Multiple "
   20625 		"redefinition of the same component is not supported",
   20626 		xmlSchemaGetComponentDesignation(&str, prev),
   20627 		NULL);
   20628 	    FREE_AND_NULL(str)
   20629 	    err = pctxt->err;
   20630 	    redef = redef->next;
   20631 	    continue;
   20632 	}
   20633 	redef = redef->next;
   20634     } while (redef != NULL);
   20635 
   20636     return(err);
   20637 }
   20638 
   20639 static int
   20640 xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
   20641 {
   20642     int err = 0;
   20643     xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
   20644     xmlSchemaBasicItemPtr item;
   20645 
   20646     if (redef == NULL)
   20647 	return(0);
   20648 
   20649     do {
   20650 	if (redef->target == NULL) {
   20651 	    redef = redef->next;
   20652 	    continue;
   20653 	}
   20654 	item = redef->item;
   20655 
   20656 	switch (item->type) {
   20657 	    case XML_SCHEMA_TYPE_SIMPLE:
   20658 	    case XML_SCHEMA_TYPE_COMPLEX:
   20659 		/*
   20660 		* Since the spec wants the {name} of the redefined
   20661 		* type to be 'absent', we'll NULL it.
   20662 		*/
   20663 		(WXS_TYPE_CAST redef->target)->name = NULL;
   20664 
   20665 		/*
   20666 		* TODO: Seems like there's nothing more to do. The normal
   20667 		* inheritance mechanism is used. But not 100% sure.
   20668 		*/
   20669 		break;
   20670 	    case XML_SCHEMA_TYPE_GROUP:
   20671 		/*
   20672 		* URGENT TODO:
   20673 		* SPEC src-redefine:
   20674 		* (6.2.2) "The {model group} of the model group definition
   20675 		* which corresponds to it per XML Representation of Model
   20676 		* Group Definition Schema Components ($3.7.2) must be a
   20677 		* `valid restriction` of the {model group} of that model
   20678 		* group definition in I, as defined in Particle Valid
   20679 		* (Restriction) ($3.9.6)."
   20680 		*/
   20681 		break;
   20682 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   20683 		/*
   20684 		* SPEC src-redefine:
   20685 		* (7.2.2) "The {attribute uses} and {attribute wildcard} of
   20686 		* the attribute group definition which corresponds to it
   20687 		* per XML Representation of Attribute Group Definition Schema
   20688 		* Components ($3.6.2) must be `valid restrictions` of the
   20689 		* {attribute uses} and {attribute wildcard} of that attribute
   20690 		* group definition in I, as defined in clause 2, clause 3 and
   20691 		* clause 4 of Derivation Valid (Restriction, Complex)
   20692 		* ($3.4.6) (where references to the base type definition are
   20693 		* understood as references to the attribute group definition
   20694 		* in I)."
   20695 		*/
   20696 		err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
   20697 		    XML_SCHEMA_ACTION_REDEFINE,
   20698 		    item, redef->target,
   20699 		    (WXS_ATTR_GROUP_CAST item)->attrUses,
   20700 		    (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
   20701 		    (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
   20702 		    (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
   20703 		if (err == -1)
   20704 		    return(-1);
   20705 		break;
   20706 	    default:
   20707 		break;
   20708 	}
   20709 	redef = redef->next;
   20710     } while (redef != NULL);
   20711     return(0);
   20712 }
   20713 
   20714 
   20715 static int
   20716 xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
   20717 		       xmlSchemaBucketPtr bucket)
   20718 {
   20719     xmlSchemaBasicItemPtr item;
   20720     int err;
   20721     xmlHashTablePtr *table;
   20722     const xmlChar *name;
   20723     int i;
   20724 
   20725 #define WXS_GET_GLOBAL_HASH(c, slot) { \
   20726     if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
   20727 	table = &(WXS_IMPBUCKET((c))->schema->slot); \
   20728     else \
   20729 	table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
   20730 
   20731     /*
   20732     * Add global components to the schema's hash tables.
   20733     * This is the place where duplicate components will be
   20734     * detected.
   20735     * TODO: I think normally we should support imports of the
   20736     *   same namespace from multiple locations. We don't do currently,
   20737     *   but if we do then according to:
   20738     *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
   20739     *   we would need, if imported directly, to import redefined
   20740     *   components as well to be able to catch clashing components.
   20741     *   (I hope I'll still know what this means after some months :-()
   20742     */
   20743     if (bucket == NULL)
   20744 	return(-1);
   20745     if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
   20746 	return(0);
   20747     bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
   20748 
   20749     for (i = 0; i < bucket->globals->nbItems; i++) {
   20750 	item = bucket->globals->items[i];
   20751 	table = NULL;
   20752 	switch (item->type) {
   20753 	    case XML_SCHEMA_TYPE_COMPLEX:
   20754 	    case XML_SCHEMA_TYPE_SIMPLE:
   20755 		if (WXS_REDEFINED_TYPE(item))
   20756 		    continue;
   20757 		name = (WXS_TYPE_CAST item)->name;
   20758 		WXS_GET_GLOBAL_HASH(bucket, typeDecl)
   20759 		break;
   20760 	    case XML_SCHEMA_TYPE_ELEMENT:
   20761 		name = (WXS_ELEM_CAST item)->name;
   20762 		WXS_GET_GLOBAL_HASH(bucket, elemDecl)
   20763 		break;
   20764 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
   20765 		name = (WXS_ATTR_CAST item)->name;
   20766 		WXS_GET_GLOBAL_HASH(bucket, attrDecl)
   20767 		break;
   20768 	    case XML_SCHEMA_TYPE_GROUP:
   20769 		if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
   20770 		    continue;
   20771 		name = (WXS_MODEL_GROUPDEF_CAST item)->name;
   20772 		WXS_GET_GLOBAL_HASH(bucket, groupDecl)
   20773 		break;
   20774 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   20775 		if (WXS_REDEFINED_ATTR_GROUP(item))
   20776 		    continue;
   20777 		name = (WXS_ATTR_GROUP_CAST item)->name;
   20778 		WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
   20779 		break;
   20780 	    case XML_SCHEMA_TYPE_IDC_KEY:
   20781 	    case XML_SCHEMA_TYPE_IDC_UNIQUE:
   20782 	    case XML_SCHEMA_TYPE_IDC_KEYREF:
   20783 		name = (WXS_IDC_CAST item)->name;
   20784 		WXS_GET_GLOBAL_HASH(bucket, idcDef)
   20785 		break;
   20786 	    case XML_SCHEMA_TYPE_NOTATION:
   20787 		name = ((xmlSchemaNotationPtr) item)->name;
   20788 		WXS_GET_GLOBAL_HASH(bucket, notaDecl)
   20789 		break;
   20790 	    default:
   20791 		PERROR_INT("xmlSchemaAddComponents",
   20792 		    "Unexpected global component type");
   20793 		continue;
   20794 	}
   20795 	if (*table == NULL) {
   20796 	    *table = xmlHashCreateDict(10, pctxt->dict);
   20797 	    if (*table == NULL) {
   20798 		PERROR_INT("xmlSchemaAddComponents",
   20799 		    "failed to create a component hash table");
   20800 		return(-1);
   20801 	    }
   20802 	}
   20803 	err = xmlHashAddEntry(*table, name, item);
   20804 	if (err != 0) {
   20805 	    xmlChar *str = NULL;
   20806 
   20807 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20808 		XML_SCHEMAP_REDEFINED_TYPE,
   20809 		WXS_ITEM_NODE(item),
   20810 		WXS_BASIC_CAST item,
   20811 		"A global %s '%s' does already exist",
   20812 		WXS_ITEM_TYPE_NAME(item),
   20813 		xmlSchemaGetComponentQName(&str, item));
   20814 	    FREE_AND_NULL(str);
   20815 	}
   20816     }
   20817     /*
   20818     * Process imported/included schemas.
   20819     */
   20820     if (bucket->relations != NULL) {
   20821 	xmlSchemaSchemaRelationPtr rel = bucket->relations;
   20822 	do {
   20823 	    if ((rel->bucket != NULL) &&
   20824 		((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
   20825 		if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
   20826 		    return(-1);
   20827 	    }
   20828 	    rel = rel->next;
   20829 	} while (rel != NULL);
   20830     }
   20831     return(0);
   20832 }
   20833 
   20834 static int
   20835 xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
   20836 			 xmlSchemaBucketPtr rootBucket)
   20837 {
   20838     xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
   20839     xmlSchemaTreeItemPtr item, *items;
   20840     int nbItems, i, ret = 0;
   20841     xmlSchemaBucketPtr oldbucket = con->bucket;
   20842     xmlSchemaElementPtr elemDecl;
   20843 
   20844 #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
   20845 
   20846     if ((con->pending == NULL) ||
   20847 	(con->pending->nbItems == 0))
   20848 	return(0);
   20849 
   20850     /*
   20851     * Since xmlSchemaFixupComplexType() will create new particles
   20852     * (local components), and those particle components need a bucket
   20853     * on the constructor, we'll assure here that the constructor has
   20854     * a bucket.
   20855     * TODO: Think about storing locals _only_ on the main bucket.
   20856     */
   20857     if (con->bucket == NULL)
   20858 	con->bucket = rootBucket;
   20859 
   20860     /* TODO:
   20861     * SPEC (src-redefine):
   20862     * (6.2) "If it has no such self-reference, then all of the
   20863     * following must be true:"
   20864 
   20865     * (6.2.2) The {model group} of the model group definition which
   20866     * corresponds to it per XML Representation of Model Group
   20867     * Definition Schema Components ($3.7.2) must be a `valid
   20868     * restriction` of the {model group} of that model group definition
   20869     * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
   20870     */
   20871     xmlSchemaCheckSRCRedefineFirst(pctxt);
   20872 
   20873     /*
   20874     * Add global components to the schemata's hash tables.
   20875     */
   20876     xmlSchemaAddComponents(pctxt, rootBucket);
   20877 
   20878     pctxt->ctxtType = NULL;
   20879     items = (xmlSchemaTreeItemPtr *) con->pending->items;
   20880     nbItems = con->pending->nbItems;
   20881     /*
   20882     * Now that we have parsed *all* the schema document(s) and converted
   20883     * them to schema components, we can resolve references, apply component
   20884     * constraints, create the FSA from the content model, etc.
   20885     */
   20886     /*
   20887     * Resolve references of..
   20888     *
   20889     * 1. element declarations:
   20890     *   - the type definition
   20891     *   - the substitution group affiliation
   20892     * 2. simple/complex types:
   20893     *   - the base type definition
   20894     *   - the memberTypes of union types
   20895     *   - the itemType of list types
   20896     * 3. attributes declarations and attribute uses:
   20897     *   - the type definition
   20898     *   - if an attribute use, then the attribute declaration
   20899     * 4. attribute group references:
   20900     *   - the attribute group definition
   20901     * 5. particles:
   20902     *   - the term of the particle (e.g. a model group)
   20903     * 6. IDC key-references:
   20904     *   - the referenced IDC 'key' or 'unique' definition
   20905     * 7. Attribute prohibitions which had a "ref" attribute.
   20906     */
   20907     for (i = 0; i < nbItems; i++) {
   20908 	item = items[i];
   20909 	switch (item->type) {
   20910 	    case XML_SCHEMA_TYPE_ELEMENT:
   20911 		xmlSchemaResolveElementReferences(
   20912 		    (xmlSchemaElementPtr) item, pctxt);
   20913 		FIXHFAILURE;
   20914 		break;
   20915 	    case XML_SCHEMA_TYPE_COMPLEX:
   20916 	    case XML_SCHEMA_TYPE_SIMPLE:
   20917 		xmlSchemaResolveTypeReferences(
   20918 		    (xmlSchemaTypePtr) item, pctxt);
   20919 		FIXHFAILURE;
   20920 		break;
   20921 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
   20922 		xmlSchemaResolveAttrTypeReferences(
   20923 		    (xmlSchemaAttributePtr) item, pctxt);
   20924 		FIXHFAILURE;
   20925 		break;
   20926 	    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   20927 		xmlSchemaResolveAttrUseReferences(
   20928 		    (xmlSchemaAttributeUsePtr) item, pctxt);
   20929 		FIXHFAILURE;
   20930 		break;
   20931 	    case XML_SCHEMA_EXTRA_QNAMEREF:
   20932 		if ((WXS_QNAME_CAST item)->itemType ==
   20933 		    XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
   20934 		{
   20935 		    xmlSchemaResolveAttrGroupReferences(
   20936 			WXS_QNAME_CAST item, pctxt);
   20937 		}
   20938 		FIXHFAILURE;
   20939 		break;
   20940 	    case XML_SCHEMA_TYPE_SEQUENCE:
   20941 	    case XML_SCHEMA_TYPE_CHOICE:
   20942 	    case XML_SCHEMA_TYPE_ALL:
   20943 		xmlSchemaResolveModelGroupParticleReferences(pctxt,
   20944 		    WXS_MODEL_GROUP_CAST item);
   20945 		FIXHFAILURE;
   20946 		break;
   20947 	    case XML_SCHEMA_TYPE_IDC_KEY:
   20948 	    case XML_SCHEMA_TYPE_IDC_UNIQUE:
   20949 	    case XML_SCHEMA_TYPE_IDC_KEYREF:
   20950 		xmlSchemaResolveIDCKeyReferences(
   20951 		    (xmlSchemaIDCPtr) item, pctxt);
   20952 		FIXHFAILURE;
   20953 		break;
   20954 	    case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
   20955 		/*
   20956 		* Handle attribue prohibition which had a
   20957 		* "ref" attribute.
   20958 		*/
   20959 		xmlSchemaResolveAttrUseProhibReferences(
   20960 		    WXS_ATTR_PROHIB_CAST item, pctxt);
   20961 		FIXHFAILURE;
   20962 		break;
   20963 	    default:
   20964 		break;
   20965 	}
   20966     }
   20967     if (pctxt->nberrors != 0)
   20968 	goto exit_error;
   20969 
   20970     /*
   20971     * Now that all references are resolved we
   20972     * can check for circularity of...
   20973     * 1. the base axis of type definitions
   20974     * 2. nested model group definitions
   20975     * 3. nested attribute group definitions
   20976     * TODO: check for circual substitution groups.
   20977     */
   20978     for (i = 0; i < nbItems; i++) {
   20979 	item = items[i];
   20980 	/*
   20981 	* Let's better stop on the first error here.
   20982 	*/
   20983 	switch (item->type) {
   20984 	    case XML_SCHEMA_TYPE_COMPLEX:
   20985 	    case XML_SCHEMA_TYPE_SIMPLE:
   20986 		xmlSchemaCheckTypeDefCircular(
   20987 		    (xmlSchemaTypePtr) item, pctxt);
   20988 		FIXHFAILURE;
   20989 		if (pctxt->nberrors != 0)
   20990 		    goto exit_error;
   20991 		break;
   20992 	    case XML_SCHEMA_TYPE_GROUP:
   20993 		xmlSchemaCheckGroupDefCircular(
   20994 		    (xmlSchemaModelGroupDefPtr) item, pctxt);
   20995 		FIXHFAILURE;
   20996 		if (pctxt->nberrors != 0)
   20997 		    goto exit_error;
   20998 		break;
   20999 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   21000 		xmlSchemaCheckAttrGroupCircular(
   21001 		    (xmlSchemaAttributeGroupPtr) item, pctxt);
   21002 		FIXHFAILURE;
   21003 		if (pctxt->nberrors != 0)
   21004 		    goto exit_error;
   21005 		break;
   21006 	    default:
   21007 		break;
   21008 	}
   21009     }
   21010     if (pctxt->nberrors != 0)
   21011 	goto exit_error;
   21012     /*
   21013     * Model group definition references:
   21014     * Such a reference is reflected by a particle at the component
   21015     * level. Until now the 'term' of such particles pointed
   21016     * to the model group definition; this was done, in order to
   21017     * ease circularity checks. Now we need to set the 'term' of
   21018     * such particles to the model group of the model group definition.
   21019     */
   21020     for (i = 0; i < nbItems; i++) {
   21021 	item = items[i];
   21022 	switch (item->type) {
   21023 	    case XML_SCHEMA_TYPE_SEQUENCE:
   21024 	    case XML_SCHEMA_TYPE_CHOICE:
   21025 		xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
   21026 		    WXS_MODEL_GROUP_CAST item);
   21027 		break;
   21028 	    default:
   21029 		break;
   21030 	}
   21031     }
   21032     if (pctxt->nberrors != 0)
   21033 	goto exit_error;
   21034     /*
   21035     * Expand attribute group references of attribute group definitions.
   21036     */
   21037     for (i = 0; i < nbItems; i++) {
   21038 	item = items[i];
   21039 	switch (item->type) {
   21040             case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   21041 		if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
   21042 		    WXS_ATTR_GROUP_HAS_REFS(item))
   21043 		{
   21044 		    xmlSchemaAttributeGroupExpandRefs(pctxt,
   21045 			WXS_ATTR_GROUP_CAST item);
   21046 		    FIXHFAILURE;
   21047 		}
   21048 		break;
   21049 	    default:
   21050 		break;
   21051 	}
   21052     }
   21053     if (pctxt->nberrors != 0)
   21054 	goto exit_error;
   21055     /*
   21056     * First compute the variety of simple types. This is needed as
   21057     * a seperate step, since otherwise we won't be able to detect
   21058     * circular union types in all cases.
   21059     */
   21060     for (i = 0; i < nbItems; i++) {
   21061 	item = items[i];
   21062 	switch (item->type) {
   21063             case XML_SCHEMA_TYPE_SIMPLE:
   21064 		if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
   21065 		    xmlSchemaFixupSimpleTypeStageOne(pctxt,
   21066 			(xmlSchemaTypePtr) item);
   21067 		    FIXHFAILURE;
   21068 		}
   21069 		break;
   21070 	    default:
   21071 		break;
   21072 	}
   21073     }
   21074     if (pctxt->nberrors != 0)
   21075 	goto exit_error;
   21076     /*
   21077     * Detect circular union types. Note that this needs the variety to
   21078     * be already computed.
   21079     */
   21080     for (i = 0; i < nbItems; i++) {
   21081 	item = items[i];
   21082 	switch (item->type) {
   21083             case XML_SCHEMA_TYPE_SIMPLE:
   21084 		if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
   21085 		    xmlSchemaCheckUnionTypeDefCircular(pctxt,
   21086 			(xmlSchemaTypePtr) item);
   21087 		    FIXHFAILURE;
   21088 		}
   21089 		break;
   21090 	    default:
   21091 		break;
   21092 	}
   21093     }
   21094     if (pctxt->nberrors != 0)
   21095 	goto exit_error;
   21096 
   21097     /*
   21098     * Do the complete type fixup for simple types.
   21099     */
   21100     for (i = 0; i < nbItems; i++) {
   21101 	item = items[i];
   21102 	switch (item->type) {
   21103             case XML_SCHEMA_TYPE_SIMPLE:
   21104 		if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
   21105 		    xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
   21106 		    FIXHFAILURE;
   21107 		}
   21108 		break;
   21109 	    default:
   21110 		break;
   21111 	}
   21112     }
   21113     if (pctxt->nberrors != 0)
   21114 	goto exit_error;
   21115     /*
   21116     * At this point we need build and check all simple types.
   21117     */
   21118     /*
   21119     * Apply contraints for attribute declarations.
   21120     */
   21121     for (i = 0; i < nbItems; i++) {
   21122 	item = items[i];
   21123 	switch (item->type) {
   21124 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
   21125 		xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
   21126 		FIXHFAILURE;
   21127 		break;
   21128 	    default:
   21129 		break;
   21130 	}
   21131     }
   21132     if (pctxt->nberrors != 0)
   21133 	goto exit_error;
   21134     /*
   21135     * Apply constraints for attribute uses.
   21136     */
   21137     for (i = 0; i < nbItems; i++) {
   21138 	item = items[i];
   21139 	switch (item->type) {
   21140 	    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   21141 		if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
   21142 		    xmlSchemaCheckAttrUsePropsCorrect(pctxt,
   21143 			WXS_ATTR_USE_CAST item);
   21144 		    FIXHFAILURE;
   21145 		}
   21146 		break;
   21147 	    default:
   21148 		break;
   21149 	}
   21150     }
   21151     if (pctxt->nberrors != 0)
   21152 	goto exit_error;
   21153 
   21154     /*
   21155     * Apply constraints for attribute group definitions.
   21156     */
   21157     for (i = 0; i < nbItems; i++) {
   21158 	item = items[i];
   21159 	switch (item->type) {
   21160 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   21161 	    if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
   21162 		( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
   21163 	    {
   21164 		xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
   21165 		FIXHFAILURE;
   21166 	    }
   21167 	    break;
   21168 	default:
   21169 	    break;
   21170 	}
   21171     }
   21172     if (pctxt->nberrors != 0)
   21173 	goto exit_error;
   21174 
   21175     /*
   21176     * Apply constraints for redefinitions.
   21177     */
   21178     if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
   21179 	xmlSchemaCheckSRCRedefineSecond(pctxt);
   21180     if (pctxt->nberrors != 0)
   21181 	goto exit_error;
   21182 
   21183     /*
   21184     * Complex types are builded and checked.
   21185     */
   21186     for (i = 0; i < nbItems; i++) {
   21187 	item = con->pending->items[i];
   21188 	switch (item->type) {
   21189 	    case XML_SCHEMA_TYPE_COMPLEX:
   21190 		if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
   21191 		    xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
   21192 		    FIXHFAILURE;
   21193 		}
   21194 		break;
   21195 	    default:
   21196 		break;
   21197 	}
   21198     }
   21199     if (pctxt->nberrors != 0)
   21200 	goto exit_error;
   21201 
   21202     /*
   21203     * The list could have changed, since xmlSchemaFixupComplexType()
   21204     * will create particles and model groups in some cases.
   21205     */
   21206     items = (xmlSchemaTreeItemPtr *) con->pending->items;
   21207     nbItems = con->pending->nbItems;
   21208 
   21209     /*
   21210     * Apply some constraints for element declarations.
   21211     */
   21212     for (i = 0; i < nbItems; i++) {
   21213 	item = items[i];
   21214 	switch (item->type) {
   21215 	    case XML_SCHEMA_TYPE_ELEMENT:
   21216 		elemDecl = (xmlSchemaElementPtr) item;
   21217 
   21218 		if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
   21219 		{
   21220 		    xmlSchemaCheckElementDeclComponent(
   21221 			(xmlSchemaElementPtr) elemDecl, pctxt);
   21222 		    FIXHFAILURE;
   21223 		}
   21224 
   21225 #ifdef WXS_ELEM_DECL_CONS_ENABLED
   21226 		/*
   21227 		* Schema Component Constraint: Element Declarations Consistent
   21228 		* Apply this constraint to local types of element declarations.
   21229 		*/
   21230 		if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
   21231 		    (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
   21232 		    (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
   21233 		{
   21234 		    xmlSchemaCheckElementDeclConsistent(pctxt,
   21235 			WXS_BASIC_CAST elemDecl,
   21236 			WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
   21237 			NULL, NULL, 0);
   21238 		}
   21239 #endif
   21240 		break;
   21241 	    default:
   21242 		break;
   21243 	}
   21244     }
   21245     if (pctxt->nberrors != 0)
   21246 	goto exit_error;
   21247 
   21248     /*
   21249     * Finally we can build the automaton from the content model of
   21250     * complex types.
   21251     */
   21252 
   21253     for (i = 0; i < nbItems; i++) {
   21254 	item = items[i];
   21255 	switch (item->type) {
   21256 	    case XML_SCHEMA_TYPE_COMPLEX:
   21257 		xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
   21258 		/* FIXHFAILURE; */
   21259 		break;
   21260 	    default:
   21261 		break;
   21262 	}
   21263     }
   21264     if (pctxt->nberrors != 0)
   21265 	goto exit_error;
   21266     /*
   21267     * URGENT TODO: cos-element-consistent
   21268     */
   21269     goto exit;
   21270 
   21271 exit_error:
   21272     ret = pctxt->err;
   21273     goto exit;
   21274 
   21275 exit_failure:
   21276     ret = -1;
   21277 
   21278 exit:
   21279     /*
   21280     * Reset the constructor. This is needed for XSI acquisition, since
   21281     * those items will be processed over and over again for every XSI
   21282     * if not cleared here.
   21283     */
   21284     con->bucket = oldbucket;
   21285     con->pending->nbItems = 0;
   21286     if (con->substGroups != NULL) {
   21287 	xmlHashFree(con->substGroups,
   21288 	    (xmlHashDeallocator) xmlSchemaSubstGroupFree);
   21289 	con->substGroups = NULL;
   21290     }
   21291     if (con->redefs != NULL) {
   21292 	xmlSchemaRedefListFree(con->redefs);
   21293 	con->redefs = NULL;
   21294     }
   21295     return(ret);
   21296 }
   21297 /**
   21298  * xmlSchemaParse:
   21299  * @ctxt:  a schema validation context
   21300  *
   21301  * parse a schema definition resource and build an internal
   21302  * XML Shema struture which can be used to validate instances.
   21303  *
   21304  * Returns the internal XML Schema structure built from the resource or
   21305  *         NULL in case of error
   21306  */
   21307 xmlSchemaPtr
   21308 xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
   21309 {
   21310     xmlSchemaPtr mainSchema = NULL;
   21311     xmlSchemaBucketPtr bucket = NULL;
   21312     int res;
   21313 
   21314     /*
   21315     * This one is used if the schema to be parsed was specified via
   21316     * the API; i.e. not automatically by the validated instance document.
   21317     */
   21318 
   21319     xmlSchemaInitTypes();
   21320 
   21321     if (ctxt == NULL)
   21322         return (NULL);
   21323 
   21324     /* TODO: Init the context. Is this all we need?*/
   21325     ctxt->nberrors = 0;
   21326     ctxt->err = 0;
   21327     ctxt->counter = 0;
   21328 
   21329     /* Create the *main* schema. */
   21330     mainSchema = xmlSchemaNewSchema(ctxt);
   21331     if (mainSchema == NULL)
   21332 	goto exit_failure;
   21333     /*
   21334     * Create the schema constructor.
   21335     */
   21336     if (ctxt->constructor == NULL) {
   21337 	ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
   21338 	if (ctxt->constructor == NULL)
   21339 	    return(NULL);
   21340 	/* Take ownership of the constructor to be able to free it. */
   21341 	ctxt->ownsConstructor = 1;
   21342     }
   21343     ctxt->constructor->mainSchema = mainSchema;
   21344     /*
   21345     * Locate and add the schema document.
   21346     */
   21347     res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
   21348 	ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
   21349 	NULL, NULL, &bucket);
   21350     if (res == -1)
   21351 	goto exit_failure;
   21352     if (res != 0)
   21353 	goto exit;
   21354 
   21355     if (bucket == NULL) {
   21356 	/* TODO: Error code, actually we failed to *locate* the schema. */
   21357 	if (ctxt->URL)
   21358 	    xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
   21359 		NULL, NULL,
   21360 		"Failed to locate the main schema resource at '%s'",
   21361 		ctxt->URL, NULL);
   21362 	else
   21363 	    xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
   21364 		NULL, NULL,
   21365 		"Failed to locate the main schema resource",
   21366 		    NULL, NULL);
   21367 	goto exit;
   21368     }
   21369     /* Then do the parsing for good. */
   21370     if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
   21371 	goto exit_failure;
   21372     if (ctxt->nberrors != 0)
   21373 	goto exit;
   21374 
   21375     mainSchema->doc = bucket->doc;
   21376     mainSchema->preserve = ctxt->preserve;
   21377 
   21378     ctxt->schema = mainSchema;
   21379 
   21380     if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
   21381 	goto exit_failure;
   21382 
   21383     /*
   21384     * TODO: This is not nice, since we cannot distinguish from the
   21385     * result if there was an internal error or not.
   21386     */
   21387 exit:
   21388     if (ctxt->nberrors != 0) {
   21389 	if (mainSchema) {
   21390 	    xmlSchemaFree(mainSchema);
   21391 	    mainSchema = NULL;
   21392 	}
   21393 	if (ctxt->constructor) {
   21394 	    xmlSchemaConstructionCtxtFree(ctxt->constructor);
   21395 	    ctxt->constructor = NULL;
   21396 	    ctxt->ownsConstructor = 0;
   21397 	}
   21398     }
   21399     ctxt->schema = NULL;
   21400     return(mainSchema);
   21401 exit_failure:
   21402     /*
   21403     * Quite verbose, but should catch internal errors, which were
   21404     * not communitated.
   21405     */
   21406     if (mainSchema) {
   21407         xmlSchemaFree(mainSchema);
   21408 	mainSchema = NULL;
   21409     }
   21410     if (ctxt->constructor) {
   21411 	xmlSchemaConstructionCtxtFree(ctxt->constructor);
   21412 	ctxt->constructor = NULL;
   21413 	ctxt->ownsConstructor = 0;
   21414     }
   21415     PERROR_INT2("xmlSchemaParse",
   21416 	"An internal error occured");
   21417     ctxt->schema = NULL;
   21418     return(NULL);
   21419 }
   21420 
   21421 /**
   21422  * xmlSchemaSetParserErrors:
   21423  * @ctxt:  a schema validation context
   21424  * @err:  the error callback
   21425  * @warn:  the warning callback
   21426  * @ctx:  contextual data for the callbacks
   21427  *
   21428  * Set the callback functions used to handle errors for a validation context
   21429  */
   21430 void
   21431 xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
   21432                          xmlSchemaValidityErrorFunc err,
   21433                          xmlSchemaValidityWarningFunc warn, void *ctx)
   21434 {
   21435     if (ctxt == NULL)
   21436         return;
   21437     ctxt->error = err;
   21438     ctxt->warning = warn;
   21439     ctxt->errCtxt = ctx;
   21440     if (ctxt->vctxt != NULL)
   21441 	xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
   21442 }
   21443 
   21444 /**
   21445  * xmlSchemaSetParserStructuredErrors:
   21446  * @ctxt:  a schema parser context
   21447  * @serror:  the structured error function
   21448  * @ctx: the functions context
   21449  *
   21450  * Set the structured error callback
   21451  */
   21452 void
   21453 xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
   21454 				   xmlStructuredErrorFunc serror,
   21455 				   void *ctx)
   21456 {
   21457     if (ctxt == NULL)
   21458 	return;
   21459     ctxt->serror = serror;
   21460     ctxt->errCtxt = ctx;
   21461     if (ctxt->vctxt != NULL)
   21462 	xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
   21463 }
   21464 
   21465 /**
   21466  * xmlSchemaGetParserErrors:
   21467  * @ctxt:  a XMl-Schema parser context
   21468  * @err: the error callback result
   21469  * @warn: the warning callback result
   21470  * @ctx: contextual data for the callbacks result
   21471  *
   21472  * Get the callback information used to handle errors for a parser context
   21473  *
   21474  * Returns -1 in case of failure, 0 otherwise
   21475  */
   21476 int
   21477 xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
   21478 			 xmlSchemaValidityErrorFunc * err,
   21479 			 xmlSchemaValidityWarningFunc * warn, void **ctx)
   21480 {
   21481 	if (ctxt == NULL)
   21482 		return(-1);
   21483 	if (err != NULL)
   21484 		*err = ctxt->error;
   21485 	if (warn != NULL)
   21486 		*warn = ctxt->warning;
   21487 	if (ctx != NULL)
   21488 		*ctx = ctxt->errCtxt;
   21489 	return(0);
   21490 }
   21491 
   21492 /**
   21493  * xmlSchemaFacetTypeToString:
   21494  * @type:  the facet type
   21495  *
   21496  * Convert the xmlSchemaTypeType to a char string.
   21497  *
   21498  * Returns the char string representation of the facet type if the
   21499  *     type is a facet and an "Internal Error" string otherwise.
   21500  */
   21501 static const xmlChar *
   21502 xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
   21503 {
   21504     switch (type) {
   21505         case XML_SCHEMA_FACET_PATTERN:
   21506             return (BAD_CAST "pattern");
   21507         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   21508             return (BAD_CAST "maxExclusive");
   21509         case XML_SCHEMA_FACET_MAXINCLUSIVE:
   21510             return (BAD_CAST "maxInclusive");
   21511         case XML_SCHEMA_FACET_MINEXCLUSIVE:
   21512             return (BAD_CAST "minExclusive");
   21513         case XML_SCHEMA_FACET_MININCLUSIVE:
   21514             return (BAD_CAST "minInclusive");
   21515         case XML_SCHEMA_FACET_WHITESPACE:
   21516             return (BAD_CAST "whiteSpace");
   21517         case XML_SCHEMA_FACET_ENUMERATION:
   21518             return (BAD_CAST "enumeration");
   21519         case XML_SCHEMA_FACET_LENGTH:
   21520             return (BAD_CAST "length");
   21521         case XML_SCHEMA_FACET_MAXLENGTH:
   21522             return (BAD_CAST "maxLength");
   21523         case XML_SCHEMA_FACET_MINLENGTH:
   21524             return (BAD_CAST "minLength");
   21525         case XML_SCHEMA_FACET_TOTALDIGITS:
   21526             return (BAD_CAST "totalDigits");
   21527         case XML_SCHEMA_FACET_FRACTIONDIGITS:
   21528             return (BAD_CAST "fractionDigits");
   21529         default:
   21530             break;
   21531     }
   21532     return (BAD_CAST "Internal Error");
   21533 }
   21534 
   21535 static xmlSchemaWhitespaceValueType
   21536 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
   21537 {
   21538     /*
   21539     * The normalization type can be changed only for types which are derived
   21540     * from xsd:string.
   21541     */
   21542     if (type->type == XML_SCHEMA_TYPE_BASIC) {
   21543 	/*
   21544 	* Note that we assume a whitespace of preserve for anySimpleType.
   21545 	*/
   21546 	if ((type->builtInType == XML_SCHEMAS_STRING) ||
   21547 	    (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
   21548 	    return(XML_SCHEMA_WHITESPACE_PRESERVE);
   21549 	else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
   21550 	    return(XML_SCHEMA_WHITESPACE_REPLACE);
   21551 	else {
   21552 	    /*
   21553 	    * For all `atomic` datatypes other than string (and types `derived`
   21554 	    * by `restriction` from it) the value of whiteSpace is fixed to
   21555 	    * collapse
   21556 	    * Note that this includes built-in list datatypes.
   21557 	    */
   21558 	    return(XML_SCHEMA_WHITESPACE_COLLAPSE);
   21559 	}
   21560     } else if (WXS_IS_LIST(type)) {
   21561 	/*
   21562 	* For list types the facet "whiteSpace" is fixed to "collapse".
   21563 	*/
   21564 	return (XML_SCHEMA_WHITESPACE_COLLAPSE);
   21565     } else if (WXS_IS_UNION(type)) {
   21566 	return (XML_SCHEMA_WHITESPACE_UNKNOWN);
   21567     } else if (WXS_IS_ATOMIC(type)) {
   21568 	if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
   21569 	    return (XML_SCHEMA_WHITESPACE_PRESERVE);
   21570 	else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
   21571 	    return (XML_SCHEMA_WHITESPACE_REPLACE);
   21572 	else
   21573 	    return (XML_SCHEMA_WHITESPACE_COLLAPSE);
   21574     }
   21575     return (-1);
   21576 }
   21577 
   21578 /************************************************************************
   21579  *									*
   21580  *			Simple type validation				*
   21581  *									*
   21582  ************************************************************************/
   21583 
   21584 
   21585 /************************************************************************
   21586  *									*
   21587  *			DOM Validation code				*
   21588  *									*
   21589  ************************************************************************/
   21590 
   21591 /**
   21592  * xmlSchemaAssembleByLocation:
   21593  * @pctxt:  a schema parser context
   21594  * @vctxt:  a schema validation context
   21595  * @schema: the existing schema
   21596  * @node: the node that fired the assembling
   21597  * @nsName: the namespace name of the new schema
   21598  * @location: the location of the schema
   21599  *
   21600  * Expands an existing schema by an additional schema.
   21601  *
   21602  * Returns 0 if the new schema is correct, a positive error code
   21603  * number otherwise and -1 in case of an internal or API error.
   21604  */
   21605 static int
   21606 xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
   21607 			    xmlSchemaPtr schema,
   21608 			    xmlNodePtr node,
   21609 			    const xmlChar *nsName,
   21610 			    const xmlChar *location)
   21611 {
   21612     int ret = 0;
   21613     xmlSchemaParserCtxtPtr pctxt;
   21614     xmlSchemaBucketPtr bucket = NULL;
   21615 
   21616     if ((vctxt == NULL) || (schema == NULL))
   21617 	return (-1);
   21618 
   21619     if (vctxt->pctxt == NULL) {
   21620 	VERROR_INT("xmlSchemaAssembleByLocation",
   21621 	    "no parser context available");
   21622 	return(-1);
   21623     }
   21624     pctxt = vctxt->pctxt;
   21625     if (pctxt->constructor == NULL) {
   21626 	PERROR_INT("xmlSchemaAssembleByLocation",
   21627 	    "no constructor");
   21628 	return(-1);
   21629     }
   21630     /*
   21631     * Acquire the schema document.
   21632     */
   21633     location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
   21634 	location, node);
   21635     /*
   21636     * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
   21637     * the process will automatically change this to
   21638     * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
   21639     */
   21640     ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
   21641 	location, NULL, NULL, 0, node, NULL, nsName,
   21642 	&bucket);
   21643     if (ret != 0)
   21644 	return(ret);
   21645     if (bucket == NULL) {
   21646 	/*
   21647 	* Generate a warning that the document could not be located.
   21648 	*/
   21649 	xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
   21650 	    node, NULL,
   21651 	    "The document at location '%s' could not be acquired",
   21652 	    location, NULL, NULL);
   21653 	return(ret);
   21654     }
   21655     /*
   21656     * The first located schema will be handled as if all other
   21657     * schemas imported by XSI were imported by this first schema.
   21658     */
   21659     if ((bucket != NULL) &&
   21660 	(WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
   21661 	WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
   21662     /*
   21663     * TODO: Is this handled like an import? I.e. is it not an error
   21664     * if the schema cannot be located?
   21665     */
   21666     if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
   21667 	return(0);
   21668     /*
   21669     * We will reuse the parser context for every schema imported
   21670     * directly via XSI. So reset the context.
   21671     */
   21672     pctxt->nberrors = 0;
   21673     pctxt->err = 0;
   21674     pctxt->doc = bucket->doc;
   21675 
   21676     ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
   21677     if (ret == -1) {
   21678 	pctxt->doc = NULL;
   21679 	goto exit_failure;
   21680     }
   21681     /* Paranoid error channelling. */
   21682     if ((ret == 0) && (pctxt->nberrors != 0))
   21683 	ret = pctxt->err;
   21684     if (pctxt->nberrors == 0) {
   21685 	/*
   21686 	* Only bother to fixup pending components, if there was
   21687 	* no error yet.
   21688 	* For every XSI acquired schema (and its sub-schemata) we will
   21689 	* fixup the components.
   21690 	*/
   21691 	xmlSchemaFixupComponents(pctxt, bucket);
   21692 	ret = pctxt->err;
   21693 	/*
   21694 	* Not nice, but we need somehow to channel the schema parser
   21695 	* error to the validation context.
   21696 	*/
   21697 	if ((ret != 0) && (vctxt->err == 0))
   21698 	    vctxt->err = ret;
   21699 	vctxt->nberrors += pctxt->nberrors;
   21700     } else {
   21701 	/* Add to validation error sum. */
   21702 	vctxt->nberrors += pctxt->nberrors;
   21703     }
   21704     pctxt->doc = NULL;
   21705     return(ret);
   21706 exit_failure:
   21707     pctxt->doc = NULL;
   21708     return (-1);
   21709 }
   21710 
   21711 static xmlSchemaAttrInfoPtr
   21712 xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
   21713 			 int metaType)
   21714 {
   21715     if (vctxt->nbAttrInfos == 0)
   21716 	return (NULL);
   21717     {
   21718 	int i;
   21719 	xmlSchemaAttrInfoPtr iattr;
   21720 
   21721 	for (i = 0; i < vctxt->nbAttrInfos; i++) {
   21722 	    iattr = vctxt->attrInfos[i];
   21723 	    if (iattr->metaType == metaType)
   21724 		return (iattr);
   21725 	}
   21726 
   21727     }
   21728     return (NULL);
   21729 }
   21730 
   21731 /**
   21732  * xmlSchemaAssembleByXSI:
   21733  * @vctxt:  a schema validation context
   21734  *
   21735  * Expands an existing schema by an additional schema using
   21736  * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
   21737  * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
   21738  * must be set to 1.
   21739  *
   21740  * Returns 0 if the new schema is correct, a positive error code
   21741  * number otherwise and -1 in case of an internal or API error.
   21742  */
   21743 static int
   21744 xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
   21745 {
   21746     const xmlChar *cur, *end;
   21747     const xmlChar *nsname = NULL, *location;
   21748     int count = 0;
   21749     int ret = 0;
   21750     xmlSchemaAttrInfoPtr iattr;
   21751 
   21752     /*
   21753     * Parse the value; we will assume an even number of values
   21754     * to be given (this is how Xerces and XSV work).
   21755     *
   21756     * URGENT TODO: !! This needs to work for both
   21757     * @noNamespaceSchemaLocation AND @schemaLocation on the same
   21758     * element !!
   21759     */
   21760     iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   21761 	XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
   21762     if (iattr == NULL)
   21763 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   21764 	XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
   21765     if (iattr == NULL)
   21766 	return (0);
   21767     cur = iattr->value;
   21768     do {
   21769 	/*
   21770 	* TODO: Move the string parsing mechanism away from here.
   21771 	*/
   21772 	if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
   21773 	    /*
   21774 	    * Get the namespace name.
   21775 	    */
   21776 	    while (IS_BLANK_CH(*cur))
   21777 		cur++;
   21778 	    end = cur;
   21779 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   21780 		end++;
   21781 	    if (end == cur)
   21782 		break;
   21783 	    count++; /* TODO: Don't use the schema's dict. */
   21784 	    nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
   21785 	    cur = end;
   21786 	}
   21787 	/*
   21788 	* Get the URI.
   21789 	*/
   21790 	while (IS_BLANK_CH(*cur))
   21791 	    cur++;
   21792 	end = cur;
   21793 	while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   21794 	    end++;
   21795 	if (end == cur) {
   21796 	    if (iattr->metaType ==
   21797 		XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
   21798 	    {
   21799 		/*
   21800 		* If using @schemaLocation then tuples are expected.
   21801 		* I.e. the namespace name *and* the document's URI.
   21802 		*/
   21803 		xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
   21804 		    iattr->node, NULL,
   21805 		    "The value must consist of tuples: the target namespace "
   21806 		    "name and the document's URI", NULL, NULL, NULL);
   21807 	    }
   21808 	    break;
   21809 	}
   21810 	count++; /* TODO: Don't use the schema's dict. */
   21811 	location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
   21812 	cur = end;
   21813 	ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
   21814 	    iattr->node, nsname, location);
   21815 	if (ret == -1) {
   21816 	    VERROR_INT("xmlSchemaAssembleByXSI",
   21817 		"assembling schemata");
   21818 	    return (-1);
   21819 	}
   21820     } while (*cur != 0);
   21821     return (ret);
   21822 }
   21823 
   21824 static const xmlChar *
   21825 xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
   21826 			 const xmlChar *prefix)
   21827 {
   21828     if (vctxt->sax != NULL) {
   21829 	int i, j;
   21830 	xmlSchemaNodeInfoPtr inode;
   21831 
   21832 	for (i = vctxt->depth; i >= 0; i--) {
   21833 	    if (vctxt->elemInfos[i]->nbNsBindings != 0) {
   21834 		inode = vctxt->elemInfos[i];
   21835 		for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
   21836 		    if (((prefix == NULL) &&
   21837 			    (inode->nsBindings[j] == NULL)) ||
   21838 			((prefix != NULL) && xmlStrEqual(prefix,
   21839 			    inode->nsBindings[j]))) {
   21840 
   21841 			/*
   21842 			* Note that the namespace bindings are already
   21843 			* in a string dict.
   21844 			*/
   21845 			return (inode->nsBindings[j+1]);
   21846 		    }
   21847 		}
   21848 	    }
   21849 	}
   21850 	return (NULL);
   21851 #ifdef LIBXML_READER_ENABLED
   21852     } else if (vctxt->reader != NULL) {
   21853 	xmlChar *nsName;
   21854 
   21855 	nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
   21856 	if (nsName != NULL) {
   21857 	    const xmlChar *ret;
   21858 
   21859 	    ret = xmlDictLookup(vctxt->dict, nsName, -1);
   21860 	    xmlFree(nsName);
   21861 	    return (ret);
   21862 	} else
   21863 	    return (NULL);
   21864 #endif
   21865     } else {
   21866 	xmlNsPtr ns;
   21867 
   21868 	if ((vctxt->inode->node == NULL) ||
   21869 	    (vctxt->inode->node->doc == NULL)) {
   21870 	    VERROR_INT("xmlSchemaLookupNamespace",
   21871 		"no node or node's doc avaliable");
   21872 	    return (NULL);
   21873 	}
   21874 	ns = xmlSearchNs(vctxt->inode->node->doc,
   21875 	    vctxt->inode->node, prefix);
   21876 	if (ns != NULL)
   21877 	    return (ns->href);
   21878 	return (NULL);
   21879     }
   21880 }
   21881 
   21882 /*
   21883 * This one works on the schema of the validation context.
   21884 */
   21885 static int
   21886 xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
   21887 			  xmlSchemaPtr schema,
   21888 			  xmlNodePtr node,
   21889 			  const xmlChar *value,
   21890 			  xmlSchemaValPtr *val,
   21891 			  int valNeeded)
   21892 {
   21893     int ret;
   21894 
   21895     if (vctxt && (vctxt->schema == NULL)) {
   21896 	VERROR_INT("xmlSchemaValidateNotation",
   21897 	    "a schema is needed on the validation context");
   21898 	return (-1);
   21899     }
   21900     ret = xmlValidateQName(value, 1);
   21901     if (ret != 0)
   21902 	return (ret);
   21903     {
   21904 	xmlChar *localName = NULL;
   21905 	xmlChar *prefix = NULL;
   21906 
   21907 	localName = xmlSplitQName2(value, &prefix);
   21908 	if (prefix != NULL) {
   21909 	    const xmlChar *nsName = NULL;
   21910 
   21911 	    if (vctxt != NULL)
   21912 		nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
   21913 	    else if (node != NULL) {
   21914 		xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
   21915 		if (ns != NULL)
   21916 		    nsName = ns->href;
   21917 	    } else {
   21918 		xmlFree(prefix);
   21919 		xmlFree(localName);
   21920 		return (1);
   21921 	    }
   21922 	    if (nsName == NULL) {
   21923 		xmlFree(prefix);
   21924 		xmlFree(localName);
   21925 		return (1);
   21926 	    }
   21927 	    if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
   21928 		if ((valNeeded) && (val != NULL)) {
   21929 		    (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
   21930 						       xmlStrdup(nsName));
   21931 		    if (*val == NULL)
   21932 			ret = -1;
   21933 		}
   21934 	    } else
   21935 		ret = 1;
   21936 	    xmlFree(prefix);
   21937 	    xmlFree(localName);
   21938 	} else {
   21939 	    if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
   21940 		if (valNeeded && (val != NULL)) {
   21941 		    (*val) = xmlSchemaNewNOTATIONValue(
   21942 			BAD_CAST xmlStrdup(value), NULL);
   21943 		    if (*val == NULL)
   21944 			ret = -1;
   21945 		}
   21946 	    } else
   21947 		return (1);
   21948 	}
   21949     }
   21950     return (ret);
   21951 }
   21952 
   21953 static int
   21954 xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
   21955 		       const xmlChar* lname,
   21956 		       const xmlChar* nsname)
   21957 {
   21958     int i;
   21959 
   21960     lname = xmlDictLookup(vctxt->dict, lname, -1);
   21961     if (lname == NULL)
   21962 	return(-1);
   21963     if (nsname != NULL) {
   21964 	nsname = xmlDictLookup(vctxt->dict, nsname, -1);
   21965 	if (nsname == NULL)
   21966 	    return(-1);
   21967     }
   21968     for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
   21969 	if ((vctxt->nodeQNames->items [i] == lname) &&
   21970 	    (vctxt->nodeQNames->items[i +1] == nsname))
   21971 	    /* Already there */
   21972 	    return(i);
   21973     }
   21974     /* Add new entry. */
   21975     i = vctxt->nodeQNames->nbItems;
   21976     xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
   21977     xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
   21978     return(i);
   21979 }
   21980 
   21981 /************************************************************************
   21982  *									*
   21983  *  Validation of identity-constraints (IDC)                            *
   21984  *									*
   21985  ************************************************************************/
   21986 
   21987 /**
   21988  * xmlSchemaAugmentIDC:
   21989  * @idcDef: the IDC definition
   21990  *
   21991  * Creates an augmented IDC definition item.
   21992  *
   21993  * Returns the item, or NULL on internal errors.
   21994  */
   21995 static void
   21996 xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef,
   21997 		    xmlSchemaValidCtxtPtr vctxt)
   21998 {
   21999     xmlSchemaIDCAugPtr aidc;
   22000 
   22001     aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
   22002     if (aidc == NULL) {
   22003 	xmlSchemaVErrMemory(vctxt,
   22004 	    "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
   22005 	    NULL);
   22006 	return;
   22007     }
   22008     aidc->keyrefDepth = -1;
   22009     aidc->def = idcDef;
   22010     aidc->next = NULL;
   22011     if (vctxt->aidcs == NULL)
   22012 	vctxt->aidcs = aidc;
   22013     else {
   22014 	aidc->next = vctxt->aidcs;
   22015 	vctxt->aidcs = aidc;
   22016     }
   22017     /*
   22018     * Save if we have keyrefs at all.
   22019     */
   22020     if ((vctxt->hasKeyrefs == 0) &&
   22021 	(idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
   22022 	vctxt->hasKeyrefs = 1;
   22023 }
   22024 
   22025 /**
   22026  * xmlSchemaAugmentImportedIDC:
   22027  * @imported: the imported schema
   22028  *
   22029  * Creates an augmented IDC definition for the imported schema.
   22030  */
   22031 static void
   22032 xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) {
   22033     if (imported->schema->idcDef != NULL) {
   22034 	    xmlHashScan(imported->schema->idcDef ,
   22035 	    (xmlHashScanner) xmlSchemaAugmentIDC, vctxt);
   22036     }
   22037 }
   22038 
   22039 /**
   22040  * xmlSchemaIDCNewBinding:
   22041  * @idcDef: the IDC definition of this binding
   22042  *
   22043  * Creates a new IDC binding.
   22044  *
   22045  * Returns the new IDC binding, NULL on internal errors.
   22046  */
   22047 static xmlSchemaPSVIIDCBindingPtr
   22048 xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
   22049 {
   22050     xmlSchemaPSVIIDCBindingPtr ret;
   22051 
   22052     ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
   22053 	    sizeof(xmlSchemaPSVIIDCBinding));
   22054     if (ret == NULL) {
   22055 	xmlSchemaVErrMemory(NULL,
   22056 	    "allocating a PSVI IDC binding item", NULL);
   22057 	return (NULL);
   22058     }
   22059     memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
   22060     ret->definition = idcDef;
   22061     return (ret);
   22062 }
   22063 
   22064 /**
   22065  * xmlSchemaIDCStoreNodeTableItem:
   22066  * @vctxt: the WXS validation context
   22067  * @item: the IDC node table item
   22068  *
   22069  * The validation context is used to store IDC node table items.
   22070  * They are stored to avoid copying them if IDC node-tables are merged
   22071  * with corresponding parent IDC node-tables (bubbling).
   22072  *
   22073  * Returns 0 if succeeded, -1 on internal errors.
   22074  */
   22075 static int
   22076 xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
   22077 			       xmlSchemaPSVIIDCNodePtr item)
   22078 {
   22079     /*
   22080     * Add to gobal list.
   22081     */
   22082     if (vctxt->idcNodes == NULL) {
   22083 	vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
   22084 	    xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
   22085 	if (vctxt->idcNodes == NULL) {
   22086 	    xmlSchemaVErrMemory(vctxt,
   22087 		"allocating the IDC node table item list", NULL);
   22088 	    return (-1);
   22089 	}
   22090 	vctxt->sizeIdcNodes = 20;
   22091     } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
   22092 	vctxt->sizeIdcNodes *= 2;
   22093 	vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
   22094 	    xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
   22095 	    sizeof(xmlSchemaPSVIIDCNodePtr));
   22096 	if (vctxt->idcNodes == NULL) {
   22097 	    xmlSchemaVErrMemory(vctxt,
   22098 		"re-allocating the IDC node table item list", NULL);
   22099 	    return (-1);
   22100 	}
   22101     }
   22102     vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
   22103 
   22104     return (0);
   22105 }
   22106 
   22107 /**
   22108  * xmlSchemaIDCStoreKey:
   22109  * @vctxt: the WXS validation context
   22110  * @item: the IDC key
   22111  *
   22112  * The validation context is used to store an IDC key.
   22113  *
   22114  * Returns 0 if succeeded, -1 on internal errors.
   22115  */
   22116 static int
   22117 xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
   22118 		     xmlSchemaPSVIIDCKeyPtr key)
   22119 {
   22120     /*
   22121     * Add to gobal list.
   22122     */
   22123     if (vctxt->idcKeys == NULL) {
   22124 	vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
   22125 	    xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
   22126 	if (vctxt->idcKeys == NULL) {
   22127 	    xmlSchemaVErrMemory(vctxt,
   22128 		"allocating the IDC key storage list", NULL);
   22129 	    return (-1);
   22130 	}
   22131 	vctxt->sizeIdcKeys = 40;
   22132     } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
   22133 	vctxt->sizeIdcKeys *= 2;
   22134 	vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
   22135 	    xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
   22136 	    sizeof(xmlSchemaPSVIIDCKeyPtr));
   22137 	if (vctxt->idcKeys == NULL) {
   22138 	    xmlSchemaVErrMemory(vctxt,
   22139 		"re-allocating the IDC key storage list", NULL);
   22140 	    return (-1);
   22141 	}
   22142     }
   22143     vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
   22144 
   22145     return (0);
   22146 }
   22147 
   22148 /**
   22149  * xmlSchemaIDCAppendNodeTableItem:
   22150  * @bind: the IDC binding
   22151  * @ntItem: the node-table item
   22152  *
   22153  * Appends the IDC node-table item to the binding.
   22154  *
   22155  * Returns 0 on success and -1 on internal errors.
   22156  */
   22157 static int
   22158 xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
   22159 				xmlSchemaPSVIIDCNodePtr ntItem)
   22160 {
   22161     if (bind->nodeTable == NULL) {
   22162 	bind->sizeNodes = 10;
   22163 	bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   22164 	    xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
   22165 	if (bind->nodeTable == NULL) {
   22166 	    xmlSchemaVErrMemory(NULL,
   22167 		"allocating an array of IDC node-table items", NULL);
   22168 	    return(-1);
   22169 	}
   22170     } else if (bind->sizeNodes <= bind->nbNodes) {
   22171 	bind->sizeNodes *= 2;
   22172 	bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   22173 	    xmlRealloc(bind->nodeTable, bind->sizeNodes *
   22174 		sizeof(xmlSchemaPSVIIDCNodePtr));
   22175 	if (bind->nodeTable == NULL) {
   22176 	    xmlSchemaVErrMemory(NULL,
   22177 		"re-allocating an array of IDC node-table items", NULL);
   22178 	    return(-1);
   22179 	}
   22180     }
   22181     bind->nodeTable[bind->nbNodes++] = ntItem;
   22182     return(0);
   22183 }
   22184 
   22185 /**
   22186  * xmlSchemaIDCAcquireBinding:
   22187  * @vctxt: the WXS validation context
   22188  * @matcher: the IDC matcher
   22189  *
   22190  * Looks up an PSVI IDC binding, for the IDC definition and
   22191  * of the given matcher. If none found, a new one is created
   22192  * and added to the IDC table.
   22193  *
   22194  * Returns an IDC binding or NULL on internal errors.
   22195  */
   22196 static xmlSchemaPSVIIDCBindingPtr
   22197 xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
   22198 			  xmlSchemaIDCMatcherPtr matcher)
   22199 {
   22200     xmlSchemaNodeInfoPtr ielem;
   22201 
   22202     ielem = vctxt->elemInfos[matcher->depth];
   22203 
   22204     if (ielem->idcTable == NULL) {
   22205 	ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
   22206 	if (ielem->idcTable == NULL)
   22207 	    return (NULL);
   22208 	return(ielem->idcTable);
   22209     } else {
   22210 	xmlSchemaPSVIIDCBindingPtr bind = NULL;
   22211 
   22212 	bind = ielem->idcTable;
   22213 	do {
   22214 	    if (bind->definition == matcher->aidc->def)
   22215 		return(bind);
   22216 	    if (bind->next == NULL) {
   22217 		bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
   22218 		if (bind->next == NULL)
   22219 		    return (NULL);
   22220 		return(bind->next);
   22221 	    }
   22222 	    bind = bind->next;
   22223 	} while (bind != NULL);
   22224     }
   22225     return (NULL);
   22226 }
   22227 
   22228 static xmlSchemaItemListPtr
   22229 xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
   22230 			     xmlSchemaIDCMatcherPtr matcher)
   22231 {
   22232     if (matcher->targets == NULL)
   22233 	matcher->targets = xmlSchemaItemListCreate();
   22234     return(matcher->targets);
   22235 }
   22236 
   22237 /**
   22238  * xmlSchemaIDCFreeKey:
   22239  * @key: the IDC key
   22240  *
   22241  * Frees an IDC key together with its compiled value.
   22242  */
   22243 static void
   22244 xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
   22245 {
   22246     if (key->val != NULL)
   22247 	xmlSchemaFreeValue(key->val);
   22248     xmlFree(key);
   22249 }
   22250 
   22251 /**
   22252  * xmlSchemaIDCFreeBinding:
   22253  *
   22254  * Frees an IDC binding. Note that the node table-items
   22255  * are not freed.
   22256  */
   22257 static void
   22258 xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
   22259 {
   22260     if (bind->nodeTable != NULL)
   22261 	xmlFree(bind->nodeTable);
   22262     if (bind->dupls != NULL)
   22263 	xmlSchemaItemListFree(bind->dupls);
   22264     xmlFree(bind);
   22265 }
   22266 
   22267 /**
   22268  * xmlSchemaIDCFreeIDCTable:
   22269  * @bind: the first IDC binding in the list
   22270  *
   22271  * Frees an IDC table, i.e. all the IDC bindings in the list.
   22272  */
   22273 static void
   22274 xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
   22275 {
   22276     xmlSchemaPSVIIDCBindingPtr prev;
   22277 
   22278     while (bind != NULL) {
   22279 	prev = bind;
   22280 	bind = bind->next;
   22281 	xmlSchemaIDCFreeBinding(prev);
   22282     }
   22283 }
   22284 
   22285 /**
   22286  * xmlSchemaIDCFreeMatcherList:
   22287  * @matcher: the first IDC matcher in the list
   22288  *
   22289  * Frees a list of IDC matchers.
   22290  */
   22291 static void
   22292 xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
   22293 {
   22294     xmlSchemaIDCMatcherPtr next;
   22295 
   22296     while (matcher != NULL) {
   22297 	next = matcher->next;
   22298 	if (matcher->keySeqs != NULL) {
   22299 	    int i;
   22300 	    for (i = 0; i < matcher->sizeKeySeqs; i++)
   22301 		if (matcher->keySeqs[i] != NULL)
   22302 		    xmlFree(matcher->keySeqs[i]);
   22303 	    xmlFree(matcher->keySeqs);
   22304 	}
   22305 	if (matcher->targets != NULL) {
   22306 	    if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
   22307 		int i;
   22308 		xmlSchemaPSVIIDCNodePtr idcNode;
   22309 		/*
   22310 		* Node-table items for keyrefs are not stored globally
   22311 		* to the validation context, since they are not bubbled.
   22312 		* We need to free them here.
   22313 		*/
   22314 		for (i = 0; i < matcher->targets->nbItems; i++) {
   22315 		    idcNode =
   22316 			(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
   22317 		    xmlFree(idcNode->keys);
   22318 		    xmlFree(idcNode);
   22319 		}
   22320 	    }
   22321 	    xmlSchemaItemListFree(matcher->targets);
   22322 	}
   22323 	xmlFree(matcher);
   22324 	matcher = next;
   22325     }
   22326 }
   22327 
   22328 /**
   22329  * xmlSchemaIDCReleaseMatcherList:
   22330  * @vctxt: the WXS validation context
   22331  * @matcher: the first IDC matcher in the list
   22332  *
   22333  * Caches a list of IDC matchers for reuse.
   22334  */
   22335 static void
   22336 xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
   22337 			       xmlSchemaIDCMatcherPtr matcher)
   22338 {
   22339     xmlSchemaIDCMatcherPtr next;
   22340 
   22341     while (matcher != NULL) {
   22342 	next = matcher->next;
   22343 	if (matcher->keySeqs != NULL) {
   22344 	    int i;
   22345 	    /*
   22346 	    * Don't free the array, but only the content.
   22347 	    */
   22348 	    for (i = 0; i < matcher->sizeKeySeqs; i++)
   22349 		if (matcher->keySeqs[i] != NULL) {
   22350 		    xmlFree(matcher->keySeqs[i]);
   22351 		    matcher->keySeqs[i] = NULL;
   22352 		}
   22353 	}
   22354 	if (matcher->targets) {
   22355 	    if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
   22356 		int i;
   22357 		xmlSchemaPSVIIDCNodePtr idcNode;
   22358 		/*
   22359 		* Node-table items for keyrefs are not stored globally
   22360 		* to the validation context, since they are not bubbled.
   22361 		* We need to free them here.
   22362 		*/
   22363 		for (i = 0; i < matcher->targets->nbItems; i++) {
   22364 		    idcNode =
   22365 			(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
   22366 		    xmlFree(idcNode->keys);
   22367 		    xmlFree(idcNode);
   22368 		}
   22369 	    }
   22370 	    xmlSchemaItemListFree(matcher->targets);
   22371 	    matcher->targets = NULL;
   22372 	}
   22373 	matcher->next = NULL;
   22374 	/*
   22375 	* Cache the matcher.
   22376 	*/
   22377 	if (vctxt->idcMatcherCache != NULL)
   22378 	    matcher->nextCached = vctxt->idcMatcherCache;
   22379 	vctxt->idcMatcherCache = matcher;
   22380 
   22381 	matcher = next;
   22382     }
   22383 }
   22384 
   22385 /**
   22386  * xmlSchemaIDCAddStateObject:
   22387  * @vctxt: the WXS validation context
   22388  * @matcher: the IDC matcher
   22389  * @sel: the XPath information
   22390  * @parent: the parent "selector" state object if any
   22391  * @type: "selector" or "field"
   22392  *
   22393  * Creates/reuses and activates state objects for the given
   22394  * XPath information; if the XPath expression consists of unions,
   22395  * multiple state objects are created for every unioned expression.
   22396  *
   22397  * Returns 0 on success and -1 on internal errors.
   22398  */
   22399 static int
   22400 xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
   22401 			xmlSchemaIDCMatcherPtr matcher,
   22402 			xmlSchemaIDCSelectPtr sel,
   22403 			int type)
   22404 {
   22405     xmlSchemaIDCStateObjPtr sto;
   22406 
   22407     /*
   22408     * Reuse the state objects from the pool.
   22409     */
   22410     if (vctxt->xpathStatePool != NULL) {
   22411 	sto = vctxt->xpathStatePool;
   22412 	vctxt->xpathStatePool = sto->next;
   22413 	sto->next = NULL;
   22414     } else {
   22415 	/*
   22416 	* Create a new state object.
   22417 	*/
   22418 	sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
   22419 	if (sto == NULL) {
   22420 	    xmlSchemaVErrMemory(NULL,
   22421 		"allocating an IDC state object", NULL);
   22422 	    return (-1);
   22423 	}
   22424 	memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
   22425     }
   22426     /*
   22427     * Add to global list.
   22428     */
   22429     if (vctxt->xpathStates != NULL)
   22430 	sto->next = vctxt->xpathStates;
   22431     vctxt->xpathStates = sto;
   22432 
   22433     /*
   22434     * Free the old xpath validation context.
   22435     */
   22436     if (sto->xpathCtxt != NULL)
   22437 	xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
   22438 
   22439     /*
   22440     * Create a new XPath (pattern) validation context.
   22441     */
   22442     sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
   22443 	(xmlPatternPtr) sel->xpathComp);
   22444     if (sto->xpathCtxt == NULL) {
   22445 	VERROR_INT("xmlSchemaIDCAddStateObject",
   22446 	    "failed to create an XPath validation context");
   22447 	return (-1);
   22448     }
   22449     sto->type = type;
   22450     sto->depth = vctxt->depth;
   22451     sto->matcher = matcher;
   22452     sto->sel = sel;
   22453     sto->nbHistory = 0;
   22454 
   22455 #ifdef DEBUG_IDC
   22456     xmlGenericError(xmlGenericErrorContext, "IDC:   STO push '%s'\n",
   22457 	sto->sel->xpath);
   22458 #endif
   22459     return (0);
   22460 }
   22461 
   22462 /**
   22463  * xmlSchemaXPathEvaluate:
   22464  * @vctxt: the WXS validation context
   22465  * @nodeType: the nodeType of the current node
   22466  *
   22467  * Evaluates all active XPath state objects.
   22468  *
   22469  * Returns the number of IC "field" state objects which resolved to
   22470  * this node, 0 if none resolved and -1 on internal errors.
   22471  */
   22472 static int
   22473 xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
   22474 		       xmlElementType nodeType)
   22475 {
   22476     xmlSchemaIDCStateObjPtr sto, head = NULL, first;
   22477     int res, resolved = 0, depth = vctxt->depth;
   22478 
   22479     if (vctxt->xpathStates == NULL)
   22480 	return (0);
   22481 
   22482     if (nodeType == XML_ATTRIBUTE_NODE)
   22483 	depth++;
   22484 #ifdef DEBUG_IDC
   22485     {
   22486 	xmlChar *str = NULL;
   22487 	xmlGenericError(xmlGenericErrorContext,
   22488 	    "IDC: EVAL on %s, depth %d, type %d\n",
   22489 	    xmlSchemaFormatQName(&str, vctxt->inode->nsName,
   22490 		vctxt->inode->localName), depth, nodeType);
   22491 	FREE_AND_NULL(str)
   22492     }
   22493 #endif
   22494     /*
   22495     * Process all active XPath state objects.
   22496     */
   22497     first = vctxt->xpathStates;
   22498     sto = first;
   22499     while (sto != head) {
   22500 #ifdef DEBUG_IDC
   22501 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
   22502 	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] selector '%s'\n",
   22503 		sto->matcher->aidc->def->name, sto->sel->xpath);
   22504 	else
   22505 	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] field '%s'\n",
   22506 		sto->matcher->aidc->def->name, sto->sel->xpath);
   22507 #endif
   22508 	if (nodeType == XML_ELEMENT_NODE)
   22509 	    res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
   22510 		vctxt->inode->localName, vctxt->inode->nsName);
   22511 	else
   22512 	    res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
   22513 		vctxt->inode->localName, vctxt->inode->nsName);
   22514 
   22515 	if (res == -1) {
   22516 	    VERROR_INT("xmlSchemaXPathEvaluate",
   22517 		"calling xmlStreamPush()");
   22518 	    return (-1);
   22519 	}
   22520 	if (res == 0)
   22521 	    goto next_sto;
   22522 	/*
   22523 	* Full match.
   22524 	*/
   22525 #ifdef DEBUG_IDC
   22526 	xmlGenericError(xmlGenericErrorContext, "IDC:     "
   22527 	    "MATCH\n");
   22528 #endif
   22529 	/*
   22530 	* Register a match in the state object history.
   22531 	*/
   22532 	if (sto->history == NULL) {
   22533 	    sto->history = (int *) xmlMalloc(5 * sizeof(int));
   22534 	    if (sto->history == NULL) {
   22535 		xmlSchemaVErrMemory(NULL,
   22536 		    "allocating the state object history", NULL);
   22537 		return(-1);
   22538 	    }
   22539 	    sto->sizeHistory = 5;
   22540 	} else if (sto->sizeHistory <= sto->nbHistory) {
   22541 	    sto->sizeHistory *= 2;
   22542 	    sto->history = (int *) xmlRealloc(sto->history,
   22543 		sto->sizeHistory * sizeof(int));
   22544 	    if (sto->history == NULL) {
   22545 		xmlSchemaVErrMemory(NULL,
   22546 		    "re-allocating the state object history", NULL);
   22547 		return(-1);
   22548 	    }
   22549 	}
   22550 	sto->history[sto->nbHistory++] = depth;
   22551 
   22552 #ifdef DEBUG_IDC
   22553 	xmlGenericError(xmlGenericErrorContext, "IDC:       push match '%d'\n",
   22554 	    vctxt->depth);
   22555 #endif
   22556 
   22557 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
   22558 	    xmlSchemaIDCSelectPtr sel;
   22559 	    /*
   22560 	    * Activate state objects for the IDC fields of
   22561 	    * the IDC selector.
   22562 	    */
   22563 #ifdef DEBUG_IDC
   22564 	    xmlGenericError(xmlGenericErrorContext, "IDC:     "
   22565 		"activating field states\n");
   22566 #endif
   22567 	    sel = sto->matcher->aidc->def->fields;
   22568 	    while (sel != NULL) {
   22569 		if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
   22570 		    sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
   22571 		    return (-1);
   22572 		sel = sel->next;
   22573 	    }
   22574 	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
   22575 	    /*
   22576 	    * An IDC key node was found by the IDC field.
   22577 	    */
   22578 #ifdef DEBUG_IDC
   22579 	    xmlGenericError(xmlGenericErrorContext,
   22580 		"IDC:     key found\n");
   22581 #endif
   22582 	    /*
   22583 	    * Notify that the character value of this node is
   22584 	    * needed.
   22585 	    */
   22586 	    if (resolved == 0) {
   22587 		if ((vctxt->inode->flags &
   22588 		    XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
   22589 		vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
   22590 	    }
   22591 	    resolved++;
   22592 	}
   22593 next_sto:
   22594 	if (sto->next == NULL) {
   22595 	    /*
   22596 	    * Evaluate field state objects created on this node as well.
   22597 	    */
   22598 	    head = first;
   22599 	    sto = vctxt->xpathStates;
   22600 	} else
   22601 	    sto = sto->next;
   22602     }
   22603     return (resolved);
   22604 }
   22605 
   22606 static const xmlChar *
   22607 xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
   22608 			      xmlChar **buf,
   22609 			      xmlSchemaPSVIIDCKeyPtr *seq,
   22610 			      int count)
   22611 {
   22612     int i, res;
   22613     xmlChar *value = NULL;
   22614 
   22615     *buf = xmlStrdup(BAD_CAST "[");
   22616     for (i = 0; i < count; i++) {
   22617 	*buf = xmlStrcat(*buf, BAD_CAST "'");
   22618 	res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
   22619 	    xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
   22620 	    &value);
   22621 	if (res == 0)
   22622 	    *buf = xmlStrcat(*buf, BAD_CAST value);
   22623 	else {
   22624 	    VERROR_INT("xmlSchemaFormatIDCKeySequence",
   22625 		"failed to compute a canonical value");
   22626 	    *buf = xmlStrcat(*buf, BAD_CAST "???");
   22627 	}
   22628 	if (i < count -1)
   22629 	    *buf = xmlStrcat(*buf, BAD_CAST "', ");
   22630 	else
   22631 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
   22632 	if (value != NULL) {
   22633 	    xmlFree(value);
   22634 	    value = NULL;
   22635 	}
   22636     }
   22637     *buf = xmlStrcat(*buf, BAD_CAST "]");
   22638 
   22639     return (BAD_CAST *buf);
   22640 }
   22641 
   22642 /**
   22643  * xmlSchemaXPathPop:
   22644  * @vctxt: the WXS validation context
   22645  *
   22646  * Pops all XPath states.
   22647  *
   22648  * Returns 0 on success and -1 on internal errors.
   22649  */
   22650 static int
   22651 xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
   22652 {
   22653     xmlSchemaIDCStateObjPtr sto;
   22654     int res;
   22655 
   22656     if (vctxt->xpathStates == NULL)
   22657 	return(0);
   22658     sto = vctxt->xpathStates;
   22659     do {
   22660 	res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
   22661 	if (res == -1)
   22662 	    return (-1);
   22663 	sto = sto->next;
   22664     } while (sto != NULL);
   22665     return(0);
   22666 }
   22667 
   22668 /**
   22669  * xmlSchemaXPathProcessHistory:
   22670  * @vctxt: the WXS validation context
   22671  * @type: the simple/complex type of the current node if any at all
   22672  * @val: the precompiled value
   22673  *
   22674  * Processes and pops the history items of the IDC state objects.
   22675  * IDC key-sequences are validated/created on IDC bindings.
   22676  *
   22677  * Returns 0 on success and -1 on internal errors.
   22678  */
   22679 static int
   22680 xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
   22681 			     int depth)
   22682 {
   22683     xmlSchemaIDCStateObjPtr sto, nextsto;
   22684     int res, matchDepth;
   22685     xmlSchemaPSVIIDCKeyPtr key = NULL;
   22686     xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
   22687 
   22688     if (vctxt->xpathStates == NULL)
   22689 	return (0);
   22690     sto = vctxt->xpathStates;
   22691 
   22692 #ifdef DEBUG_IDC
   22693     {
   22694 	xmlChar *str = NULL;
   22695 	xmlGenericError(xmlGenericErrorContext,
   22696 	    "IDC: BACK on %s, depth %d\n",
   22697 	    xmlSchemaFormatQName(&str, vctxt->inode->nsName,
   22698 		vctxt->inode->localName), vctxt->depth);
   22699 	FREE_AND_NULL(str)
   22700     }
   22701 #endif
   22702     /*
   22703     * Evaluate the state objects.
   22704     */
   22705     while (sto != NULL) {
   22706 	res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
   22707 	if (res == -1) {
   22708 	    VERROR_INT("xmlSchemaXPathProcessHistory",
   22709 		"calling xmlStreamPop()");
   22710 	    return (-1);
   22711 	}
   22712 #ifdef DEBUG_IDC
   22713 	xmlGenericError(xmlGenericErrorContext, "IDC:   stream pop '%s'\n",
   22714 	    sto->sel->xpath);
   22715 #endif
   22716 	if (sto->nbHistory == 0)
   22717 	    goto deregister_check;
   22718 
   22719 	matchDepth = sto->history[sto->nbHistory -1];
   22720 
   22721 	/*
   22722 	* Only matches at the current depth are of interest.
   22723 	*/
   22724 	if (matchDepth != depth) {
   22725 	    sto = sto->next;
   22726 	    continue;
   22727 	}
   22728 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
   22729 	    /*
   22730 	    * NOTE: According to
   22731 	    *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
   22732 	    *   ... the simple-content of complex types is also allowed.
   22733 	    */
   22734 
   22735 	    if (WXS_IS_COMPLEX(type)) {
   22736 		if (WXS_HAS_SIMPLE_CONTENT(type)) {
   22737 		    /*
   22738 		    * Sanity check for complex types with simple content.
   22739 		    */
   22740 		    simpleType = type->contentTypeDef;
   22741 		    if (simpleType == NULL) {
   22742 			VERROR_INT("xmlSchemaXPathProcessHistory",
   22743 			    "field resolves to a CT with simple content "
   22744 			    "but the CT is missing the ST definition");
   22745 			return (-1);
   22746 		    }
   22747 		} else
   22748 		    simpleType = NULL;
   22749 	    } else
   22750 		simpleType = type;
   22751 	    if (simpleType == NULL) {
   22752 		xmlChar *str = NULL;
   22753 
   22754 		/*
   22755 		* Not qualified if the field resolves to a node of non
   22756 		* simple type.
   22757 		*/
   22758 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   22759 		    XML_SCHEMAV_CVC_IDC, NULL,
   22760 		    WXS_BASIC_CAST sto->matcher->aidc->def,
   22761 		    "The XPath '%s' of a field of %s does evaluate to a node of "
   22762 		    "non-simple type",
   22763 		    sto->sel->xpath,
   22764 		    xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
   22765 		FREE_AND_NULL(str);
   22766 		sto->nbHistory--;
   22767 		goto deregister_check;
   22768 	    }
   22769 
   22770 	    if ((key == NULL) && (vctxt->inode->val == NULL)) {
   22771 		/*
   22772 		* Failed to provide the normalized value; maybe
   22773 		* the value was invalid.
   22774 		*/
   22775 		VERROR(XML_SCHEMAV_CVC_IDC,
   22776 		    WXS_BASIC_CAST sto->matcher->aidc->def,
   22777 		    "Warning: No precomputed value available, the value "
   22778 		    "was either invalid or something strange happend");
   22779 		sto->nbHistory--;
   22780 		goto deregister_check;
   22781 	    } else {
   22782 		xmlSchemaIDCMatcherPtr matcher = sto->matcher;
   22783 		xmlSchemaPSVIIDCKeyPtr *keySeq;
   22784 		int pos, idx;
   22785 
   22786 		/*
   22787 		* The key will be anchored on the matcher's list of
   22788 		* key-sequences. The position in this list is determined
   22789 		* by the target node's depth relative to the matcher's
   22790 		* depth of creation (i.e. the depth of the scope element).
   22791 		*
   22792 		* Element        Depth    Pos   List-entries
   22793 		* <scope>          0              NULL
   22794 		*   <bar>          1              NULL
   22795 		*     <target/>    2       2      target
   22796 		*   <bar>
   22797                 * </scope>
   22798 		*
   22799 		* The size of the list is only dependant on the depth of
   22800 		* the tree.
   22801 		* An entry will be NULLed in selector_leave, i.e. when
   22802 		* we hit the target's
   22803 		*/
   22804 		pos = sto->depth - matcher->depth;
   22805 		idx = sto->sel->index;
   22806 
   22807 		/*
   22808 		* Create/grow the array of key-sequences.
   22809 		*/
   22810 		if (matcher->keySeqs == NULL) {
   22811 		    if (pos > 9)
   22812 			matcher->sizeKeySeqs = pos * 2;
   22813 		    else
   22814 			matcher->sizeKeySeqs = 10;
   22815 		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
   22816 			xmlMalloc(matcher->sizeKeySeqs *
   22817 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
   22818 		    if (matcher->keySeqs == NULL) {
   22819 			xmlSchemaVErrMemory(NULL,
   22820 			    "allocating an array of key-sequences",
   22821 			    NULL);
   22822 			return(-1);
   22823 		    }
   22824 		    memset(matcher->keySeqs, 0,
   22825 			matcher->sizeKeySeqs *
   22826 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
   22827 		} else if (pos >= matcher->sizeKeySeqs) {
   22828 		    int i = matcher->sizeKeySeqs;
   22829 
   22830 		    matcher->sizeKeySeqs *= 2;
   22831 		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
   22832 			xmlRealloc(matcher->keySeqs,
   22833 			matcher->sizeKeySeqs *
   22834 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
   22835 		    if (matcher->keySeqs == NULL) {
   22836 			xmlSchemaVErrMemory(NULL,
   22837 			    "reallocating an array of key-sequences",
   22838 			    NULL);
   22839 			return (-1);
   22840 		    }
   22841 		    /*
   22842 		    * The array needs to be NULLed.
   22843 		    * TODO: Use memset?
   22844 		    */
   22845 		    for (; i < matcher->sizeKeySeqs; i++)
   22846 			matcher->keySeqs[i] = NULL;
   22847 		}
   22848 
   22849 		/*
   22850 		* Get/create the key-sequence.
   22851 		*/
   22852 		keySeq = matcher->keySeqs[pos];
   22853 		if (keySeq == NULL) {
   22854 		    goto create_sequence;
   22855 		} else if (keySeq[idx] != NULL) {
   22856 		    xmlChar *str = NULL;
   22857 		    /*
   22858 		    * cvc-identity-constraint:
   22859 		    * 3 For each node in the `target node set` all
   22860 		    * of the {fields}, with that node as the context
   22861 		    * node, evaluate to either an empty node-set or
   22862 		    * a node-set with exactly one member, which must
   22863 		    * have a simple type.
   22864 		    *
   22865 		    * The key was already set; report an error.
   22866 		    */
   22867 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
   22868 			XML_SCHEMAV_CVC_IDC, NULL,
   22869 			WXS_BASIC_CAST matcher->aidc->def,
   22870 			"The XPath '%s' of a field of %s evaluates to a "
   22871 			"node-set with more than one member",
   22872 			sto->sel->xpath,
   22873 			xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
   22874 		    FREE_AND_NULL(str);
   22875 		    sto->nbHistory--;
   22876 		    goto deregister_check;
   22877 		} else
   22878 		    goto create_key;
   22879 
   22880 create_sequence:
   22881 		/*
   22882 		* Create a key-sequence.
   22883 		*/
   22884 		keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
   22885 		    matcher->aidc->def->nbFields *
   22886 		    sizeof(xmlSchemaPSVIIDCKeyPtr));
   22887 		if (keySeq == NULL) {
   22888 		    xmlSchemaVErrMemory(NULL,
   22889 			"allocating an IDC key-sequence", NULL);
   22890 		    return(-1);
   22891 		}
   22892 		memset(keySeq, 0, matcher->aidc->def->nbFields *
   22893 		    sizeof(xmlSchemaPSVIIDCKeyPtr));
   22894 		matcher->keySeqs[pos] = keySeq;
   22895 create_key:
   22896 		/*
   22897 		* Create a key once per node only.
   22898 		*/
   22899 		if (key == NULL) {
   22900 		    key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
   22901 			sizeof(xmlSchemaPSVIIDCKey));
   22902 		    if (key == NULL) {
   22903 			xmlSchemaVErrMemory(NULL,
   22904 			    "allocating a IDC key", NULL);
   22905 			xmlFree(keySeq);
   22906 			matcher->keySeqs[pos] = NULL;
   22907 			return(-1);
   22908 		    }
   22909 		    /*
   22910 		    * Consume the compiled value.
   22911 		    */
   22912 		    key->type = simpleType;
   22913 		    key->val = vctxt->inode->val;
   22914 		    vctxt->inode->val = NULL;
   22915 		    /*
   22916 		    * Store the key in a global list.
   22917 		    */
   22918 		    if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
   22919 			xmlSchemaIDCFreeKey(key);
   22920 			return (-1);
   22921 		    }
   22922 		}
   22923 		keySeq[idx] = key;
   22924 	    }
   22925 	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
   22926 
   22927 	    xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
   22928 	    /* xmlSchemaPSVIIDCBindingPtr bind; */
   22929 	    xmlSchemaPSVIIDCNodePtr ntItem;
   22930 	    xmlSchemaIDCMatcherPtr matcher;
   22931 	    xmlSchemaIDCPtr idc;
   22932 	    xmlSchemaItemListPtr targets;
   22933 	    int pos, i, j, nbKeys;
   22934 	    /*
   22935 	    * Here we have the following scenario:
   22936 	    * An IDC 'selector' state object resolved to a target node,
   22937 	    * during the time this target node was in the
   22938 	    * ancestor-or-self axis, the 'field' state object(s) looked
   22939 	    * out for matching nodes to create a key-sequence for this
   22940 	    * target node. Now we are back to this target node and need
   22941 	    * to put the key-sequence, together with the target node
   22942 	    * itself, into the node-table of the corresponding IDC
   22943 	    * binding.
   22944 	    */
   22945 	    matcher = sto->matcher;
   22946 	    idc = matcher->aidc->def;
   22947 	    nbKeys = idc->nbFields;
   22948 	    pos = depth - matcher->depth;
   22949 	    /*
   22950 	    * Check if the matcher has any key-sequences at all, plus
   22951 	    * if it has a key-sequence for the current target node.
   22952 	    */
   22953 	    if ((matcher->keySeqs == NULL) ||
   22954 		(matcher->sizeKeySeqs <= pos)) {
   22955 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
   22956 		    goto selector_key_error;
   22957 		else
   22958 		    goto selector_leave;
   22959 	    }
   22960 
   22961 	    keySeq = &(matcher->keySeqs[pos]);
   22962 	    if (*keySeq == NULL) {
   22963 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
   22964 		    goto selector_key_error;
   22965 		else
   22966 		    goto selector_leave;
   22967 	    }
   22968 
   22969 	    for (i = 0; i < nbKeys; i++) {
   22970 		if ((*keySeq)[i] == NULL) {
   22971 		    /*
   22972 		    * Not qualified, if not all fields did resolve.
   22973 		    */
   22974 		    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
   22975 			/*
   22976 			* All fields of a "key" IDC must resolve.
   22977 			*/
   22978 			goto selector_key_error;
   22979 		    }
   22980 		    goto selector_leave;
   22981 		}
   22982 	    }
   22983 	    /*
   22984 	    * All fields did resolve.
   22985 	    */
   22986 
   22987 	    /*
   22988 	    * 4.1 If the {identity-constraint category} is unique(/key),
   22989 	    * then no two members of the `qualified node set` have
   22990 	    * `key-sequences` whose members are pairwise equal, as
   22991 	    * defined by Equal in [XML Schemas: Datatypes].
   22992 	    *
   22993 	    * Get the IDC binding from the matcher and check for
   22994 	    * duplicate key-sequences.
   22995 	    */
   22996 #if 0
   22997 	    bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
   22998 #endif
   22999 	    targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
   23000 	    if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
   23001 		(targets->nbItems != 0)) {
   23002 		xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
   23003 
   23004 		i = 0;
   23005 		res = 0;
   23006 		/*
   23007 		* Compare the key-sequences, key by key.
   23008 		*/
   23009 		do {
   23010 		    bkeySeq =
   23011 			((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys;
   23012 		    for (j = 0; j < nbKeys; j++) {
   23013 			ckey = (*keySeq)[j];
   23014 			bkey = bkeySeq[j];
   23015 			res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
   23016 			if (res == -1) {
   23017 			    return (-1);
   23018 			} else if (res == 0) {
   23019 			    /*
   23020 			    * One of the keys differs, so the key-sequence
   23021 			    * won't be equal; get out.
   23022 			    */
   23023 			    break;
   23024 			}
   23025 		    }
   23026 		    if (res == 1) {
   23027 			/*
   23028 			* Duplicate key-sequence found.
   23029 			*/
   23030 			break;
   23031 		    }
   23032 		    i++;
   23033 		} while (i < targets->nbItems);
   23034 		if (i != targets->nbItems) {
   23035 		    xmlChar *str = NULL, *strB = NULL;
   23036 		    /*
   23037 		    * TODO: Try to report the key-sequence.
   23038 		    */
   23039 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
   23040 			XML_SCHEMAV_CVC_IDC, NULL,
   23041 			WXS_BASIC_CAST idc,
   23042 			"Duplicate key-sequence %s in %s",
   23043 			xmlSchemaFormatIDCKeySequence(vctxt, &str,
   23044 			    (*keySeq), nbKeys),
   23045 			xmlSchemaGetIDCDesignation(&strB, idc));
   23046 		    FREE_AND_NULL(str);
   23047 		    FREE_AND_NULL(strB);
   23048 		    goto selector_leave;
   23049 		}
   23050 	    }
   23051 	    /*
   23052 	    * Add a node-table item to the IDC binding.
   23053 	    */
   23054 	    ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
   23055 		sizeof(xmlSchemaPSVIIDCNode));
   23056 	    if (ntItem == NULL) {
   23057 		xmlSchemaVErrMemory(NULL,
   23058 		    "allocating an IDC node-table item", NULL);
   23059 		xmlFree(*keySeq);
   23060 		*keySeq = NULL;
   23061 		return(-1);
   23062 	    }
   23063 	    memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
   23064 
   23065 	    /*
   23066 	    * Store the node-table item in a global list.
   23067 	    */
   23068 	    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
   23069 		if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
   23070 		    xmlFree(ntItem);
   23071 		    xmlFree(*keySeq);
   23072 		    *keySeq = NULL;
   23073 		    return (-1);
   23074 		}
   23075 		ntItem->nodeQNameID = -1;
   23076 	    } else {
   23077 		/*
   23078 		* Save a cached QName for this node on the IDC node, to be
   23079 		* able to report it, even if the node is not saved.
   23080 		*/
   23081 		ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
   23082 		    vctxt->inode->localName, vctxt->inode->nsName);
   23083 		if (ntItem->nodeQNameID == -1) {
   23084 		    xmlFree(ntItem);
   23085 		    xmlFree(*keySeq);
   23086 		    *keySeq = NULL;
   23087 		    return (-1);
   23088 		}
   23089 	    }
   23090 	    /*
   23091 	    * Init the node-table item: Save the node, position and
   23092 	    * consume the key-sequence.
   23093 	    */
   23094 	    ntItem->node = vctxt->node;
   23095 	    ntItem->nodeLine = vctxt->inode->nodeLine;
   23096 	    ntItem->keys = *keySeq;
   23097 	    *keySeq = NULL;
   23098 #if 0
   23099 	    if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
   23100 #endif
   23101 	    if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
   23102 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
   23103 		    /*
   23104 		    * Free the item, since keyref items won't be
   23105 		    * put on a global list.
   23106 		    */
   23107 		    xmlFree(ntItem->keys);
   23108 		    xmlFree(ntItem);
   23109 		}
   23110 		return (-1);
   23111 	    }
   23112 
   23113 	    goto selector_leave;
   23114 selector_key_error:
   23115 	    {
   23116 		xmlChar *str = NULL;
   23117 		/*
   23118 		* 4.2.1 (KEY) The `target node set` and the
   23119 		* `qualified node set` are equal, that is, every
   23120 		* member of the `target node set` is also a member
   23121 		* of the `qualified node set` and vice versa.
   23122 		*/
   23123 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   23124 		    XML_SCHEMAV_CVC_IDC, NULL,
   23125 		    WXS_BASIC_CAST idc,
   23126 		    "Not all fields of %s evaluate to a node",
   23127 		    xmlSchemaGetIDCDesignation(&str, idc), NULL);
   23128 		FREE_AND_NULL(str);
   23129 	    }
   23130 selector_leave:
   23131 	    /*
   23132 	    * Free the key-sequence if not added to the IDC table.
   23133 	    */
   23134 	    if ((keySeq != NULL) && (*keySeq != NULL)) {
   23135 		xmlFree(*keySeq);
   23136 		*keySeq = NULL;
   23137 	    }
   23138 	} /* if selector */
   23139 
   23140 	sto->nbHistory--;
   23141 
   23142 deregister_check:
   23143 	/*
   23144 	* Deregister state objects if they reach the depth of creation.
   23145 	*/
   23146 	if ((sto->nbHistory == 0) && (sto->depth == depth)) {
   23147 #ifdef DEBUG_IDC
   23148 	    xmlGenericError(xmlGenericErrorContext, "IDC:   STO pop '%s'\n",
   23149 		sto->sel->xpath);
   23150 #endif
   23151 	    if (vctxt->xpathStates != sto) {
   23152 		VERROR_INT("xmlSchemaXPathProcessHistory",
   23153 		    "The state object to be removed is not the first "
   23154 		    "in the list");
   23155 	    }
   23156 	    nextsto = sto->next;
   23157 	    /*
   23158 	    * Unlink from the list of active XPath state objects.
   23159 	    */
   23160 	    vctxt->xpathStates = sto->next;
   23161 	    sto->next = vctxt->xpathStatePool;
   23162 	    /*
   23163 	    * Link it to the pool of reusable state objects.
   23164 	    */
   23165 	    vctxt->xpathStatePool = sto;
   23166 	    sto = nextsto;
   23167 	} else
   23168 	    sto = sto->next;
   23169     } /* while (sto != NULL) */
   23170     return (0);
   23171 }
   23172 
   23173 /**
   23174  * xmlSchemaIDCRegisterMatchers:
   23175  * @vctxt: the WXS validation context
   23176  * @elemDecl: the element declaration
   23177  *
   23178  * Creates helper objects to evaluate IDC selectors/fields
   23179  * successively.
   23180  *
   23181  * Returns 0 if OK and -1 on internal errors.
   23182  */
   23183 static int
   23184 xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
   23185 			     xmlSchemaElementPtr elemDecl)
   23186 {
   23187     xmlSchemaIDCMatcherPtr matcher, last = NULL;
   23188     xmlSchemaIDCPtr idc, refIdc;
   23189     xmlSchemaIDCAugPtr aidc;
   23190 
   23191     idc = (xmlSchemaIDCPtr) elemDecl->idcs;
   23192     if (idc == NULL)
   23193 	return (0);
   23194 
   23195 #ifdef DEBUG_IDC
   23196     {
   23197 	xmlChar *str = NULL;
   23198 	xmlGenericError(xmlGenericErrorContext,
   23199 	    "IDC: REGISTER on %s, depth %d\n",
   23200 	    (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
   23201 		vctxt->inode->localName), vctxt->depth);
   23202 	FREE_AND_NULL(str)
   23203     }
   23204 #endif
   23205     if (vctxt->inode->idcMatchers != NULL) {
   23206 	VERROR_INT("xmlSchemaIDCRegisterMatchers",
   23207 	    "The chain of IDC matchers is expected to be empty");
   23208 	return (-1);
   23209     }
   23210     do {
   23211 	if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
   23212 	    /*
   23213 	    * Since IDCs bubbles are expensive we need to know the
   23214 	    * depth at which the bubbles should stop; this will be
   23215 	    * the depth of the top-most keyref IDC. If no keyref
   23216 	    * references a key/unique IDC, the keyrefDepth will
   23217 	    * be -1, indicating that no bubbles are needed.
   23218 	    */
   23219 	    refIdc = (xmlSchemaIDCPtr) idc->ref->item;
   23220 	    if (refIdc != NULL) {
   23221 		/*
   23222 		* Remember that we have keyrefs on this node.
   23223 		*/
   23224 		vctxt->inode->hasKeyrefs = 1;
   23225 		/*
   23226 		* Lookup the referenced augmented IDC info.
   23227 		*/
   23228 		aidc = vctxt->aidcs;
   23229 		while (aidc != NULL) {
   23230 		    if (aidc->def == refIdc)
   23231 			break;
   23232 		    aidc = aidc->next;
   23233 		}
   23234 		if (aidc == NULL) {
   23235 		    VERROR_INT("xmlSchemaIDCRegisterMatchers",
   23236 			"Could not find an augmented IDC item for an IDC "
   23237 			"definition");
   23238 		    return (-1);
   23239 		}
   23240 		if ((aidc->keyrefDepth == -1) ||
   23241 		    (vctxt->depth < aidc->keyrefDepth))
   23242 		    aidc->keyrefDepth = vctxt->depth;
   23243 	    }
   23244 	}
   23245 	/*
   23246 	* Lookup the augmented IDC item for the IDC definition.
   23247 	*/
   23248 	aidc = vctxt->aidcs;
   23249 	while (aidc != NULL) {
   23250 	    if (aidc->def == idc)
   23251 		break;
   23252 	    aidc = aidc->next;
   23253 	}
   23254 	if (aidc == NULL) {
   23255 	    VERROR_INT("xmlSchemaIDCRegisterMatchers",
   23256 		"Could not find an augmented IDC item for an IDC definition");
   23257 	    return (-1);
   23258 	}
   23259 	/*
   23260 	* Create an IDC matcher for every IDC definition.
   23261 	*/
   23262 	if (vctxt->idcMatcherCache != NULL) {
   23263 	    /*
   23264 	    * Reuse a cached matcher.
   23265 	    */
   23266 	    matcher = vctxt->idcMatcherCache;
   23267 	    vctxt->idcMatcherCache = matcher->nextCached;
   23268 	    matcher->nextCached = NULL;
   23269 	} else {
   23270 	    matcher = (xmlSchemaIDCMatcherPtr)
   23271 		xmlMalloc(sizeof(xmlSchemaIDCMatcher));
   23272 	    if (matcher == NULL) {
   23273 		xmlSchemaVErrMemory(vctxt,
   23274 		    "allocating an IDC matcher", NULL);
   23275 		return (-1);
   23276 	    }
   23277 	    memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
   23278 	}
   23279 	if (last == NULL)
   23280 	    vctxt->inode->idcMatchers = matcher;
   23281 	else
   23282 	    last->next = matcher;
   23283 	last = matcher;
   23284 
   23285 	matcher->type = IDC_MATCHER;
   23286 	matcher->depth = vctxt->depth;
   23287 	matcher->aidc = aidc;
   23288 	matcher->idcType = aidc->def->type;
   23289 #ifdef DEBUG_IDC
   23290 	xmlGenericError(xmlGenericErrorContext, "IDC:   register matcher\n");
   23291 #endif
   23292 	/*
   23293 	* Init the automaton state object.
   23294 	*/
   23295 	if (xmlSchemaIDCAddStateObject(vctxt, matcher,
   23296 	    idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
   23297 	    return (-1);
   23298 
   23299 	idc = idc->next;
   23300     } while (idc != NULL);
   23301     return (0);
   23302 }
   23303 
   23304 static int
   23305 xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
   23306 			   xmlSchemaNodeInfoPtr ielem)
   23307 {
   23308     xmlSchemaPSVIIDCBindingPtr bind;
   23309     int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
   23310     xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
   23311     xmlSchemaPSVIIDCNodePtr *targets, *dupls;
   23312 
   23313     xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
   23314     /* vctxt->createIDCNodeTables */
   23315     while (matcher != NULL) {
   23316 	/*
   23317 	* Skip keyref IDCs and empty IDC target-lists.
   23318 	*/
   23319 	if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
   23320 	    WXS_ILIST_IS_EMPTY(matcher->targets))
   23321 	{
   23322 	    matcher = matcher->next;
   23323 	    continue;
   23324 	}
   23325 	/*
   23326 	* If we _want_ the IDC node-table to be created in any case
   23327 	* then do so. Otherwise create them only if keyrefs need them.
   23328 	*/
   23329 	if ((! vctxt->createIDCNodeTables) &&
   23330 	    ((matcher->aidc->keyrefDepth == -1) ||
   23331 	     (matcher->aidc->keyrefDepth > vctxt->depth)))
   23332 	{
   23333 	    matcher = matcher->next;
   23334 	    continue;
   23335 	}
   23336 	/*
   23337 	* Get/create the IDC binding on this element for the IDC definition.
   23338 	*/
   23339 	bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
   23340 
   23341 	if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
   23342 	    dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
   23343 	    nbDupls = bind->dupls->nbItems;
   23344 	} else {
   23345 	    dupls = NULL;
   23346 	    nbDupls = 0;
   23347 	}
   23348 	if (bind->nodeTable != NULL) {
   23349 	    nbNodeTable = bind->nbNodes;
   23350 	} else {
   23351 	    nbNodeTable = 0;
   23352 	}
   23353 
   23354 	if ((nbNodeTable == 0) && (nbDupls == 0)) {
   23355 	    /*
   23356 	    * Transfer all IDC target-nodes to the IDC node-table.
   23357 	    */
   23358 	    bind->nodeTable =
   23359 		(xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
   23360 	    bind->sizeNodes = matcher->targets->sizeItems;
   23361 	    bind->nbNodes = matcher->targets->nbItems;
   23362 
   23363 	    matcher->targets->items = NULL;
   23364 	    matcher->targets->sizeItems = 0;
   23365 	    matcher->targets->nbItems = 0;
   23366 	} else {
   23367 	    /*
   23368 	    * Compare the key-sequences and add to the IDC node-table.
   23369 	    */
   23370 	    nbTargets = matcher->targets->nbItems;
   23371 	    targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
   23372 	    nbFields = matcher->aidc->def->nbFields;
   23373 	    i = 0;
   23374 	    do {
   23375 		keys = targets[i]->keys;
   23376 		if (nbDupls) {
   23377 		    /*
   23378 		    * Search in already found duplicates first.
   23379 		    */
   23380 		    j = 0;
   23381 		    do {
   23382 			if (nbFields == 1) {
   23383 			    res = xmlSchemaAreValuesEqual(keys[0]->val,
   23384 				dupls[j]->keys[0]->val);
   23385 			    if (res == -1)
   23386 				goto internal_error;
   23387 			    if (res == 1) {
   23388 				/*
   23389 				* Equal key-sequence.
   23390 				*/
   23391 				goto next_target;
   23392 			    }
   23393 			} else {
   23394 			    res = 0;
   23395 			    ntkeys = dupls[j]->keys;
   23396 			    for (k = 0; k < nbFields; k++) {
   23397 				res = xmlSchemaAreValuesEqual(keys[k]->val,
   23398 				    ntkeys[k]->val);
   23399 				if (res == -1)
   23400 				    goto internal_error;
   23401 				if (res == 0) {
   23402 				    /*
   23403 				    * One of the keys differs.
   23404 				    */
   23405 				    break;
   23406 				}
   23407 			    }
   23408 			    if (res == 1) {
   23409 				/*
   23410 				* Equal key-sequence found.
   23411 				*/
   23412 				goto next_target;
   23413 			    }
   23414 			}
   23415 			j++;
   23416 		    } while (j < nbDupls);
   23417 		}
   23418 		if (nbNodeTable) {
   23419 		    j = 0;
   23420 		    do {
   23421 			if (nbFields == 1) {
   23422 			    res = xmlSchemaAreValuesEqual(keys[0]->val,
   23423 				bind->nodeTable[j]->keys[0]->val);
   23424 			    if (res == -1)
   23425 				goto internal_error;
   23426 			    if (res == 0) {
   23427 				/*
   23428 				* The key-sequence differs.
   23429 				*/
   23430 				goto next_node_table_entry;
   23431 			    }
   23432 			} else {
   23433 			    res = 0;
   23434 			    ntkeys = bind->nodeTable[j]->keys;
   23435 			    for (k = 0; k < nbFields; k++) {
   23436 				res = xmlSchemaAreValuesEqual(keys[k]->val,
   23437 				    ntkeys[k]->val);
   23438 				if (res == -1)
   23439 				    goto internal_error;
   23440 				if (res == 0) {
   23441 				    /*
   23442 				    * One of the keys differs.
   23443 				    */
   23444 				    goto next_node_table_entry;
   23445 				}
   23446 			    }
   23447 			}
   23448 			/*
   23449 			* Add the duplicate to the list of duplicates.
   23450 			*/
   23451 			if (bind->dupls == NULL) {
   23452 			    bind->dupls = xmlSchemaItemListCreate();
   23453 			    if (bind->dupls == NULL)
   23454 				goto internal_error;
   23455 			}
   23456 			if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
   23457 			    goto internal_error;
   23458 			/*
   23459 			* Remove the duplicate entry from the IDC node-table.
   23460 			*/
   23461 			bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
   23462 			bind->nbNodes--;
   23463 
   23464 			goto next_target;
   23465 
   23466 next_node_table_entry:
   23467 			j++;
   23468 		    } while (j < nbNodeTable);
   23469 		}
   23470 		/*
   23471 		* If everything is fine, then add the IDC target-node to
   23472 		* the IDC node-table.
   23473 		*/
   23474 		if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
   23475 		    goto internal_error;
   23476 
   23477 next_target:
   23478 		i++;
   23479 	    } while (i < nbTargets);
   23480 	}
   23481 	matcher = matcher->next;
   23482     }
   23483     return(0);
   23484 
   23485 internal_error:
   23486     return(-1);
   23487 }
   23488 
   23489 /**
   23490  * xmlSchemaBubbleIDCNodeTables:
   23491  * @depth: the current tree depth
   23492  *
   23493  * Merges IDC bindings of an element at @depth into the corresponding IDC
   23494  * bindings of its parent element. If a duplicate note-table entry is found,
   23495  * both, the parent node-table entry and child entry are discarded from the
   23496  * node-table of the parent.
   23497  *
   23498  * Returns 0 if OK and -1 on internal errors.
   23499  */
   23500 static int
   23501 xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
   23502 {
   23503     xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
   23504     xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
   23505     xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
   23506     xmlSchemaIDCAugPtr aidc;
   23507     int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
   23508 
   23509     bind = vctxt->inode->idcTable;
   23510     if (bind == NULL) {
   23511 	/* Fine, no table, no bubbles. */
   23512 	return (0);
   23513     }
   23514 
   23515     parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
   23516     /*
   23517     * Walk all bindings; create new or add to existing bindings.
   23518     * Remove duplicate key-sequences.
   23519     */
   23520     while (bind != NULL) {
   23521 
   23522 	if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
   23523 	    goto next_binding;
   23524 	/*
   23525 	* Check if the key/unique IDC table needs to be bubbled.
   23526 	*/
   23527 	if (! vctxt->createIDCNodeTables) {
   23528 	    aidc = vctxt->aidcs;
   23529 	    do {
   23530 		if (aidc->def == bind->definition) {
   23531 		    if ((aidc->keyrefDepth == -1) ||
   23532 			(aidc->keyrefDepth >= vctxt->depth)) {
   23533 			goto next_binding;
   23534 		    }
   23535 		    break;
   23536 		}
   23537 		aidc = aidc->next;
   23538 	    } while (aidc != NULL);
   23539 	}
   23540 
   23541 	if (parTable != NULL)
   23542 	    parBind = *parTable;
   23543 	/*
   23544 	* Search a matching parent binding for the
   23545 	* IDC definition.
   23546 	*/
   23547 	while (parBind != NULL) {
   23548 	    if (parBind->definition == bind->definition)
   23549 		break;
   23550 	    parBind = parBind->next;
   23551 	}
   23552 
   23553 	if (parBind != NULL) {
   23554 	    /*
   23555 	    * Compare every node-table entry of the child node,
   23556 	    * i.e. the key-sequence within, ...
   23557 	    */
   23558 	    oldNum = parBind->nbNodes; /* Skip newly added items. */
   23559 
   23560 	    if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
   23561 		oldDupls = parBind->dupls->nbItems;
   23562 		dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
   23563 	    } else {
   23564 		dupls = NULL;
   23565 		oldDupls = 0;
   23566 	    }
   23567 
   23568 	    parNodes = parBind->nodeTable;
   23569 	    nbFields = bind->definition->nbFields;
   23570 
   23571 	    for (i = 0; i < bind->nbNodes; i++) {
   23572 		node = bind->nodeTable[i];
   23573 		if (node == NULL)
   23574 		    continue;
   23575 		/*
   23576 		* ...with every key-sequence of the parent node, already
   23577 		* evaluated to be a duplicate key-sequence.
   23578 		*/
   23579 		if (oldDupls) {
   23580 		    j = 0;
   23581 		    while (j < oldDupls) {
   23582 			if (nbFields == 1) {
   23583 			    ret = xmlSchemaAreValuesEqual(
   23584 				node->keys[0]->val,
   23585 				dupls[j]->keys[0]->val);
   23586 			    if (ret == -1)
   23587 				goto internal_error;
   23588 			    if (ret == 0) {
   23589 				j++;
   23590 				continue;
   23591 			    }
   23592 			} else {
   23593 			    parNode = dupls[j];
   23594 			    for (k = 0; k < nbFields; k++) {
   23595 				ret = xmlSchemaAreValuesEqual(
   23596 				    node->keys[k]->val,
   23597 				    parNode->keys[k]->val);
   23598 				if (ret == -1)
   23599 				    goto internal_error;
   23600 				if (ret == 0)
   23601 				    break;
   23602 			    }
   23603 			}
   23604 			if (ret == 1)
   23605 			    /* Duplicate found. */
   23606 			    break;
   23607 			j++;
   23608 		    }
   23609 		    if (j != oldDupls) {
   23610 			/* Duplicate found. Skip this entry. */
   23611 			continue;
   23612 		    }
   23613 		}
   23614 		/*
   23615 		* ... and with every key-sequence of the parent node.
   23616 		*/
   23617 		if (oldNum) {
   23618 		    j = 0;
   23619 		    while (j < oldNum) {
   23620 			parNode = parNodes[j];
   23621 			if (nbFields == 1) {
   23622 			    ret = xmlSchemaAreValuesEqual(
   23623 				node->keys[0]->val,
   23624 				parNode->keys[0]->val);
   23625 			    if (ret == -1)
   23626 				goto internal_error;
   23627 			    if (ret == 0) {
   23628 				j++;
   23629 				continue;
   23630 			    }
   23631 			} else {
   23632 			    for (k = 0; k < nbFields; k++) {
   23633 				ret = xmlSchemaAreValuesEqual(
   23634 				    node->keys[k]->val,
   23635 				    parNode->keys[k]->val);
   23636 				if (ret == -1)
   23637 				    goto internal_error;
   23638 				if (ret == 0)
   23639 				    break;
   23640 			    }
   23641 			}
   23642 			if (ret == 1)
   23643 			    /* Duplicate found. */
   23644 			    break;
   23645 			j++;
   23646 		    }
   23647 		    if (j != oldNum) {
   23648 			/*
   23649 			* Handle duplicates. Move the duplicate in
   23650 			* the parent's node-table to the list of
   23651 			* duplicates.
   23652 			*/
   23653 			oldNum--;
   23654 			parBind->nbNodes--;
   23655 			/*
   23656 			* Move last old item to pos of duplicate.
   23657 			*/
   23658 			parNodes[j] = parNodes[oldNum];
   23659 
   23660 			if (parBind->nbNodes != oldNum) {
   23661 			    /*
   23662 			    * If new items exist, move last new item to
   23663 			    * last of old items.
   23664 			    */
   23665 			    parNodes[oldNum] =
   23666 				parNodes[parBind->nbNodes];
   23667 			}
   23668 			if (parBind->dupls == NULL) {
   23669 			    parBind->dupls = xmlSchemaItemListCreate();
   23670 			    if (parBind->dupls == NULL)
   23671 				goto internal_error;
   23672 			}
   23673 			xmlSchemaItemListAdd(parBind->dupls, parNode);
   23674 		    } else {
   23675 			/*
   23676 			* Add the node-table entry (node and key-sequence) of
   23677 			* the child node to the node table of the parent node.
   23678 			*/
   23679 			if (parBind->nodeTable == NULL) {
   23680 			    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   23681 				xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
   23682 			    if (parBind->nodeTable == NULL) {
   23683 				xmlSchemaVErrMemory(NULL,
   23684 				    "allocating IDC list of node-table items", NULL);
   23685 				goto internal_error;
   23686 			    }
   23687 			    parBind->sizeNodes = 1;
   23688 			} else if (parBind->nbNodes >= parBind->sizeNodes) {
   23689 			    parBind->sizeNodes *= 2;
   23690 			    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   23691 				xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
   23692 				sizeof(xmlSchemaPSVIIDCNodePtr));
   23693 			    if (parBind->nodeTable == NULL) {
   23694 				xmlSchemaVErrMemory(NULL,
   23695 				    "re-allocating IDC list of node-table items", NULL);
   23696 				goto internal_error;
   23697 			    }
   23698 			}
   23699 			parNodes = parBind->nodeTable;
   23700 			/*
   23701 			* Append the new node-table entry to the 'new node-table
   23702 			* entries' section.
   23703 			*/
   23704 			parNodes[parBind->nbNodes++] = node;
   23705 		    }
   23706 
   23707 		}
   23708 
   23709 	    }
   23710 	} else {
   23711 	    /*
   23712 	    * No binding for the IDC was found: create a new one and
   23713 	    * copy all node-tables.
   23714 	    */
   23715 	    parBind = xmlSchemaIDCNewBinding(bind->definition);
   23716 	    if (parBind == NULL)
   23717 		goto internal_error;
   23718 
   23719 	    /*
   23720 	    * TODO: Hmm, how to optimize the initial number of
   23721 	    * allocated entries?
   23722 	    */
   23723 	    if (bind->nbNodes != 0) {
   23724 		/*
   23725 		* Add all IDC node-table entries.
   23726 		*/
   23727 		if (! vctxt->psviExposeIDCNodeTables) {
   23728 		    /*
   23729 		    * Just move the entries.
   23730 		    * NOTE: this is quite save here, since
   23731 		    * all the keyref lookups have already been
   23732 		    * performed.
   23733 		    */
   23734 		    parBind->nodeTable = bind->nodeTable;
   23735 		    bind->nodeTable = NULL;
   23736 		    parBind->sizeNodes = bind->sizeNodes;
   23737 		    bind->sizeNodes = 0;
   23738 		    parBind->nbNodes = bind->nbNodes;
   23739 		    bind->nbNodes = 0;
   23740 		} else {
   23741 		    /*
   23742 		    * Copy the entries.
   23743 		    */
   23744 		    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   23745 			xmlMalloc(bind->nbNodes *
   23746 			sizeof(xmlSchemaPSVIIDCNodePtr));
   23747 		    if (parBind->nodeTable == NULL) {
   23748 			xmlSchemaVErrMemory(NULL,
   23749 			    "allocating an array of IDC node-table "
   23750 			    "items", NULL);
   23751 			xmlSchemaIDCFreeBinding(parBind);
   23752 			goto internal_error;
   23753 		    }
   23754 		    parBind->sizeNodes = bind->nbNodes;
   23755 		    parBind->nbNodes = bind->nbNodes;
   23756 		    memcpy(parBind->nodeTable, bind->nodeTable,
   23757 			bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
   23758 		}
   23759 	    }
   23760 	    if (bind->dupls) {
   23761 		/*
   23762 		* Move the duplicates.
   23763 		*/
   23764 		if (parBind->dupls != NULL)
   23765 		    xmlSchemaItemListFree(parBind->dupls);
   23766 		parBind->dupls = bind->dupls;
   23767 		bind->dupls = NULL;
   23768 	    }
   23769             if (parTable != NULL) {
   23770                 if (*parTable == NULL)
   23771                     *parTable = parBind;
   23772                 else {
   23773                     parBind->next = *parTable;
   23774                     *parTable = parBind;
   23775                 }
   23776             }
   23777 	}
   23778 
   23779 next_binding:
   23780 	bind = bind->next;
   23781     }
   23782     return (0);
   23783 
   23784 internal_error:
   23785     return(-1);
   23786 }
   23787 
   23788 /**
   23789  * xmlSchemaCheckCVCIDCKeyRef:
   23790  * @vctxt: the WXS validation context
   23791  * @elemDecl: the element declaration
   23792  *
   23793  * Check the cvc-idc-keyref constraints.
   23794  */
   23795 static int
   23796 xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
   23797 {
   23798     xmlSchemaIDCMatcherPtr matcher;
   23799     xmlSchemaPSVIIDCBindingPtr bind;
   23800 
   23801     matcher = vctxt->inode->idcMatchers;
   23802     /*
   23803     * Find a keyref.
   23804     */
   23805     while (matcher != NULL) {
   23806 	if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
   23807 	    matcher->targets &&
   23808 	    matcher->targets->nbItems)
   23809 	{
   23810 	    int i, j, k, res, nbFields, hasDupls;
   23811 	    xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
   23812 	    xmlSchemaPSVIIDCNodePtr refNode = NULL;
   23813 
   23814 	    nbFields = matcher->aidc->def->nbFields;
   23815 
   23816 	    /*
   23817 	    * Find the IDC node-table for the referenced IDC key/unique.
   23818 	    */
   23819 	    bind = vctxt->inode->idcTable;
   23820 	    while (bind != NULL) {
   23821 		if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
   23822 		    bind->definition)
   23823 		    break;
   23824 		bind = bind->next;
   23825 	    }
   23826 	    hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
   23827 	    /*
   23828 	    * Search for a matching key-sequences.
   23829 	    */
   23830 	    for (i = 0; i < matcher->targets->nbItems; i++) {
   23831 		res = 0;
   23832 		refNode = matcher->targets->items[i];
   23833 		if (bind != NULL) {
   23834 		    refKeys = refNode->keys;
   23835 		    for (j = 0; j < bind->nbNodes; j++) {
   23836 			keys = bind->nodeTable[j]->keys;
   23837 			for (k = 0; k < nbFields; k++) {
   23838 			    res = xmlSchemaAreValuesEqual(keys[k]->val,
   23839 				refKeys[k]->val);
   23840 			    if (res == 0)
   23841 				break;
   23842 			    else if (res == -1) {
   23843 				return (-1);
   23844 			    }
   23845 			}
   23846 			if (res == 1) {
   23847 			    /*
   23848 			    * Match found.
   23849 			    */
   23850 			    break;
   23851 			}
   23852 		    }
   23853 		    if ((res == 0) && hasDupls) {
   23854 			/*
   23855 			* Search in duplicates
   23856 			*/
   23857 			for (j = 0; j < bind->dupls->nbItems; j++) {
   23858 			    keys = ((xmlSchemaPSVIIDCNodePtr)
   23859 				bind->dupls->items[j])->keys;
   23860 			    for (k = 0; k < nbFields; k++) {
   23861 				res = xmlSchemaAreValuesEqual(keys[k]->val,
   23862 				    refKeys[k]->val);
   23863 				if (res == 0)
   23864 				    break;
   23865 				else if (res == -1) {
   23866 				    return (-1);
   23867 				}
   23868 			    }
   23869 			    if (res == 1) {
   23870 				/*
   23871 				* Match in duplicates found.
   23872 				*/
   23873 				xmlChar *str = NULL, *strB = NULL;
   23874 				xmlSchemaKeyrefErr(vctxt,
   23875 				    XML_SCHEMAV_CVC_IDC, refNode,
   23876 				    (xmlSchemaTypePtr) matcher->aidc->def,
   23877 				    "More than one match found for "
   23878 				    "key-sequence %s of keyref '%s'",
   23879 				    xmlSchemaFormatIDCKeySequence(vctxt, &str,
   23880 					refNode->keys, nbFields),
   23881 				    xmlSchemaGetComponentQName(&strB,
   23882 					matcher->aidc->def));
   23883 				FREE_AND_NULL(str);
   23884 				FREE_AND_NULL(strB);
   23885 				break;
   23886 			    }
   23887 			}
   23888 		    }
   23889 		}
   23890 
   23891 		if (res == 0) {
   23892 		    xmlChar *str = NULL, *strB = NULL;
   23893 		    xmlSchemaKeyrefErr(vctxt,
   23894 			XML_SCHEMAV_CVC_IDC, refNode,
   23895 			(xmlSchemaTypePtr) matcher->aidc->def,
   23896 			"No match found for key-sequence %s of keyref '%s'",
   23897 			xmlSchemaFormatIDCKeySequence(vctxt, &str,
   23898 			    refNode->keys, nbFields),
   23899 			xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
   23900 		    FREE_AND_NULL(str);
   23901 		    FREE_AND_NULL(strB);
   23902 		}
   23903 	    }
   23904 	}
   23905 	matcher = matcher->next;
   23906     }
   23907     /* TODO: Return an error if any error encountered. */
   23908     return (0);
   23909 }
   23910 
   23911 /************************************************************************
   23912  *									*
   23913  *			XML Reader validation code                      *
   23914  *									*
   23915  ************************************************************************/
   23916 
   23917 static xmlSchemaAttrInfoPtr
   23918 xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
   23919 {
   23920     xmlSchemaAttrInfoPtr iattr;
   23921     /*
   23922     * Grow/create list of attribute infos.
   23923     */
   23924     if (vctxt->attrInfos == NULL) {
   23925 	vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
   23926 	    xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
   23927 	vctxt->sizeAttrInfos = 1;
   23928 	if (vctxt->attrInfos == NULL) {
   23929 	    xmlSchemaVErrMemory(vctxt,
   23930 		"allocating attribute info list", NULL);
   23931 	    return (NULL);
   23932 	}
   23933     } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
   23934 	vctxt->sizeAttrInfos++;
   23935 	vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
   23936 	    xmlRealloc(vctxt->attrInfos,
   23937 		vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
   23938 	if (vctxt->attrInfos == NULL) {
   23939 	    xmlSchemaVErrMemory(vctxt,
   23940 		"re-allocating attribute info list", NULL);
   23941 	    return (NULL);
   23942 	}
   23943     } else {
   23944 	iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
   23945 	if (iattr->localName != NULL) {
   23946 	    VERROR_INT("xmlSchemaGetFreshAttrInfo",
   23947 		"attr info not cleared");
   23948 	    return (NULL);
   23949 	}
   23950 	iattr->nodeType = XML_ATTRIBUTE_NODE;
   23951 	return (iattr);
   23952     }
   23953     /*
   23954     * Create an attribute info.
   23955     */
   23956     iattr = (xmlSchemaAttrInfoPtr)
   23957 	xmlMalloc(sizeof(xmlSchemaAttrInfo));
   23958     if (iattr == NULL) {
   23959 	xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
   23960 	return (NULL);
   23961     }
   23962     memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
   23963     iattr->nodeType = XML_ATTRIBUTE_NODE;
   23964     vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
   23965 
   23966     return (iattr);
   23967 }
   23968 
   23969 static int
   23970 xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
   23971 			xmlNodePtr attrNode,
   23972 			int nodeLine,
   23973 			const xmlChar *localName,
   23974 			const xmlChar *nsName,
   23975 			int ownedNames,
   23976 			xmlChar *value,
   23977 			int ownedValue)
   23978 {
   23979     xmlSchemaAttrInfoPtr attr;
   23980 
   23981     attr = xmlSchemaGetFreshAttrInfo(vctxt);
   23982     if (attr == NULL) {
   23983 	VERROR_INT("xmlSchemaPushAttribute",
   23984 	    "calling xmlSchemaGetFreshAttrInfo()");
   23985 	return (-1);
   23986     }
   23987     attr->node = attrNode;
   23988     attr->nodeLine = nodeLine;
   23989     attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
   23990     attr->localName = localName;
   23991     attr->nsName = nsName;
   23992     if (ownedNames)
   23993 	attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
   23994     /*
   23995     * Evaluate if it's an XSI attribute.
   23996     */
   23997     if (nsName != NULL) {
   23998 	if (xmlStrEqual(localName, BAD_CAST "nil")) {
   23999 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
   24000 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
   24001 	    }
   24002 	} else if (xmlStrEqual(localName, BAD_CAST "type")) {
   24003 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
   24004 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
   24005 	    }
   24006 	} else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
   24007 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
   24008 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
   24009 	    }
   24010 	} else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
   24011 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
   24012 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
   24013 	    }
   24014 	} else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
   24015 	    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
   24016 	}
   24017     }
   24018     attr->value = value;
   24019     if (ownedValue)
   24020 	attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
   24021     if (attr->metaType != 0)
   24022 	attr->state = XML_SCHEMAS_ATTR_META;
   24023     return (0);
   24024 }
   24025 
   24026 /**
   24027  * xmlSchemaClearElemInfo:
   24028  * @vctxt: the WXS validation context
   24029  * @ielem: the element information item
   24030  */
   24031 static void
   24032 xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
   24033 		       xmlSchemaNodeInfoPtr ielem)
   24034 {
   24035     ielem->hasKeyrefs = 0;
   24036     ielem->appliedXPath = 0;
   24037     if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
   24038 	FREE_AND_NULL(ielem->localName);
   24039 	FREE_AND_NULL(ielem->nsName);
   24040     } else {
   24041 	ielem->localName = NULL;
   24042 	ielem->nsName = NULL;
   24043     }
   24044     if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
   24045 	FREE_AND_NULL(ielem->value);
   24046     } else {
   24047 	ielem->value = NULL;
   24048     }
   24049     if (ielem->val != NULL) {
   24050 	/*
   24051 	* PSVI TODO: Be careful not to free it when the value is
   24052 	* exposed via PSVI.
   24053 	*/
   24054 	xmlSchemaFreeValue(ielem->val);
   24055 	ielem->val = NULL;
   24056     }
   24057     if (ielem->idcMatchers != NULL) {
   24058 	/*
   24059 	* REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
   24060 	*   Does it work?
   24061 	*/
   24062 	xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
   24063 #if 0
   24064 	xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
   24065 #endif
   24066 	ielem->idcMatchers = NULL;
   24067     }
   24068     if (ielem->idcTable != NULL) {
   24069 	/*
   24070 	* OPTIMIZE TODO: Use a pool of IDC tables??.
   24071 	*/
   24072 	xmlSchemaIDCFreeIDCTable(ielem->idcTable);
   24073 	ielem->idcTable = NULL;
   24074     }
   24075     if (ielem->regexCtxt != NULL) {
   24076 	xmlRegFreeExecCtxt(ielem->regexCtxt);
   24077 	ielem->regexCtxt = NULL;
   24078     }
   24079     if (ielem->nsBindings != NULL) {
   24080 	xmlFree((xmlChar **)ielem->nsBindings);
   24081 	ielem->nsBindings = NULL;
   24082 	ielem->nbNsBindings = 0;
   24083 	ielem->sizeNsBindings = 0;
   24084     }
   24085 }
   24086 
   24087 /**
   24088  * xmlSchemaGetFreshElemInfo:
   24089  * @vctxt: the schema validation context
   24090  *
   24091  * Creates/reuses and initializes the element info item for
   24092  * the currect tree depth.
   24093  *
   24094  * Returns the element info item or NULL on API or internal errors.
   24095  */
   24096 static xmlSchemaNodeInfoPtr
   24097 xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
   24098 {
   24099     xmlSchemaNodeInfoPtr info = NULL;
   24100 
   24101     if (vctxt->depth > vctxt->sizeElemInfos) {
   24102 	VERROR_INT("xmlSchemaGetFreshElemInfo",
   24103 	    "inconsistent depth encountered");
   24104 	return (NULL);
   24105     }
   24106     if (vctxt->elemInfos == NULL) {
   24107 	vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
   24108 	    xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
   24109 	if (vctxt->elemInfos == NULL) {
   24110 	    xmlSchemaVErrMemory(vctxt,
   24111 		"allocating the element info array", NULL);
   24112 	    return (NULL);
   24113 	}
   24114 	memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
   24115 	vctxt->sizeElemInfos = 10;
   24116     } else if (vctxt->sizeElemInfos <= vctxt->depth) {
   24117 	int i = vctxt->sizeElemInfos;
   24118 
   24119 	vctxt->sizeElemInfos *= 2;
   24120 	vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
   24121 	    xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
   24122 	    sizeof(xmlSchemaNodeInfoPtr));
   24123 	if (vctxt->elemInfos == NULL) {
   24124 	    xmlSchemaVErrMemory(vctxt,
   24125 		"re-allocating the element info array", NULL);
   24126 	    return (NULL);
   24127 	}
   24128 	/*
   24129 	* We need the new memory to be NULLed.
   24130 	* TODO: Use memset instead?
   24131 	*/
   24132 	for (; i < vctxt->sizeElemInfos; i++)
   24133 	    vctxt->elemInfos[i] = NULL;
   24134     } else
   24135 	info = vctxt->elemInfos[vctxt->depth];
   24136 
   24137     if (info == NULL) {
   24138 	info = (xmlSchemaNodeInfoPtr)
   24139 	    xmlMalloc(sizeof(xmlSchemaNodeInfo));
   24140 	if (info == NULL) {
   24141 	    xmlSchemaVErrMemory(vctxt,
   24142 		"allocating an element info", NULL);
   24143 	    return (NULL);
   24144 	}
   24145 	vctxt->elemInfos[vctxt->depth] = info;
   24146     } else {
   24147 	if (info->localName != NULL) {
   24148 	    VERROR_INT("xmlSchemaGetFreshElemInfo",
   24149 		"elem info has not been cleared");
   24150 	    return (NULL);
   24151 	}
   24152     }
   24153     memset(info, 0, sizeof(xmlSchemaNodeInfo));
   24154     info->nodeType = XML_ELEMENT_NODE;
   24155     info->depth = vctxt->depth;
   24156 
   24157     return (info);
   24158 }
   24159 
   24160 #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
   24161 #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
   24162 #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
   24163 
   24164 static int
   24165 xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
   24166 			xmlNodePtr node,
   24167 			xmlSchemaTypePtr type,
   24168 			xmlSchemaValType valType,
   24169 			const xmlChar * value,
   24170 			xmlSchemaValPtr val,
   24171 			unsigned long length,
   24172 			int fireErrors)
   24173 {
   24174     int ret, error = 0;
   24175 
   24176     xmlSchemaTypePtr tmpType;
   24177     xmlSchemaFacetLinkPtr facetLink;
   24178     xmlSchemaFacetPtr facet;
   24179     unsigned long len = 0;
   24180     xmlSchemaWhitespaceValueType ws;
   24181 
   24182     /*
   24183     * In Libxml2, derived built-in types have currently no explicit facets.
   24184     */
   24185     if (type->type == XML_SCHEMA_TYPE_BASIC)
   24186 	return (0);
   24187 
   24188     /*
   24189     * NOTE: Do not jump away, if the facetSet of the given type is
   24190     * empty: until now, "pattern" and "enumeration" facets of the
   24191     * *base types* need to be checked as well.
   24192     */
   24193     if (type->facetSet == NULL)
   24194 	goto pattern_and_enum;
   24195 
   24196     if (! WXS_IS_ATOMIC(type)) {
   24197 	if (WXS_IS_LIST(type))
   24198 	    goto WXS_IS_LIST;
   24199 	else
   24200 	    goto pattern_and_enum;
   24201     }
   24202 
   24203     /*
   24204     * Whitespace handling is only of importance for string-based
   24205     * types.
   24206     */
   24207     tmpType = xmlSchemaGetPrimitiveType(type);
   24208     if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
   24209 	WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
   24210 	ws = xmlSchemaGetWhiteSpaceFacetValue(type);
   24211     } else
   24212 	ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
   24213 
   24214     /*
   24215     * If the value was not computed (for string or
   24216     * anySimpleType based types), then use the provided
   24217     * type.
   24218     */
   24219     if (val != NULL)
   24220 	valType = xmlSchemaGetValType(val);
   24221 
   24222     ret = 0;
   24223     for (facetLink = type->facetSet; facetLink != NULL;
   24224 	facetLink = facetLink->next) {
   24225 	/*
   24226 	* Skip the pattern "whiteSpace": it is used to
   24227 	* format the character content beforehand.
   24228 	*/
   24229 	switch (facetLink->facet->type) {
   24230 	    case XML_SCHEMA_FACET_WHITESPACE:
   24231 	    case XML_SCHEMA_FACET_PATTERN:
   24232 	    case XML_SCHEMA_FACET_ENUMERATION:
   24233 		continue;
   24234 	    case XML_SCHEMA_FACET_LENGTH:
   24235 	    case XML_SCHEMA_FACET_MINLENGTH:
   24236 	    case XML_SCHEMA_FACET_MAXLENGTH:
   24237 		ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
   24238 		    valType, value, val, &len, ws);
   24239 		break;
   24240 	    default:
   24241 		ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
   24242 		    valType, value, val, ws);
   24243 		break;
   24244 	}
   24245 	if (ret < 0) {
   24246 	    AERROR_INT("xmlSchemaValidateFacets",
   24247 		"validating against a atomic type facet");
   24248 	    return (-1);
   24249 	} else if (ret > 0) {
   24250 	    if (fireErrors)
   24251 		xmlSchemaFacetErr(actxt, ret, node,
   24252 		value, len, type, facetLink->facet, NULL, NULL, NULL);
   24253 	    else
   24254 		return (ret);
   24255 	    if (error == 0)
   24256 		error = ret;
   24257 	}
   24258 	ret = 0;
   24259     }
   24260 
   24261 WXS_IS_LIST:
   24262     if (! WXS_IS_LIST(type))
   24263 	goto pattern_and_enum;
   24264     /*
   24265     * "length", "minLength" and "maxLength" of list types.
   24266     */
   24267     ret = 0;
   24268     for (facetLink = type->facetSet; facetLink != NULL;
   24269 	facetLink = facetLink->next) {
   24270 
   24271 	switch (facetLink->facet->type) {
   24272 	    case XML_SCHEMA_FACET_LENGTH:
   24273 	    case XML_SCHEMA_FACET_MINLENGTH:
   24274 	    case XML_SCHEMA_FACET_MAXLENGTH:
   24275 		ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
   24276 		    value, length, NULL);
   24277 		break;
   24278 	    default:
   24279 		continue;
   24280 	}
   24281 	if (ret < 0) {
   24282 	    AERROR_INT("xmlSchemaValidateFacets",
   24283 		"validating against a list type facet");
   24284 	    return (-1);
   24285 	} else if (ret > 0) {
   24286 	    if (fireErrors)
   24287 		xmlSchemaFacetErr(actxt, ret, node,
   24288 		value, length, type, facetLink->facet, NULL, NULL, NULL);
   24289 	    else
   24290 		return (ret);
   24291 	    if (error == 0)
   24292 		error = ret;
   24293 	}
   24294 	ret = 0;
   24295     }
   24296 
   24297 pattern_and_enum:
   24298     if (error >= 0) {
   24299 	int found = 0;
   24300 	/*
   24301 	* Process enumerations. Facet values are in the value space
   24302 	* of the defining type's base type. This seems to be a bug in the
   24303 	* XML Schema 1.0 spec. Use the whitespace type of the base type.
   24304 	* Only the first set of enumerations in the ancestor-or-self axis
   24305 	* is used for validation.
   24306 	*/
   24307 	ret = 0;
   24308 	tmpType = type;
   24309 	do {
   24310 	    for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
   24311 		if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
   24312 		    continue;
   24313 		found = 1;
   24314 		ret = xmlSchemaAreValuesEqual(facet->val, val);
   24315 		if (ret == 1)
   24316 		    break;
   24317 		else if (ret < 0) {
   24318 		    AERROR_INT("xmlSchemaValidateFacets",
   24319 			"validating against an enumeration facet");
   24320 		    return (-1);
   24321 		}
   24322 	    }
   24323 	    if (ret != 0)
   24324 		break;
   24325 	    /*
   24326 	    * Break on the first set of enumerations. Any additional
   24327 	    *  enumerations which might be existent on the ancestors
   24328 	    *  of the current type are restricted by this set; thus
   24329 	    *  *must* *not* be taken into account.
   24330 	    */
   24331 	    if (found)
   24332 		break;
   24333 	    tmpType = tmpType->baseType;
   24334 	} while ((tmpType != NULL) &&
   24335 	    (tmpType->type != XML_SCHEMA_TYPE_BASIC));
   24336 	if (found && (ret == 0)) {
   24337 	    ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
   24338 	    if (fireErrors) {
   24339 		xmlSchemaFacetErr(actxt, ret, node,
   24340 		    value, 0, type, NULL, NULL, NULL, NULL);
   24341 	    } else
   24342 		return (ret);
   24343 	    if (error == 0)
   24344 		error = ret;
   24345 	}
   24346     }
   24347 
   24348     if (error >= 0) {
   24349 	int found;
   24350 	/*
   24351 	* Process patters. Pattern facets are ORed at type level
   24352 	* and ANDed if derived. Walk the base type axis.
   24353 	*/
   24354 	tmpType = type;
   24355 	facet = NULL;
   24356 	do {
   24357 	    found = 0;
   24358 	    for (facetLink = tmpType->facetSet; facetLink != NULL;
   24359 		facetLink = facetLink->next) {
   24360 		if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
   24361 		    continue;
   24362 		found = 1;
   24363 		/*
   24364 		* NOTE that for patterns, @value needs to be the
   24365 		* normalized vaule.
   24366 		*/
   24367 		ret = xmlRegexpExec(facetLink->facet->regexp, value);
   24368 		if (ret == 1)
   24369 		    break;
   24370 		else if (ret < 0) {
   24371 		    AERROR_INT("xmlSchemaValidateFacets",
   24372 			"validating against a pattern facet");
   24373 		    return (-1);
   24374 		} else {
   24375 		    /*
   24376 		    * Save the last non-validating facet.
   24377 		    */
   24378 		    facet = facetLink->facet;
   24379 		}
   24380 	    }
   24381 	    if (found && (ret != 1)) {
   24382 		ret = XML_SCHEMAV_CVC_PATTERN_VALID;
   24383 		if (fireErrors) {
   24384 		    xmlSchemaFacetErr(actxt, ret, node,
   24385 			value, 0, type, facet, NULL, NULL, NULL);
   24386 		} else
   24387 		    return (ret);
   24388 		if (error == 0)
   24389 		    error = ret;
   24390 		break;
   24391 	    }
   24392 	    tmpType = tmpType->baseType;
   24393 	} while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
   24394     }
   24395 
   24396     return (error);
   24397 }
   24398 
   24399 static xmlChar *
   24400 xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
   24401 			const xmlChar *value)
   24402 {
   24403     switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
   24404 	case XML_SCHEMA_WHITESPACE_COLLAPSE:
   24405 	    return (xmlSchemaCollapseString(value));
   24406 	case XML_SCHEMA_WHITESPACE_REPLACE:
   24407 	    return (xmlSchemaWhiteSpaceReplace(value));
   24408 	default:
   24409 	    return (NULL);
   24410     }
   24411 }
   24412 
   24413 static int
   24414 xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
   24415 		       const xmlChar *value,
   24416 		       xmlSchemaValPtr *val,
   24417 		       int valNeeded)
   24418 {
   24419     int ret;
   24420     const xmlChar *nsName;
   24421     xmlChar *local, *prefix = NULL;
   24422 
   24423     ret = xmlValidateQName(value, 1);
   24424     if (ret != 0) {
   24425 	if (ret == -1) {
   24426 	    VERROR_INT("xmlSchemaValidateQName",
   24427 		"calling xmlValidateQName()");
   24428 	    return (-1);
   24429 	}
   24430 	return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
   24431     }
   24432     /*
   24433     * NOTE: xmlSplitQName2 will always return a duplicated
   24434     * strings.
   24435     */
   24436     local = xmlSplitQName2(value, &prefix);
   24437     if (local == NULL)
   24438 	local = xmlStrdup(value);
   24439     /*
   24440     * OPTIMIZE TODO: Use flags for:
   24441     *  - is there any namespace binding?
   24442     *  - is there a default namespace?
   24443     */
   24444     nsName = xmlSchemaLookupNamespace(vctxt, prefix);
   24445 
   24446     if (prefix != NULL) {
   24447 	xmlFree(prefix);
   24448 	/*
   24449 	* A namespace must be found if the prefix is
   24450 	* NOT NULL.
   24451 	*/
   24452 	if (nsName == NULL) {
   24453 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
   24454 	    xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
   24455 		WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
   24456 		"The QName value '%s' has no "
   24457 		"corresponding namespace declaration in "
   24458 		"scope", value, NULL);
   24459 	    if (local != NULL)
   24460 		xmlFree(local);
   24461 	    return (ret);
   24462 	}
   24463     }
   24464     if (valNeeded && val) {
   24465 	if (nsName != NULL)
   24466 	    *val = xmlSchemaNewQNameValue(
   24467 		BAD_CAST xmlStrdup(nsName), BAD_CAST local);
   24468 	else
   24469 	    *val = xmlSchemaNewQNameValue(NULL,
   24470 		BAD_CAST local);
   24471     } else
   24472 	xmlFree(local);
   24473     return (0);
   24474 }
   24475 
   24476 /*
   24477 * cvc-simple-type
   24478 */
   24479 static int
   24480 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
   24481 			     xmlNodePtr node,
   24482 			     xmlSchemaTypePtr type,
   24483 			     const xmlChar *value,
   24484 			     xmlSchemaValPtr *retVal,
   24485 			     int fireErrors,
   24486 			     int normalize,
   24487 			     int isNormalized)
   24488 {
   24489     int ret = 0, valNeeded = (retVal) ? 1 : 0;
   24490     xmlSchemaValPtr val = NULL;
   24491     /* xmlSchemaWhitespaceValueType ws; */
   24492     xmlChar *normValue = NULL;
   24493 
   24494 #define NORMALIZE(atype) \
   24495     if ((! isNormalized) && \
   24496     (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
   24497 	normValue = xmlSchemaNormalizeValue(atype, value); \
   24498 	if (normValue != NULL) \
   24499 	    value = normValue; \
   24500 	isNormalized = 1; \
   24501     }
   24502 
   24503     if ((retVal != NULL) && (*retVal != NULL)) {
   24504 	xmlSchemaFreeValue(*retVal);
   24505 	*retVal = NULL;
   24506     }
   24507     /*
   24508     * 3.14.4 Simple Type Definition Validation Rules
   24509     * Validation Rule: String Valid
   24510     */
   24511     /*
   24512     * 1 It is schema-valid with respect to that definition as defined
   24513     * by Datatype Valid in [XML Schemas: Datatypes].
   24514     */
   24515     /*
   24516     * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
   24517     * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
   24518     * the string must be a `declared entity name`.
   24519     */
   24520     /*
   24521     * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
   24522     * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
   24523     * then every whitespace-delimited substring of the string must be a `declared
   24524     * entity name`.
   24525     */
   24526     /*
   24527     * 2.3 otherwise no further condition applies.
   24528     */
   24529     if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
   24530 	valNeeded = 1;
   24531     if (value == NULL)
   24532 	value = BAD_CAST "";
   24533     if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
   24534 	xmlSchemaTypePtr biType; /* The built-in type. */
   24535 	/*
   24536 	* SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
   24537 	* a literal in the `lexical space` of {base type definition}"
   24538 	*/
   24539 	/*
   24540 	* Whitespace-normalize.
   24541 	*/
   24542 	NORMALIZE(type);
   24543 	if (type->type != XML_SCHEMA_TYPE_BASIC) {
   24544 	    /*
   24545 	    * Get the built-in type.
   24546 	    */
   24547 	    biType = type->baseType;
   24548 	    while ((biType != NULL) &&
   24549 		(biType->type != XML_SCHEMA_TYPE_BASIC))
   24550 		biType = biType->baseType;
   24551 
   24552 	    if (biType == NULL) {
   24553 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24554 		    "could not get the built-in type");
   24555 		goto internal_error;
   24556 	    }
   24557 	} else
   24558 	    biType = type;
   24559 	/*
   24560 	* NOTATIONs need to be processed here, since they need
   24561 	* to lookup in the hashtable of NOTATION declarations of the schema.
   24562 	*/
   24563 	if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
   24564 	    switch (biType->builtInType) {
   24565 		case XML_SCHEMAS_NOTATION:
   24566 		    ret = xmlSchemaValidateNotation(
   24567 			(xmlSchemaValidCtxtPtr) actxt,
   24568 			((xmlSchemaValidCtxtPtr) actxt)->schema,
   24569 			NULL, value, &val, valNeeded);
   24570 		    break;
   24571 		case XML_SCHEMAS_QNAME:
   24572 		    ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
   24573 			value, &val, valNeeded);
   24574 		    break;
   24575 		default:
   24576 		    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
   24577 		    if (valNeeded)
   24578 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
   24579 			    value, &val, node);
   24580 		    else
   24581 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
   24582 			    value, NULL, node);
   24583 		    break;
   24584 	    }
   24585 	} else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
   24586 	    switch (biType->builtInType) {
   24587 		case XML_SCHEMAS_NOTATION:
   24588 		    ret = xmlSchemaValidateNotation(NULL,
   24589 			((xmlSchemaParserCtxtPtr) actxt)->schema, node,
   24590 			value, &val, valNeeded);
   24591 		    break;
   24592 		default:
   24593 		    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
   24594 		    if (valNeeded)
   24595 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
   24596 			    value, &val, node);
   24597 		    else
   24598 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
   24599 			    value, NULL, node);
   24600 		    break;
   24601 	    }
   24602 	} else {
   24603 	    /*
   24604 	    * Validation via a public API is not implemented yet.
   24605 	    */
   24606 	    TODO
   24607 	    goto internal_error;
   24608 	}
   24609 	if (ret != 0) {
   24610 	    if (ret < 0) {
   24611 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24612 		    "validating against a built-in type");
   24613 		goto internal_error;
   24614 	    }
   24615 	    if (WXS_IS_LIST(type))
   24616 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   24617 	    else
   24618 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
   24619 	}
   24620 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
   24621 	    /*
   24622 	    * Check facets.
   24623 	    */
   24624 	    ret = xmlSchemaValidateFacets(actxt, node, type,
   24625 		(xmlSchemaValType) biType->builtInType, value, val,
   24626 		0, fireErrors);
   24627 	    if (ret != 0) {
   24628 		if (ret < 0) {
   24629 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24630 			"validating facets of atomic simple type");
   24631 		    goto internal_error;
   24632 		}
   24633 		if (WXS_IS_LIST(type))
   24634 		    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   24635 		else
   24636 		    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
   24637 	    }
   24638 	}
   24639 	if (fireErrors && (ret > 0))
   24640 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
   24641     } else if (WXS_IS_LIST(type)) {
   24642 
   24643 	xmlSchemaTypePtr itemType;
   24644 	const xmlChar *cur, *end;
   24645 	xmlChar *tmpValue = NULL;
   24646 	unsigned long len = 0;
   24647 	xmlSchemaValPtr prevVal = NULL, curVal = NULL;
   24648 	/* 1.2.2 if {variety} is `list` then the string must be a sequence
   24649 	* of white space separated tokens, each of which `match`es a literal
   24650 	* in the `lexical space` of {item type definition}
   24651 	*/
   24652 	/*
   24653 	* Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
   24654 	* the list type has an enum or pattern facet.
   24655 	*/
   24656 	NORMALIZE(type);
   24657 	/*
   24658 	* VAL TODO: Optimize validation of empty values.
   24659 	* VAL TODO: We do not have computed values for lists.
   24660 	*/
   24661 	itemType = WXS_LIST_ITEMTYPE(type);
   24662 	cur = value;
   24663 	do {
   24664 	    while (IS_BLANK_CH(*cur))
   24665 		cur++;
   24666 	    end = cur;
   24667 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   24668 		end++;
   24669 	    if (end == cur)
   24670 		break;
   24671 	    tmpValue = xmlStrndup(cur, end - cur);
   24672 	    len++;
   24673 
   24674 	    if (valNeeded)
   24675 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
   24676 		    tmpValue, &curVal, fireErrors, 0, 1);
   24677 	    else
   24678 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
   24679 		    tmpValue, NULL, fireErrors, 0, 1);
   24680 	    FREE_AND_NULL(tmpValue);
   24681 	    if (curVal != NULL) {
   24682 		/*
   24683 		* Add to list of computed values.
   24684 		*/
   24685 		if (val == NULL)
   24686 		    val = curVal;
   24687 		else
   24688 		    xmlSchemaValueAppend(prevVal, curVal);
   24689 		prevVal = curVal;
   24690 		curVal = NULL;
   24691 	    }
   24692 	    if (ret != 0) {
   24693 		if (ret < 0) {
   24694 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24695 			"validating an item of list simple type");
   24696 		    goto internal_error;
   24697 		}
   24698 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   24699 		break;
   24700 	    }
   24701 	    cur = end;
   24702 	} while (*cur != 0);
   24703 	FREE_AND_NULL(tmpValue);
   24704 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
   24705 	    /*
   24706 	    * Apply facets (pattern, enumeration).
   24707 	    */
   24708 	    ret = xmlSchemaValidateFacets(actxt, node, type,
   24709 		XML_SCHEMAS_UNKNOWN, value, val,
   24710 		len, fireErrors);
   24711 	    if (ret != 0) {
   24712 		if (ret < 0) {
   24713 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24714 			"validating facets of list simple type");
   24715 		    goto internal_error;
   24716 		}
   24717 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   24718 	    }
   24719 	}
   24720 	if (fireErrors && (ret > 0)) {
   24721 	    /*
   24722 	    * Report the normalized value.
   24723 	    */
   24724 	    normalize = 1;
   24725 	    NORMALIZE(type);
   24726 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
   24727 	}
   24728     } else if (WXS_IS_UNION(type)) {
   24729 	xmlSchemaTypeLinkPtr memberLink;
   24730 	/*
   24731 	* TODO: For all datatypes `derived` by `union`  whiteSpace does
   24732 	* not apply directly; however, the normalization behavior of `union`
   24733 	* types is controlled by the value of whiteSpace on that one of the
   24734 	* `memberTypes` against which the `union` is successfully validated.
   24735 	*
   24736 	* This means that the value is normalized by the first validating
   24737 	* member type, then the facets of the union type are applied. This
   24738 	* needs changing of the value!
   24739 	*/
   24740 
   24741 	/*
   24742 	* 1.2.3 if {variety} is `union` then the string must `match` a
   24743 	* literal in the `lexical space` of at least one member of
   24744 	* {member type definitions}
   24745 	*/
   24746 	memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
   24747 	if (memberLink == NULL) {
   24748 	    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24749 		"union simple type has no member types");
   24750 	    goto internal_error;
   24751 	}
   24752 	/*
   24753 	* Always normalize union type values, since we currently
   24754 	* cannot store the whitespace information with the value
   24755 	* itself; otherwise a later value-comparison would be
   24756 	* not possible.
   24757 	*/
   24758 	while (memberLink != NULL) {
   24759 	    if (valNeeded)
   24760 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
   24761 		    memberLink->type, value, &val, 0, 1, 0);
   24762 	    else
   24763 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
   24764 		    memberLink->type, value, NULL, 0, 1, 0);
   24765 	    if (ret <= 0)
   24766 		break;
   24767 	    memberLink = memberLink->next;
   24768 	}
   24769 	if (ret != 0) {
   24770 	    if (ret < 0) {
   24771 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24772 		    "validating members of union simple type");
   24773 		goto internal_error;
   24774 	    }
   24775 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
   24776 	}
   24777 	/*
   24778 	* Apply facets (pattern, enumeration).
   24779 	*/
   24780 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
   24781 	    /*
   24782 	    * The normalization behavior of `union` types is controlled by
   24783 	    * the value of whiteSpace on that one of the `memberTypes`
   24784 	    * against which the `union` is successfully validated.
   24785 	    */
   24786 	    NORMALIZE(memberLink->type);
   24787 	    ret = xmlSchemaValidateFacets(actxt, node, type,
   24788 		XML_SCHEMAS_UNKNOWN, value, val,
   24789 		0, fireErrors);
   24790 	    if (ret != 0) {
   24791 		if (ret < 0) {
   24792 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24793 			"validating facets of union simple type");
   24794 		    goto internal_error;
   24795 		}
   24796 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
   24797 	    }
   24798 	}
   24799 	if (fireErrors && (ret > 0))
   24800 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
   24801     }
   24802 
   24803     if (normValue != NULL)
   24804 	xmlFree(normValue);
   24805     if (ret == 0) {
   24806 	if (retVal != NULL)
   24807 	    *retVal = val;
   24808 	else if (val != NULL)
   24809 	    xmlSchemaFreeValue(val);
   24810     } else if (val != NULL)
   24811 	xmlSchemaFreeValue(val);
   24812     return (ret);
   24813 internal_error:
   24814     if (normValue != NULL)
   24815 	xmlFree(normValue);
   24816     if (val != NULL)
   24817 	xmlSchemaFreeValue(val);
   24818     return (-1);
   24819 }
   24820 
   24821 static int
   24822 xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
   24823 			   const xmlChar *value,
   24824 			   const xmlChar **nsName,
   24825 			   const xmlChar **localName)
   24826 {
   24827     int ret = 0;
   24828 
   24829     if ((nsName == NULL) || (localName == NULL))
   24830 	return (-1);
   24831     *nsName = NULL;
   24832     *localName = NULL;
   24833 
   24834     ret = xmlValidateQName(value, 1);
   24835     if (ret == -1)
   24836 	return (-1);
   24837     if (ret > 0) {
   24838 	xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
   24839 	    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
   24840 	    value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
   24841 	return (1);
   24842     }
   24843     {
   24844 	xmlChar *local = NULL;
   24845 	xmlChar *prefix;
   24846 
   24847 	/*
   24848 	* NOTE: xmlSplitQName2 will return a duplicated
   24849 	* string.
   24850 	*/
   24851 	local = xmlSplitQName2(value, &prefix);
   24852 	if (local == NULL)
   24853 	    *localName = xmlDictLookup(vctxt->dict, value, -1);
   24854 	else {
   24855 	    *localName = xmlDictLookup(vctxt->dict, local, -1);
   24856 	    xmlFree(local);
   24857 	}
   24858 
   24859 	*nsName = xmlSchemaLookupNamespace(vctxt, prefix);
   24860 
   24861 	if (prefix != NULL) {
   24862 	    xmlFree(prefix);
   24863 	    /*
   24864 	    * A namespace must be found if the prefix is NOT NULL.
   24865 	    */
   24866 	    if (*nsName == NULL) {
   24867 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   24868 		    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
   24869 		    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
   24870 		    "The QName value '%s' has no "
   24871 		    "corresponding namespace declaration in scope",
   24872 		    value, NULL);
   24873 		return (2);
   24874 	    }
   24875 	}
   24876     }
   24877     return (0);
   24878 }
   24879 
   24880 static int
   24881 xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
   24882 			xmlSchemaAttrInfoPtr iattr,
   24883 			xmlSchemaTypePtr *localType,
   24884 			xmlSchemaElementPtr elemDecl)
   24885 {
   24886     int ret = 0;
   24887     /*
   24888     * cvc-elt (3.3.4) : (4)
   24889     * AND
   24890     * Schema-Validity Assessment (Element) (cvc-assess-elt)
   24891     *   (1.2.1.2.1) - (1.2.1.2.4)
   24892     * Handle 'xsi:type'.
   24893     */
   24894     if (localType == NULL)
   24895 	return (-1);
   24896     *localType = NULL;
   24897     if (iattr == NULL)
   24898 	return (0);
   24899     else {
   24900 	const xmlChar *nsName = NULL, *local = NULL;
   24901 	/*
   24902 	* TODO: We should report a *warning* that the type was overriden
   24903 	* by the instance.
   24904 	*/
   24905 	ACTIVATE_ATTRIBUTE(iattr);
   24906 	/*
   24907 	* (cvc-elt) (3.3.4) : (4.1)
   24908 	* (cvc-assess-elt) (1.2.1.2.2)
   24909 	*/
   24910 	ret = xmlSchemaVExpandQName(vctxt, iattr->value,
   24911 	    &nsName, &local);
   24912 	if (ret != 0) {
   24913 	    if (ret < 0) {
   24914 		VERROR_INT("xmlSchemaValidateElementByDeclaration",
   24915 		    "calling xmlSchemaQNameExpand() to validate the "
   24916 		    "attribute 'xsi:type'");
   24917 		goto internal_error;
   24918 	    }
   24919 	    goto exit;
   24920 	}
   24921 	/*
   24922 	* (cvc-elt) (3.3.4) : (4.2)
   24923 	* (cvc-assess-elt) (1.2.1.2.3)
   24924 	*/
   24925 	*localType = xmlSchemaGetType(vctxt->schema, local, nsName);
   24926 	if (*localType == NULL) {
   24927 	    xmlChar *str = NULL;
   24928 
   24929 	    xmlSchemaCustomErr(ACTXT_CAST vctxt,
   24930 		XML_SCHEMAV_CVC_ELT_4_2, NULL,
   24931 		WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
   24932 		"The QName value '%s' of the xsi:type attribute does not "
   24933 		"resolve to a type definition",
   24934 		xmlSchemaFormatQName(&str, nsName, local), NULL);
   24935 	    FREE_AND_NULL(str);
   24936 	    ret = vctxt->err;
   24937 	    goto exit;
   24938 	}
   24939 	if (elemDecl != NULL) {
   24940 	    int set = 0;
   24941 
   24942 	    /*
   24943 	    * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
   24944 	    * "The `local type definition` must be validly
   24945 	    * derived from the {type definition} given the union of
   24946 	    * the {disallowed substitutions} and the {type definition}'s
   24947 	    * {prohibited substitutions}, as defined in
   24948 	    * Type Derivation OK (Complex) ($3.4.6)
   24949 	    * (if it is a complex type definition),
   24950 	    * or given {disallowed substitutions} as defined in Type
   24951 	    * Derivation OK (Simple) ($3.14.6) (if it is a simple type
   24952 	    * definition)."
   24953 	    *
   24954 	    * {disallowed substitutions}: the "block" on the element decl.
   24955 	    * {prohibited substitutions}: the "block" on the type def.
   24956 	    */
   24957 	    /*
   24958 	    * OPTIMIZE TODO: We could map types already evaluated
   24959 	    * to be validly derived from other types to avoid checking
   24960 	    * this over and over for the same types.
   24961 	    */
   24962 	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
   24963 		(elemDecl->subtypes->flags &
   24964 		    XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
   24965 		set |= SUBSET_EXTENSION;
   24966 
   24967 	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
   24968 		(elemDecl->subtypes->flags &
   24969 		    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
   24970 		set |= SUBSET_RESTRICTION;
   24971 
   24972 	    /*
   24973 	    * REMOVED and CHANGED since this produced a parser context
   24974 	    * which adds to the string dict of the schema. So this would
   24975 	    * change the schema and we don't want this. We don't need
   24976 	    * the parser context anymore.
   24977 	    *
   24978 	    * if ((vctxt->pctxt == NULL) &&
   24979 	    *	(xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
   24980 	    *	    return (-1);
   24981 	    */
   24982 
   24983 	    if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
   24984 		elemDecl->subtypes, set) != 0) {
   24985 		xmlChar *str = NULL;
   24986 
   24987 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   24988 		    XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
   24989 		    "The type definition '%s', specified by xsi:type, is "
   24990 		    "blocked or not validly derived from the type definition "
   24991 		    "of the element declaration",
   24992 		    xmlSchemaFormatQName(&str,
   24993 			(*localType)->targetNamespace,
   24994 			(*localType)->name),
   24995 		    NULL);
   24996 		FREE_AND_NULL(str);
   24997 		ret = vctxt->err;
   24998 		*localType = NULL;
   24999 	    }
   25000 	}
   25001     }
   25002 exit:
   25003     ACTIVATE_ELEM;
   25004     return (ret);
   25005 internal_error:
   25006     ACTIVATE_ELEM;
   25007     return (-1);
   25008 }
   25009 
   25010 static int
   25011 xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
   25012 {
   25013     xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
   25014     xmlSchemaTypePtr actualType;
   25015 
   25016     /*
   25017     * cvc-elt (3.3.4) : 1
   25018     */
   25019     if (elemDecl == NULL) {
   25020 	VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
   25021 	    "No matching declaration available");
   25022         return (vctxt->err);
   25023     }
   25024     actualType = WXS_ELEM_TYPEDEF(elemDecl);
   25025     /*
   25026     * cvc-elt (3.3.4) : 2
   25027     */
   25028     if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
   25029 	VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
   25030 	    "The element declaration is abstract");
   25031         return (vctxt->err);
   25032     }
   25033     if (actualType == NULL) {
   25034 	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
   25035 	    "The type definition is absent");
   25036 	return (XML_SCHEMAV_CVC_TYPE_1);
   25037     }
   25038     if (vctxt->nbAttrInfos != 0) {
   25039 	int ret;
   25040 	xmlSchemaAttrInfoPtr iattr;
   25041 	/*
   25042 	* cvc-elt (3.3.4) : 3
   25043 	* Handle 'xsi:nil'.
   25044 	*/
   25045 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   25046 	    XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
   25047 	if (iattr) {
   25048 	    ACTIVATE_ATTRIBUTE(iattr);
   25049 	    /*
   25050 	    * Validate the value.
   25051 	    */
   25052 	    ret = xmlSchemaVCheckCVCSimpleType(
   25053 		ACTXT_CAST vctxt, NULL,
   25054 		xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
   25055 		iattr->value, &(iattr->val), 1, 0, 0);
   25056 	    ACTIVATE_ELEM;
   25057 	    if (ret < 0) {
   25058 		VERROR_INT("xmlSchemaValidateElemDecl",
   25059 		    "calling xmlSchemaVCheckCVCSimpleType() to "
   25060 		    "validate the attribute 'xsi:nil'");
   25061 		return (-1);
   25062 	    }
   25063 	    if (ret == 0) {
   25064 		if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
   25065 		    /*
   25066 		    * cvc-elt (3.3.4) : 3.1
   25067 		    */
   25068 		    VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
   25069 			"The element is not 'nillable'");
   25070 		    /* Does not return an error on purpose. */
   25071 		} else {
   25072 		    if (xmlSchemaValueGetAsBoolean(iattr->val)) {
   25073 			/*
   25074 			* cvc-elt (3.3.4) : 3.2.2
   25075 			*/
   25076 			if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
   25077 			    (elemDecl->value != NULL)) {
   25078 			    VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
   25079 				"The element cannot be 'nilled' because "
   25080 				"there is a fixed value constraint defined "
   25081 				"for it");
   25082 			     /* Does not return an error on purpose. */
   25083 			} else
   25084 			    vctxt->inode->flags |=
   25085 				XML_SCHEMA_ELEM_INFO_NILLED;
   25086 		    }
   25087 		}
   25088 	    }
   25089 	}
   25090 	/*
   25091 	* cvc-elt (3.3.4) : 4
   25092 	* Handle 'xsi:type'.
   25093 	*/
   25094 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   25095 	    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
   25096 	if (iattr) {
   25097 	    xmlSchemaTypePtr localType = NULL;
   25098 
   25099 	    ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
   25100 		elemDecl);
   25101 	    if (ret != 0) {
   25102 		if (ret == -1) {
   25103 		    VERROR_INT("xmlSchemaValidateElemDecl",
   25104 			"calling xmlSchemaProcessXSIType() to "
   25105 			"process the attribute 'xsi:type'");
   25106 		    return (-1);
   25107 		}
   25108 		/* Does not return an error on purpose. */
   25109 	    }
   25110 	    if (localType != NULL) {
   25111 		vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
   25112 		actualType = localType;
   25113 	    }
   25114 	}
   25115     }
   25116     /*
   25117     * IDC: Register identity-constraint XPath matchers.
   25118     */
   25119     if ((elemDecl->idcs != NULL) &&
   25120 	(xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
   25121 	    return (-1);
   25122     /*
   25123     * No actual type definition.
   25124     */
   25125     if (actualType == NULL) {
   25126 	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
   25127 	    "The type definition is absent");
   25128 	return (XML_SCHEMAV_CVC_TYPE_1);
   25129     }
   25130     /*
   25131     * Remember the actual type definition.
   25132     */
   25133     vctxt->inode->typeDef = actualType;
   25134 
   25135     return (0);
   25136 }
   25137 
   25138 static int
   25139 xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
   25140 {
   25141     xmlSchemaAttrInfoPtr iattr;
   25142     int ret = 0, i;
   25143 
   25144     /*
   25145     * SPEC cvc-type (3.1.1)
   25146     * "The attributes of must be empty, excepting those whose namespace
   25147     * name is identical to http://www.w3.org/2001/XMLSchema-instance and
   25148     * whose local name is one of type, nil, schemaLocation or
   25149     * noNamespaceSchemaLocation."
   25150     */
   25151     if (vctxt->nbAttrInfos == 0)
   25152 	return (0);
   25153     for (i = 0; i < vctxt->nbAttrInfos; i++) {
   25154 	iattr = vctxt->attrInfos[i];
   25155 	if (! iattr->metaType) {
   25156 	    ACTIVATE_ATTRIBUTE(iattr)
   25157 	    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
   25158 		XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
   25159 	    ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
   25160         }
   25161     }
   25162     ACTIVATE_ELEM
   25163     return (ret);
   25164 }
   25165 
   25166 /*
   25167 * Cleanup currently used attribute infos.
   25168 */
   25169 static void
   25170 xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
   25171 {
   25172     int i;
   25173     xmlSchemaAttrInfoPtr attr;
   25174 
   25175     if (vctxt->nbAttrInfos == 0)
   25176 	return;
   25177     for (i = 0; i < vctxt->nbAttrInfos; i++) {
   25178 	attr = vctxt->attrInfos[i];
   25179 	if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
   25180 	    if (attr->localName != NULL)
   25181 		xmlFree((xmlChar *) attr->localName);
   25182 	    if (attr->nsName != NULL)
   25183 		xmlFree((xmlChar *) attr->nsName);
   25184 	}
   25185 	if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
   25186 	    if (attr->value != NULL)
   25187 		xmlFree((xmlChar *) attr->value);
   25188 	}
   25189 	if (attr->val != NULL) {
   25190 	    xmlSchemaFreeValue(attr->val);
   25191 	    attr->val = NULL;
   25192 	}
   25193 	memset(attr, 0, sizeof(xmlSchemaAttrInfo));
   25194     }
   25195     vctxt->nbAttrInfos = 0;
   25196 }
   25197 
   25198 /*
   25199 * 3.4.4 Complex Type Definition Validation Rules
   25200 *   Element Locally Valid (Complex Type) (cvc-complex-type)
   25201 * 3.2.4 Attribute Declaration Validation Rules
   25202 *   Validation Rule: Attribute Locally Valid (cvc-attribute)
   25203 *   Attribute Locally Valid (Use) (cvc-au)
   25204 *
   25205 * Only "assessed" attribute information items will be visible to
   25206 * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
   25207 */
   25208 static int
   25209 xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
   25210 {
   25211     xmlSchemaTypePtr type = vctxt->inode->typeDef;
   25212     xmlSchemaItemListPtr attrUseList;
   25213     xmlSchemaAttributeUsePtr attrUse = NULL;
   25214     xmlSchemaAttributePtr attrDecl = NULL;
   25215     xmlSchemaAttrInfoPtr iattr, tmpiattr;
   25216     int i, j, found, nbAttrs, nbUses;
   25217     int xpathRes = 0, res, wildIDs = 0, fixed;
   25218     xmlNodePtr defAttrOwnerElem = NULL;
   25219 
   25220     /*
   25221     * SPEC (cvc-attribute)
   25222     * (1) "The declaration must not be `absent` (see Missing
   25223     * Sub-components ($5.3) for how this can fail to be
   25224     * the case)."
   25225     * (2) "Its {type definition} must not be absent."
   25226     *
   25227     * NOTE (1) + (2): This is not handled here, since we currently do not
   25228     * allow validation against schemas which have missing sub-components.
   25229     *
   25230     * SPEC (cvc-complex-type)
   25231     * (3) "For each attribute information item in the element information
   25232     * item's [attributes] excepting those whose [namespace name] is
   25233     * identical to http://www.w3.org/2001/XMLSchema-instance and whose
   25234     * [local name] is one of type, nil, schemaLocation or
   25235     * noNamespaceSchemaLocation, the appropriate case among the following
   25236     * must be true:
   25237     *
   25238     */
   25239     attrUseList = (xmlSchemaItemListPtr) type->attrUses;
   25240     /*
   25241     * @nbAttrs is the number of attributes present in the instance.
   25242     */
   25243     nbAttrs = vctxt->nbAttrInfos;
   25244     if (attrUseList != NULL)
   25245 	nbUses = attrUseList->nbItems;
   25246     else
   25247 	nbUses = 0;
   25248     for (i = 0; i < nbUses; i++) {
   25249         found = 0;
   25250 	attrUse = attrUseList->items[i];
   25251 	attrDecl = WXS_ATTRUSE_DECL(attrUse);
   25252         for (j = 0; j < nbAttrs; j++) {
   25253 	    iattr = vctxt->attrInfos[j];
   25254 	    /*
   25255 	    * SPEC (cvc-complex-type) (3)
   25256 	    * Skip meta attributes.
   25257 	    */
   25258 	    if (iattr->metaType)
   25259 		continue;
   25260 	    if (iattr->localName[0] != attrDecl->name[0])
   25261 		continue;
   25262 	    if (!xmlStrEqual(iattr->localName, attrDecl->name))
   25263 		continue;
   25264 	    if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
   25265 		continue;
   25266 	    found = 1;
   25267 	    /*
   25268 	    * SPEC (cvc-complex-type)
   25269 	    * (3.1) "If there is among the {attribute uses} an attribute
   25270 	    * use with an {attribute declaration} whose {name} matches
   25271 	    * the attribute information item's [local name] and whose
   25272 	    * {target namespace} is identical to the attribute information
   25273 	    * item's [namespace name] (where an `absent` {target namespace}
   25274 	    * is taken to be identical to a [namespace name] with no value),
   25275 	    * then the attribute information must be `valid` with respect
   25276 	    * to that attribute use as per Attribute Locally Valid (Use)
   25277 	    * ($3.5.4). In this case the {attribute declaration} of that
   25278 	    * attribute use is the `context-determined declaration` for the
   25279 	    * attribute information item with respect to Schema-Validity
   25280 	    * Assessment (Attribute) ($3.2.4) and
   25281 	    * Assessment Outcome (Attribute) ($3.2.5).
   25282 	    */
   25283 	    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
   25284 	    iattr->use = attrUse;
   25285 	    /*
   25286 	    * Context-determined declaration.
   25287 	    */
   25288 	    iattr->decl = attrDecl;
   25289 	    iattr->typeDef = attrDecl->subtypes;
   25290 	    break;
   25291 	}
   25292 
   25293 	if (found)
   25294 	    continue;
   25295 
   25296 	if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
   25297 	    /*
   25298 	    * Handle non-existent, required attributes.
   25299 	    *
   25300 	    * SPEC (cvc-complex-type)
   25301 	    * (4) "The {attribute declaration} of each attribute use in
   25302 	    * the {attribute uses} whose {required} is true matches one
   25303 	    * of the attribute information items in the element information
   25304 	    * item's [attributes] as per clause 3.1 above."
   25305 	    */
   25306 	    tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
   25307 	    if (tmpiattr == NULL) {
   25308 		VERROR_INT(
   25309 		    "xmlSchemaVAttributesComplex",
   25310 		    "calling xmlSchemaGetFreshAttrInfo()");
   25311 		return (-1);
   25312 	    }
   25313 	    tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
   25314 	    tmpiattr->use = attrUse;
   25315 	    tmpiattr->decl = attrDecl;
   25316 	} else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
   25317 	    ((attrUse->defValue != NULL) ||
   25318 	     (attrDecl->defValue != NULL))) {
   25319 	    /*
   25320 	    * Handle non-existent, optional, default/fixed attributes.
   25321 	    */
   25322 	    tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
   25323 	    if (tmpiattr == NULL) {
   25324 		VERROR_INT(
   25325 		    "xmlSchemaVAttributesComplex",
   25326 		    "calling xmlSchemaGetFreshAttrInfo()");
   25327 		return (-1);
   25328 	    }
   25329 	    tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
   25330 	    tmpiattr->use = attrUse;
   25331 	    tmpiattr->decl = attrDecl;
   25332 	    tmpiattr->typeDef = attrDecl->subtypes;
   25333 	    tmpiattr->localName = attrDecl->name;
   25334 	    tmpiattr->nsName = attrDecl->targetNamespace;
   25335 	}
   25336     }
   25337 
   25338     if (vctxt->nbAttrInfos == 0)
   25339 	return (0);
   25340     /*
   25341     * Validate against the wildcard.
   25342     */
   25343     if (type->attributeWildcard != NULL) {
   25344 	/*
   25345 	* SPEC (cvc-complex-type)
   25346 	* (3.2.1) "There must be an {attribute wildcard}."
   25347 	*/
   25348 	for (i = 0; i < nbAttrs; i++) {
   25349 	    iattr = vctxt->attrInfos[i];
   25350 	    /*
   25351 	    * SPEC (cvc-complex-type) (3)
   25352 	    * Skip meta attributes.
   25353 	    */
   25354 	    if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
   25355 		continue;
   25356 	    /*
   25357 	    * SPEC (cvc-complex-type)
   25358 	    * (3.2.2) "The attribute information item must be `valid` with
   25359 	    * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
   25360 	    *
   25361 	    * SPEC Item Valid (Wildcard) (cvc-wildcard)
   25362 	    * "... its [namespace name] must be `valid` with respect to
   25363 	    * the wildcard constraint, as defined in Wildcard allows
   25364 	    * Namespace Name ($3.10.4)."
   25365 	    */
   25366 	    if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
   25367 		    iattr->nsName) == 0) {
   25368 		/*
   25369 		* Handle processContents.
   25370 		*
   25371 		* SPEC (cvc-wildcard):
   25372 		* processContents | context-determined declaration:
   25373 		* "strict"          "mustFind"
   25374 		* "lax"             "none"
   25375 		* "skip"            "skip"
   25376 		*/
   25377 		if (type->attributeWildcard->processContents ==
   25378 		    XML_SCHEMAS_ANY_SKIP) {
   25379 		     /*
   25380 		    * context-determined declaration = "skip"
   25381 		    *
   25382 		    * SPEC PSVI Assessment Outcome (Attribute)
   25383 		    * [validity] = "notKnown"
   25384 		    * [validation attempted] = "none"
   25385 		    */
   25386 		    iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
   25387 		    continue;
   25388 		}
   25389 		/*
   25390 		* Find an attribute declaration.
   25391 		*/
   25392 		iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
   25393 		    iattr->localName, iattr->nsName);
   25394 		if (iattr->decl != NULL) {
   25395 		    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
   25396 		    /*
   25397 		    * SPEC (cvc-complex-type)
   25398 		    * (5) "Let [Definition:]  the wild IDs be the set of
   25399 		    * all attribute information item to which clause 3.2
   25400 		    * applied and whose `validation` resulted in a
   25401 		    * `context-determined declaration` of mustFind or no
   25402 		    * `context-determined declaration` at all, and whose
   25403 		    * [local name] and [namespace name] resolve (as
   25404 		    * defined by QName resolution (Instance) ($3.15.4)) to
   25405 		    * an attribute declaration whose {type definition} is
   25406 		    * or is derived from ID. Then all of the following
   25407 		    * must be true:"
   25408 		    */
   25409 		    iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
   25410 		    if (xmlSchemaIsDerivedFromBuiltInType(
   25411 			iattr->typeDef, XML_SCHEMAS_ID)) {
   25412 			/*
   25413 			* SPEC (5.1) "There must be no more than one
   25414 			* item in `wild IDs`."
   25415 			*/
   25416 			if (wildIDs != 0) {
   25417 			    /* VAL TODO */
   25418 			    iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
   25419 			    TODO
   25420 			    continue;
   25421 			}
   25422 			wildIDs++;
   25423 			/*
   25424 			* SPEC (cvc-complex-type)
   25425 			* (5.2) "If `wild IDs` is non-empty, there must not
   25426 			* be any attribute uses among the {attribute uses}
   25427 			* whose {attribute declaration}'s {type definition}
   25428 			* is or is derived from ID."
   25429 			*/
   25430                         if (attrUseList != NULL) {
   25431                             for (j = 0; j < attrUseList->nbItems; j++) {
   25432                                 if (xmlSchemaIsDerivedFromBuiltInType(
   25433                                     WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
   25434                                     XML_SCHEMAS_ID)) {
   25435                                     /* URGENT VAL TODO: implement */
   25436                             iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
   25437                                     TODO
   25438                                     break;
   25439                                 }
   25440                             }
   25441                         }
   25442 		    }
   25443 		} else if (type->attributeWildcard->processContents ==
   25444 		    XML_SCHEMAS_ANY_LAX) {
   25445 		    iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
   25446 		    /*
   25447 		    * SPEC PSVI Assessment Outcome (Attribute)
   25448 		    * [validity] = "notKnown"
   25449 		    * [validation attempted] = "none"
   25450 		    */
   25451 		} else {
   25452 		    iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
   25453 		}
   25454 	    }
   25455 	}
   25456     }
   25457 
   25458     if (vctxt->nbAttrInfos == 0)
   25459 	return (0);
   25460 
   25461     /*
   25462     * Get the owner element; needed for creation of default attributes.
   25463     * This fixes bug #341337, reported by David Grohmann.
   25464     */
   25465     if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
   25466 	xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
   25467 	if (ielem && ielem->node && ielem->node->doc)
   25468 	    defAttrOwnerElem = ielem->node;
   25469     }
   25470     /*
   25471     * Validate values, create default attributes, evaluate IDCs.
   25472     */
   25473     for (i = 0; i < vctxt->nbAttrInfos; i++) {
   25474 	iattr = vctxt->attrInfos[i];
   25475 	/*
   25476 	* VAL TODO: Note that we won't try to resolve IDCs to
   25477 	* "lax" and "skip" validated attributes. Check what to
   25478 	* do in this case.
   25479 	*/
   25480 	if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
   25481 	    (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
   25482 	    continue;
   25483 	/*
   25484 	* VAL TODO: What to do if the type definition is missing?
   25485 	*/
   25486 	if (iattr->typeDef == NULL) {
   25487 	    iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
   25488 	    continue;
   25489 	}
   25490 
   25491 	ACTIVATE_ATTRIBUTE(iattr);
   25492 	fixed = 0;
   25493 	xpathRes = 0;
   25494 
   25495 	if (vctxt->xpathStates != NULL) {
   25496 	    /*
   25497 	    * Evaluate IDCs.
   25498 	    */
   25499 	    xpathRes = xmlSchemaXPathEvaluate(vctxt,
   25500 		XML_ATTRIBUTE_NODE);
   25501 	    if (xpathRes == -1) {
   25502 		VERROR_INT("xmlSchemaVAttributesComplex",
   25503 		    "calling xmlSchemaXPathEvaluate()");
   25504 		goto internal_error;
   25505 	    }
   25506 	}
   25507 
   25508 	if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
   25509 	    /*
   25510 	    * Default/fixed attributes.
   25511 	    * We need the value only if we need to resolve IDCs or
   25512 	    * will create default attributes.
   25513 	    */
   25514 	    if ((xpathRes) || (defAttrOwnerElem)) {
   25515 		if (iattr->use->defValue != NULL) {
   25516 		    iattr->value = (xmlChar *) iattr->use->defValue;
   25517 		    iattr->val = iattr->use->defVal;
   25518 		} else {
   25519 		    iattr->value = (xmlChar *) iattr->decl->defValue;
   25520 		    iattr->val = iattr->decl->defVal;
   25521 		}
   25522 		/*
   25523 		* IDCs will consume the precomputed default value,
   25524 		* so we need to clone it.
   25525 		*/
   25526 		if (iattr->val == NULL) {
   25527 		    VERROR_INT("xmlSchemaVAttributesComplex",
   25528 			"default/fixed value on an attribute use was "
   25529 			"not precomputed");
   25530 		    goto internal_error;
   25531 		}
   25532 		iattr->val = xmlSchemaCopyValue(iattr->val);
   25533 		if (iattr->val == NULL) {
   25534 		    VERROR_INT("xmlSchemaVAttributesComplex",
   25535 			"calling xmlSchemaCopyValue()");
   25536 		    goto internal_error;
   25537 		}
   25538 	    }
   25539 	    /*
   25540 	    * PSVI: Add the default attribute to the current element.
   25541 	    * VAL TODO: Should we use the *normalized* value? This currently
   25542 	    *   uses the *initial* value.
   25543 	    */
   25544 
   25545 	    if (defAttrOwnerElem) {
   25546 		xmlChar *normValue;
   25547 		const xmlChar *value;
   25548 
   25549 		value = iattr->value;
   25550 		/*
   25551 		* Normalize the value.
   25552 		*/
   25553 		normValue = xmlSchemaNormalizeValue(iattr->typeDef,
   25554 		    iattr->value);
   25555 		if (normValue != NULL)
   25556 		    value = BAD_CAST normValue;
   25557 
   25558 		if (iattr->nsName == NULL) {
   25559 		    if (xmlNewProp(defAttrOwnerElem,
   25560 			iattr->localName, value) == NULL) {
   25561 			VERROR_INT("xmlSchemaVAttributesComplex",
   25562 			    "calling xmlNewProp()");
   25563 			if (normValue != NULL)
   25564 			    xmlFree(normValue);
   25565 			goto internal_error;
   25566 		    }
   25567 		} else {
   25568 		    xmlNsPtr ns;
   25569 
   25570 		    ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
   25571 			defAttrOwnerElem, iattr->nsName);
   25572 		    if (ns == NULL) {
   25573 			xmlChar prefix[12];
   25574 			int counter = 0;
   25575 
   25576 			/*
   25577 			* Create a namespace declaration on the validation
   25578 			* root node if no namespace declaration is in scope.
   25579 			*/
   25580 			do {
   25581 			    snprintf((char *) prefix, 12, "p%d", counter++);
   25582 			    ns = xmlSearchNs(defAttrOwnerElem->doc,
   25583 				defAttrOwnerElem, BAD_CAST prefix);
   25584 			    if (counter > 1000) {
   25585 				VERROR_INT(
   25586 				    "xmlSchemaVAttributesComplex",
   25587 				    "could not compute a ns prefix for a "
   25588 				    "default/fixed attribute");
   25589 				if (normValue != NULL)
   25590 				    xmlFree(normValue);
   25591 				goto internal_error;
   25592 			    }
   25593 			} while (ns != NULL);
   25594 			ns = xmlNewNs(vctxt->validationRoot,
   25595 			    iattr->nsName, BAD_CAST prefix);
   25596 		    }
   25597 		    /*
   25598 		    * TODO:
   25599 		    * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
   25600 		    * If we have QNames: do we need to ensure there's a
   25601 		    * prefix defined for the QName?
   25602 		    */
   25603 		    xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
   25604 		}
   25605 		if (normValue != NULL)
   25606 		    xmlFree(normValue);
   25607 	    }
   25608 	    /*
   25609 	    * Go directly to IDC evaluation.
   25610 	    */
   25611 	    goto eval_idcs;
   25612 	}
   25613 	/*
   25614 	* Validate the value.
   25615 	*/
   25616 	if (vctxt->value != NULL) {
   25617 	    /*
   25618 	    * Free last computed value; just for safety reasons.
   25619 	    */
   25620 	    xmlSchemaFreeValue(vctxt->value);
   25621 	    vctxt->value = NULL;
   25622 	}
   25623 	/*
   25624 	* Note that the attribute *use* can be unavailable, if
   25625 	* the attribute was a wild attribute.
   25626 	*/
   25627 	if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
   25628 	    ((iattr->use != NULL) &&
   25629 	     (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
   25630 	    fixed = 1;
   25631 	else
   25632 	    fixed = 0;
   25633 	/*
   25634 	* SPEC (cvc-attribute)
   25635 	* (3) "The item's `normalized value` must be locally `valid`
   25636 	* with respect to that {type definition} as per
   25637 	* String Valid ($3.14.4)."
   25638 	*
   25639 	* VAL TODO: Do we already have the
   25640 	* "normalized attribute value" here?
   25641 	*/
   25642 	if (xpathRes || fixed) {
   25643 	    iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
   25644 	    /*
   25645 	    * Request a computed value.
   25646 	    */
   25647 	    res = xmlSchemaVCheckCVCSimpleType(
   25648 		ACTXT_CAST vctxt,
   25649 		iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
   25650 		1, 1, 0);
   25651 	} else {
   25652 	    res = xmlSchemaVCheckCVCSimpleType(
   25653 		ACTXT_CAST vctxt,
   25654 		iattr->node, iattr->typeDef, iattr->value, NULL,
   25655 		1, 0, 0);
   25656 	}
   25657 
   25658 	if (res != 0) {
   25659 	    if (res == -1) {
   25660 		VERROR_INT("xmlSchemaVAttributesComplex",
   25661 		    "calling xmlSchemaStreamValidateSimpleTypeValue()");
   25662 		goto internal_error;
   25663 	    }
   25664 	    iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
   25665 	    /*
   25666 	    * SPEC PSVI Assessment Outcome (Attribute)
   25667 	    * [validity] = "invalid"
   25668 	    */
   25669 	    goto eval_idcs;
   25670 	}
   25671 
   25672 	if (fixed) {
   25673 	    /*
   25674 	    * SPEC Attribute Locally Valid (Use) (cvc-au)
   25675 	    * "For an attribute information item to be `valid`
   25676 	    * with respect to an attribute use its *normalized*
   25677 	    * value must match the *canonical* lexical
   25678 	    * representation of the attribute use's {value
   25679 	    * constraint}value, if it is present and fixed."
   25680 	    *
   25681 	    * VAL TODO: The requirement for the *canonical* value
   25682 	    * will be removed in XML Schema 1.1.
   25683 	    */
   25684 	    /*
   25685 	    * SPEC Attribute Locally Valid (cvc-attribute)
   25686 	    * (4) "The item's *actual* value must match the *value* of
   25687 	    * the {value constraint}, if it is present and fixed."
   25688 	    */
   25689 	    if (iattr->val == NULL) {
   25690 		/* VAL TODO: A value was not precomputed. */
   25691 		TODO
   25692 		goto eval_idcs;
   25693 	    }
   25694 	    if ((iattr->use != NULL) &&
   25695 		(iattr->use->defValue != NULL)) {
   25696 		if (iattr->use->defVal == NULL) {
   25697 		    /* VAL TODO: A default value was not precomputed. */
   25698 		    TODO
   25699 		    goto eval_idcs;
   25700 		}
   25701 		iattr->vcValue = iattr->use->defValue;
   25702 		/*
   25703 		if (xmlSchemaCompareValuesWhtsp(attr->val,
   25704 		    (xmlSchemaWhitespaceValueType) ws,
   25705 		    attr->use->defVal,
   25706 		    (xmlSchemaWhitespaceValueType) ws) != 0) {
   25707 		*/
   25708 		if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
   25709 		    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
   25710 	    } else {
   25711 		if (iattr->decl->defVal == NULL) {
   25712 		    /* VAL TODO: A default value was not precomputed. */
   25713 		    TODO
   25714 		    goto eval_idcs;
   25715 		}
   25716 		iattr->vcValue = iattr->decl->defValue;
   25717 		/*
   25718 		if (xmlSchemaCompareValuesWhtsp(attr->val,
   25719 		    (xmlSchemaWhitespaceValueType) ws,
   25720 		    attrDecl->defVal,
   25721 		    (xmlSchemaWhitespaceValueType) ws) != 0) {
   25722 		*/
   25723 		if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
   25724 		    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
   25725 	    }
   25726 	    /*
   25727 	    * [validity] = "valid"
   25728 	    */
   25729 	}
   25730 eval_idcs:
   25731 	/*
   25732 	* Evaluate IDCs.
   25733 	*/
   25734 	if (xpathRes) {
   25735 	    if (xmlSchemaXPathProcessHistory(vctxt,
   25736 		vctxt->depth +1) == -1) {
   25737 		VERROR_INT("xmlSchemaVAttributesComplex",
   25738 		    "calling xmlSchemaXPathEvaluate()");
   25739 		goto internal_error;
   25740 	    }
   25741 	} else if (vctxt->xpathStates != NULL)
   25742 	    xmlSchemaXPathPop(vctxt);
   25743     }
   25744 
   25745     /*
   25746     * Report errors.
   25747     */
   25748     for (i = 0; i < vctxt->nbAttrInfos; i++) {
   25749 	iattr = vctxt->attrInfos[i];
   25750 	if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
   25751 	    (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
   25752 	    (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
   25753 	    (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
   25754 	    continue;
   25755 	ACTIVATE_ATTRIBUTE(iattr);
   25756 	switch (iattr->state) {
   25757 	    case XML_SCHEMAS_ATTR_ERR_MISSING: {
   25758 		    xmlChar *str = NULL;
   25759 		    ACTIVATE_ELEM;
   25760 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
   25761 			XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
   25762 			"The attribute '%s' is required but missing",
   25763 			xmlSchemaFormatQName(&str,
   25764 			    iattr->decl->targetNamespace,
   25765 			    iattr->decl->name),
   25766 			NULL);
   25767 		    FREE_AND_NULL(str)
   25768 		    break;
   25769 		}
   25770 	    case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
   25771 		VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
   25772 		    "The type definition is absent");
   25773 		break;
   25774 	    case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
   25775 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   25776 		    XML_SCHEMAV_CVC_AU, NULL, NULL,
   25777 		    "The value '%s' does not match the fixed "
   25778 		    "value constraint '%s'",
   25779 		    iattr->value, iattr->vcValue);
   25780 		break;
   25781 	    case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
   25782 		VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
   25783 		    "No matching global attribute declaration available, but "
   25784 		    "demanded by the strict wildcard");
   25785 		break;
   25786 	    case XML_SCHEMAS_ATTR_UNKNOWN:
   25787 		if (iattr->metaType)
   25788 		    break;
   25789 		/*
   25790 		* MAYBE VAL TODO: One might report different error messages
   25791 		* for the following errors.
   25792 		*/
   25793 		if (type->attributeWildcard == NULL) {
   25794 		    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
   25795 			XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
   25796 		} else {
   25797 		    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
   25798 			XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
   25799 		}
   25800 		break;
   25801 	    default:
   25802 		break;
   25803 	}
   25804     }
   25805 
   25806     ACTIVATE_ELEM;
   25807     return (0);
   25808 internal_error:
   25809     ACTIVATE_ELEM;
   25810     return (-1);
   25811 }
   25812 
   25813 static int
   25814 xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
   25815 			      int *skip)
   25816 {
   25817     xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
   25818     /*
   25819     * The namespace of the element was already identified to be
   25820     * matching the wildcard.
   25821     */
   25822     if ((skip == NULL) || (wild == NULL) ||
   25823 	(wild->type != XML_SCHEMA_TYPE_ANY)) {
   25824 	VERROR_INT("xmlSchemaValidateElemWildcard",
   25825 	    "bad arguments");
   25826 	return (-1);
   25827     }
   25828     *skip = 0;
   25829     if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
   25830 	/*
   25831 	* URGENT VAL TODO: Either we need to position the stream to the
   25832 	* next sibling, or walk the whole subtree.
   25833 	*/
   25834 	*skip = 1;
   25835 	return (0);
   25836     }
   25837     {
   25838 	xmlSchemaElementPtr decl = NULL;
   25839 
   25840 	decl = xmlSchemaGetElem(vctxt->schema,
   25841 	    vctxt->inode->localName, vctxt->inode->nsName);
   25842 	if (decl != NULL) {
   25843 	    vctxt->inode->decl = decl;
   25844 	    return (0);
   25845 	}
   25846     }
   25847     if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
   25848 	/* VAL TODO: Change to proper error code. */
   25849 	VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
   25850 	    "No matching global element declaration available, but "
   25851 	    "demanded by the strict wildcard");
   25852 	return (vctxt->err);
   25853     }
   25854     if (vctxt->nbAttrInfos != 0) {
   25855 	xmlSchemaAttrInfoPtr iattr;
   25856 	/*
   25857 	* SPEC Validation Rule: Schema-Validity Assessment (Element)
   25858 	* (1.2.1.2.1) - (1.2.1.2.3 )
   25859 	*
   25860 	* Use the xsi:type attribute for the type definition.
   25861 	*/
   25862 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   25863 	    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
   25864 	if (iattr != NULL) {
   25865 	    if (xmlSchemaProcessXSIType(vctxt, iattr,
   25866 		&(vctxt->inode->typeDef), NULL) == -1) {
   25867 		VERROR_INT("xmlSchemaValidateElemWildcard",
   25868 		    "calling xmlSchemaProcessXSIType() to "
   25869 		    "process the attribute 'xsi:nil'");
   25870 		return (-1);
   25871 	    }
   25872 	    /*
   25873 	    * Don't return an error on purpose.
   25874 	    */
   25875 	    return (0);
   25876 	}
   25877     }
   25878     /*
   25879     * SPEC Validation Rule: Schema-Validity Assessment (Element)
   25880     *
   25881     * Fallback to "anyType".
   25882     */
   25883     vctxt->inode->typeDef =
   25884 	xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
   25885     return (0);
   25886 }
   25887 
   25888 /*
   25889 * xmlSchemaCheckCOSValidDefault:
   25890 *
   25891 * This will be called if: not nilled, no content and a default/fixed
   25892 * value is provided.
   25893 */
   25894 
   25895 static int
   25896 xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
   25897 			      const xmlChar *value,
   25898 			      xmlSchemaValPtr *val)
   25899 {
   25900     int ret = 0;
   25901     xmlSchemaNodeInfoPtr inode = vctxt->inode;
   25902 
   25903     /*
   25904     * cos-valid-default:
   25905     * Schema Component Constraint: Element Default Valid (Immediate)
   25906     * For a string to be a valid default with respect to a type
   25907     * definition the appropriate case among the following must be true:
   25908     */
   25909     if WXS_IS_COMPLEX(inode->typeDef) {
   25910 	/*
   25911 	* Complex type.
   25912 	*
   25913 	* SPEC (2.1) "its {content type} must be a simple type definition
   25914 	* or mixed."
   25915 	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
   25916 	* type}'s particle must be `emptiable` as defined by
   25917 	* Particle Emptiable ($3.9.6)."
   25918 	*/
   25919 	if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
   25920 	    ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
   25921 	     (! WXS_EMPTIABLE(inode->typeDef)))) {
   25922 	    ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
   25923 	    /* NOTE that this covers (2.2.2) as well. */
   25924 	    VERROR(ret, NULL,
   25925 		"For a string to be a valid default, the type definition "
   25926 		"must be a simple type or a complex type with simple content "
   25927 		"or mixed content and a particle emptiable");
   25928 	    return(ret);
   25929 	}
   25930     }
   25931     /*
   25932     * 1 If the type definition is a simple type definition, then the string
   25933     * must be `valid` with respect to that definition as defined by String
   25934     * Valid ($3.14.4).
   25935     *
   25936     * AND
   25937     *
   25938     * 2.2.1 If the {content type} is a simple type definition, then the
   25939     * string must be `valid` with respect to that simple type definition
   25940     * as defined by String Valid ($3.14.4).
   25941     */
   25942     if (WXS_IS_SIMPLE(inode->typeDef)) {
   25943 
   25944 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
   25945 	    NULL, inode->typeDef, value, val, 1, 1, 0);
   25946 
   25947     } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   25948 
   25949 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
   25950 	    NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
   25951     }
   25952     if (ret < 0) {
   25953 	VERROR_INT("xmlSchemaCheckCOSValidDefault",
   25954 	    "calling xmlSchemaVCheckCVCSimpleType()");
   25955     }
   25956     return (ret);
   25957 }
   25958 
   25959 static void
   25960 xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
   25961 			       const xmlChar * name ATTRIBUTE_UNUSED,
   25962 			       xmlSchemaElementPtr item,
   25963 			       xmlSchemaNodeInfoPtr inode)
   25964 {
   25965     inode->decl = item;
   25966 #ifdef DEBUG_CONTENT
   25967     {
   25968 	xmlChar *str = NULL;
   25969 
   25970 	if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
   25971 	    xmlGenericError(xmlGenericErrorContext,
   25972 		"AUTOMATON callback for '%s' [declaration]\n",
   25973 		xmlSchemaFormatQName(&str,
   25974 		inode->localName, inode->nsName));
   25975 	} else {
   25976 	    xmlGenericError(xmlGenericErrorContext,
   25977 		    "AUTOMATON callback for '%s' [wildcard]\n",
   25978 		    xmlSchemaFormatQName(&str,
   25979 		    inode->localName, inode->nsName));
   25980 
   25981 	}
   25982 	FREE_AND_NULL(str)
   25983     }
   25984 #endif
   25985 }
   25986 
   25987 static int
   25988 xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
   25989 {
   25990     vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
   25991     if (vctxt->inode == NULL) {
   25992 	VERROR_INT("xmlSchemaValidatorPushElem",
   25993 	    "calling xmlSchemaGetFreshElemInfo()");
   25994 	return (-1);
   25995     }
   25996     vctxt->nbAttrInfos = 0;
   25997     return (0);
   25998 }
   25999 
   26000 static int
   26001 xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
   26002 			     xmlSchemaNodeInfoPtr inode,
   26003 			     xmlSchemaTypePtr type,
   26004 			     const xmlChar *value)
   26005 {
   26006     if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
   26007 	return (xmlSchemaVCheckCVCSimpleType(
   26008 	    ACTXT_CAST vctxt, NULL,
   26009 	    type, value, &(inode->val), 1, 1, 0));
   26010     else
   26011 	return (xmlSchemaVCheckCVCSimpleType(
   26012 	    ACTXT_CAST vctxt, NULL,
   26013 	    type, value, NULL, 1, 0, 0));
   26014 }
   26015 
   26016 
   26017 
   26018 /*
   26019 * Process END of element.
   26020 */
   26021 static int
   26022 xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
   26023 {
   26024     int ret = 0;
   26025     xmlSchemaNodeInfoPtr inode = vctxt->inode;
   26026 
   26027     if (vctxt->nbAttrInfos != 0)
   26028 	xmlSchemaClearAttrInfos(vctxt);
   26029     if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
   26030 	/*
   26031 	* This element was not expected;
   26032 	* we will not validate child elements of broken parents.
   26033 	* Skip validation of all content of the parent.
   26034 	*/
   26035 	vctxt->skipDepth = vctxt->depth -1;
   26036 	goto end_elem;
   26037     }
   26038     if ((inode->typeDef == NULL) ||
   26039 	(inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
   26040 	/*
   26041 	* 1. the type definition might be missing if the element was
   26042 	*    error prone
   26043 	* 2. it might be abstract.
   26044 	*/
   26045 	goto end_elem;
   26046     }
   26047     /*
   26048     * Check the content model.
   26049     */
   26050     if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
   26051 	(inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
   26052 
   26053 	/*
   26054 	* Workaround for "anyType".
   26055 	*/
   26056 	if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
   26057 	    goto character_content;
   26058 
   26059 	if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
   26060 	    xmlChar *values[10];
   26061 	    int terminal, nbval = 10, nbneg;
   26062 
   26063 	    if (inode->regexCtxt == NULL) {
   26064 		/*
   26065 		* Create the regex context.
   26066 		*/
   26067 		inode->regexCtxt =
   26068 		    xmlRegNewExecCtxt(inode->typeDef->contModel,
   26069 		    (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
   26070 		    vctxt);
   26071 		if (inode->regexCtxt == NULL) {
   26072 		    VERROR_INT("xmlSchemaValidatorPopElem",
   26073 			"failed to create a regex context");
   26074 		    goto internal_error;
   26075 		}
   26076 #ifdef DEBUG_AUTOMATA
   26077 		xmlGenericError(xmlGenericErrorContext,
   26078 		    "AUTOMATON create on '%s'\n", inode->localName);
   26079 #endif
   26080 	    }
   26081 
   26082 	    /*
   26083 	     * Do not check further content if the node has been nilled
   26084 	     */
   26085 	    if (INODE_NILLED(inode)) {
   26086 		ret = 0;
   26087 #ifdef DEBUG_AUTOMATA
   26088 		xmlGenericError(xmlGenericErrorContext,
   26089 		    "AUTOMATON succeeded on nilled '%s'\n",
   26090 		    inode->localName);
   26091 #endif
   26092                 goto skip_nilled;
   26093 	    }
   26094 
   26095 	    /*
   26096 	    * Get hold of the still expected content, since a further
   26097 	    * call to xmlRegExecPushString() will loose this information.
   26098 	    */
   26099 	    xmlRegExecNextValues(inode->regexCtxt,
   26100 		&nbval, &nbneg, &values[0], &terminal);
   26101 	    ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
   26102 	    if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
   26103 		/*
   26104 		* Still missing something.
   26105 		*/
   26106 		ret = 1;
   26107 		inode->flags |=
   26108 		    XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
   26109 		xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
   26110 		    XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
   26111 		    "Missing child element(s)",
   26112 		    nbval, nbneg, values);
   26113 #ifdef DEBUG_AUTOMATA
   26114 		xmlGenericError(xmlGenericErrorContext,
   26115 		    "AUTOMATON missing ERROR on '%s'\n",
   26116 		    inode->localName);
   26117 #endif
   26118 	    } else {
   26119 		/*
   26120 		* Content model is satisfied.
   26121 		*/
   26122 		ret = 0;
   26123 #ifdef DEBUG_AUTOMATA
   26124 		xmlGenericError(xmlGenericErrorContext,
   26125 		    "AUTOMATON succeeded on '%s'\n",
   26126 		    inode->localName);
   26127 #endif
   26128 	    }
   26129 
   26130 	}
   26131     }
   26132 
   26133 skip_nilled:
   26134 
   26135     if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
   26136 	goto end_elem;
   26137 
   26138 character_content:
   26139 
   26140     if (vctxt->value != NULL) {
   26141 	xmlSchemaFreeValue(vctxt->value);
   26142 	vctxt->value = NULL;
   26143     }
   26144     /*
   26145     * Check character content.
   26146     */
   26147     if (inode->decl == NULL) {
   26148 	/*
   26149 	* Speedup if no declaration exists.
   26150 	*/
   26151 	if (WXS_IS_SIMPLE(inode->typeDef)) {
   26152 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26153 		inode, inode->typeDef, inode->value);
   26154 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   26155 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26156 		inode, inode->typeDef->contentTypeDef,
   26157 		inode->value);
   26158 	}
   26159 	if (ret < 0) {
   26160 	    VERROR_INT("xmlSchemaValidatorPopElem",
   26161 		"calling xmlSchemaVCheckCVCSimpleType()");
   26162 	    goto internal_error;
   26163 	}
   26164 	goto end_elem;
   26165     }
   26166     /*
   26167     * cvc-elt (3.3.4) : 5
   26168     * The appropriate case among the following must be true:
   26169     */
   26170     /*
   26171     * cvc-elt (3.3.4) : 5.1
   26172     * If the declaration has a {value constraint},
   26173     * the item has neither element nor character [children] and
   26174     * clause 3.2 has not applied, then all of the following must be true:
   26175     */
   26176     if ((inode->decl->value != NULL) &&
   26177 	(inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
   26178 	(! INODE_NILLED(inode))) {
   26179 	/*
   26180 	* cvc-elt (3.3.4) : 5.1.1
   26181 	* If the `actual type definition` is a `local type definition`
   26182 	* then the canonical lexical representation of the {value constraint}
   26183 	* value must be a valid default for the `actual type definition` as
   26184 	* defined in Element Default Valid (Immediate) ($3.3.6).
   26185 	*/
   26186 	/*
   26187 	* NOTE: 'local' above means types acquired by xsi:type.
   26188 	* NOTE: Although the *canonical* value is stated, it is not
   26189 	* relevant if canonical or not. Additionally XML Schema 1.1
   26190 	* will removed this requirement as well.
   26191 	*/
   26192 	if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
   26193 
   26194 	    ret = xmlSchemaCheckCOSValidDefault(vctxt,
   26195 		inode->decl->value, &(inode->val));
   26196 	    if (ret != 0) {
   26197 		if (ret < 0) {
   26198 		    VERROR_INT("xmlSchemaValidatorPopElem",
   26199 			"calling xmlSchemaCheckCOSValidDefault()");
   26200 		    goto internal_error;
   26201 		}
   26202 		goto end_elem;
   26203 	    }
   26204 	    /*
   26205 	    * Stop here, to avoid redundant validation of the value
   26206 	    * (see following).
   26207 	    */
   26208 	    goto default_psvi;
   26209 	}
   26210 	/*
   26211 	* cvc-elt (3.3.4) : 5.1.2
   26212 	* The element information item with the canonical lexical
   26213 	* representation of the {value constraint} value used as its
   26214 	* `normalized value` must be `valid` with respect to the
   26215 	* `actual type definition` as defined by Element Locally Valid (Type)
   26216 	* ($3.3.4).
   26217 	*/
   26218 	if (WXS_IS_SIMPLE(inode->typeDef)) {
   26219 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26220 		inode, inode->typeDef, inode->decl->value);
   26221 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   26222 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26223 		inode, inode->typeDef->contentTypeDef,
   26224 		inode->decl->value);
   26225 	}
   26226 	if (ret != 0) {
   26227 	    if (ret < 0) {
   26228 		VERROR_INT("xmlSchemaValidatorPopElem",
   26229 		    "calling xmlSchemaVCheckCVCSimpleType()");
   26230 		goto internal_error;
   26231 	    }
   26232 	    goto end_elem;
   26233 	}
   26234 
   26235 default_psvi:
   26236 	/*
   26237 	* PSVI: Create a text node on the instance element.
   26238 	*/
   26239 	if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
   26240 	    (inode->node != NULL)) {
   26241 	    xmlNodePtr textChild;
   26242 	    xmlChar *normValue;
   26243 	    /*
   26244 	    * VAL TODO: Normalize the value.
   26245 	    */
   26246 	    normValue = xmlSchemaNormalizeValue(inode->typeDef,
   26247 		inode->decl->value);
   26248 	    if (normValue != NULL) {
   26249 		textChild = xmlNewText(BAD_CAST normValue);
   26250 		xmlFree(normValue);
   26251 	    } else
   26252 		textChild = xmlNewText(inode->decl->value);
   26253 	    if (textChild == NULL) {
   26254 		VERROR_INT("xmlSchemaValidatorPopElem",
   26255 		    "calling xmlNewText()");
   26256 		goto internal_error;
   26257 	    } else
   26258 		xmlAddChild(inode->node, textChild);
   26259 	}
   26260 
   26261     } else if (! INODE_NILLED(inode)) {
   26262 	/*
   26263 	* 5.2.1 The element information item must be `valid` with respect
   26264 	* to the `actual type definition` as defined by Element Locally
   26265 	* Valid (Type) ($3.3.4).
   26266 	*/
   26267 	if (WXS_IS_SIMPLE(inode->typeDef)) {
   26268 	     /*
   26269 	    * SPEC (cvc-type) (3.1)
   26270 	    * "If the type definition is a simple type definition, ..."
   26271 	    * (3.1.3) "If clause 3.2 of Element Locally Valid
   26272 	    * (Element) ($3.3.4) did not apply, then the `normalized value`
   26273 	    * must be `valid` with respect to the type definition as defined
   26274 	    * by String Valid ($3.14.4).
   26275 	    */
   26276 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26277 		    inode, inode->typeDef, inode->value);
   26278 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   26279 	    /*
   26280 	    * SPEC (cvc-type) (3.2) "If the type definition is a complex type
   26281 	    * definition, then the element information item must be
   26282 	    * `valid` with respect to the type definition as per
   26283 	    * Element Locally Valid (Complex Type) ($3.4.4);"
   26284 	    *
   26285 	    * SPEC (cvc-complex-type) (2.2)
   26286 	    * "If the {content type} is a simple type definition, ...
   26287 	    * the `normalized value` of the element information item is
   26288 	    * `valid` with respect to that simple type definition as
   26289 	    * defined by String Valid ($3.14.4)."
   26290 	    */
   26291 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26292 		inode, inode->typeDef->contentTypeDef, inode->value);
   26293 	}
   26294 	if (ret != 0) {
   26295 	    if (ret < 0) {
   26296 		VERROR_INT("xmlSchemaValidatorPopElem",
   26297 		    "calling xmlSchemaVCheckCVCSimpleType()");
   26298 		goto internal_error;
   26299 	    }
   26300 	    goto end_elem;
   26301 	}
   26302 	/*
   26303 	* 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
   26304 	* not applied, all of the following must be true:
   26305 	*/
   26306 	if ((inode->decl->value != NULL) &&
   26307 	    (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
   26308 
   26309 	    /*
   26310 	    * TODO: We will need a computed value, when comparison is
   26311 	    * done on computed values.
   26312 	    */
   26313 	    /*
   26314 	    * 5.2.2.1 The element information item must have no element
   26315 	    * information item [children].
   26316 	    */
   26317 	    if (inode->flags &
   26318 		    XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
   26319 		ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
   26320 		VERROR(ret, NULL,
   26321 		    "The content must not containt element nodes since "
   26322 		    "there is a fixed value constraint");
   26323 		goto end_elem;
   26324 	    } else {
   26325 		/*
   26326 		* 5.2.2.2 The appropriate case among the following must
   26327 		* be true:
   26328 		*/
   26329 		if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
   26330 		    /*
   26331 		    * 5.2.2.2.1 If the {content type} of the `actual type
   26332 		    * definition` is mixed, then the *initial value* of the
   26333 		    * item must match the canonical lexical representation
   26334 		    * of the {value constraint} value.
   26335 		    *
   26336 		    * ... the *initial value* of an element information
   26337 		    * item is the string composed of, in order, the
   26338 		    * [character code] of each character information item in
   26339 		    * the [children] of that element information item.
   26340 		    */
   26341 		    if (! xmlStrEqual(inode->value, inode->decl->value)){
   26342 			/*
   26343 			* VAL TODO: Report invalid & expected values as well.
   26344 			* VAL TODO: Implement the canonical stuff.
   26345 			*/
   26346 			ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
   26347 			xmlSchemaCustomErr(ACTXT_CAST vctxt,
   26348 			    ret, NULL, NULL,
   26349 			    "The initial value '%s' does not match the fixed "
   26350 			    "value constraint '%s'",
   26351 			    inode->value, inode->decl->value);
   26352 			goto end_elem;
   26353 		    }
   26354 		} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   26355 		    /*
   26356 		    * 5.2.2.2.2 If the {content type} of the `actual type
   26357 		    * definition` is a simple type definition, then the
   26358 		    * *actual value* of the item must match the canonical
   26359 		    * lexical representation of the {value constraint} value.
   26360 		    */
   26361 		    /*
   26362 		    * VAL TODO: *actual value* is the normalized value, impl.
   26363 		    *           this.
   26364 		    * VAL TODO: Report invalid & expected values as well.
   26365 		    * VAL TODO: Implement a comparison with the computed values.
   26366 		    */
   26367 		    if (! xmlStrEqual(inode->value,
   26368 			    inode->decl->value)) {
   26369 			ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
   26370 			xmlSchemaCustomErr(ACTXT_CAST vctxt,
   26371 			    ret, NULL, NULL,
   26372 			    "The actual value '%s' does not match the fixed "
   26373 			    "value constraint '%s'",
   26374 			    inode->value,
   26375 			    inode->decl->value);
   26376 			goto end_elem;
   26377 		    }
   26378 		}
   26379 	    }
   26380 	}
   26381     }
   26382 
   26383 end_elem:
   26384     if (vctxt->depth < 0) {
   26385 	/* TODO: raise error? */
   26386 	return (0);
   26387     }
   26388     if (vctxt->depth == vctxt->skipDepth)
   26389 	vctxt->skipDepth = -1;
   26390     /*
   26391     * Evaluate the history of XPath state objects.
   26392     */
   26393     if (inode->appliedXPath &&
   26394 	(xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
   26395 	goto internal_error;
   26396     /*
   26397     * MAYBE TODO:
   26398     * SPEC (6) "The element information item must be `valid` with
   26399     * respect to each of the {identity-constraint definitions} as per
   26400     * Identity-constraint Satisfied ($3.11.4)."
   26401     */
   26402     /*
   26403     * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
   26404     *   need to be built in any case.
   26405     *   We will currently build IDC node-tables and bubble them only if
   26406     *   keyrefs do exist.
   26407     */
   26408 
   26409     /*
   26410     * Add the current IDC target-nodes to the IDC node-tables.
   26411     */
   26412     if ((inode->idcMatchers != NULL) &&
   26413 	(vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
   26414     {
   26415 	if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
   26416 	    goto internal_error;
   26417     }
   26418     /*
   26419     * Validate IDC keyrefs.
   26420     */
   26421     if (vctxt->inode->hasKeyrefs)
   26422 	if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
   26423 	    goto internal_error;
   26424     /*
   26425     * Merge/free the IDC table.
   26426     */
   26427     if (inode->idcTable != NULL) {
   26428 #ifdef DEBUG_IDC_NODE_TABLE
   26429 	xmlSchemaDebugDumpIDCTable(stdout,
   26430 	    inode->nsName,
   26431 	    inode->localName,
   26432 	    inode->idcTable);
   26433 #endif
   26434 	if ((vctxt->depth > 0) &&
   26435 	    (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
   26436 	{
   26437 	    /*
   26438 	    * Merge the IDC node table with the table of the parent node.
   26439 	    */
   26440 	    if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
   26441 		goto internal_error;
   26442 	}
   26443     }
   26444     /*
   26445     * Clear the current ielem.
   26446     * VAL TODO: Don't free the PSVI IDC tables if they are
   26447     * requested for the PSVI.
   26448     */
   26449     xmlSchemaClearElemInfo(vctxt, inode);
   26450     /*
   26451     * Skip further processing if we are on the validation root.
   26452     */
   26453     if (vctxt->depth == 0) {
   26454 	vctxt->depth--;
   26455 	vctxt->inode = NULL;
   26456 	return (0);
   26457     }
   26458     /*
   26459     * Reset the keyrefDepth if needed.
   26460     */
   26461     if (vctxt->aidcs != NULL) {
   26462 	xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
   26463 	do {
   26464 	    if (aidc->keyrefDepth == vctxt->depth) {
   26465 		/*
   26466 		* A 'keyrefDepth' of a key/unique IDC matches the current
   26467 		* depth, this means that we are leaving the scope of the
   26468 		* top-most keyref IDC which refers to this IDC.
   26469 		*/
   26470 		aidc->keyrefDepth = -1;
   26471 	    }
   26472 	    aidc = aidc->next;
   26473 	} while (aidc != NULL);
   26474     }
   26475     vctxt->depth--;
   26476     vctxt->inode = vctxt->elemInfos[vctxt->depth];
   26477     /*
   26478     * VAL TODO: 7 If the element information item is the `validation root`, it must be
   26479     * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
   26480     */
   26481     return (ret);
   26482 
   26483 internal_error:
   26484     vctxt->err = -1;
   26485     return (-1);
   26486 }
   26487 
   26488 /*
   26489 * 3.4.4 Complex Type Definition Validation Rules
   26490 * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
   26491 */
   26492 static int
   26493 xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
   26494 {
   26495     xmlSchemaNodeInfoPtr pielem;
   26496     xmlSchemaTypePtr ptype;
   26497     int ret = 0;
   26498 
   26499     if (vctxt->depth <= 0) {
   26500 	VERROR_INT("xmlSchemaValidateChildElem",
   26501 	    "not intended for the validation root");
   26502 	return (-1);
   26503     }
   26504     pielem = vctxt->elemInfos[vctxt->depth -1];
   26505     if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
   26506 	pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
   26507     /*
   26508     * Handle 'nilled' elements.
   26509     */
   26510     if (INODE_NILLED(pielem)) {
   26511 	/*
   26512 	* SPEC (cvc-elt) (3.3.4) : (3.2.1)
   26513 	*/
   26514 	ACTIVATE_PARENT_ELEM;
   26515 	ret = XML_SCHEMAV_CVC_ELT_3_2_1;
   26516 	VERROR(ret, NULL,
   26517 	    "Neither character nor element content is allowed, "
   26518 	    "because the element was 'nilled'");
   26519 	ACTIVATE_ELEM;
   26520 	goto unexpected_elem;
   26521     }
   26522 
   26523     ptype = pielem->typeDef;
   26524 
   26525     if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
   26526 	/*
   26527 	* Workaround for "anyType": we have currently no content model
   26528 	* assigned for "anyType", so handle it explicitely.
   26529 	* "anyType" has an unbounded, lax "any" wildcard.
   26530 	*/
   26531 	vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
   26532 	    vctxt->inode->localName,
   26533 	    vctxt->inode->nsName);
   26534 
   26535 	if (vctxt->inode->decl == NULL) {
   26536 	    xmlSchemaAttrInfoPtr iattr;
   26537 	    /*
   26538 	    * Process "xsi:type".
   26539 	    * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
   26540 	    */
   26541 	    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   26542 		XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
   26543 	    if (iattr != NULL) {
   26544 		ret = xmlSchemaProcessXSIType(vctxt, iattr,
   26545 		    &(vctxt->inode->typeDef), NULL);
   26546 		if (ret != 0) {
   26547 		    if (ret == -1) {
   26548 			VERROR_INT("xmlSchemaValidateChildElem",
   26549 			    "calling xmlSchemaProcessXSIType() to "
   26550 			    "process the attribute 'xsi:nil'");
   26551 			return (-1);
   26552 		    }
   26553 		    return (ret);
   26554 		}
   26555 	    } else {
   26556 		 /*
   26557 		 * Fallback to "anyType".
   26558 		 *
   26559 		 * SPEC (cvc-assess-elt)
   26560 		 * "If the item cannot be `strictly assessed`, [...]
   26561 		 * an element information item's schema validity may be laxly
   26562 		 * assessed if its `context-determined declaration` is not
   26563 		 * skip by `validating` with respect to the `ur-type
   26564 		 * definition` as per Element Locally Valid (Type) ($3.3.4)."
   26565 		*/
   26566 		vctxt->inode->typeDef =
   26567 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
   26568 	    }
   26569 	}
   26570 	return (0);
   26571     }
   26572 
   26573     switch (ptype->contentType) {
   26574 	case XML_SCHEMA_CONTENT_EMPTY:
   26575 	    /*
   26576 	    * SPEC (2.1) "If the {content type} is empty, then the
   26577 	    * element information item has no character or element
   26578 	    * information item [children]."
   26579 	    */
   26580 	    ACTIVATE_PARENT_ELEM
   26581 	    ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
   26582 	    VERROR(ret, NULL,
   26583 		"Element content is not allowed, "
   26584 		"because the content type is empty");
   26585 	    ACTIVATE_ELEM
   26586 	    goto unexpected_elem;
   26587 	    break;
   26588 
   26589 	case XML_SCHEMA_CONTENT_MIXED:
   26590         case XML_SCHEMA_CONTENT_ELEMENTS: {
   26591 	    xmlRegExecCtxtPtr regexCtxt;
   26592 	    xmlChar *values[10];
   26593 	    int terminal, nbval = 10, nbneg;
   26594 
   26595 	    /* VAL TODO: Optimized "anyType" validation.*/
   26596 
   26597 	    if (ptype->contModel == NULL) {
   26598 		VERROR_INT("xmlSchemaValidateChildElem",
   26599 		    "type has elem content but no content model");
   26600 		return (-1);
   26601 	    }
   26602 	    /*
   26603 	    * Safety belf for evaluation if the cont. model was already
   26604 	    * examined to be invalid.
   26605 	    */
   26606 	    if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
   26607 		VERROR_INT("xmlSchemaValidateChildElem",
   26608 		    "validating elem, but elem content is already invalid");
   26609 		return (-1);
   26610 	    }
   26611 
   26612 	    regexCtxt = pielem->regexCtxt;
   26613 	    if (regexCtxt == NULL) {
   26614 		/*
   26615 		* Create the regex context.
   26616 		*/
   26617 		regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
   26618 		    (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
   26619 		    vctxt);
   26620 		if (regexCtxt == NULL) {
   26621 		    VERROR_INT("xmlSchemaValidateChildElem",
   26622 			"failed to create a regex context");
   26623 		    return (-1);
   26624 		}
   26625 		pielem->regexCtxt = regexCtxt;
   26626 #ifdef DEBUG_AUTOMATA
   26627 		xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
   26628 		    pielem->localName);
   26629 #endif
   26630 	    }
   26631 
   26632 	    /*
   26633 	    * SPEC (2.4) "If the {content type} is element-only or mixed,
   26634 	    * then the sequence of the element information item's
   26635 	    * element information item [children], if any, taken in
   26636 	    * order, is `valid` with respect to the {content type}'s
   26637 	    * particle, as defined in Element Sequence Locally Valid
   26638 	    * (Particle) ($3.9.4)."
   26639 	    */
   26640 	    ret = xmlRegExecPushString2(regexCtxt,
   26641 		vctxt->inode->localName,
   26642 		vctxt->inode->nsName,
   26643 		vctxt->inode);
   26644 #ifdef DEBUG_AUTOMATA
   26645 	    if (ret < 0)
   26646 		xmlGenericError(xmlGenericErrorContext,
   26647 		"AUTOMATON push ERROR for '%s' on '%s'\n",
   26648 		vctxt->inode->localName, pielem->localName);
   26649 	    else
   26650 		xmlGenericError(xmlGenericErrorContext,
   26651 		"AUTOMATON push OK for '%s' on '%s'\n",
   26652 		vctxt->inode->localName, pielem->localName);
   26653 #endif
   26654 	    if (vctxt->err == XML_SCHEMAV_INTERNAL) {
   26655 		VERROR_INT("xmlSchemaValidateChildElem",
   26656 		    "calling xmlRegExecPushString2()");
   26657 		return (-1);
   26658 	    }
   26659 	    if (ret < 0) {
   26660 		xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
   26661 		    &values[0], &terminal);
   26662 		xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
   26663 		    XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
   26664 		    "This element is not expected",
   26665 		    nbval, nbneg, values);
   26666 		ret = vctxt->err;
   26667 		goto unexpected_elem;
   26668 	    } else
   26669 		ret = 0;
   26670 	}
   26671 	    break;
   26672 	case XML_SCHEMA_CONTENT_SIMPLE:
   26673 	case XML_SCHEMA_CONTENT_BASIC:
   26674 	    ACTIVATE_PARENT_ELEM
   26675 	    if (WXS_IS_COMPLEX(ptype)) {
   26676 		/*
   26677 		* SPEC (cvc-complex-type) (2.2)
   26678 		* "If the {content type} is a simple type definition, then
   26679 		* the element information item has no element information
   26680 		* item [children], ..."
   26681 		*/
   26682 		ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
   26683 		VERROR(ret, NULL, "Element content is not allowed, "
   26684 		    "because the content type is a simple type definition");
   26685 	    } else {
   26686 		/*
   26687 		* SPEC (cvc-type) (3.1.2) "The element information item must
   26688 		* have no element information item [children]."
   26689 		*/
   26690 		ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
   26691 		VERROR(ret, NULL, "Element content is not allowed, "
   26692 		    "because the type definition is simple");
   26693 	    }
   26694 	    ACTIVATE_ELEM
   26695 	    ret = vctxt->err;
   26696 	    goto unexpected_elem;
   26697 	    break;
   26698 
   26699 	default:
   26700 	    break;
   26701     }
   26702     return (ret);
   26703 unexpected_elem:
   26704     /*
   26705     * Pop this element and set the skipDepth to skip
   26706     * all further content of the parent element.
   26707     */
   26708     vctxt->skipDepth = vctxt->depth;
   26709     vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
   26710     pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
   26711     return (ret);
   26712 }
   26713 
   26714 #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
   26715 #define XML_SCHEMA_PUSH_TEXT_CREATED 2
   26716 #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
   26717 
   26718 static int
   26719 xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
   26720 		  int nodeType, const xmlChar *value, int len,
   26721 		  int mode, int *consumed)
   26722 {
   26723     /*
   26724     * Unfortunately we have to duplicate the text sometimes.
   26725     * OPTIMIZE: Maybe we could skip it, if:
   26726     *   1. content type is simple
   26727     *   2. whitespace is "collapse"
   26728     *   3. it consists of whitespace only
   26729     *
   26730     * Process character content.
   26731     */
   26732     if (consumed != NULL)
   26733 	*consumed = 0;
   26734     if (INODE_NILLED(vctxt->inode)) {
   26735 	/*
   26736 	* SPEC cvc-elt (3.3.4 - 3.2.1)
   26737 	* "The element information item must have no character or
   26738 	* element information item [children]."
   26739 	*/
   26740 	VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
   26741 	    "Neither character nor element content is allowed "
   26742 	    "because the element is 'nilled'");
   26743 	return (vctxt->err);
   26744     }
   26745     /*
   26746     * SPEC (2.1) "If the {content type} is empty, then the
   26747     * element information item has no character or element
   26748     * information item [children]."
   26749     */
   26750     if (vctxt->inode->typeDef->contentType ==
   26751 	    XML_SCHEMA_CONTENT_EMPTY) {
   26752 	VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
   26753 	    "Character content is not allowed, "
   26754 	    "because the content type is empty");
   26755 	return (vctxt->err);
   26756     }
   26757 
   26758     if (vctxt->inode->typeDef->contentType ==
   26759 	    XML_SCHEMA_CONTENT_ELEMENTS) {
   26760 	if ((nodeType != XML_TEXT_NODE) ||
   26761 	    (! xmlSchemaIsBlank((xmlChar *) value, len))) {
   26762 	    /*
   26763 	    * SPEC cvc-complex-type (2.3)
   26764 	    * "If the {content type} is element-only, then the
   26765 	    * element information item has no character information
   26766 	    * item [children] other than those whose [character
   26767 	    * code] is defined as a white space in [XML 1.0 (Second
   26768 	    * Edition)]."
   26769 	    */
   26770 	    VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
   26771 		"Character content other than whitespace is not allowed "
   26772 		"because the content type is 'element-only'");
   26773 	    return (vctxt->err);
   26774 	}
   26775 	return (0);
   26776     }
   26777 
   26778     if ((value == NULL) || (value[0] == 0))
   26779 	return (0);
   26780     /*
   26781     * Save the value.
   26782     * NOTE that even if the content type is *mixed*, we need the
   26783     * *initial value* for default/fixed value constraints.
   26784     */
   26785     if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
   26786 	((vctxt->inode->decl == NULL) ||
   26787 	(vctxt->inode->decl->value == NULL)))
   26788 	return (0);
   26789 
   26790     if (vctxt->inode->value == NULL) {
   26791 	/*
   26792 	* Set the value.
   26793 	*/
   26794 	switch (mode) {
   26795 	    case XML_SCHEMA_PUSH_TEXT_PERSIST:
   26796 		/*
   26797 		* When working on a tree.
   26798 		*/
   26799 		vctxt->inode->value = value;
   26800 		break;
   26801 	    case XML_SCHEMA_PUSH_TEXT_CREATED:
   26802 		/*
   26803 		* When working with the reader.
   26804 		* The value will be freed by the element info.
   26805 		*/
   26806 		vctxt->inode->value = value;
   26807 		if (consumed != NULL)
   26808 		    *consumed = 1;
   26809 		vctxt->inode->flags |=
   26810 		    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
   26811 		break;
   26812 	    case XML_SCHEMA_PUSH_TEXT_VOLATILE:
   26813 		/*
   26814 		* When working with SAX.
   26815 		* The value will be freed by the element info.
   26816 		*/
   26817 		if (len != -1)
   26818 		    vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
   26819 		else
   26820 		    vctxt->inode->value = BAD_CAST xmlStrdup(value);
   26821 		vctxt->inode->flags |=
   26822 		    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
   26823 		break;
   26824 	    default:
   26825 		break;
   26826 	}
   26827     } else {
   26828 	if (len < 0)
   26829 	    len = xmlStrlen(value);
   26830 	/*
   26831 	* Concat the value.
   26832 	*/
   26833 	if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
   26834 	    vctxt->inode->value = BAD_CAST xmlStrncat(
   26835 		(xmlChar *) vctxt->inode->value, value, len);
   26836 	} else {
   26837 	    vctxt->inode->value =
   26838 		BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
   26839 	    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
   26840 	}
   26841     }
   26842 
   26843     return (0);
   26844 }
   26845 
   26846 static int
   26847 xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
   26848 {
   26849     int ret = 0;
   26850 
   26851     if ((vctxt->skipDepth != -1) &&
   26852 	(vctxt->depth >= vctxt->skipDepth)) {
   26853 	VERROR_INT("xmlSchemaValidateElem",
   26854 	    "in skip-state");
   26855 	goto internal_error;
   26856     }
   26857     if (vctxt->xsiAssemble) {
   26858 	/*
   26859 	* We will stop validation if there was an error during
   26860 	* dynamic schema construction.
   26861 	* Note that we simply set @skipDepth to 0, this could
   26862 	* mean that a streaming document via SAX would be
   26863 	* still read to the end but it won't be validated any more.
   26864 	* TODO: If we are sure how to stop the validation at once
   26865 	*   for all input scenarios, then this should be changed to
   26866 	*   instantly stop the validation.
   26867 	*/
   26868 	ret = xmlSchemaAssembleByXSI(vctxt);
   26869 	if (ret != 0) {
   26870 	    if (ret == -1)
   26871 		goto internal_error;
   26872 	    vctxt->skipDepth = 0;
   26873 	    return(ret);
   26874 	}
   26875         /*
   26876          * Augment the IDC definitions for the main schema and all imported ones
   26877          * NOTE: main schema is the first in the imported list
   26878          */
   26879         xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
   26880     }
   26881     if (vctxt->depth > 0) {
   26882 	/*
   26883 	* Validate this element against the content model
   26884 	* of the parent.
   26885 	*/
   26886 	ret = xmlSchemaValidateChildElem(vctxt);
   26887 	if (ret != 0) {
   26888 	    if (ret < 0) {
   26889 		VERROR_INT("xmlSchemaValidateElem",
   26890 		    "calling xmlSchemaStreamValidateChildElement()");
   26891 		goto internal_error;
   26892 	    }
   26893 	    goto exit;
   26894 	}
   26895 	if (vctxt->depth == vctxt->skipDepth)
   26896 	    goto exit;
   26897 	if ((vctxt->inode->decl == NULL) &&
   26898 	    (vctxt->inode->typeDef == NULL)) {
   26899 	    VERROR_INT("xmlSchemaValidateElem",
   26900 		"the child element was valid but neither the "
   26901 		"declaration nor the type was set");
   26902 	    goto internal_error;
   26903 	}
   26904     } else {
   26905 	/*
   26906 	* Get the declaration of the validation root.
   26907 	*/
   26908 	vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
   26909 	    vctxt->inode->localName,
   26910 	    vctxt->inode->nsName);
   26911 	if (vctxt->inode->decl == NULL) {
   26912 	    ret = XML_SCHEMAV_CVC_ELT_1;
   26913 	    VERROR(ret, NULL,
   26914 		"No matching global declaration available "
   26915 		"for the validation root");
   26916 	    goto exit;
   26917 	}
   26918     }
   26919 
   26920     if (vctxt->inode->decl == NULL)
   26921 	goto type_validation;
   26922 
   26923     if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
   26924 	int skip;
   26925 	/*
   26926 	* Wildcards.
   26927 	*/
   26928 	ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
   26929 	if (ret != 0) {
   26930 	    if (ret < 0) {
   26931 		VERROR_INT("xmlSchemaValidateElem",
   26932 		    "calling xmlSchemaValidateElemWildcard()");
   26933 		goto internal_error;
   26934 	    }
   26935 	    goto exit;
   26936 	}
   26937 	if (skip) {
   26938 	    vctxt->skipDepth = vctxt->depth;
   26939 	    goto exit;
   26940 	}
   26941 	/*
   26942 	* The declaration might be set by the wildcard validation,
   26943 	* when the processContents is "lax" or "strict".
   26944 	*/
   26945 	if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
   26946 	    /*
   26947 	    * Clear the "decl" field to not confuse further processing.
   26948 	    */
   26949 	    vctxt->inode->decl = NULL;
   26950 	    goto type_validation;
   26951 	}
   26952     }
   26953     /*
   26954     * Validate against the declaration.
   26955     */
   26956     ret = xmlSchemaValidateElemDecl(vctxt);
   26957     if (ret != 0) {
   26958 	if (ret < 0) {
   26959 	    VERROR_INT("xmlSchemaValidateElem",
   26960 		"calling xmlSchemaValidateElemDecl()");
   26961 	    goto internal_error;
   26962 	}
   26963 	goto exit;
   26964     }
   26965     /*
   26966     * Validate against the type definition.
   26967     */
   26968 type_validation:
   26969 
   26970     if (vctxt->inode->typeDef == NULL) {
   26971 	vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
   26972 	ret = XML_SCHEMAV_CVC_TYPE_1;
   26973 	VERROR(ret, NULL,
   26974 	    "The type definition is absent");
   26975 	goto exit;
   26976     }
   26977     if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
   26978 	vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
   26979 	ret = XML_SCHEMAV_CVC_TYPE_2;
   26980 	    VERROR(ret, NULL,
   26981 	    "The type definition is abstract");
   26982 	goto exit;
   26983     }
   26984     /*
   26985     * Evaluate IDCs. Do it here, since new IDC matchers are registered
   26986     * during validation against the declaration. This must be done
   26987     * _before_ attribute validation.
   26988     */
   26989     if (vctxt->xpathStates != NULL) {
   26990 	ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
   26991 	vctxt->inode->appliedXPath = 1;
   26992 	if (ret == -1) {
   26993 	    VERROR_INT("xmlSchemaValidateElem",
   26994 		"calling xmlSchemaXPathEvaluate()");
   26995 	    goto internal_error;
   26996 	}
   26997     }
   26998     /*
   26999     * Validate attributes.
   27000     */
   27001     if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
   27002 	if ((vctxt->nbAttrInfos != 0) ||
   27003 	    (vctxt->inode->typeDef->attrUses != NULL)) {
   27004 
   27005 	    ret = xmlSchemaVAttributesComplex(vctxt);
   27006 	}
   27007     } else if (vctxt->nbAttrInfos != 0) {
   27008 
   27009 	ret = xmlSchemaVAttributesSimple(vctxt);
   27010     }
   27011     /*
   27012     * Clear registered attributes.
   27013     */
   27014     if (vctxt->nbAttrInfos != 0)
   27015 	xmlSchemaClearAttrInfos(vctxt);
   27016     if (ret == -1) {
   27017 	VERROR_INT("xmlSchemaValidateElem",
   27018 	    "calling attributes validation");
   27019 	goto internal_error;
   27020     }
   27021     /*
   27022     * Don't return an error if attributes are invalid on purpose.
   27023     */
   27024     ret = 0;
   27025 
   27026 exit:
   27027     if (ret != 0)
   27028 	vctxt->skipDepth = vctxt->depth;
   27029     return (ret);
   27030 internal_error:
   27031     return (-1);
   27032 }
   27033 
   27034 #ifdef XML_SCHEMA_READER_ENABLED
   27035 static int
   27036 xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
   27037 {
   27038     const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
   27039     int depth, nodeType, ret = 0, consumed;
   27040     xmlSchemaNodeInfoPtr ielem;
   27041 
   27042     vctxt->depth = -1;
   27043     ret = xmlTextReaderRead(vctxt->reader);
   27044     /*
   27045     * Move to the document element.
   27046     */
   27047     while (ret == 1) {
   27048 	nodeType = xmlTextReaderNodeType(vctxt->reader);
   27049 	if (nodeType == XML_ELEMENT_NODE)
   27050 	    goto root_found;
   27051 	ret = xmlTextReaderRead(vctxt->reader);
   27052     }
   27053     goto exit;
   27054 
   27055 root_found:
   27056 
   27057     do {
   27058 	depth = xmlTextReaderDepth(vctxt->reader);
   27059 	nodeType = xmlTextReaderNodeType(vctxt->reader);
   27060 
   27061 	if (nodeType == XML_ELEMENT_NODE) {
   27062 
   27063 	    vctxt->depth++;
   27064 	    if (xmlSchemaValidatorPushElem(vctxt) == -1) {
   27065 		VERROR_INT("xmlSchemaVReaderWalk",
   27066 		    "calling xmlSchemaValidatorPushElem()");
   27067 		goto internal_error;
   27068 	    }
   27069 	    ielem = vctxt->inode;
   27070 	    ielem->localName = xmlTextReaderLocalName(vctxt->reader);
   27071 	    ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
   27072 	    ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
   27073 	    /*
   27074 	    * Is the element empty?
   27075 	    */
   27076 	    ret = xmlTextReaderIsEmptyElement(vctxt->reader);
   27077 	    if (ret == -1) {
   27078 		VERROR_INT("xmlSchemaVReaderWalk",
   27079 		    "calling xmlTextReaderIsEmptyElement()");
   27080 		goto internal_error;
   27081 	    }
   27082 	    if (ret) {
   27083 		ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
   27084 	    }
   27085 	    /*
   27086 	    * Register attributes.
   27087 	    */
   27088 	    vctxt->nbAttrInfos = 0;
   27089 	    ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
   27090 	    if (ret == -1) {
   27091 		VERROR_INT("xmlSchemaVReaderWalk",
   27092 		    "calling xmlTextReaderMoveToFirstAttribute()");
   27093 		goto internal_error;
   27094 	    }
   27095 	    if (ret == 1) {
   27096 		do {
   27097 		    /*
   27098 		    * VAL TODO: How do we know that the reader works on a
   27099 		    * node tree, to be able to pass a node here?
   27100 		    */
   27101 		    if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
   27102 			(const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
   27103 			xmlTextReaderNamespaceUri(vctxt->reader), 1,
   27104 			xmlTextReaderValue(vctxt->reader), 1) == -1) {
   27105 
   27106 			VERROR_INT("xmlSchemaVReaderWalk",
   27107 			    "calling xmlSchemaValidatorPushAttribute()");
   27108 			goto internal_error;
   27109 		    }
   27110 		    ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
   27111 		    if (ret == -1) {
   27112 			VERROR_INT("xmlSchemaVReaderWalk",
   27113 			    "calling xmlTextReaderMoveToFirstAttribute()");
   27114 			goto internal_error;
   27115 		    }
   27116 		} while (ret == 1);
   27117 		/*
   27118 		* Back to element position.
   27119 		*/
   27120 		ret = xmlTextReaderMoveToElement(vctxt->reader);
   27121 		if (ret == -1) {
   27122 		    VERROR_INT("xmlSchemaVReaderWalk",
   27123 			"calling xmlTextReaderMoveToElement()");
   27124 		    goto internal_error;
   27125 		}
   27126 	    }
   27127 	    /*
   27128 	    * Validate the element.
   27129 	    */
   27130 	    ret= xmlSchemaValidateElem(vctxt);
   27131 	    if (ret != 0) {
   27132 		if (ret == -1) {
   27133 		    VERROR_INT("xmlSchemaVReaderWalk",
   27134 			"calling xmlSchemaValidateElem()");
   27135 		    goto internal_error;
   27136 		}
   27137 		goto exit;
   27138 	    }
   27139 	    if (vctxt->depth == vctxt->skipDepth) {
   27140 		int curDepth;
   27141 		/*
   27142 		* Skip all content.
   27143 		*/
   27144 		if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
   27145 		    ret = xmlTextReaderRead(vctxt->reader);
   27146 		    curDepth = xmlTextReaderDepth(vctxt->reader);
   27147 		    while ((ret == 1) && (curDepth != depth)) {
   27148 			ret = xmlTextReaderRead(vctxt->reader);
   27149 			curDepth = xmlTextReaderDepth(vctxt->reader);
   27150 		    }
   27151 		    if (ret < 0) {
   27152 			/*
   27153 			* VAL TODO: A reader error occured; what to do here?
   27154 			*/
   27155 			ret = 1;
   27156 			goto exit;
   27157 		    }
   27158 		}
   27159 		goto leave_elem;
   27160 	    }
   27161 	    /*
   27162 	    * READER VAL TODO: Is an END_ELEM really never called
   27163 	    * if the elem is empty?
   27164 	    */
   27165 	    if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
   27166 		goto leave_elem;
   27167 	} else if (nodeType == END_ELEM) {
   27168 	    /*
   27169 	    * Process END of element.
   27170 	    */
   27171 leave_elem:
   27172 	    ret = xmlSchemaValidatorPopElem(vctxt);
   27173 	    if (ret != 0) {
   27174 		if (ret < 0) {
   27175 		    VERROR_INT("xmlSchemaVReaderWalk",
   27176 			"calling xmlSchemaValidatorPopElem()");
   27177 		    goto internal_error;
   27178 		}
   27179 		goto exit;
   27180 	    }
   27181 	    if (vctxt->depth >= 0)
   27182 		ielem = vctxt->inode;
   27183 	    else
   27184 		ielem = NULL;
   27185 	} else if ((nodeType == XML_TEXT_NODE) ||
   27186 	    (nodeType == XML_CDATA_SECTION_NODE) ||
   27187 	    (nodeType == WHTSP) ||
   27188 	    (nodeType == SIGN_WHTSP)) {
   27189 	    /*
   27190 	    * Process character content.
   27191 	    */
   27192 	    xmlChar *value;
   27193 
   27194 	    if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
   27195 		nodeType = XML_TEXT_NODE;
   27196 
   27197 	    value = xmlTextReaderValue(vctxt->reader);
   27198 	    ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
   27199 		-1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
   27200 	    if (! consumed)
   27201 		xmlFree(value);
   27202 	    if (ret == -1) {
   27203 		VERROR_INT("xmlSchemaVReaderWalk",
   27204 		    "calling xmlSchemaVPushText()");
   27205 		goto internal_error;
   27206 	    }
   27207 	} else if ((nodeType == XML_ENTITY_NODE) ||
   27208 	    (nodeType == XML_ENTITY_REF_NODE)) {
   27209 	    /*
   27210 	    * VAL TODO: What to do with entities?
   27211 	    */
   27212 	    TODO
   27213 	}
   27214 	/*
   27215 	* Read next node.
   27216 	*/
   27217 	ret = xmlTextReaderRead(vctxt->reader);
   27218     } while (ret == 1);
   27219 
   27220 exit:
   27221     return (ret);
   27222 internal_error:
   27223     return (-1);
   27224 }
   27225 #endif
   27226 
   27227 /************************************************************************
   27228  *									*
   27229  *			SAX validation handlers				*
   27230  *									*
   27231  ************************************************************************/
   27232 
   27233 /*
   27234 * Process text content.
   27235 */
   27236 static void
   27237 xmlSchemaSAXHandleText(void *ctx,
   27238 		       const xmlChar * ch,
   27239 		       int len)
   27240 {
   27241     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27242 
   27243     if (vctxt->depth < 0)
   27244 	return;
   27245     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27246 	return;
   27247     if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
   27248 	vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
   27249     if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
   27250 	XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
   27251 	VERROR_INT("xmlSchemaSAXHandleCDataSection",
   27252 	    "calling xmlSchemaVPushText()");
   27253 	vctxt->err = -1;
   27254 	xmlStopParser(vctxt->parserCtxt);
   27255     }
   27256 }
   27257 
   27258 /*
   27259 * Process CDATA content.
   27260 */
   27261 static void
   27262 xmlSchemaSAXHandleCDataSection(void *ctx,
   27263 			     const xmlChar * ch,
   27264 			     int len)
   27265 {
   27266     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27267 
   27268     if (vctxt->depth < 0)
   27269 	return;
   27270     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27271 	return;
   27272     if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
   27273 	vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
   27274     if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
   27275 	XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
   27276 	VERROR_INT("xmlSchemaSAXHandleCDataSection",
   27277 	    "calling xmlSchemaVPushText()");
   27278 	vctxt->err = -1;
   27279 	xmlStopParser(vctxt->parserCtxt);
   27280     }
   27281 }
   27282 
   27283 static void
   27284 xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
   27285 			    const xmlChar * name ATTRIBUTE_UNUSED)
   27286 {
   27287     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27288 
   27289     if (vctxt->depth < 0)
   27290 	return;
   27291     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27292 	return;
   27293     /* SAX VAL TODO: What to do here? */
   27294     TODO
   27295 }
   27296 
   27297 static void
   27298 xmlSchemaSAXHandleStartElementNs(void *ctx,
   27299 				 const xmlChar * localname,
   27300 				 const xmlChar * prefix ATTRIBUTE_UNUSED,
   27301 				 const xmlChar * URI,
   27302 				 int nb_namespaces,
   27303 				 const xmlChar ** namespaces,
   27304 				 int nb_attributes,
   27305 				 int nb_defaulted ATTRIBUTE_UNUSED,
   27306 				 const xmlChar ** attributes)
   27307 {
   27308     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27309     int ret;
   27310     xmlSchemaNodeInfoPtr ielem;
   27311     int i, j;
   27312 
   27313     /*
   27314     * SAX VAL TODO: What to do with nb_defaulted?
   27315     */
   27316     /*
   27317     * Skip elements if inside a "skip" wildcard or invalid.
   27318     */
   27319     vctxt->depth++;
   27320     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27321 	return;
   27322     /*
   27323     * Push the element.
   27324     */
   27325     if (xmlSchemaValidatorPushElem(vctxt) == -1) {
   27326 	VERROR_INT("xmlSchemaSAXHandleStartElementNs",
   27327 	    "calling xmlSchemaValidatorPushElem()");
   27328 	goto internal_error;
   27329     }
   27330     ielem = vctxt->inode;
   27331     /*
   27332     * TODO: Is this OK?
   27333     */
   27334     ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
   27335     ielem->localName = localname;
   27336     ielem->nsName = URI;
   27337     ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
   27338     /*
   27339     * Register namespaces on the elem info.
   27340     */
   27341     if (nb_namespaces != 0) {
   27342 	/*
   27343 	* Although the parser builds its own namespace list,
   27344 	* we have no access to it, so we'll use an own one.
   27345 	*/
   27346         for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
   27347 	    /*
   27348 	    * Store prefix and namespace name.
   27349 	    */
   27350 	    if (ielem->nsBindings == NULL) {
   27351 		ielem->nsBindings =
   27352 		    (const xmlChar **) xmlMalloc(10 *
   27353 			sizeof(const xmlChar *));
   27354 		if (ielem->nsBindings == NULL) {
   27355 		    xmlSchemaVErrMemory(vctxt,
   27356 			"allocating namespace bindings for SAX validation",
   27357 			NULL);
   27358 		    goto internal_error;
   27359 		}
   27360 		ielem->nbNsBindings = 0;
   27361 		ielem->sizeNsBindings = 5;
   27362 	    } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
   27363 		ielem->sizeNsBindings *= 2;
   27364 		ielem->nsBindings =
   27365 		    (const xmlChar **) xmlRealloc(
   27366 			(void *) ielem->nsBindings,
   27367 			ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
   27368 		if (ielem->nsBindings == NULL) {
   27369 		    xmlSchemaVErrMemory(vctxt,
   27370 			"re-allocating namespace bindings for SAX validation",
   27371 			NULL);
   27372 		    goto internal_error;
   27373 		}
   27374 	    }
   27375 
   27376 	    ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
   27377 	    if (namespaces[j+1][0] == 0) {
   27378 		/*
   27379 		* Handle xmlns="".
   27380 		*/
   27381 		ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
   27382 	    } else
   27383 		ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
   27384 		    namespaces[j+1];
   27385 	    ielem->nbNsBindings++;
   27386 	}
   27387     }
   27388     /*
   27389     * Register attributes.
   27390     * SAX VAL TODO: We are not adding namespace declaration
   27391     * attributes yet.
   27392     */
   27393     if (nb_attributes != 0) {
   27394 	xmlChar *value;
   27395 
   27396         for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
   27397 	    /*
   27398 	    * Duplicate the value, changing any &#38; to a literal ampersand.
   27399 	    *
   27400 	    * libxml2 differs from normal SAX here in that it escapes all ampersands
   27401 	    * as &#38; instead of delivering the raw converted string. Changing the
   27402 	    * behavior at this point would break applications that use this API, so
   27403 	    * we are forced to work around it. There is no danger of accidentally
   27404 	    * decoding some entity other than &#38; in this step because without
   27405 	    * unescaped ampersands there can be no other entities in the string.
   27406 	    */
   27407 	    value = xmlStringLenDecodeEntities(vctxt->parserCtxt, attributes[j+3],
   27408 		attributes[j+4] - attributes[j+3], XML_SUBSTITUTE_REF, 0, 0, 0);
   27409 	    /*
   27410 	    * TODO: Set the node line.
   27411 	    */
   27412 	    ret = xmlSchemaValidatorPushAttribute(vctxt,
   27413 		NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
   27414 		value, 1);
   27415 	    if (ret == -1) {
   27416 		VERROR_INT("xmlSchemaSAXHandleStartElementNs",
   27417 		    "calling xmlSchemaValidatorPushAttribute()");
   27418 		goto internal_error;
   27419 	    }
   27420 	}
   27421     }
   27422     /*
   27423     * Validate the element.
   27424     */
   27425     ret = xmlSchemaValidateElem(vctxt);
   27426     if (ret != 0) {
   27427 	if (ret == -1) {
   27428 	    VERROR_INT("xmlSchemaSAXHandleStartElementNs",
   27429 		"calling xmlSchemaValidateElem()");
   27430 	    goto internal_error;
   27431 	}
   27432 	goto exit;
   27433     }
   27434 
   27435 exit:
   27436     return;
   27437 internal_error:
   27438     vctxt->err = -1;
   27439     xmlStopParser(vctxt->parserCtxt);
   27440     return;
   27441 }
   27442 
   27443 static void
   27444 xmlSchemaSAXHandleEndElementNs(void *ctx,
   27445 			       const xmlChar * localname ATTRIBUTE_UNUSED,
   27446 			       const xmlChar * prefix ATTRIBUTE_UNUSED,
   27447 			       const xmlChar * URI ATTRIBUTE_UNUSED)
   27448 {
   27449     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27450     int res;
   27451 
   27452     /*
   27453     * Skip elements if inside a "skip" wildcard or if invalid.
   27454     */
   27455     if (vctxt->skipDepth != -1) {
   27456 	if (vctxt->depth > vctxt->skipDepth) {
   27457 	    vctxt->depth--;
   27458 	    return;
   27459 	} else
   27460 	    vctxt->skipDepth = -1;
   27461     }
   27462     /*
   27463     * SAX VAL TODO: Just a temporary check.
   27464     */
   27465     if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
   27466 	(!xmlStrEqual(vctxt->inode->nsName, URI))) {
   27467 	VERROR_INT("xmlSchemaSAXHandleEndElementNs",
   27468 	    "elem pop mismatch");
   27469     }
   27470     res = xmlSchemaValidatorPopElem(vctxt);
   27471     if (res != 0) {
   27472 	if (res < 0) {
   27473 	    VERROR_INT("xmlSchemaSAXHandleEndElementNs",
   27474 		"calling xmlSchemaValidatorPopElem()");
   27475 	    goto internal_error;
   27476 	}
   27477 	goto exit;
   27478     }
   27479 exit:
   27480     return;
   27481 internal_error:
   27482     vctxt->err = -1;
   27483     xmlStopParser(vctxt->parserCtxt);
   27484     return;
   27485 }
   27486 
   27487 /************************************************************************
   27488  *									*
   27489  *			Validation interfaces				*
   27490  *									*
   27491  ************************************************************************/
   27492 
   27493 /**
   27494  * xmlSchemaNewValidCtxt:
   27495  * @schema:  a precompiled XML Schemas
   27496  *
   27497  * Create an XML Schemas validation context based on the given schema.
   27498  *
   27499  * Returns the validation context or NULL in case of error
   27500  */
   27501 xmlSchemaValidCtxtPtr
   27502 xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
   27503 {
   27504     xmlSchemaValidCtxtPtr ret;
   27505 
   27506     ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
   27507     if (ret == NULL) {
   27508         xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
   27509         return (NULL);
   27510     }
   27511     memset(ret, 0, sizeof(xmlSchemaValidCtxt));
   27512     ret->type = XML_SCHEMA_CTXT_VALIDATOR;
   27513     ret->dict = xmlDictCreate();
   27514     ret->nodeQNames = xmlSchemaItemListCreate();
   27515     ret->schema = schema;
   27516     return (ret);
   27517 }
   27518 
   27519 /**
   27520  * xmlSchemaValidateSetFilename:
   27521  * @vctxt: the schema validation context
   27522  * @filename: the file name
   27523  *
   27524  * Workaround to provide file error reporting information when this is
   27525  * not provided by current APIs
   27526  */
   27527 void
   27528 xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
   27529     if (vctxt == NULL)
   27530         return;
   27531     if (vctxt->filename != NULL)
   27532         xmlFree(vctxt->filename);
   27533     if (filename != NULL)
   27534         vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
   27535     else
   27536         vctxt->filename = NULL;
   27537 }
   27538 
   27539 /**
   27540  * xmlSchemaClearValidCtxt:
   27541  * @vctxt: the schema validation context
   27542  *
   27543  * Free the resources associated to the schema validation context;
   27544  * leaves some fields alive intended for reuse of the context.
   27545  */
   27546 static void
   27547 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
   27548 {
   27549     if (vctxt == NULL)
   27550         return;
   27551 
   27552     /*
   27553     * TODO: Should we clear the flags?
   27554     *   Might be problematic if one reuses the context
   27555     *   and assumes that the options remain the same.
   27556     */
   27557     vctxt->flags = 0;
   27558     vctxt->validationRoot = NULL;
   27559     vctxt->doc = NULL;
   27560 #ifdef LIBXML_READER_ENABLED
   27561     vctxt->reader = NULL;
   27562 #endif
   27563     vctxt->hasKeyrefs = 0;
   27564 
   27565     if (vctxt->value != NULL) {
   27566         xmlSchemaFreeValue(vctxt->value);
   27567 	vctxt->value = NULL;
   27568     }
   27569     /*
   27570     * Augmented IDC information.
   27571     */
   27572     if (vctxt->aidcs != NULL) {
   27573 	xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
   27574 	do {
   27575 	    next = cur->next;
   27576 	    xmlFree(cur);
   27577 	    cur = next;
   27578 	} while (cur != NULL);
   27579 	vctxt->aidcs = NULL;
   27580     }
   27581     if (vctxt->idcMatcherCache != NULL) {
   27582 	xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
   27583 
   27584 	while (matcher) {
   27585 	    tmp = matcher;
   27586 	    matcher = matcher->nextCached;
   27587 	    xmlSchemaIDCFreeMatcherList(tmp);
   27588 	}
   27589 	vctxt->idcMatcherCache = NULL;
   27590     }
   27591 
   27592 
   27593     if (vctxt->idcNodes != NULL) {
   27594 	int i;
   27595 	xmlSchemaPSVIIDCNodePtr item;
   27596 
   27597 	for (i = 0; i < vctxt->nbIdcNodes; i++) {
   27598 	    item = vctxt->idcNodes[i];
   27599 	    xmlFree(item->keys);
   27600 	    xmlFree(item);
   27601 	}
   27602 	xmlFree(vctxt->idcNodes);
   27603 	vctxt->idcNodes = NULL;
   27604 	vctxt->nbIdcNodes = 0;
   27605 	vctxt->sizeIdcNodes = 0;
   27606     }
   27607     /*
   27608     * Note that we won't delete the XPath state pool here.
   27609     */
   27610     if (vctxt->xpathStates != NULL) {
   27611 	xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
   27612 	vctxt->xpathStates = NULL;
   27613     }
   27614     /*
   27615     * Attribute info.
   27616     */
   27617     if (vctxt->nbAttrInfos != 0) {
   27618 	xmlSchemaClearAttrInfos(vctxt);
   27619     }
   27620     /*
   27621     * Element info.
   27622     */
   27623     if (vctxt->elemInfos != NULL) {
   27624 	int i;
   27625 	xmlSchemaNodeInfoPtr ei;
   27626 
   27627 	for (i = 0; i < vctxt->sizeElemInfos; i++) {
   27628 	    ei = vctxt->elemInfos[i];
   27629 	    if (ei == NULL)
   27630 		break;
   27631 	    xmlSchemaClearElemInfo(vctxt, ei);
   27632 	}
   27633     }
   27634     xmlSchemaItemListClear(vctxt->nodeQNames);
   27635     /* Recreate the dict. */
   27636     xmlDictFree(vctxt->dict);
   27637     /*
   27638     * TODO: Is is save to recreate it? Do we have a scenario
   27639     * where the user provides the dict?
   27640     */
   27641     vctxt->dict = xmlDictCreate();
   27642 
   27643     if (vctxt->filename != NULL) {
   27644         xmlFree(vctxt->filename);
   27645 	vctxt->filename = NULL;
   27646     }
   27647 }
   27648 
   27649 /**
   27650  * xmlSchemaFreeValidCtxt:
   27651  * @ctxt:  the schema validation context
   27652  *
   27653  * Free the resources associated to the schema validation context
   27654  */
   27655 void
   27656 xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
   27657 {
   27658     if (ctxt == NULL)
   27659         return;
   27660     if (ctxt->value != NULL)
   27661         xmlSchemaFreeValue(ctxt->value);
   27662     if (ctxt->pctxt != NULL)
   27663 	xmlSchemaFreeParserCtxt(ctxt->pctxt);
   27664     if (ctxt->idcNodes != NULL) {
   27665 	int i;
   27666 	xmlSchemaPSVIIDCNodePtr item;
   27667 
   27668 	for (i = 0; i < ctxt->nbIdcNodes; i++) {
   27669 	    item = ctxt->idcNodes[i];
   27670 	    xmlFree(item->keys);
   27671 	    xmlFree(item);
   27672 	}
   27673 	xmlFree(ctxt->idcNodes);
   27674     }
   27675     if (ctxt->idcKeys != NULL) {
   27676 	int i;
   27677 	for (i = 0; i < ctxt->nbIdcKeys; i++)
   27678 	    xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
   27679 	xmlFree(ctxt->idcKeys);
   27680     }
   27681 
   27682     if (ctxt->xpathStates != NULL) {
   27683 	xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
   27684 	ctxt->xpathStates = NULL;
   27685     }
   27686     if (ctxt->xpathStatePool != NULL) {
   27687 	xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
   27688 	ctxt->xpathStatePool = NULL;
   27689     }
   27690 
   27691     /*
   27692     * Augmented IDC information.
   27693     */
   27694     if (ctxt->aidcs != NULL) {
   27695 	xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
   27696 	do {
   27697 	    next = cur->next;
   27698 	    xmlFree(cur);
   27699 	    cur = next;
   27700 	} while (cur != NULL);
   27701     }
   27702     if (ctxt->attrInfos != NULL) {
   27703 	int i;
   27704 	xmlSchemaAttrInfoPtr attr;
   27705 
   27706 	/* Just a paranoid call to the cleanup. */
   27707 	if (ctxt->nbAttrInfos != 0)
   27708 	    xmlSchemaClearAttrInfos(ctxt);
   27709 	for (i = 0; i < ctxt->sizeAttrInfos; i++) {
   27710 	    attr = ctxt->attrInfos[i];
   27711 	    xmlFree(attr);
   27712 	}
   27713 	xmlFree(ctxt->attrInfos);
   27714     }
   27715     if (ctxt->elemInfos != NULL) {
   27716 	int i;
   27717 	xmlSchemaNodeInfoPtr ei;
   27718 
   27719 	for (i = 0; i < ctxt->sizeElemInfos; i++) {
   27720 	    ei = ctxt->elemInfos[i];
   27721 	    if (ei == NULL)
   27722 		break;
   27723 	    xmlSchemaClearElemInfo(ctxt, ei);
   27724 	    xmlFree(ei);
   27725 	}
   27726 	xmlFree(ctxt->elemInfos);
   27727     }
   27728     if (ctxt->nodeQNames != NULL)
   27729 	xmlSchemaItemListFree(ctxt->nodeQNames);
   27730     if (ctxt->dict != NULL)
   27731 	xmlDictFree(ctxt->dict);
   27732     if (ctxt->filename != NULL)
   27733 	xmlFree(ctxt->filename);
   27734     xmlFree(ctxt);
   27735 }
   27736 
   27737 /**
   27738  * xmlSchemaIsValid:
   27739  * @ctxt: the schema validation context
   27740  *
   27741  * Check if any error was detected during validation.
   27742  *
   27743  * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
   27744  *         of internal error.
   27745  */
   27746 int
   27747 xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
   27748 {
   27749     if (ctxt == NULL)
   27750         return(-1);
   27751     return(ctxt->err == 0);
   27752 }
   27753 
   27754 /**
   27755  * xmlSchemaSetValidErrors:
   27756  * @ctxt:  a schema validation context
   27757  * @err:  the error function
   27758  * @warn: the warning function
   27759  * @ctx: the functions context
   27760  *
   27761  * Set the error and warning callback informations
   27762  */
   27763 void
   27764 xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
   27765                         xmlSchemaValidityErrorFunc err,
   27766                         xmlSchemaValidityWarningFunc warn, void *ctx)
   27767 {
   27768     if (ctxt == NULL)
   27769         return;
   27770     ctxt->error = err;
   27771     ctxt->warning = warn;
   27772     ctxt->errCtxt = ctx;
   27773     if (ctxt->pctxt != NULL)
   27774 	xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
   27775 }
   27776 
   27777 /**
   27778  * xmlSchemaSetValidStructuredErrors:
   27779  * @ctxt:  a schema validation context
   27780  * @serror:  the structured error function
   27781  * @ctx: the functions context
   27782  *
   27783  * Set the structured error callback
   27784  */
   27785 void
   27786 xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
   27787 				  xmlStructuredErrorFunc serror, void *ctx)
   27788 {
   27789     if (ctxt == NULL)
   27790         return;
   27791 	ctxt->serror = serror;
   27792     ctxt->error = NULL;
   27793     ctxt->warning = NULL;
   27794     ctxt->errCtxt = ctx;
   27795     if (ctxt->pctxt != NULL)
   27796 	xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
   27797 }
   27798 
   27799 /**
   27800  * xmlSchemaGetValidErrors:
   27801  * @ctxt: a XML-Schema validation context
   27802  * @err: the error function result
   27803  * @warn: the warning function result
   27804  * @ctx: the functions context result
   27805  *
   27806  * Get the error and warning callback informations
   27807  *
   27808  * Returns -1 in case of error and 0 otherwise
   27809  */
   27810 int
   27811 xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
   27812 			xmlSchemaValidityErrorFunc * err,
   27813 			xmlSchemaValidityWarningFunc * warn, void **ctx)
   27814 {
   27815 	if (ctxt == NULL)
   27816 		return (-1);
   27817 	if (err != NULL)
   27818 		*err = ctxt->error;
   27819 	if (warn != NULL)
   27820 		*warn = ctxt->warning;
   27821 	if (ctx != NULL)
   27822 		*ctx = ctxt->errCtxt;
   27823 	return (0);
   27824 }
   27825 
   27826 
   27827 /**
   27828  * xmlSchemaSetValidOptions:
   27829  * @ctxt:	a schema validation context
   27830  * @options: a combination of xmlSchemaValidOption
   27831  *
   27832  * Sets the options to be used during the validation.
   27833  *
   27834  * Returns 0 in case of success, -1 in case of an
   27835  * API error.
   27836  */
   27837 int
   27838 xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
   27839 			 int options)
   27840 
   27841 {
   27842     int i;
   27843 
   27844     if (ctxt == NULL)
   27845 	return (-1);
   27846     /*
   27847     * WARNING: Change the start value if adding to the
   27848     * xmlSchemaValidOption.
   27849     * TODO: Is there an other, more easy to maintain,
   27850     * way?
   27851     */
   27852     for (i = 1; i < (int) sizeof(int) * 8; i++) {
   27853         if (options & 1<<i)
   27854 	    return (-1);
   27855     }
   27856     ctxt->options = options;
   27857     return (0);
   27858 }
   27859 
   27860 /**
   27861  * xmlSchemaValidCtxtGetOptions:
   27862  * @ctxt: a schema validation context
   27863  *
   27864  * Get the validation context options.
   27865  *
   27866  * Returns the option combination or -1 on error.
   27867  */
   27868 int
   27869 xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
   27870 
   27871 {
   27872     if (ctxt == NULL)
   27873 	return (-1);
   27874     else
   27875 	return (ctxt->options);
   27876 }
   27877 
   27878 static int
   27879 xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
   27880 {
   27881     xmlAttrPtr attr;
   27882     int ret = 0;
   27883     xmlSchemaNodeInfoPtr ielem = NULL;
   27884     xmlNodePtr node, valRoot;
   27885     const xmlChar *nsName;
   27886 
   27887     /* DOC VAL TODO: Move this to the start function. */
   27888     if (vctxt->validationRoot != NULL)
   27889         valRoot = vctxt->validationRoot;
   27890     else
   27891 	valRoot = xmlDocGetRootElement(vctxt->doc);
   27892     if (valRoot == NULL) {
   27893 	/* VAL TODO: Error code? */
   27894 	VERROR(1, NULL, "The document has no document element");
   27895 	return (1);
   27896     }
   27897     vctxt->depth = -1;
   27898     vctxt->validationRoot = valRoot;
   27899     node = valRoot;
   27900     while (node != NULL) {
   27901 	if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27902 	    goto next_sibling;
   27903 	if (node->type == XML_ELEMENT_NODE) {
   27904 
   27905 	    /*
   27906 	    * Init the node-info.
   27907 	    */
   27908 	    vctxt->depth++;
   27909 	    if (xmlSchemaValidatorPushElem(vctxt) == -1)
   27910 		goto internal_error;
   27911 	    ielem = vctxt->inode;
   27912 	    ielem->node = node;
   27913 	    ielem->nodeLine = node->line;
   27914 	    ielem->localName = node->name;
   27915 	    if (node->ns != NULL)
   27916 		ielem->nsName = node->ns->href;
   27917 	    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
   27918 	    /*
   27919 	    * Register attributes.
   27920 	    * DOC VAL TODO: We do not register namespace declaration
   27921 	    * attributes yet.
   27922 	    */
   27923 	    vctxt->nbAttrInfos = 0;
   27924 	    if (node->properties != NULL) {
   27925 		attr = node->properties;
   27926 		do {
   27927 		    if (attr->ns != NULL)
   27928 			nsName = attr->ns->href;
   27929 		    else
   27930 			nsName = NULL;
   27931 		    ret = xmlSchemaValidatorPushAttribute(vctxt,
   27932 			(xmlNodePtr) attr,
   27933 			/*
   27934 			* Note that we give it the line number of the
   27935 			* parent element.
   27936 			*/
   27937 			ielem->nodeLine,
   27938 			attr->name, nsName, 0,
   27939 			xmlNodeListGetString(attr->doc, attr->children, 1), 1);
   27940 		    if (ret == -1) {
   27941 			VERROR_INT("xmlSchemaDocWalk",
   27942 			    "calling xmlSchemaValidatorPushAttribute()");
   27943 			goto internal_error;
   27944 		    }
   27945 		    attr = attr->next;
   27946 		} while (attr);
   27947 	    }
   27948 	    /*
   27949 	    * Validate the element.
   27950 	    */
   27951 	    ret = xmlSchemaValidateElem(vctxt);
   27952 	    if (ret != 0) {
   27953 		if (ret == -1) {
   27954 		    VERROR_INT("xmlSchemaDocWalk",
   27955 			"calling xmlSchemaValidateElem()");
   27956 		    goto internal_error;
   27957 		}
   27958 		/*
   27959 		* Don't stop validation; just skip the content
   27960 		* of this element.
   27961 		*/
   27962 		goto leave_node;
   27963 	    }
   27964 	    if ((vctxt->skipDepth != -1) &&
   27965 		(vctxt->depth >= vctxt->skipDepth))
   27966 		goto leave_node;
   27967 	} else if ((node->type == XML_TEXT_NODE) ||
   27968 	    (node->type == XML_CDATA_SECTION_NODE)) {
   27969 	    /*
   27970 	    * Process character content.
   27971 	    */
   27972 	    if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
   27973 		ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
   27974 	    ret = xmlSchemaVPushText(vctxt, node->type, node->content,
   27975 		-1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
   27976 	    if (ret < 0) {
   27977 		VERROR_INT("xmlSchemaVDocWalk",
   27978 		    "calling xmlSchemaVPushText()");
   27979 		goto internal_error;
   27980 	    }
   27981 	    /*
   27982 	    * DOC VAL TODO: Should we skip further validation of the
   27983 	    * element content here?
   27984 	    */
   27985 	} else if ((node->type == XML_ENTITY_NODE) ||
   27986 	    (node->type == XML_ENTITY_REF_NODE)) {
   27987 	    /*
   27988 	    * DOC VAL TODO: What to do with entities?
   27989 	    */
   27990 	    VERROR_INT("xmlSchemaVDocWalk",
   27991 		"there is at least one entity reference in the node-tree "
   27992 		"currently being validated. Processing of entities with "
   27993 		"this XML Schema processor is not supported (yet). Please "
   27994 		"substitute entities before validation.");
   27995 	    goto internal_error;
   27996 	} else {
   27997 	    goto leave_node;
   27998 	    /*
   27999 	    * DOC VAL TODO: XInclude nodes, etc.
   28000 	    */
   28001 	}
   28002 	/*
   28003 	* Walk the doc.
   28004 	*/
   28005 	if (node->children != NULL) {
   28006 	    node = node->children;
   28007 	    continue;
   28008 	}
   28009 leave_node:
   28010 	if (node->type == XML_ELEMENT_NODE) {
   28011 	    /*
   28012 	    * Leaving the scope of an element.
   28013 	    */
   28014 	    if (node != vctxt->inode->node) {
   28015 		VERROR_INT("xmlSchemaVDocWalk",
   28016 		    "element position mismatch");
   28017 		goto internal_error;
   28018 	    }
   28019 	    ret = xmlSchemaValidatorPopElem(vctxt);
   28020 	    if (ret != 0) {
   28021 		if (ret < 0) {
   28022 		    VERROR_INT("xmlSchemaVDocWalk",
   28023 			"calling xmlSchemaValidatorPopElem()");
   28024 		    goto internal_error;
   28025 		}
   28026 	    }
   28027 	    if (node == valRoot)
   28028 		goto exit;
   28029 	}
   28030 next_sibling:
   28031 	if (node->next != NULL)
   28032 	    node = node->next;
   28033 	else {
   28034 	    node = node->parent;
   28035 	    goto leave_node;
   28036 	}
   28037     }
   28038 
   28039 exit:
   28040     return (ret);
   28041 internal_error:
   28042     return (-1);
   28043 }
   28044 
   28045 static int
   28046 xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
   28047     /*
   28048     * Some initialization.
   28049     */
   28050     vctxt->err = 0;
   28051     vctxt->nberrors = 0;
   28052     vctxt->depth = -1;
   28053     vctxt->skipDepth = -1;
   28054     vctxt->xsiAssemble = 0;
   28055     vctxt->hasKeyrefs = 0;
   28056 #ifdef ENABLE_IDC_NODE_TABLES_TEST
   28057     vctxt->createIDCNodeTables = 1;
   28058 #else
   28059     vctxt->createIDCNodeTables = 0;
   28060 #endif
   28061     /*
   28062     * Create a schema + parser if necessary.
   28063     */
   28064     if (vctxt->schema == NULL) {
   28065 	xmlSchemaParserCtxtPtr pctxt;
   28066 
   28067 	vctxt->xsiAssemble = 1;
   28068 	/*
   28069 	* If not schema was given then we will create a schema
   28070 	* dynamically using XSI schema locations.
   28071 	*
   28072 	* Create the schema parser context.
   28073 	*/
   28074 	if ((vctxt->pctxt == NULL) &&
   28075 	   (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
   28076 	   return (-1);
   28077 	pctxt = vctxt->pctxt;
   28078 	pctxt->xsiAssemble = 1;
   28079 	/*
   28080 	* Create the schema.
   28081 	*/
   28082 	vctxt->schema = xmlSchemaNewSchema(pctxt);
   28083 	if (vctxt->schema == NULL)
   28084 	    return (-1);
   28085 	/*
   28086 	* Create the schema construction context.
   28087 	*/
   28088 	pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
   28089 	if (pctxt->constructor == NULL)
   28090 	    return(-1);
   28091 	pctxt->constructor->mainSchema = vctxt->schema;
   28092 	/*
   28093 	* Take ownership of the constructor to be able to free it.
   28094 	*/
   28095 	pctxt->ownsConstructor = 1;
   28096     }
   28097     /*
   28098     * Augment the IDC definitions for the main schema and all imported ones
   28099     * NOTE: main schema if the first in the imported list
   28100     */
   28101     xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
   28102 
   28103     return(0);
   28104 }
   28105 
   28106 static void
   28107 xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
   28108     if (vctxt->xsiAssemble) {
   28109 	if (vctxt->schema != NULL) {
   28110 	    xmlSchemaFree(vctxt->schema);
   28111 	    vctxt->schema = NULL;
   28112 	}
   28113     }
   28114     xmlSchemaClearValidCtxt(vctxt);
   28115 }
   28116 
   28117 static int
   28118 xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
   28119 {
   28120     int ret = 0;
   28121 
   28122     if (xmlSchemaPreRun(vctxt) < 0)
   28123         return(-1);
   28124 
   28125     if (vctxt->doc != NULL) {
   28126 	/*
   28127 	 * Tree validation.
   28128 	 */
   28129 	ret = xmlSchemaVDocWalk(vctxt);
   28130 #ifdef LIBXML_READER_ENABLED
   28131     } else if (vctxt->reader != NULL) {
   28132 	/*
   28133 	 * XML Reader validation.
   28134 	 */
   28135 #ifdef XML_SCHEMA_READER_ENABLED
   28136 	ret = xmlSchemaVReaderWalk(vctxt);
   28137 #endif
   28138 #endif
   28139     } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
   28140 	/*
   28141 	 * SAX validation.
   28142 	 */
   28143 	ret = xmlParseDocument(vctxt->parserCtxt);
   28144     } else {
   28145 	VERROR_INT("xmlSchemaVStart",
   28146 	    "no instance to validate");
   28147 	ret = -1;
   28148     }
   28149 
   28150     xmlSchemaPostRun(vctxt);
   28151     if (ret == 0)
   28152 	ret = vctxt->err;
   28153     return (ret);
   28154 }
   28155 
   28156 /**
   28157  * xmlSchemaValidateOneElement:
   28158  * @ctxt:  a schema validation context
   28159  * @elem:  an element node
   28160  *
   28161  * Validate a branch of a tree, starting with the given @elem.
   28162  *
   28163  * Returns 0 if the element and its subtree is valid, a positive error
   28164  * code number otherwise and -1 in case of an internal or API error.
   28165  */
   28166 int
   28167 xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
   28168 {
   28169     if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
   28170 	return (-1);
   28171 
   28172     if (ctxt->schema == NULL)
   28173 	return (-1);
   28174 
   28175     ctxt->doc = elem->doc;
   28176     ctxt->node = elem;
   28177     ctxt->validationRoot = elem;
   28178     return(xmlSchemaVStart(ctxt));
   28179 }
   28180 
   28181 /**
   28182  * xmlSchemaValidateDoc:
   28183  * @ctxt:  a schema validation context
   28184  * @doc:  a parsed document tree
   28185  *
   28186  * Validate a document tree in memory.
   28187  *
   28188  * Returns 0 if the document is schemas valid, a positive error code
   28189  *     number otherwise and -1 in case of internal or API error.
   28190  */
   28191 int
   28192 xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
   28193 {
   28194     if ((ctxt == NULL) || (doc == NULL))
   28195         return (-1);
   28196 
   28197     ctxt->doc = doc;
   28198     ctxt->node = xmlDocGetRootElement(doc);
   28199     if (ctxt->node == NULL) {
   28200         xmlSchemaCustomErr(ACTXT_CAST ctxt,
   28201 	    XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
   28202 	    (xmlNodePtr) doc, NULL,
   28203 	    "The document has no document element", NULL, NULL);
   28204         return (ctxt->err);
   28205     }
   28206     ctxt->validationRoot = ctxt->node;
   28207     return (xmlSchemaVStart(ctxt));
   28208 }
   28209 
   28210 
   28211 /************************************************************************
   28212  *									*
   28213  *		Function and data for SAX streaming API			*
   28214  *									*
   28215  ************************************************************************/
   28216 typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
   28217 typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
   28218 
   28219 struct _xmlSchemaSplitSAXData {
   28220     xmlSAXHandlerPtr      user_sax;
   28221     void                 *user_data;
   28222     xmlSchemaValidCtxtPtr ctxt;
   28223     xmlSAXHandlerPtr      schemas_sax;
   28224 };
   28225 
   28226 #define XML_SAX_PLUG_MAGIC 0xdc43ba21
   28227 
   28228 struct _xmlSchemaSAXPlug {
   28229     unsigned int magic;
   28230 
   28231     /* the original callbacks informations */
   28232     xmlSAXHandlerPtr     *user_sax_ptr;
   28233     xmlSAXHandlerPtr      user_sax;
   28234     void                **user_data_ptr;
   28235     void                 *user_data;
   28236 
   28237     /* the block plugged back and validation informations */
   28238     xmlSAXHandler         schemas_sax;
   28239     xmlSchemaValidCtxtPtr ctxt;
   28240 };
   28241 
   28242 /* All those functions just bounces to the user provided SAX handlers */
   28243 static void
   28244 internalSubsetSplit(void *ctx, const xmlChar *name,
   28245 	       const xmlChar *ExternalID, const xmlChar *SystemID)
   28246 {
   28247     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28248     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28249         (ctxt->user_sax->internalSubset != NULL))
   28250 	ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
   28251 	                               SystemID);
   28252 }
   28253 
   28254 static int
   28255 isStandaloneSplit(void *ctx)
   28256 {
   28257     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28258     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28259         (ctxt->user_sax->isStandalone != NULL))
   28260 	return(ctxt->user_sax->isStandalone(ctxt->user_data));
   28261     return(0);
   28262 }
   28263 
   28264 static int
   28265 hasInternalSubsetSplit(void *ctx)
   28266 {
   28267     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28268     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28269         (ctxt->user_sax->hasInternalSubset != NULL))
   28270 	return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
   28271     return(0);
   28272 }
   28273 
   28274 static int
   28275 hasExternalSubsetSplit(void *ctx)
   28276 {
   28277     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28278     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28279         (ctxt->user_sax->hasExternalSubset != NULL))
   28280 	return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
   28281     return(0);
   28282 }
   28283 
   28284 static void
   28285 externalSubsetSplit(void *ctx, const xmlChar *name,
   28286 	       const xmlChar *ExternalID, const xmlChar *SystemID)
   28287 {
   28288     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28289     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28290         (ctxt->user_sax->externalSubset != NULL))
   28291 	ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
   28292 	                               SystemID);
   28293 }
   28294 
   28295 static xmlParserInputPtr
   28296 resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
   28297 {
   28298     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28299     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28300         (ctxt->user_sax->resolveEntity != NULL))
   28301 	return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
   28302 	                                     systemId));
   28303     return(NULL);
   28304 }
   28305 
   28306 static xmlEntityPtr
   28307 getEntitySplit(void *ctx, const xmlChar *name)
   28308 {
   28309     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28310     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28311         (ctxt->user_sax->getEntity != NULL))
   28312 	return(ctxt->user_sax->getEntity(ctxt->user_data, name));
   28313     return(NULL);
   28314 }
   28315 
   28316 static xmlEntityPtr
   28317 getParameterEntitySplit(void *ctx, const xmlChar *name)
   28318 {
   28319     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28320     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28321         (ctxt->user_sax->getParameterEntity != NULL))
   28322 	return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
   28323     return(NULL);
   28324 }
   28325 
   28326 
   28327 static void
   28328 entityDeclSplit(void *ctx, const xmlChar *name, int type,
   28329           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
   28330 {
   28331     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28332     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28333         (ctxt->user_sax->entityDecl != NULL))
   28334 	ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
   28335 	                           systemId, content);
   28336 }
   28337 
   28338 static void
   28339 attributeDeclSplit(void *ctx, const xmlChar * elem,
   28340                    const xmlChar * name, int type, int def,
   28341                    const xmlChar * defaultValue, xmlEnumerationPtr tree)
   28342 {
   28343     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28344     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28345         (ctxt->user_sax->attributeDecl != NULL)) {
   28346 	ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
   28347 	                              def, defaultValue, tree);
   28348     } else {
   28349 	xmlFreeEnumeration(tree);
   28350     }
   28351 }
   28352 
   28353 static void
   28354 elementDeclSplit(void *ctx, const xmlChar *name, int type,
   28355 	    xmlElementContentPtr content)
   28356 {
   28357     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28358     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28359         (ctxt->user_sax->elementDecl != NULL))
   28360 	ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
   28361 }
   28362 
   28363 static void
   28364 notationDeclSplit(void *ctx, const xmlChar *name,
   28365 	     const xmlChar *publicId, const xmlChar *systemId)
   28366 {
   28367     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28368     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28369         (ctxt->user_sax->notationDecl != NULL))
   28370 	ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
   28371 	                             systemId);
   28372 }
   28373 
   28374 static void
   28375 unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
   28376 		   const xmlChar *publicId, const xmlChar *systemId,
   28377 		   const xmlChar *notationName)
   28378 {
   28379     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28380     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28381         (ctxt->user_sax->unparsedEntityDecl != NULL))
   28382 	ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
   28383 	                                   systemId, notationName);
   28384 }
   28385 
   28386 static void
   28387 setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
   28388 {
   28389     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28390     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28391         (ctxt->user_sax->setDocumentLocator != NULL))
   28392 	ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
   28393 }
   28394 
   28395 static void
   28396 startDocumentSplit(void *ctx)
   28397 {
   28398     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28399     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28400         (ctxt->user_sax->startDocument != NULL))
   28401 	ctxt->user_sax->startDocument(ctxt->user_data);
   28402 }
   28403 
   28404 static void
   28405 endDocumentSplit(void *ctx)
   28406 {
   28407     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28408     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28409         (ctxt->user_sax->endDocument != NULL))
   28410 	ctxt->user_sax->endDocument(ctxt->user_data);
   28411 }
   28412 
   28413 static void
   28414 processingInstructionSplit(void *ctx, const xmlChar *target,
   28415                       const xmlChar *data)
   28416 {
   28417     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28418     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28419         (ctxt->user_sax->processingInstruction != NULL))
   28420 	ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
   28421 }
   28422 
   28423 static void
   28424 commentSplit(void *ctx, const xmlChar *value)
   28425 {
   28426     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28427     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28428         (ctxt->user_sax->comment != NULL))
   28429 	ctxt->user_sax->comment(ctxt->user_data, value);
   28430 }
   28431 
   28432 /*
   28433  * Varargs error callbacks to the user application, harder ...
   28434  */
   28435 
   28436 static void XMLCDECL
   28437 warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
   28438     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28439     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28440         (ctxt->user_sax->warning != NULL)) {
   28441 	TODO
   28442     }
   28443 }
   28444 static void XMLCDECL
   28445 errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
   28446     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28447     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28448         (ctxt->user_sax->error != NULL)) {
   28449 	TODO
   28450     }
   28451 }
   28452 static void XMLCDECL
   28453 fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
   28454     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28455     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28456         (ctxt->user_sax->fatalError != NULL)) {
   28457 	TODO
   28458     }
   28459 }
   28460 
   28461 /*
   28462  * Those are function where both the user handler and the schemas handler
   28463  * need to be called.
   28464  */
   28465 static void
   28466 charactersSplit(void *ctx, const xmlChar *ch, int len)
   28467 {
   28468     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28469     if (ctxt == NULL)
   28470         return;
   28471     if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
   28472 	ctxt->user_sax->characters(ctxt->user_data, ch, len);
   28473     if (ctxt->ctxt != NULL)
   28474 	xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
   28475 }
   28476 
   28477 static void
   28478 ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
   28479 {
   28480     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28481     if (ctxt == NULL)
   28482         return;
   28483     if ((ctxt->user_sax != NULL) &&
   28484         (ctxt->user_sax->ignorableWhitespace != NULL))
   28485 	ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
   28486     if (ctxt->ctxt != NULL)
   28487 	xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
   28488 }
   28489 
   28490 static void
   28491 cdataBlockSplit(void *ctx, const xmlChar *value, int len)
   28492 {
   28493     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28494     if (ctxt == NULL)
   28495         return;
   28496     if ((ctxt->user_sax != NULL) &&
   28497         (ctxt->user_sax->cdataBlock != NULL))
   28498 	ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
   28499     if (ctxt->ctxt != NULL)
   28500 	xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
   28501 }
   28502 
   28503 static void
   28504 referenceSplit(void *ctx, const xmlChar *name)
   28505 {
   28506     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28507     if (ctxt == NULL)
   28508         return;
   28509     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28510         (ctxt->user_sax->reference != NULL))
   28511 	ctxt->user_sax->reference(ctxt->user_data, name);
   28512     if (ctxt->ctxt != NULL)
   28513         xmlSchemaSAXHandleReference(ctxt->user_data, name);
   28514 }
   28515 
   28516 static void
   28517 startElementNsSplit(void *ctx, const xmlChar * localname,
   28518 		    const xmlChar * prefix, const xmlChar * URI,
   28519 		    int nb_namespaces, const xmlChar ** namespaces,
   28520 		    int nb_attributes, int nb_defaulted,
   28521 		    const xmlChar ** attributes) {
   28522     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28523     if (ctxt == NULL)
   28524         return;
   28525     if ((ctxt->user_sax != NULL) &&
   28526         (ctxt->user_sax->startElementNs != NULL))
   28527 	ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
   28528 	                               URI, nb_namespaces, namespaces,
   28529 				       nb_attributes, nb_defaulted,
   28530 				       attributes);
   28531     if (ctxt->ctxt != NULL)
   28532 	xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
   28533 	                                 URI, nb_namespaces, namespaces,
   28534 					 nb_attributes, nb_defaulted,
   28535 					 attributes);
   28536 }
   28537 
   28538 static void
   28539 endElementNsSplit(void *ctx, const xmlChar * localname,
   28540 		    const xmlChar * prefix, const xmlChar * URI) {
   28541     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28542     if (ctxt == NULL)
   28543         return;
   28544     if ((ctxt->user_sax != NULL) &&
   28545         (ctxt->user_sax->endElementNs != NULL))
   28546 	ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
   28547     if (ctxt->ctxt != NULL)
   28548 	xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
   28549 }
   28550 
   28551 /**
   28552  * xmlSchemaSAXPlug:
   28553  * @ctxt:  a schema validation context
   28554  * @sax:  a pointer to the original xmlSAXHandlerPtr
   28555  * @user_data:  a pointer to the original SAX user data pointer
   28556  *
   28557  * Plug a SAX based validation layer in a SAX parsing event flow.
   28558  * The original @saxptr and @dataptr data are replaced by new pointers
   28559  * but the calls to the original will be maintained.
   28560  *
   28561  * Returns a pointer to a data structure needed to unplug the validation layer
   28562  *         or NULL in case of errors.
   28563  */
   28564 xmlSchemaSAXPlugPtr
   28565 xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
   28566 		 xmlSAXHandlerPtr *sax, void **user_data)
   28567 {
   28568     xmlSchemaSAXPlugPtr ret;
   28569     xmlSAXHandlerPtr old_sax;
   28570 
   28571     if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
   28572         return(NULL);
   28573 
   28574     /*
   28575      * We only allow to plug into SAX2 event streams
   28576      */
   28577     old_sax = *sax;
   28578     if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
   28579         return(NULL);
   28580     if ((old_sax != NULL) &&
   28581         (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
   28582         ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
   28583         return(NULL);
   28584 
   28585     /*
   28586      * everything seems right allocate the local data needed for that layer
   28587      */
   28588     ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
   28589     if (ret == NULL) {
   28590         return(NULL);
   28591     }
   28592     memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
   28593     ret->magic = XML_SAX_PLUG_MAGIC;
   28594     ret->schemas_sax.initialized = XML_SAX2_MAGIC;
   28595     ret->ctxt = ctxt;
   28596     ret->user_sax_ptr = sax;
   28597     ret->user_sax = old_sax;
   28598     if (old_sax == NULL) {
   28599         /*
   28600 	 * go direct, no need for the split block and functions.
   28601 	 */
   28602 	ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
   28603 	ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
   28604 	/*
   28605 	 * Note that we use the same text-function for both, to prevent
   28606 	 * the parser from testing for ignorable whitespace.
   28607 	 */
   28608 	ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
   28609 	ret->schemas_sax.characters = xmlSchemaSAXHandleText;
   28610 
   28611 	ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
   28612 	ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
   28613 
   28614 	ret->user_data = ctxt;
   28615 	*user_data = ctxt;
   28616     } else {
   28617        /*
   28618         * for each callback unused by Schemas initialize it to the Split
   28619 	* routine only if non NULL in the user block, this can speed up
   28620 	* things at the SAX level.
   28621 	*/
   28622         if (old_sax->internalSubset != NULL)
   28623             ret->schemas_sax.internalSubset = internalSubsetSplit;
   28624         if (old_sax->isStandalone != NULL)
   28625             ret->schemas_sax.isStandalone = isStandaloneSplit;
   28626         if (old_sax->hasInternalSubset != NULL)
   28627             ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
   28628         if (old_sax->hasExternalSubset != NULL)
   28629             ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
   28630         if (old_sax->resolveEntity != NULL)
   28631             ret->schemas_sax.resolveEntity = resolveEntitySplit;
   28632         if (old_sax->getEntity != NULL)
   28633             ret->schemas_sax.getEntity = getEntitySplit;
   28634         if (old_sax->entityDecl != NULL)
   28635             ret->schemas_sax.entityDecl = entityDeclSplit;
   28636         if (old_sax->notationDecl != NULL)
   28637             ret->schemas_sax.notationDecl = notationDeclSplit;
   28638         if (old_sax->attributeDecl != NULL)
   28639             ret->schemas_sax.attributeDecl = attributeDeclSplit;
   28640         if (old_sax->elementDecl != NULL)
   28641             ret->schemas_sax.elementDecl = elementDeclSplit;
   28642         if (old_sax->unparsedEntityDecl != NULL)
   28643             ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
   28644         if (old_sax->setDocumentLocator != NULL)
   28645             ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
   28646         if (old_sax->startDocument != NULL)
   28647             ret->schemas_sax.startDocument = startDocumentSplit;
   28648         if (old_sax->endDocument != NULL)
   28649             ret->schemas_sax.endDocument = endDocumentSplit;
   28650         if (old_sax->processingInstruction != NULL)
   28651             ret->schemas_sax.processingInstruction = processingInstructionSplit;
   28652         if (old_sax->comment != NULL)
   28653             ret->schemas_sax.comment = commentSplit;
   28654         if (old_sax->warning != NULL)
   28655             ret->schemas_sax.warning = warningSplit;
   28656         if (old_sax->error != NULL)
   28657             ret->schemas_sax.error = errorSplit;
   28658         if (old_sax->fatalError != NULL)
   28659             ret->schemas_sax.fatalError = fatalErrorSplit;
   28660         if (old_sax->getParameterEntity != NULL)
   28661             ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
   28662         if (old_sax->externalSubset != NULL)
   28663             ret->schemas_sax.externalSubset = externalSubsetSplit;
   28664 
   28665 	/*
   28666 	 * the 6 schemas callback have to go to the splitter functions
   28667 	 * Note that we use the same text-function for ignorableWhitespace
   28668 	 * if possible, to prevent the parser from testing for ignorable
   28669 	 * whitespace.
   28670 	 */
   28671         ret->schemas_sax.characters = charactersSplit;
   28672 	if ((old_sax->ignorableWhitespace != NULL) &&
   28673 	    (old_sax->ignorableWhitespace != old_sax->characters))
   28674 	    ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
   28675 	else
   28676 	    ret->schemas_sax.ignorableWhitespace = charactersSplit;
   28677         ret->schemas_sax.cdataBlock = cdataBlockSplit;
   28678         ret->schemas_sax.reference = referenceSplit;
   28679         ret->schemas_sax.startElementNs = startElementNsSplit;
   28680         ret->schemas_sax.endElementNs = endElementNsSplit;
   28681 
   28682 	ret->user_data_ptr = user_data;
   28683 	ret->user_data = *user_data;
   28684 	*user_data = ret;
   28685     }
   28686 
   28687     /*
   28688      * plug the pointers back.
   28689      */
   28690     *sax = &(ret->schemas_sax);
   28691     ctxt->sax = *sax;
   28692     ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
   28693     xmlSchemaPreRun(ctxt);
   28694     return(ret);
   28695 }
   28696 
   28697 /**
   28698  * xmlSchemaSAXUnplug:
   28699  * @plug:  a data structure returned by xmlSchemaSAXPlug
   28700  *
   28701  * Unplug a SAX based validation layer in a SAX parsing event flow.
   28702  * The original pointers used in the call are restored.
   28703  *
   28704  * Returns 0 in case of success and -1 in case of failure.
   28705  */
   28706 int
   28707 xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
   28708 {
   28709     xmlSAXHandlerPtr *sax;
   28710     void **user_data;
   28711 
   28712     if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
   28713         return(-1);
   28714     plug->magic = 0;
   28715 
   28716     xmlSchemaPostRun(plug->ctxt);
   28717     /* restore the data */
   28718     sax = plug->user_sax_ptr;
   28719     *sax = plug->user_sax;
   28720     if (plug->user_sax != NULL) {
   28721 	user_data = plug->user_data_ptr;
   28722 	*user_data = plug->user_data;
   28723     }
   28724 
   28725     /* free and return */
   28726     xmlFree(plug);
   28727     return(0);
   28728 }
   28729 
   28730 /**
   28731  * xmlSchemaValidateSetLocator:
   28732  * @vctxt: a schema validation context
   28733  * @f: the locator function pointer
   28734  * @ctxt: the locator context
   28735  *
   28736  * Allows to set a locator function to the validation context,
   28737  * which will be used to provide file and line information since
   28738  * those are not provided as part of the SAX validation flow
   28739  * Setting @f to NULL disable the locator.
   28740  */
   28741 
   28742 void
   28743 xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
   28744                             xmlSchemaValidityLocatorFunc f,
   28745 			    void *ctxt)
   28746 {
   28747     if (vctxt == NULL) return;
   28748     vctxt->locFunc = f;
   28749     vctxt->locCtxt = ctxt;
   28750 }
   28751 
   28752 /**
   28753  * xmlSchemaValidateStreamLocator:
   28754  * @ctx: the xmlTextReaderPtr used
   28755  * @file: returned file information
   28756  * @line: returned line information
   28757  *
   28758  * Internal locator function for the readers
   28759  *
   28760  * Returns 0 in case the Schema validation could be (des)activated and
   28761  *         -1 in case of error.
   28762  */
   28763 static int
   28764 xmlSchemaValidateStreamLocator(void *ctx, const char **file,
   28765                                unsigned long *line) {
   28766     xmlParserCtxtPtr ctxt;
   28767 
   28768     if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
   28769         return(-1);
   28770 
   28771     if (file != NULL)
   28772         *file = NULL;
   28773     if (line != NULL)
   28774         *line = 0;
   28775 
   28776     ctxt = (xmlParserCtxtPtr) ctx;
   28777     if (ctxt->input != NULL) {
   28778        if (file != NULL)
   28779            *file = ctxt->input->filename;
   28780        if (line != NULL)
   28781            *line = ctxt->input->line;
   28782        return(0);
   28783     }
   28784     return(-1);
   28785 }
   28786 
   28787 /**
   28788  * xmlSchemaValidateStream:
   28789  * @ctxt:  a schema validation context
   28790  * @input:  the input to use for reading the data
   28791  * @enc:  an optional encoding information
   28792  * @sax:  a SAX handler for the resulting events
   28793  * @user_data:  the context to provide to the SAX handler.
   28794  *
   28795  * Validate an input based on a flow of SAX event from the parser
   28796  * and forward the events to the @sax handler with the provided @user_data
   28797  * the user provided @sax handler must be a SAX2 one.
   28798  *
   28799  * Returns 0 if the document is schemas valid, a positive error code
   28800  *     number otherwise and -1 in case of internal or API error.
   28801  */
   28802 int
   28803 xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
   28804                         xmlParserInputBufferPtr input, xmlCharEncoding enc,
   28805                         xmlSAXHandlerPtr sax, void *user_data)
   28806 {
   28807     xmlSchemaSAXPlugPtr plug = NULL;
   28808     xmlSAXHandlerPtr old_sax = NULL;
   28809     xmlParserCtxtPtr pctxt = NULL;
   28810     xmlParserInputPtr inputStream = NULL;
   28811     int ret;
   28812 
   28813     if ((ctxt == NULL) || (input == NULL))
   28814         return (-1);
   28815 
   28816     /*
   28817      * prepare the parser
   28818      */
   28819     pctxt = xmlNewParserCtxt();
   28820     if (pctxt == NULL)
   28821         return (-1);
   28822     old_sax = pctxt->sax;
   28823     pctxt->sax = sax;
   28824     pctxt->userData = user_data;
   28825 #if 0
   28826     if (options)
   28827         xmlCtxtUseOptions(pctxt, options);
   28828 #endif
   28829     pctxt->linenumbers = 1;
   28830     xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
   28831 
   28832     inputStream = xmlNewIOInputStream(pctxt, input, enc);;
   28833     if (inputStream == NULL) {
   28834         ret = -1;
   28835 	goto done;
   28836     }
   28837     inputPush(pctxt, inputStream);
   28838     ctxt->parserCtxt = pctxt;
   28839     ctxt->input = input;
   28840 
   28841     /*
   28842      * Plug the validation and launch the parsing
   28843      */
   28844     plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
   28845     if (plug == NULL) {
   28846         ret = -1;
   28847 	goto done;
   28848     }
   28849     ctxt->input = input;
   28850     ctxt->enc = enc;
   28851     ctxt->sax = pctxt->sax;
   28852     ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
   28853     ret = xmlSchemaVStart(ctxt);
   28854 
   28855     if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
   28856 	ret = ctxt->parserCtxt->errNo;
   28857 	if (ret == 0)
   28858 	    ret = 1;
   28859     }
   28860 
   28861 done:
   28862     ctxt->parserCtxt = NULL;
   28863     ctxt->sax = NULL;
   28864     ctxt->input = NULL;
   28865     if (plug != NULL) {
   28866         xmlSchemaSAXUnplug(plug);
   28867     }
   28868     /* cleanup */
   28869     if (pctxt != NULL) {
   28870 	pctxt->sax = old_sax;
   28871 	xmlFreeParserCtxt(pctxt);
   28872     }
   28873     return (ret);
   28874 }
   28875 
   28876 /**
   28877  * xmlSchemaValidateFile:
   28878  * @ctxt: a schema validation context
   28879  * @filename: the URI of the instance
   28880  * @options: a future set of options, currently unused
   28881  *
   28882  * Do a schemas validation of the given resource, it will use the
   28883  * SAX streamable validation internally.
   28884  *
   28885  * Returns 0 if the document is valid, a positive error code
   28886  *     number otherwise and -1 in case of an internal or API error.
   28887  */
   28888 int
   28889 xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
   28890                       const char * filename,
   28891 		      int options ATTRIBUTE_UNUSED)
   28892 {
   28893     int ret;
   28894     xmlParserInputBufferPtr input;
   28895 
   28896     if ((ctxt == NULL) || (filename == NULL))
   28897         return (-1);
   28898 
   28899     input = xmlParserInputBufferCreateFilename(filename,
   28900 	XML_CHAR_ENCODING_NONE);
   28901     if (input == NULL)
   28902 	return (-1);
   28903     ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
   28904 	NULL, NULL);
   28905     return (ret);
   28906 }
   28907 
   28908 /**
   28909  * xmlSchemaValidCtxtGetParserCtxt:
   28910  * @ctxt: a schema validation context
   28911  *
   28912  * allow access to the parser context of the schema validation context
   28913  *
   28914  * Returns the parser context of the schema validation context or NULL
   28915  *         in case of error.
   28916  */
   28917 xmlParserCtxtPtr
   28918 xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
   28919 {
   28920     if (ctxt == NULL)
   28921         return(NULL);
   28922     return (ctxt->parserCtxt);
   28923 }
   28924 
   28925 #define bottom_xmlschemas
   28926 #include "elfgcchack.h"
   28927 #endif /* LIBXML_SCHEMAS_ENABLED */
   28928