Home | History | Annotate | Download | only in libxml2
      1 /*
      2  * schemas.c : implementation of the XML Schema handling and
      3  *             schema validity checking
      4  *
      5  * See Copyright for the status of this software.
      6  *
      7  * Daniel Veillard <veillard (at) redhat.com>
      8  */
      9 
     10 /*
     11  * TODO:
     12  *   - when types are redefined in includes, check that all
     13  *     types in the redef list are equal
     14  *     -> need a type equality operation.
     15  *   - if we don't intend to use the schema for schemas, we
     16  *     need to validate all schema attributes (ref, type, name)
     17  *     against their types.
     18  *   - Eliminate item creation for: ??
     19  *
     20  * URGENT TODO:
     21  *   - For xsi-driven schema acquisition, augment the IDCs after every
     22  *     acquisition episode (xmlSchemaAugmentIDC).
     23  *
     24  * NOTES:
     25  *   - Elimated item creation for: <restriction>, <extension>,
     26  *     <simpleContent>, <complexContent>, <list>, <union>
     27  *
     28  * PROBLEMS:
     29  *   - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
     30  *     IDC XPath expression and chameleon includes: the targetNamespace is changed, so
     31  *     XPath will have trouble to resolve to this namespace, since not known.
     32  *
     33  *
     34  * CONSTRAINTS:
     35  *
     36  * Schema Component Constraint:
     37  *   All Group Limited (cos-all-limited)
     38  *   Status: complete
     39  *   (1.2)
     40  *     In xmlSchemaGroupDefReferenceTermFixup() and
     41  *   (2)
     42  *     In xmlSchemaParseModelGroup()
     43  *     TODO: Actually this should go to component-level checks,
     44  *     but is done here due to performance. Move it to an other layer
     45  *     is schema construction via an API is implemented.
     46  */
     47 #define IN_LIBXML
     48 #include "libxml.h"
     49 
     50 #ifdef LIBXML_SCHEMAS_ENABLED
     51 
     52 #include <string.h>
     53 #include <libxml/xmlmemory.h>
     54 #include <libxml/parser.h>
     55 #include <libxml/parserInternals.h>
     56 #include <libxml/hash.h>
     57 #include <libxml/uri.h>
     58 #include <libxml/xmlschemas.h>
     59 #include <libxml/schemasInternals.h>
     60 #include <libxml/xmlschemastypes.h>
     61 #include <libxml/xmlautomata.h>
     62 #include <libxml/xmlregexp.h>
     63 #include <libxml/dict.h>
     64 #include <libxml/encoding.h>
     65 #include <libxml/xmlIO.h>
     66 #ifdef LIBXML_PATTERN_ENABLED
     67 #include <libxml/pattern.h>
     68 #endif
     69 #ifdef LIBXML_READER_ENABLED
     70 #include <libxml/xmlreader.h>
     71 #endif
     72 
     73 /* #define DEBUG 1 */
     74 
     75 /* #define DEBUG_CONTENT 1 */
     76 
     77 /* #define DEBUG_TYPE 1 */
     78 
     79 /* #define DEBUG_CONTENT_REGEXP 1 */
     80 
     81 /* #define DEBUG_AUTOMATA 1 */
     82 
     83 /* #define DEBUG_IDC */
     84 
     85 /* #define DEBUG_IDC_NODE_TABLE */
     86 
     87 /* #define WXS_ELEM_DECL_CONS_ENABLED */
     88 
     89 #ifdef DEBUG_IDC
     90  #ifndef DEBUG_IDC_NODE_TABLE
     91   #define DEBUG_IDC_NODE_TABLE
     92  #endif
     93 #endif
     94 
     95 /* #define ENABLE_PARTICLE_RESTRICTION 1 */
     96 
     97 #define ENABLE_REDEFINE
     98 
     99 /* #define ENABLE_NAMED_LOCALS */
    100 
    101 /* #define ENABLE_IDC_NODE_TABLES_TEST */
    102 
    103 #define DUMP_CONTENT_MODEL
    104 
    105 #ifdef LIBXML_READER_ENABLED
    106 /* #define XML_SCHEMA_READER_ENABLED */
    107 #endif
    108 
    109 #define UNBOUNDED (1 << 30)
    110 #define TODO 								\
    111     xmlGenericError(xmlGenericErrorContext,				\
    112 	    "Unimplemented block at %s:%d\n",				\
    113             __FILE__, __LINE__);
    114 
    115 #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
    116 
    117 /*
    118  * The XML Schemas namespaces
    119  */
    120 static const xmlChar *xmlSchemaNs = (const xmlChar *)
    121     "http://www.w3.org/2001/XMLSchema";
    122 
    123 static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
    124     "http://www.w3.org/2001/XMLSchema-instance";
    125 
    126 static const xmlChar *xmlNamespaceNs = (const xmlChar *)
    127     "http://www.w3.org/2000/xmlns/";
    128 
    129 /*
    130 * Come casting macros.
    131 */
    132 #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
    133 #define PCTXT_CAST (xmlSchemaParserCtxtPtr)
    134 #define VCTXT_CAST (xmlSchemaValidCtxtPtr)
    135 #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
    136 #define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
    137 #define WXS_PTC_CAST (xmlSchemaParticlePtr)
    138 #define WXS_TYPE_CAST (xmlSchemaTypePtr)
    139 #define WXS_ELEM_CAST (xmlSchemaElementPtr)
    140 #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
    141 #define WXS_ATTR_CAST (xmlSchemaAttributePtr)
    142 #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
    143 #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
    144 #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
    145 #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
    146 #define WXS_IDC_CAST (xmlSchemaIDCPtr)
    147 #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
    148 #define WXS_LIST_CAST (xmlSchemaItemListPtr)
    149 
    150 /*
    151 * Macros to query common properties of components.
    152 */
    153 #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
    154 
    155 #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
    156 /*
    157 * Macros for element declarations.
    158 */
    159 #define WXS_ELEM_TYPEDEF(e) (e)->subtypes
    160 
    161 #define WXS_SUBST_HEAD(item) (item)->refDecl
    162 /*
    163 * Macros for attribute declarations.
    164 */
    165 #define WXS_ATTR_TYPEDEF(a) (a)->subtypes
    166 /*
    167 * Macros for attribute uses.
    168 */
    169 #define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl
    170 
    171 #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
    172 
    173 #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
    174 
    175 #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
    176 /*
    177 * Macros for attribute groups.
    178 */
    179 #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
    180 #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
    181 /*
    182 * Macros for particles.
    183 */
    184 #define WXS_PARTICLE(p) WXS_PTC_CAST (p)
    185 
    186 #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
    187 
    188 #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
    189 
    190 #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
    191 /*
    192 * Macros for model groups definitions.
    193 */
    194 #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
    195 /*
    196 * Macros for model groups.
    197 */
    198 #define WXS_IS_MODEL_GROUP(i) \
    199     (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
    200      ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
    201      ((i)->type == XML_SCHEMA_TYPE_ALL))
    202 
    203 #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
    204 /*
    205 * Macros for schema buckets.
    206 */
    207 #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
    208     ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
    209 
    210 #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
    211     ((t) == XML_SCHEMA_SCHEMA_IMPORT))
    212 
    213 #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
    214 
    215 #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
    216 /*
    217 * Macros for complex/simple types.
    218 */
    219 #define WXS_IS_ANYTYPE(i) \
    220      (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
    221       ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
    222 
    223 #define WXS_IS_COMPLEX(i) \
    224     (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
    225      ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
    226 
    227 #define WXS_IS_SIMPLE(item) \
    228     ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
    229      ((item->type == XML_SCHEMA_TYPE_BASIC) && \
    230       (item->builtInType != XML_SCHEMAS_ANYTYPE)))
    231 
    232 #define WXS_IS_ANY_SIMPLE_TYPE(i) \
    233     (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
    234       ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
    235 
    236 #define WXS_IS_RESTRICTION(t) \
    237     ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
    238 
    239 #define WXS_IS_EXTENSION(t) \
    240     ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
    241 
    242 #define WXS_IS_TYPE_NOT_FIXED(i) \
    243     (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
    244      (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
    245 
    246 #define WXS_IS_TYPE_NOT_FIXED_1(item) \
    247     (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
    248      (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
    249 
    250 #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
    251 
    252 #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
    253 /*
    254 * Macros for exclusively for complex types.
    255 */
    256 #define WXS_HAS_COMPLEX_CONTENT(item) \
    257     ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
    258      (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
    259      (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
    260 
    261 #define WXS_HAS_SIMPLE_CONTENT(item) \
    262     ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
    263      (item->contentType == XML_SCHEMA_CONTENT_BASIC))
    264 
    265 #define WXS_HAS_MIXED_CONTENT(item) \
    266     (item->contentType == XML_SCHEMA_CONTENT_MIXED)
    267 
    268 #define WXS_EMPTIABLE(t) \
    269     (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
    270 
    271 #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
    272 
    273 #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
    274 
    275 #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
    276 /*
    277 * Macros for exclusively for simple types.
    278 */
    279 #define WXS_LIST_ITEMTYPE(t) (t)->subtypes
    280 
    281 #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
    282 
    283 #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
    284 
    285 #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
    286 /*
    287 * Misc parser context macros.
    288 */
    289 #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
    290 
    291 #define WXS_HAS_BUCKETS(ctx) \
    292 ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
    293 (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
    294 
    295 #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
    296 
    297 #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
    298 
    299 #define WXS_SCHEMA(ctx) (ctx)->schema
    300 
    301 #define WXS_ADD_LOCAL(ctx, item) \
    302     xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
    303 
    304 #define WXS_ADD_GLOBAL(ctx, item) \
    305     xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
    306 
    307 #define WXS_ADD_PENDING(ctx, item) \
    308     xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
    309 /*
    310 * xmlSchemaItemList macros.
    311 */
    312 #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
    313 /*
    314 * Misc macros.
    315 */
    316 #define IS_SCHEMA(node, type) \
    317    ((node != NULL) && (node->ns != NULL) && \
    318     (xmlStrEqual(node->name, (const xmlChar *) type)) && \
    319     (xmlStrEqual(node->ns->href, xmlSchemaNs)))
    320 
    321 #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
    322 
    323 /*
    324 * Since we put the default/fixed values into the dict, we can
    325 * use pointer comparison for those values.
    326 * REMOVED: (xmlStrEqual((v1), (v2)))
    327 */
    328 #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
    329 
    330 #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
    331 
    332 #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
    333 
    334 #define HFAILURE if (res == -1) goto exit_failure;
    335 
    336 #define HERROR if (res != 0) goto exit_error;
    337 
    338 #define HSTOP(ctx) if ((ctx)->stop) goto exit;
    339 /*
    340 * Some flags used for various schema constraints.
    341 */
    342 #define SUBSET_RESTRICTION  1<<0
    343 #define SUBSET_EXTENSION    1<<1
    344 #define SUBSET_SUBSTITUTION 1<<2
    345 #define SUBSET_LIST         1<<3
    346 #define SUBSET_UNION        1<<4
    347 
    348 typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
    349 typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
    350 
    351 typedef struct _xmlSchemaItemList xmlSchemaItemList;
    352 typedef xmlSchemaItemList *xmlSchemaItemListPtr;
    353 struct _xmlSchemaItemList {
    354     void **items;  /* used for dynamic addition of schemata */
    355     int nbItems; /* used for dynamic addition of schemata */
    356     int sizeItems; /* used for dynamic addition of schemata */
    357 };
    358 
    359 #define XML_SCHEMA_CTXT_PARSER 1
    360 #define XML_SCHEMA_CTXT_VALIDATOR 2
    361 
    362 typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
    363 typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
    364 struct _xmlSchemaAbstractCtxt {
    365     int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
    366 };
    367 
    368 typedef struct _xmlSchemaBucket xmlSchemaBucket;
    369 typedef xmlSchemaBucket *xmlSchemaBucketPtr;
    370 
    371 #define XML_SCHEMA_SCHEMA_MAIN 0
    372 #define XML_SCHEMA_SCHEMA_IMPORT 1
    373 #define XML_SCHEMA_SCHEMA_INCLUDE 2
    374 #define XML_SCHEMA_SCHEMA_REDEFINE 3
    375 
    376 /**
    377  * xmlSchemaSchemaRelation:
    378  *
    379  * Used to create a graph of schema relationships.
    380  */
    381 typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
    382 typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
    383 struct _xmlSchemaSchemaRelation {
    384     xmlSchemaSchemaRelationPtr next;
    385     int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
    386     const xmlChar *importNamespace;
    387     xmlSchemaBucketPtr bucket;
    388 };
    389 
    390 #define XML_SCHEMA_BUCKET_MARKED 1<<0
    391 #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
    392 
    393 struct _xmlSchemaBucket {
    394     int type;
    395     int flags;
    396     const xmlChar *schemaLocation;
    397     const xmlChar *origTargetNamespace;
    398     const xmlChar *targetNamespace;
    399     xmlDocPtr doc;
    400     xmlSchemaSchemaRelationPtr relations;
    401     int located;
    402     int parsed;
    403     int imported;
    404     int preserveDoc;
    405     xmlSchemaItemListPtr globals; /* Global components. */
    406     xmlSchemaItemListPtr locals; /* Local components. */
    407 };
    408 
    409 /**
    410  * xmlSchemaImport:
    411  * (extends xmlSchemaBucket)
    412  *
    413  * Reflects a schema. Holds some information
    414  * about the schema and its toplevel components. Duplicate
    415  * toplevel components are not checked at this level.
    416  */
    417 typedef struct _xmlSchemaImport xmlSchemaImport;
    418 typedef xmlSchemaImport *xmlSchemaImportPtr;
    419 struct _xmlSchemaImport {
    420     int type; /* Main OR import OR include. */
    421     int flags;
    422     const xmlChar *schemaLocation; /* The URI of the schema document. */
    423     /* For chameleon includes, @origTargetNamespace will be NULL */
    424     const xmlChar *origTargetNamespace;
    425     /*
    426     * For chameleon includes, @targetNamespace will be the
    427     * targetNamespace of the including schema.
    428     */
    429     const xmlChar *targetNamespace;
    430     xmlDocPtr doc; /* The schema node-tree. */
    431     /* @relations will hold any included/imported/redefined schemas. */
    432     xmlSchemaSchemaRelationPtr relations;
    433     int located;
    434     int parsed;
    435     int imported;
    436     int preserveDoc;
    437     xmlSchemaItemListPtr globals;
    438     xmlSchemaItemListPtr locals;
    439     /* The imported schema. */
    440     xmlSchemaPtr schema;
    441 };
    442 
    443 /*
    444 * (extends xmlSchemaBucket)
    445 */
    446 typedef struct _xmlSchemaInclude xmlSchemaInclude;
    447 typedef xmlSchemaInclude *xmlSchemaIncludePtr;
    448 struct _xmlSchemaInclude {
    449     int type;
    450     int flags;
    451     const xmlChar *schemaLocation;
    452     const xmlChar *origTargetNamespace;
    453     const xmlChar *targetNamespace;
    454     xmlDocPtr doc;
    455     xmlSchemaSchemaRelationPtr relations;
    456     int located;
    457     int parsed;
    458     int imported;
    459     int preserveDoc;
    460     xmlSchemaItemListPtr globals; /* Global components. */
    461     xmlSchemaItemListPtr locals; /* Local components. */
    462 
    463     /* The owning main or import schema bucket. */
    464     xmlSchemaImportPtr ownerImport;
    465 };
    466 
    467 /**
    468  * xmlSchemaBasicItem:
    469  *
    470  * The abstract base type for schema components.
    471  */
    472 typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
    473 typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
    474 struct _xmlSchemaBasicItem {
    475     xmlSchemaTypeType type;
    476 };
    477 
    478 /**
    479  * xmlSchemaAnnotItem:
    480  *
    481  * The abstract base type for annotated schema components.
    482  * (Extends xmlSchemaBasicItem)
    483  */
    484 typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
    485 typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
    486 struct _xmlSchemaAnnotItem {
    487     xmlSchemaTypeType type;
    488     xmlSchemaAnnotPtr annot;
    489 };
    490 
    491 /**
    492  * xmlSchemaTreeItem:
    493  *
    494  * The abstract base type for tree-like structured schema components.
    495  * (Extends xmlSchemaAnnotItem)
    496  */
    497 typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
    498 typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
    499 struct _xmlSchemaTreeItem {
    500     xmlSchemaTypeType type;
    501     xmlSchemaAnnotPtr annot;
    502     xmlSchemaTreeItemPtr next;
    503     xmlSchemaTreeItemPtr children;
    504 };
    505 
    506 
    507 #define XML_SCHEMA_ATTR_USE_FIXED 1<<0
    508 /**
    509  * xmlSchemaAttributeUsePtr:
    510  *
    511  * The abstract base type for tree-like structured schema components.
    512  * (Extends xmlSchemaTreeItem)
    513  */
    514 typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
    515 typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
    516 struct _xmlSchemaAttributeUse {
    517     xmlSchemaTypeType type;
    518     xmlSchemaAnnotPtr annot;
    519     xmlSchemaAttributeUsePtr next; /* The next attr. use. */
    520     /*
    521     * The attr. decl. OR a QName-ref. to an attr. decl. OR
    522     * a QName-ref. to an attribute group definition.
    523     */
    524     xmlSchemaAttributePtr attrDecl;
    525 
    526     int flags;
    527     xmlNodePtr node;
    528     int occurs; /* required, optional */
    529     const xmlChar * defValue;
    530     xmlSchemaValPtr defVal;
    531 };
    532 
    533 /**
    534  * xmlSchemaAttributeUseProhibPtr:
    535  *
    536  * A helper component to reflect attribute prohibitions.
    537  * (Extends xmlSchemaBasicItem)
    538  */
    539 typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
    540 typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
    541 struct _xmlSchemaAttributeUseProhib {
    542     xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
    543     xmlNodePtr node;
    544     const xmlChar *name;
    545     const xmlChar *targetNamespace;
    546     int isRef;
    547 };
    548 
    549 /**
    550  * xmlSchemaRedef:
    551  */
    552 typedef struct _xmlSchemaRedef xmlSchemaRedef;
    553 typedef xmlSchemaRedef *xmlSchemaRedefPtr;
    554 struct _xmlSchemaRedef {
    555     xmlSchemaRedefPtr next;
    556     xmlSchemaBasicItemPtr item; /* The redefining component. */
    557     xmlSchemaBasicItemPtr reference; /* The referencing component. */
    558     xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
    559     const xmlChar *refName; /* The name of the to-be-redefined component. */
    560     const xmlChar *refTargetNs; /* The target namespace of the
    561                                    to-be-redefined comp. */
    562     xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
    563 };
    564 
    565 /**
    566  * xmlSchemaConstructionCtxt:
    567  */
    568 typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
    569 typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
    570 struct _xmlSchemaConstructionCtxt {
    571     xmlSchemaPtr mainSchema; /* The main schema. */
    572     xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
    573     xmlDictPtr dict;
    574     xmlSchemaItemListPtr buckets; /* List of schema buckets. */
    575     /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
    576     xmlSchemaBucketPtr bucket; /* The current schema bucket */
    577     xmlSchemaItemListPtr pending; /* All Components of all schemas that
    578                                      need to be fixed. */
    579     xmlHashTablePtr substGroups;
    580     xmlSchemaRedefPtr redefs;
    581     xmlSchemaRedefPtr lastRedef;
    582 };
    583 
    584 #define XML_SCHEMAS_PARSE_ERROR		1
    585 #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
    586 
    587 struct _xmlSchemaParserCtxt {
    588     int type;
    589     void *errCtxt;             /* user specific error context */
    590     xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
    591     xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
    592     int err;
    593     int nberrors;
    594     xmlStructuredErrorFunc serror;
    595 
    596     xmlSchemaConstructionCtxtPtr constructor;
    597     int ownsConstructor; /* TODO: Move this to parser *flags*. */
    598 
    599     /* xmlSchemaPtr topschema;	*/
    600     /* xmlHashTablePtr namespaces;  */
    601 
    602     xmlSchemaPtr schema;        /* The main schema in use */
    603     int counter;
    604 
    605     const xmlChar *URL;
    606     xmlDocPtr doc;
    607     int preserve;		/* Whether the doc should be freed  */
    608 
    609     const char *buffer;
    610     int size;
    611 
    612     /*
    613      * Used to build complex element content models
    614      */
    615     xmlAutomataPtr am;
    616     xmlAutomataStatePtr start;
    617     xmlAutomataStatePtr end;
    618     xmlAutomataStatePtr state;
    619 
    620     xmlDictPtr dict;		/* dictionnary for interned string names */
    621     xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
    622     int options;
    623     xmlSchemaValidCtxtPtr vctxt;
    624     int isS4S;
    625     int isRedefine;
    626     int xsiAssemble;
    627     int stop; /* If the parser should stop; i.e. a critical error. */
    628     const xmlChar *targetNamespace;
    629     xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
    630 
    631     xmlSchemaRedefPtr redef; /* Used for redefinitions. */
    632     int redefCounter; /* Used for redefinitions. */
    633     xmlSchemaItemListPtr attrProhibs;
    634 };
    635 
    636 /**
    637  * xmlSchemaQNameRef:
    638  *
    639  * A component reference item (not a schema component)
    640  * (Extends xmlSchemaBasicItem)
    641  */
    642 typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
    643 typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
    644 struct _xmlSchemaQNameRef {
    645     xmlSchemaTypeType type;
    646     xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
    647     xmlSchemaTypeType itemType;
    648     const xmlChar *name;
    649     const xmlChar *targetNamespace;
    650     xmlNodePtr node;
    651 };
    652 
    653 /**
    654  * xmlSchemaParticle:
    655  *
    656  * A particle component.
    657  * (Extends xmlSchemaTreeItem)
    658  */
    659 typedef struct _xmlSchemaParticle xmlSchemaParticle;
    660 typedef xmlSchemaParticle *xmlSchemaParticlePtr;
    661 struct _xmlSchemaParticle {
    662     xmlSchemaTypeType type;
    663     xmlSchemaAnnotPtr annot;
    664     xmlSchemaTreeItemPtr next; /* next particle */
    665     xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
    666 	a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
    667         etc.) */
    668     int minOccurs;
    669     int maxOccurs;
    670     xmlNodePtr node;
    671 };
    672 
    673 /**
    674  * xmlSchemaModelGroup:
    675  *
    676  * A model group component.
    677  * (Extends xmlSchemaTreeItem)
    678  */
    679 typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
    680 typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
    681 struct _xmlSchemaModelGroup {
    682     xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
    683     xmlSchemaAnnotPtr annot;
    684     xmlSchemaTreeItemPtr next; /* not used */
    685     xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
    686     xmlNodePtr node;
    687 };
    688 
    689 #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
    690 #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
    691 /**
    692  * xmlSchemaModelGroupDef:
    693  *
    694  * A model group definition component.
    695  * (Extends xmlSchemaTreeItem)
    696  */
    697 typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
    698 typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
    699 struct _xmlSchemaModelGroupDef {
    700     xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
    701     xmlSchemaAnnotPtr annot;
    702     xmlSchemaTreeItemPtr next; /* not used */
    703     xmlSchemaTreeItemPtr children; /* the "model group" */
    704     const xmlChar *name;
    705     const xmlChar *targetNamespace;
    706     xmlNodePtr node;
    707     int flags;
    708 };
    709 
    710 typedef struct _xmlSchemaIDC xmlSchemaIDC;
    711 typedef xmlSchemaIDC *xmlSchemaIDCPtr;
    712 
    713 /**
    714  * xmlSchemaIDCSelect:
    715  *
    716  * The identity-constraint "field" and "selector" item, holding the
    717  * XPath expression.
    718  */
    719 typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
    720 typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
    721 struct _xmlSchemaIDCSelect {
    722     xmlSchemaIDCSelectPtr next;
    723     xmlSchemaIDCPtr idc;
    724     int index; /* an index position if significant for IDC key-sequences */
    725     const xmlChar *xpath; /* the XPath expression */
    726     void *xpathComp; /* the compiled XPath expression */
    727 };
    728 
    729 /**
    730  * xmlSchemaIDC:
    731  *
    732  * The identity-constraint definition component.
    733  * (Extends xmlSchemaAnnotItem)
    734  */
    735 
    736 struct _xmlSchemaIDC {
    737     xmlSchemaTypeType type;
    738     xmlSchemaAnnotPtr annot;
    739     xmlSchemaIDCPtr next;
    740     xmlNodePtr node;
    741     const xmlChar *name;
    742     const xmlChar *targetNamespace;
    743     xmlSchemaIDCSelectPtr selector;
    744     xmlSchemaIDCSelectPtr fields;
    745     int nbFields;
    746     xmlSchemaQNameRefPtr ref;
    747 };
    748 
    749 /**
    750  * xmlSchemaIDCAug:
    751  *
    752  * The augmented IDC information used for validation.
    753  */
    754 typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
    755 typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
    756 struct _xmlSchemaIDCAug {
    757     xmlSchemaIDCAugPtr next; /* next in a list */
    758     xmlSchemaIDCPtr def; /* the IDC definition */
    759     int keyrefDepth; /* the lowest tree level to which IDC
    760                         tables need to be bubbled upwards */
    761 };
    762 
    763 /**
    764  * xmlSchemaPSVIIDCKeySequence:
    765  *
    766  * The key sequence of a node table item.
    767  */
    768 typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
    769 typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
    770 struct _xmlSchemaPSVIIDCKey {
    771     xmlSchemaTypePtr type;
    772     xmlSchemaValPtr val;
    773 };
    774 
    775 /**
    776  * xmlSchemaPSVIIDCNode:
    777  *
    778  * The node table item of a node table.
    779  */
    780 typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
    781 typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
    782 struct _xmlSchemaPSVIIDCNode {
    783     xmlNodePtr node;
    784     xmlSchemaPSVIIDCKeyPtr *keys;
    785     int nodeLine;
    786     int nodeQNameID;
    787 
    788 };
    789 
    790 /**
    791  * xmlSchemaPSVIIDCBinding:
    792  *
    793  * The identity-constraint binding item of the [identity-constraint table].
    794  */
    795 typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
    796 typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
    797 struct _xmlSchemaPSVIIDCBinding {
    798     xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
    799     xmlSchemaIDCPtr definition; /* the IDC definition */
    800     xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
    801     int nbNodes; /* number of entries in the node table */
    802     int sizeNodes; /* size of the node table */
    803     xmlSchemaItemListPtr dupls;
    804 };
    805 
    806 
    807 #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
    808 #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
    809 
    810 #define XPATH_STATE_OBJ_MATCHES -2
    811 #define XPATH_STATE_OBJ_BLOCKED -3
    812 
    813 typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
    814 typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
    815 
    816 /**
    817  * xmlSchemaIDCStateObj:
    818  *
    819  * The state object used to evaluate XPath expressions.
    820  */
    821 typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
    822 typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
    823 struct _xmlSchemaIDCStateObj {
    824     int type;
    825     xmlSchemaIDCStateObjPtr next; /* next if in a list */
    826     int depth; /* depth of creation */
    827     int *history; /* list of (depth, state-id) tuples */
    828     int nbHistory;
    829     int sizeHistory;
    830     xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
    831                                        matcher */
    832     xmlSchemaIDCSelectPtr sel;
    833     void *xpathCtxt;
    834 };
    835 
    836 #define IDC_MATCHER 0
    837 
    838 /**
    839  * xmlSchemaIDCMatcher:
    840  *
    841  * Used to evaluate IDC selectors (and fields).
    842  */
    843 struct _xmlSchemaIDCMatcher {
    844     int type;
    845     int depth; /* the tree depth at creation time */
    846     xmlSchemaIDCMatcherPtr next; /* next in the list */
    847     xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
    848     xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
    849     int idcType;
    850     xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
    851                                          elements */
    852     int sizeKeySeqs;
    853     xmlSchemaItemListPtr targets; /* list of target-node
    854                                      (xmlSchemaPSVIIDCNodePtr) entries */
    855 };
    856 
    857 /*
    858 * Element info flags.
    859 */
    860 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES  1<<0
    861 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
    862 #define XML_SCHEMA_ELEM_INFO_NILLED	       1<<2
    863 #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE	       1<<3
    864 
    865 #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED      1<<4
    866 #define XML_SCHEMA_ELEM_INFO_EMPTY             1<<5
    867 #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT       1<<6
    868 
    869 #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT  1<<7
    870 #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT  1<<8
    871 #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED  1<<9
    872 #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE  1<<10
    873 
    874 /**
    875  * xmlSchemaNodeInfo:
    876  *
    877  * Holds information of an element node.
    878  */
    879 struct _xmlSchemaNodeInfo {
    880     int nodeType;
    881     xmlNodePtr node;
    882     int nodeLine;
    883     const xmlChar *localName;
    884     const xmlChar *nsName;
    885     const xmlChar *value;
    886     xmlSchemaValPtr val; /* the pre-computed value if any */
    887     xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
    888 
    889     int flags; /* combination of node info flags */
    890 
    891     int valNeeded;
    892     int normVal;
    893 
    894     xmlSchemaElementPtr decl; /* the element/attribute declaration */
    895     int depth;
    896     xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
    897                                             for the scope element*/
    898     xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
    899                                            element */
    900     xmlRegExecCtxtPtr regexCtxt;
    901 
    902     const xmlChar **nsBindings; /* Namespace bindings on this element */
    903     int nbNsBindings;
    904     int sizeNsBindings;
    905 
    906     int hasKeyrefs;
    907     int appliedXPath; /* Indicates that an XPath has been applied. */
    908 };
    909 
    910 #define XML_SCHEMAS_ATTR_UNKNOWN 1
    911 #define XML_SCHEMAS_ATTR_ASSESSED 2
    912 #define XML_SCHEMAS_ATTR_PROHIBITED 3
    913 #define XML_SCHEMAS_ATTR_ERR_MISSING 4
    914 #define XML_SCHEMAS_ATTR_INVALID_VALUE 5
    915 #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
    916 #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
    917 #define XML_SCHEMAS_ATTR_DEFAULT 8
    918 #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
    919 #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
    920 #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
    921 #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
    922 #define XML_SCHEMAS_ATTR_WILD_SKIP 13
    923 #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
    924 #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
    925 #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
    926 #define XML_SCHEMAS_ATTR_META 17
    927 /*
    928 * @metaType values of xmlSchemaAttrInfo.
    929 */
    930 #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
    931 #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
    932 #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
    933 #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
    934 #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
    935 
    936 typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
    937 typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
    938 struct _xmlSchemaAttrInfo {
    939     int nodeType;
    940     xmlNodePtr node;
    941     int nodeLine;
    942     const xmlChar *localName;
    943     const xmlChar *nsName;
    944     const xmlChar *value;
    945     xmlSchemaValPtr val; /* the pre-computed value if any */
    946     xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
    947     int flags; /* combination of node info flags */
    948 
    949     xmlSchemaAttributePtr decl; /* the attribute declaration */
    950     xmlSchemaAttributeUsePtr use;  /* the attribute use */
    951     int state;
    952     int metaType;
    953     const xmlChar *vcValue; /* the value constraint value */
    954     xmlSchemaNodeInfoPtr parent;
    955 };
    956 
    957 
    958 #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
    959 /**
    960  * xmlSchemaValidCtxt:
    961  *
    962  * A Schemas validation context
    963  */
    964 struct _xmlSchemaValidCtxt {
    965     int type;
    966     void *errCtxt;             /* user specific data block */
    967     xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
    968     xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
    969     xmlStructuredErrorFunc serror;
    970 
    971     xmlSchemaPtr schema;        /* The schema in use */
    972     xmlDocPtr doc;
    973     xmlParserInputBufferPtr input;
    974     xmlCharEncoding enc;
    975     xmlSAXHandlerPtr sax;
    976     xmlParserCtxtPtr parserCtxt;
    977     void *user_data; /* TODO: What is this for? */
    978 
    979     int err;
    980     int nberrors;
    981 
    982     xmlNodePtr node;
    983     xmlNodePtr cur;
    984     /* xmlSchemaTypePtr type; */
    985 
    986     xmlRegExecCtxtPtr regexp;
    987     xmlSchemaValPtr value;
    988 
    989     int valueWS;
    990     int options;
    991     xmlNodePtr validationRoot;
    992     xmlSchemaParserCtxtPtr pctxt;
    993     int xsiAssemble;
    994 
    995     int depth;
    996     xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */
    997     int sizeElemInfos;
    998     xmlSchemaNodeInfoPtr inode; /* the current element information */
    999 
   1000     xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */
   1001 
   1002     xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
   1003     xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
   1004     xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
   1005 
   1006     xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
   1007     int nbIdcNodes;
   1008     int sizeIdcNodes;
   1009 
   1010     xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
   1011     int nbIdcKeys;
   1012     int sizeIdcKeys;
   1013 
   1014     int flags;
   1015 
   1016     xmlDictPtr dict;
   1017 
   1018 #ifdef LIBXML_READER_ENABLED
   1019     xmlTextReaderPtr reader;
   1020 #endif
   1021 
   1022     xmlSchemaAttrInfoPtr *attrInfos;
   1023     int nbAttrInfos;
   1024     int sizeAttrInfos;
   1025 
   1026     int skipDepth;
   1027     xmlSchemaItemListPtr nodeQNames;
   1028     int hasKeyrefs;
   1029     int createIDCNodeTables;
   1030     int psviExposeIDCNodeTables;
   1031 };
   1032 
   1033 /**
   1034  * xmlSchemaSubstGroup:
   1035  *
   1036  *
   1037  */
   1038 typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
   1039 typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
   1040 struct _xmlSchemaSubstGroup {
   1041     xmlSchemaElementPtr head;
   1042     xmlSchemaItemListPtr members;
   1043 };
   1044 
   1045 /************************************************************************
   1046  * 									*
   1047  * 			Some predeclarations				*
   1048  * 									*
   1049  ************************************************************************/
   1050 
   1051 static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
   1052                                  xmlSchemaPtr schema,
   1053                                  xmlNodePtr node);
   1054 static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
   1055                                  xmlSchemaPtr schema,
   1056                                  xmlNodePtr node);
   1057 static int
   1058 xmlSchemaTypeFixup(xmlSchemaTypePtr type,
   1059                    xmlSchemaAbstractCtxtPtr ctxt);
   1060 static const xmlChar *
   1061 xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
   1062 static int
   1063 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   1064                      xmlNodePtr node);
   1065 static int
   1066 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
   1067                        xmlSchemaParserCtxtPtr ctxt);
   1068 static void
   1069 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
   1070 static xmlSchemaWhitespaceValueType
   1071 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
   1072 static xmlSchemaTreeItemPtr
   1073 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   1074 			 xmlNodePtr node, xmlSchemaTypeType type,
   1075 			 int withParticle);
   1076 static const xmlChar *
   1077 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
   1078 static xmlSchemaTypeLinkPtr
   1079 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
   1080 static void
   1081 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
   1082 		     const char *funcName,
   1083 		     const char *message);
   1084 static int
   1085 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
   1086 			     xmlSchemaTypePtr type,
   1087 			     xmlSchemaTypePtr baseType,
   1088 			     int subset);
   1089 static void
   1090 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
   1091 				   xmlSchemaParserCtxtPtr ctxt);
   1092 static void
   1093 xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
   1094 static xmlSchemaQNameRefPtr
   1095 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
   1096 				xmlSchemaPtr schema,
   1097 				xmlNodePtr node);
   1098 
   1099 /************************************************************************
   1100  *									*
   1101  * 			Helper functions			        *
   1102  *									*
   1103  ************************************************************************/
   1104 
   1105 /**
   1106  * xmlSchemaItemTypeToStr:
   1107  * @type: the type of the schema item
   1108  *
   1109  * Returns the component name of a schema item.
   1110  */
   1111 static const xmlChar *
   1112 xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
   1113 {
   1114     switch (type) {
   1115 	case XML_SCHEMA_TYPE_BASIC:
   1116 	    return(BAD_CAST "simple type definition");
   1117 	case XML_SCHEMA_TYPE_SIMPLE:
   1118 	    return(BAD_CAST "simple type definition");
   1119 	case XML_SCHEMA_TYPE_COMPLEX:
   1120 	    return(BAD_CAST "complex type definition");
   1121 	case XML_SCHEMA_TYPE_ELEMENT:
   1122 	    return(BAD_CAST "element declaration");
   1123 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   1124 	    return(BAD_CAST "attribute use");
   1125 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   1126 	    return(BAD_CAST "attribute declaration");
   1127 	case XML_SCHEMA_TYPE_GROUP:
   1128 	    return(BAD_CAST "model group definition");
   1129 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1130 	    return(BAD_CAST "attribute group definition");
   1131 	case XML_SCHEMA_TYPE_NOTATION:
   1132 	    return(BAD_CAST "notation declaration");
   1133 	case XML_SCHEMA_TYPE_SEQUENCE:
   1134 	    return(BAD_CAST "model group (sequence)");
   1135 	case XML_SCHEMA_TYPE_CHOICE:
   1136 	    return(BAD_CAST "model group (choice)");
   1137 	case XML_SCHEMA_TYPE_ALL:
   1138 	    return(BAD_CAST "model group (all)");
   1139 	case XML_SCHEMA_TYPE_PARTICLE:
   1140 	    return(BAD_CAST "particle");
   1141 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1142 	    return(BAD_CAST "unique identity-constraint");
   1143 	    /* return(BAD_CAST "IDC (unique)"); */
   1144 	case XML_SCHEMA_TYPE_IDC_KEY:
   1145 	    return(BAD_CAST "key identity-constraint");
   1146 	    /* return(BAD_CAST "IDC (key)"); */
   1147 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1148 	    return(BAD_CAST "keyref identity-constraint");
   1149 	    /* return(BAD_CAST "IDC (keyref)"); */
   1150 	case XML_SCHEMA_TYPE_ANY:
   1151 	    return(BAD_CAST "wildcard (any)");
   1152 	case XML_SCHEMA_EXTRA_QNAMEREF:
   1153 	    return(BAD_CAST "[helper component] QName reference");
   1154 	case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
   1155 	    return(BAD_CAST "[helper component] attribute use prohibition");
   1156 	default:
   1157 	    return(BAD_CAST "Not a schema component");
   1158     }
   1159 }
   1160 
   1161 /**
   1162  * xmlSchemaGetComponentTypeStr:
   1163  * @type: the type of the schema item
   1164  *
   1165  * Returns the component name of a schema item.
   1166  */
   1167 static const xmlChar *
   1168 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
   1169 {
   1170     switch (item->type) {
   1171 	case XML_SCHEMA_TYPE_BASIC:
   1172 	    if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
   1173 		return(BAD_CAST "complex type definition");
   1174 	    else
   1175 		return(BAD_CAST "simple type definition");
   1176 	default:
   1177 	    return(xmlSchemaItemTypeToStr(item->type));
   1178     }
   1179 }
   1180 
   1181 /**
   1182  * xmlSchemaGetComponentNode:
   1183  * @item: a schema component
   1184  *
   1185  * Returns node associated with the schema component.
   1186  * NOTE that such a node need not be available; plus, a component's
   1187  * node need not to reflect the component directly, since there is no
   1188  * one-to-one relationship between the XML Schema representation and
   1189  * the component representation.
   1190  */
   1191 static xmlNodePtr
   1192 xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
   1193 {
   1194     switch (item->type) {
   1195 	case XML_SCHEMA_TYPE_ELEMENT:
   1196 	    return (((xmlSchemaElementPtr) item)->node);
   1197 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   1198 	    return (((xmlSchemaAttributePtr) item)->node);
   1199 	case XML_SCHEMA_TYPE_COMPLEX:
   1200 	case XML_SCHEMA_TYPE_SIMPLE:
   1201 	    return (((xmlSchemaTypePtr) item)->node);
   1202 	case XML_SCHEMA_TYPE_ANY:
   1203 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   1204 	    return (((xmlSchemaWildcardPtr) item)->node);
   1205 	case XML_SCHEMA_TYPE_PARTICLE:
   1206 	    return (((xmlSchemaParticlePtr) item)->node);
   1207 	case XML_SCHEMA_TYPE_SEQUENCE:
   1208 	case XML_SCHEMA_TYPE_CHOICE:
   1209 	case XML_SCHEMA_TYPE_ALL:
   1210 	    return (((xmlSchemaModelGroupPtr) item)->node);
   1211 	case XML_SCHEMA_TYPE_GROUP:
   1212 	    return (((xmlSchemaModelGroupDefPtr) item)->node);
   1213 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1214 	    return (((xmlSchemaAttributeGroupPtr) item)->node);
   1215 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1216 	case XML_SCHEMA_TYPE_IDC_KEY:
   1217 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1218 	    return (((xmlSchemaIDCPtr) item)->node);
   1219 	case XML_SCHEMA_EXTRA_QNAMEREF:
   1220 	    return(((xmlSchemaQNameRefPtr) item)->node);
   1221 	/* TODO: What to do with NOTATIONs?
   1222 	case XML_SCHEMA_TYPE_NOTATION:
   1223 	    return (((xmlSchemaNotationPtr) item)->node);
   1224 	*/
   1225 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   1226 	    return (((xmlSchemaAttributeUsePtr) item)->node);
   1227 	default:
   1228 	    return (NULL);
   1229     }
   1230 }
   1231 
   1232 #if 0
   1233 /**
   1234  * xmlSchemaGetNextComponent:
   1235  * @item: a schema component
   1236  *
   1237  * Returns the next sibling of the schema component.
   1238  */
   1239 static xmlSchemaBasicItemPtr
   1240 xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
   1241 {
   1242     switch (item->type) {
   1243 	case XML_SCHEMA_TYPE_ELEMENT:
   1244 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
   1245 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   1246 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
   1247 	case XML_SCHEMA_TYPE_COMPLEX:
   1248 	case XML_SCHEMA_TYPE_SIMPLE:
   1249 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
   1250 	case XML_SCHEMA_TYPE_ANY:
   1251 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   1252 	    return (NULL);
   1253 	case XML_SCHEMA_TYPE_PARTICLE:
   1254 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
   1255 	case XML_SCHEMA_TYPE_SEQUENCE:
   1256 	case XML_SCHEMA_TYPE_CHOICE:
   1257 	case XML_SCHEMA_TYPE_ALL:
   1258 	    return (NULL);
   1259 	case XML_SCHEMA_TYPE_GROUP:
   1260 	    return (NULL);
   1261 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1262 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
   1263 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1264 	case XML_SCHEMA_TYPE_IDC_KEY:
   1265 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1266 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
   1267 	default:
   1268 	    return (NULL);
   1269     }
   1270 }
   1271 #endif
   1272 
   1273 
   1274 /**
   1275  * xmlSchemaFormatQName:
   1276  * @buf: the string buffer
   1277  * @namespaceName:  the namespace name
   1278  * @localName: the local name
   1279  *
   1280  * Returns the given QName in the format "{namespaceName}localName" or
   1281  * just "localName" if @namespaceName is NULL.
   1282  *
   1283  * Returns the localName if @namespaceName is NULL, a formatted
   1284  * string otherwise.
   1285  */
   1286 static const xmlChar*
   1287 xmlSchemaFormatQName(xmlChar **buf,
   1288 		     const xmlChar *namespaceName,
   1289 		     const xmlChar *localName)
   1290 {
   1291     FREE_AND_NULL(*buf)
   1292     if (namespaceName != NULL) {
   1293 	*buf = xmlStrdup(BAD_CAST "{");
   1294 	*buf = xmlStrcat(*buf, namespaceName);
   1295 	*buf = xmlStrcat(*buf, BAD_CAST "}");
   1296     }
   1297     if (localName != NULL) {
   1298 	if (namespaceName == NULL)
   1299 	    return(localName);
   1300 	*buf = xmlStrcat(*buf, localName);
   1301     } else {
   1302 	*buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
   1303     }
   1304     return ((const xmlChar *) *buf);
   1305 }
   1306 
   1307 static const xmlChar*
   1308 xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
   1309 {
   1310     if (ns != NULL)
   1311 	return (xmlSchemaFormatQName(buf, ns->href, localName));
   1312     else
   1313 	return (xmlSchemaFormatQName(buf, NULL, localName));
   1314 }
   1315 
   1316 static const xmlChar *
   1317 xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
   1318 {
   1319     switch (item->type) {
   1320 	case XML_SCHEMA_TYPE_ELEMENT:
   1321 	    return (((xmlSchemaElementPtr) item)->name);
   1322 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   1323 	    return (((xmlSchemaAttributePtr) item)->name);
   1324 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1325 	    return (((xmlSchemaAttributeGroupPtr) item)->name);
   1326 	case XML_SCHEMA_TYPE_BASIC:
   1327 	case XML_SCHEMA_TYPE_SIMPLE:
   1328 	case XML_SCHEMA_TYPE_COMPLEX:
   1329 	    return (((xmlSchemaTypePtr) item)->name);
   1330 	case XML_SCHEMA_TYPE_GROUP:
   1331 	    return (((xmlSchemaModelGroupDefPtr) item)->name);
   1332 	case XML_SCHEMA_TYPE_IDC_KEY:
   1333 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1334 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1335 	    return (((xmlSchemaIDCPtr) item)->name);
   1336 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   1337 	    if (WXS_ATTRUSE_DECL(item) != NULL) {
   1338 		return(xmlSchemaGetComponentName(
   1339 		    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
   1340 	    } else
   1341 		return(NULL);
   1342 	case XML_SCHEMA_EXTRA_QNAMEREF:
   1343 	    return (((xmlSchemaQNameRefPtr) item)->name);
   1344 	case XML_SCHEMA_TYPE_NOTATION:
   1345 	    return (((xmlSchemaNotationPtr) item)->name);
   1346 	default:
   1347 	    /*
   1348 	    * Other components cannot have names.
   1349 	    */
   1350 	    break;
   1351     }
   1352     return (NULL);
   1353 }
   1354 
   1355 #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
   1356 #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
   1357 /*
   1358 static const xmlChar *
   1359 xmlSchemaGetQNameRefName(void *ref)
   1360 {
   1361     return(((xmlSchemaQNameRefPtr) ref)->name);
   1362 }
   1363 
   1364 static const xmlChar *
   1365 xmlSchemaGetQNameRefTargetNs(void *ref)
   1366 {
   1367     return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
   1368 }
   1369 */
   1370 
   1371 static const xmlChar *
   1372 xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
   1373 {
   1374     switch (item->type) {
   1375 	case XML_SCHEMA_TYPE_ELEMENT:
   1376 	    return (((xmlSchemaElementPtr) item)->targetNamespace);
   1377 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   1378 	    return (((xmlSchemaAttributePtr) item)->targetNamespace);
   1379 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1380 	    return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
   1381 	case XML_SCHEMA_TYPE_BASIC:
   1382 	    return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
   1383 	case XML_SCHEMA_TYPE_SIMPLE:
   1384 	case XML_SCHEMA_TYPE_COMPLEX:
   1385 	    return (((xmlSchemaTypePtr) item)->targetNamespace);
   1386 	case XML_SCHEMA_TYPE_GROUP:
   1387 	    return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
   1388 	case XML_SCHEMA_TYPE_IDC_KEY:
   1389 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1390 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1391 	    return (((xmlSchemaIDCPtr) item)->targetNamespace);
   1392 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   1393 	    if (WXS_ATTRUSE_DECL(item) != NULL) {
   1394 		return(xmlSchemaGetComponentTargetNs(
   1395 		    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
   1396 	    }
   1397 	    /* TODO: Will returning NULL break something? */
   1398 	    break;
   1399 	case XML_SCHEMA_EXTRA_QNAMEREF:
   1400 	    return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
   1401 	case XML_SCHEMA_TYPE_NOTATION:
   1402 	    return (((xmlSchemaNotationPtr) item)->targetNamespace);
   1403 	default:
   1404 	    /*
   1405 	    * Other components cannot have names.
   1406 	    */
   1407 	    break;
   1408     }
   1409     return (NULL);
   1410 }
   1411 
   1412 static const xmlChar*
   1413 xmlSchemaGetComponentQName(xmlChar **buf,
   1414 			   void *item)
   1415 {
   1416     return (xmlSchemaFormatQName(buf,
   1417 	xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
   1418 	xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
   1419 }
   1420 
   1421 static const xmlChar*
   1422 xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
   1423 {
   1424     xmlChar *str = NULL;
   1425 
   1426     *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
   1427     *buf = xmlStrcat(*buf, BAD_CAST " '");
   1428     *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
   1429 	(xmlSchemaBasicItemPtr) item));
   1430     *buf = xmlStrcat(*buf, BAD_CAST "'");
   1431     FREE_AND_NULL(str);
   1432     return(*buf);
   1433 }
   1434 
   1435 static const xmlChar*
   1436 xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
   1437 {
   1438     return(xmlSchemaGetComponentDesignation(buf, idc));
   1439 }
   1440 
   1441 /**
   1442  * xmlSchemaWildcardPCToString:
   1443  * @pc: the type of processContents
   1444  *
   1445  * Returns a string representation of the type of
   1446  * processContents.
   1447  */
   1448 static const xmlChar *
   1449 xmlSchemaWildcardPCToString(int pc)
   1450 {
   1451     switch (pc) {
   1452 	case XML_SCHEMAS_ANY_SKIP:
   1453 	    return (BAD_CAST "skip");
   1454 	case XML_SCHEMAS_ANY_LAX:
   1455 	    return (BAD_CAST "lax");
   1456 	case XML_SCHEMAS_ANY_STRICT:
   1457 	    return (BAD_CAST "strict");
   1458 	default:
   1459 	    return (BAD_CAST "invalid process contents");
   1460     }
   1461 }
   1462 
   1463 /**
   1464  * xmlSchemaGetCanonValueWhtspExt:
   1465  * @val: the precomputed value
   1466  * @retValue: the returned value
   1467  * @ws: the whitespace type of the value
   1468  *
   1469  * Get a the cononical representation of the value.
   1470  * The caller has to free the returned retValue.
   1471  *
   1472  * Returns 0 if the value could be built and -1 in case of
   1473  *         API errors or if the value type is not supported yet.
   1474  */
   1475 static int
   1476 xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
   1477 			       xmlSchemaWhitespaceValueType ws,
   1478 			       xmlChar **retValue)
   1479 {
   1480     int list;
   1481     xmlSchemaValType valType;
   1482     const xmlChar *value, *value2 = NULL;
   1483 
   1484 
   1485     if ((retValue == NULL) || (val == NULL))
   1486 	return (-1);
   1487     list = xmlSchemaValueGetNext(val) ? 1 : 0;
   1488     *retValue = NULL;
   1489     do {
   1490 	value = NULL;
   1491 	valType = xmlSchemaGetValType(val);
   1492 	switch (valType) {
   1493 	    case XML_SCHEMAS_STRING:
   1494 	    case XML_SCHEMAS_NORMSTRING:
   1495 	    case XML_SCHEMAS_ANYSIMPLETYPE:
   1496 		value = xmlSchemaValueGetAsString(val);
   1497 		if (value != NULL) {
   1498 		    if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
   1499 			value2 = xmlSchemaCollapseString(value);
   1500 		    else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
   1501 			value2 = xmlSchemaWhiteSpaceReplace(value);
   1502 		    if (value2 != NULL)
   1503 			value = value2;
   1504 		}
   1505 		break;
   1506 	    default:
   1507 		if (xmlSchemaGetCanonValue(val, &value2) == -1) {
   1508 		    if (value2 != NULL)
   1509 			xmlFree((xmlChar *) value2);
   1510 		    goto internal_error;
   1511 		}
   1512 		value = value2;
   1513 	}
   1514 	if (*retValue == NULL)
   1515 	    if (value == NULL) {
   1516 		if (! list)
   1517 		    *retValue = xmlStrdup(BAD_CAST "");
   1518 	    } else
   1519 		*retValue = xmlStrdup(value);
   1520 	else if (value != NULL) {
   1521 	    /* List. */
   1522 	    *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
   1523 	    *retValue = xmlStrcat((xmlChar *) *retValue, value);
   1524 	}
   1525 	FREE_AND_NULL(value2)
   1526 	val = xmlSchemaValueGetNext(val);
   1527     } while (val != NULL);
   1528 
   1529     return (0);
   1530 internal_error:
   1531     if (*retValue != NULL)
   1532 	xmlFree((xmlChar *) (*retValue));
   1533     if (value2 != NULL)
   1534 	xmlFree((xmlChar *) value2);
   1535     return (-1);
   1536 }
   1537 
   1538 /**
   1539  * xmlSchemaFormatItemForReport:
   1540  * @buf: the string buffer
   1541  * @itemDes: the designation of the item
   1542  * @itemName: the name of the item
   1543  * @item: the item as an object
   1544  * @itemNode: the node of the item
   1545  * @local: the local name
   1546  * @parsing: if the function is used during the parse
   1547  *
   1548  * Returns a representation of the given item used
   1549  * for error reports.
   1550  *
   1551  * The following order is used to build the resulting
   1552  * designation if the arguments are not NULL:
   1553  * 1a. If itemDes not NULL -> itemDes
   1554  * 1b. If (itemDes not NULL) and (itemName not NULL)
   1555  *     -> itemDes + itemName
   1556  * 2. If the preceding was NULL and (item not NULL) -> item
   1557  * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
   1558  *
   1559  * If the itemNode is an attribute node, the name of the attribute
   1560  * will be appended to the result.
   1561  *
   1562  * Returns the formatted string and sets @buf to the resulting value.
   1563  */
   1564 static xmlChar*
   1565 xmlSchemaFormatItemForReport(xmlChar **buf,
   1566 		     const xmlChar *itemDes,
   1567 		     xmlSchemaBasicItemPtr item,
   1568 		     xmlNodePtr itemNode)
   1569 {
   1570     xmlChar *str = NULL;
   1571     int named = 1;
   1572 
   1573     if (*buf != NULL) {
   1574 	xmlFree(*buf);
   1575 	*buf = NULL;
   1576     }
   1577 
   1578     if (itemDes != NULL) {
   1579 	*buf = xmlStrdup(itemDes);
   1580     } else if (item != NULL) {
   1581 	switch (item->type) {
   1582 	case XML_SCHEMA_TYPE_BASIC: {
   1583 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
   1584 
   1585 	    if (WXS_IS_ATOMIC(type))
   1586 		*buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
   1587 	    else if (WXS_IS_LIST(type))
   1588 		*buf = xmlStrdup(BAD_CAST "list type 'xs:");
   1589 	    else if (WXS_IS_UNION(type))
   1590 		*buf = xmlStrdup(BAD_CAST "union type 'xs:");
   1591 	    else
   1592 		*buf = xmlStrdup(BAD_CAST "simple type 'xs:");
   1593 	    *buf = xmlStrcat(*buf, type->name);
   1594 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1595 	    }
   1596 	    break;
   1597 	case XML_SCHEMA_TYPE_SIMPLE: {
   1598 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
   1599 
   1600 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
   1601 		*buf = xmlStrdup(BAD_CAST"");
   1602 	    } else {
   1603 		*buf = xmlStrdup(BAD_CAST "local ");
   1604 	    }
   1605 	    if (WXS_IS_ATOMIC(type))
   1606 		*buf = xmlStrcat(*buf, BAD_CAST "atomic type");
   1607 	    else if (WXS_IS_LIST(type))
   1608 		*buf = xmlStrcat(*buf, BAD_CAST "list type");
   1609 	    else if (WXS_IS_UNION(type))
   1610 		*buf = xmlStrcat(*buf, BAD_CAST "union type");
   1611 	    else
   1612 		*buf = xmlStrcat(*buf, BAD_CAST "simple type");
   1613 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
   1614 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1615 		*buf = xmlStrcat(*buf, type->name);
   1616 		*buf = xmlStrcat(*buf, BAD_CAST "'");
   1617 	    }
   1618 	    }
   1619 	    break;
   1620 	case XML_SCHEMA_TYPE_COMPLEX: {
   1621 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
   1622 
   1623 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
   1624 		*buf = xmlStrdup(BAD_CAST "");
   1625 	    else
   1626 		*buf = xmlStrdup(BAD_CAST "local ");
   1627 	    *buf = xmlStrcat(*buf, BAD_CAST "complex type");
   1628 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
   1629 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1630 		*buf = xmlStrcat(*buf, type->name);
   1631 		*buf = xmlStrcat(*buf, BAD_CAST "'");
   1632 	    }
   1633 	    }
   1634 	    break;
   1635 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
   1636 		xmlSchemaAttributeUsePtr ause;
   1637 
   1638 		ause = WXS_ATTR_USE_CAST item;
   1639 		*buf = xmlStrdup(BAD_CAST "attribute use ");
   1640 		if (WXS_ATTRUSE_DECL(ause) != NULL) {
   1641 		    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1642 		    *buf = xmlStrcat(*buf,
   1643 			xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
   1644 		    FREE_AND_NULL(str)
   1645 			*buf = xmlStrcat(*buf, BAD_CAST "'");
   1646 		} else {
   1647 		    *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
   1648 		}
   1649 	    }
   1650 	    break;
   1651 	case XML_SCHEMA_TYPE_ATTRIBUTE: {
   1652 		xmlSchemaAttributePtr attr;
   1653 
   1654 		attr = (xmlSchemaAttributePtr) item;
   1655 		*buf = xmlStrdup(BAD_CAST "attribute decl.");
   1656 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1657 		*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
   1658 		    attr->targetNamespace, attr->name));
   1659 		FREE_AND_NULL(str)
   1660 		    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1661 	    }
   1662 	    break;
   1663 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1664 	    xmlSchemaGetComponentDesignation(buf, item);
   1665 	    break;
   1666 	case XML_SCHEMA_TYPE_ELEMENT: {
   1667 		xmlSchemaElementPtr elem;
   1668 
   1669 		elem = (xmlSchemaElementPtr) item;
   1670 		*buf = xmlStrdup(BAD_CAST "element decl.");
   1671 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1672 		*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
   1673 		    elem->targetNamespace, elem->name));
   1674 		*buf = xmlStrcat(*buf, BAD_CAST "'");
   1675 	    }
   1676 	    break;
   1677 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1678 	case XML_SCHEMA_TYPE_IDC_KEY:
   1679 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1680 	    if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
   1681 		*buf = xmlStrdup(BAD_CAST "unique '");
   1682 	    else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
   1683 		*buf = xmlStrdup(BAD_CAST "key '");
   1684 	    else
   1685 		*buf = xmlStrdup(BAD_CAST "keyRef '");
   1686 	    *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
   1687 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1688 	    break;
   1689 	case XML_SCHEMA_TYPE_ANY:
   1690 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   1691 	    *buf = xmlStrdup(xmlSchemaWildcardPCToString(
   1692 		    ((xmlSchemaWildcardPtr) item)->processContents));
   1693 	    *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
   1694 	    break;
   1695 	case XML_SCHEMA_FACET_MININCLUSIVE:
   1696 	case XML_SCHEMA_FACET_MINEXCLUSIVE:
   1697 	case XML_SCHEMA_FACET_MAXINCLUSIVE:
   1698 	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   1699 	case XML_SCHEMA_FACET_TOTALDIGITS:
   1700 	case XML_SCHEMA_FACET_FRACTIONDIGITS:
   1701 	case XML_SCHEMA_FACET_PATTERN:
   1702 	case XML_SCHEMA_FACET_ENUMERATION:
   1703 	case XML_SCHEMA_FACET_WHITESPACE:
   1704 	case XML_SCHEMA_FACET_LENGTH:
   1705 	case XML_SCHEMA_FACET_MAXLENGTH:
   1706 	case XML_SCHEMA_FACET_MINLENGTH:
   1707 	    *buf = xmlStrdup(BAD_CAST "facet '");
   1708 	    *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
   1709 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1710 	    break;
   1711 	case XML_SCHEMA_TYPE_GROUP: {
   1712 		*buf = xmlStrdup(BAD_CAST "model group def.");
   1713 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1714 		*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
   1715 		*buf = xmlStrcat(*buf, BAD_CAST "'");
   1716 		FREE_AND_NULL(str)
   1717 	    }
   1718 	    break;
   1719 	case XML_SCHEMA_TYPE_SEQUENCE:
   1720 	case XML_SCHEMA_TYPE_CHOICE:
   1721 	case XML_SCHEMA_TYPE_ALL:
   1722 	case XML_SCHEMA_TYPE_PARTICLE:
   1723 	    *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
   1724 	    break;
   1725 	case XML_SCHEMA_TYPE_NOTATION: {
   1726 		*buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
   1727 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1728 		*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
   1729 		*buf = xmlStrcat(*buf, BAD_CAST "'");
   1730 		FREE_AND_NULL(str);
   1731 	    }
   1732 	default:
   1733 	    named = 0;
   1734 	}
   1735     } else
   1736 	named = 0;
   1737 
   1738     if ((named == 0) && (itemNode != NULL)) {
   1739 	xmlNodePtr elem;
   1740 
   1741 	if (itemNode->type == XML_ATTRIBUTE_NODE)
   1742 	    elem = itemNode->parent;
   1743 	else
   1744 	    elem = itemNode;
   1745 	*buf = xmlStrdup(BAD_CAST "Element '");
   1746 	if (elem->ns != NULL) {
   1747 	    *buf = xmlStrcat(*buf,
   1748 		xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
   1749 	    FREE_AND_NULL(str)
   1750 	} else
   1751 	    *buf = xmlStrcat(*buf, elem->name);
   1752 	*buf = xmlStrcat(*buf, BAD_CAST "'");
   1753 
   1754     }
   1755     if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
   1756 	*buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
   1757 	if (itemNode->ns != NULL) {
   1758 	    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
   1759 		itemNode->ns->href, itemNode->name));
   1760 	    FREE_AND_NULL(str)
   1761 	} else
   1762 	    *buf = xmlStrcat(*buf, itemNode->name);
   1763 	*buf = xmlStrcat(*buf, BAD_CAST "'");
   1764     }
   1765     FREE_AND_NULL(str)
   1766 
   1767     return (*buf);
   1768 }
   1769 
   1770 /**
   1771  * xmlSchemaFormatFacetEnumSet:
   1772  * @buf: the string buffer
   1773  * @type: the type holding the enumeration facets
   1774  *
   1775  * Builds a string consisting of all enumeration elements.
   1776  *
   1777  * Returns a string of all enumeration elements.
   1778  */
   1779 static const xmlChar *
   1780 xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
   1781 			    xmlChar **buf, xmlSchemaTypePtr type)
   1782 {
   1783     xmlSchemaFacetPtr facet;
   1784     xmlSchemaWhitespaceValueType ws;
   1785     xmlChar *value = NULL;
   1786     int res, found = 0;
   1787 
   1788     if (*buf != NULL)
   1789 	xmlFree(*buf);
   1790     *buf = NULL;
   1791 
   1792     do {
   1793 	/*
   1794 	* Use the whitespace type of the base type.
   1795 	*/
   1796 	ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
   1797 	for (facet = type->facets; facet != NULL; facet = facet->next) {
   1798 	    if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
   1799 		continue;
   1800 	    found = 1;
   1801 	    res = xmlSchemaGetCanonValueWhtspExt(facet->val,
   1802 		ws, &value);
   1803 	    if (res == -1) {
   1804 		xmlSchemaInternalErr(actxt,
   1805 		    "xmlSchemaFormatFacetEnumSet",
   1806 		    "compute the canonical lexical representation");
   1807 		if (*buf != NULL)
   1808 		    xmlFree(*buf);
   1809 		*buf = NULL;
   1810 		return (NULL);
   1811 	    }
   1812 	    if (*buf == NULL)
   1813 		*buf = xmlStrdup(BAD_CAST "'");
   1814 	    else
   1815 		*buf = xmlStrcat(*buf, BAD_CAST ", '");
   1816 	    *buf = xmlStrcat(*buf, BAD_CAST value);
   1817 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1818 	    if (value != NULL) {
   1819 		xmlFree((xmlChar *)value);
   1820 		value = NULL;
   1821 	    }
   1822 	}
   1823 	/*
   1824 	* The enumeration facet of a type restricts the enumeration
   1825 	* facet of the ancestor type; i.e., such restricted enumerations
   1826 	* do not belong to the set of the given type. Thus we break
   1827 	* on the first found enumeration.
   1828 	*/
   1829 	if (found)
   1830 	    break;
   1831 	type = type->baseType;
   1832     } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
   1833 
   1834     return ((const xmlChar *) *buf);
   1835 }
   1836 
   1837 /************************************************************************
   1838  *									*
   1839  * 			Error functions				        *
   1840  *									*
   1841  ************************************************************************/
   1842 
   1843 #if 0
   1844 static void
   1845 xmlSchemaErrMemory(const char *msg)
   1846 {
   1847     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
   1848                      msg);
   1849 }
   1850 #endif
   1851 
   1852 static void
   1853 xmlSchemaPSimpleErr(const char *msg)
   1854 {
   1855     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
   1856                      msg);
   1857 }
   1858 
   1859 /**
   1860  * xmlSchemaPErrMemory:
   1861  * @node: a context node
   1862  * @extra:  extra informations
   1863  *
   1864  * Handle an out of memory condition
   1865  */
   1866 static void
   1867 xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
   1868                     const char *extra, xmlNodePtr node)
   1869 {
   1870     if (ctxt != NULL)
   1871         ctxt->nberrors++;
   1872     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
   1873                      extra);
   1874 }
   1875 
   1876 /**
   1877  * xmlSchemaPErr:
   1878  * @ctxt: the parsing context
   1879  * @node: the context node
   1880  * @error: the error code
   1881  * @msg: the error message
   1882  * @str1: extra data
   1883  * @str2: extra data
   1884  *
   1885  * Handle a parser error
   1886  */
   1887 static void
   1888 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
   1889               const char *msg, const xmlChar * str1, const xmlChar * str2)
   1890 {
   1891     xmlGenericErrorFunc channel = NULL;
   1892     xmlStructuredErrorFunc schannel = NULL;
   1893     void *data = NULL;
   1894 
   1895     if (ctxt != NULL) {
   1896         ctxt->nberrors++;
   1897 	ctxt->err = error;
   1898         channel = ctxt->error;
   1899         data = ctxt->errCtxt;
   1900 	schannel = ctxt->serror;
   1901     }
   1902     __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
   1903                     error, XML_ERR_ERROR, NULL, 0,
   1904                     (const char *) str1, (const char *) str2, NULL, 0, 0,
   1905                     msg, str1, str2);
   1906 }
   1907 
   1908 /**
   1909  * xmlSchemaPErr2:
   1910  * @ctxt: the parsing context
   1911  * @node: the context node
   1912  * @node: the current child
   1913  * @error: the error code
   1914  * @msg: the error message
   1915  * @str1: extra data
   1916  * @str2: extra data
   1917  *
   1918  * Handle a parser error
   1919  */
   1920 static void
   1921 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
   1922                xmlNodePtr child, int error,
   1923                const char *msg, const xmlChar * str1, const xmlChar * str2)
   1924 {
   1925     if (child != NULL)
   1926         xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
   1927     else
   1928         xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
   1929 }
   1930 
   1931 
   1932 /**
   1933  * xmlSchemaPErrExt:
   1934  * @ctxt: the parsing context
   1935  * @node: the context node
   1936  * @error: the error code
   1937  * @strData1: extra data
   1938  * @strData2: extra data
   1939  * @strData3: extra data
   1940  * @msg: the message
   1941  * @str1:  extra parameter for the message display
   1942  * @str2:  extra parameter for the message display
   1943  * @str3:  extra parameter for the message display
   1944  * @str4:  extra parameter for the message display
   1945  * @str5:  extra parameter for the message display
   1946  *
   1947  * Handle a parser error
   1948  */
   1949 static void
   1950 xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
   1951 		const xmlChar * strData1, const xmlChar * strData2,
   1952 		const xmlChar * strData3, const char *msg, const xmlChar * str1,
   1953 		const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
   1954 		const xmlChar * str5)
   1955 {
   1956 
   1957     xmlGenericErrorFunc channel = NULL;
   1958     xmlStructuredErrorFunc schannel = NULL;
   1959     void *data = NULL;
   1960 
   1961     if (ctxt != NULL) {
   1962         ctxt->nberrors++;
   1963 	ctxt->err = error;
   1964         channel = ctxt->error;
   1965         data = ctxt->errCtxt;
   1966 	schannel = ctxt->serror;
   1967     }
   1968     __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
   1969                     error, XML_ERR_ERROR, NULL, 0,
   1970                     (const char *) strData1, (const char *) strData2,
   1971 		    (const char *) strData3, 0, 0, msg, str1, str2,
   1972 		    str3, str4, str5);
   1973 }
   1974 
   1975 /************************************************************************
   1976  *									*
   1977  * 			Allround error functions			*
   1978  *									*
   1979  ************************************************************************/
   1980 
   1981 /**
   1982  * xmlSchemaVTypeErrMemory:
   1983  * @node: a context node
   1984  * @extra:  extra informations
   1985  *
   1986  * Handle an out of memory condition
   1987  */
   1988 static void
   1989 xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
   1990                     const char *extra, xmlNodePtr node)
   1991 {
   1992     if (ctxt != NULL) {
   1993         ctxt->nberrors++;
   1994         ctxt->err = XML_SCHEMAV_INTERNAL;
   1995     }
   1996     __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
   1997                      extra);
   1998 }
   1999 
   2000 static void
   2001 xmlSchemaPSimpleInternalErr(xmlNodePtr node,
   2002 			    const char *msg, const xmlChar *str)
   2003 {
   2004      __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
   2005 	 msg, (const char *) str);
   2006 }
   2007 
   2008 #define WXS_ERROR_TYPE_ERROR 1
   2009 #define WXS_ERROR_TYPE_WARNING 2
   2010 /**
   2011  * xmlSchemaErr3:
   2012  * @ctxt: the validation context
   2013  * @node: the context node
   2014  * @error: the error code
   2015  * @msg: the error message
   2016  * @str1: extra data
   2017  * @str2: extra data
   2018  * @str3: extra data
   2019  *
   2020  * Handle a validation error
   2021  */
   2022 static void
   2023 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
   2024 		  xmlErrorLevel errorLevel,
   2025 		  int error, xmlNodePtr node, int line, const char *msg,
   2026 		  const xmlChar *str1, const xmlChar *str2,
   2027 		  const xmlChar *str3, const xmlChar *str4)
   2028 {
   2029     xmlStructuredErrorFunc schannel = NULL;
   2030     xmlGenericErrorFunc channel = NULL;
   2031     void *data = NULL;
   2032 
   2033     if (ctxt != NULL) {
   2034 	if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
   2035 	    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
   2036 	    const char *file = NULL;
   2037 	    if (errorLevel != XML_ERR_WARNING) {
   2038 		vctxt->nberrors++;
   2039 		vctxt->err = error;
   2040 		channel = vctxt->error;
   2041 	    } else {
   2042 		channel = vctxt->warning;
   2043 	    }
   2044 	    schannel = vctxt->serror;
   2045 	    data = vctxt->errCtxt;
   2046 
   2047 	    /*
   2048 	    * Error node. If we specify a line number, then
   2049 	    * do not channel any node to the error function.
   2050 	    */
   2051 	    if (line == 0) {
   2052 		if ((node == NULL) &&
   2053 		    (vctxt->depth >= 0) &&
   2054 		    (vctxt->inode != NULL)) {
   2055 		    node = vctxt->inode->node;
   2056 		}
   2057 		/*
   2058 		* Get filename and line if no node-tree.
   2059 		*/
   2060 		if ((node == NULL) &&
   2061 		    (vctxt->parserCtxt != NULL) &&
   2062 		    (vctxt->parserCtxt->input != NULL)) {
   2063 		    file = vctxt->parserCtxt->input->filename;
   2064 		    line = vctxt->parserCtxt->input->line;
   2065 		}
   2066 	    } else {
   2067 		/*
   2068 		* Override the given node's (if any) position
   2069 		* and channel only the given line number.
   2070 		*/
   2071 		node = NULL;
   2072 		/*
   2073 		* Get filename.
   2074 		*/
   2075 		if (vctxt->doc != NULL)
   2076 		    file = (const char *) vctxt->doc->URL;
   2077 		else if ((vctxt->parserCtxt != NULL) &&
   2078 		    (vctxt->parserCtxt->input != NULL))
   2079 		    file = vctxt->parserCtxt->input->filename;
   2080 	    }
   2081 	    __xmlRaiseError(schannel, channel, data, ctxt,
   2082 		node, XML_FROM_SCHEMASV,
   2083 		error, errorLevel, file, line,
   2084 		(const char *) str1, (const char *) str2,
   2085 		(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
   2086 
   2087 	} else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
   2088 	    xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
   2089 	    if (errorLevel != XML_ERR_WARNING) {
   2090 		pctxt->nberrors++;
   2091 		pctxt->err = error;
   2092 		channel = pctxt->error;
   2093 	    } else {
   2094 		channel = pctxt->warning;
   2095 	    }
   2096 	    schannel = pctxt->serror;
   2097 	    data = pctxt->errCtxt;
   2098 	    __xmlRaiseError(schannel, channel, data, ctxt,
   2099 		node, XML_FROM_SCHEMASP, error,
   2100 		errorLevel, NULL, 0,
   2101 		(const char *) str1, (const char *) str2,
   2102 		(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
   2103 	} else {
   2104 	    TODO
   2105 	}
   2106     }
   2107 }
   2108 
   2109 /**
   2110  * xmlSchemaErr3:
   2111  * @ctxt: the validation context
   2112  * @node: the context node
   2113  * @error: the error code
   2114  * @msg: the error message
   2115  * @str1: extra data
   2116  * @str2: extra data
   2117  * @str3: extra data
   2118  *
   2119  * Handle a validation error
   2120  */
   2121 static void
   2122 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
   2123 	      int error, xmlNodePtr node, const char *msg,
   2124 	      const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
   2125 {
   2126     xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
   2127 	msg, str1, str2, str3, NULL);
   2128 }
   2129 
   2130 static void
   2131 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
   2132 	      int error, xmlNodePtr node, const char *msg,
   2133 	      const xmlChar *str1, const xmlChar *str2,
   2134 	      const xmlChar *str3, const xmlChar *str4)
   2135 {
   2136     xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
   2137 	msg, str1, str2, str3, str4);
   2138 }
   2139 
   2140 static void
   2141 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
   2142 	     int error, xmlNodePtr node, const char *msg,
   2143 	     const xmlChar *str1, const xmlChar *str2)
   2144 {
   2145     xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
   2146 }
   2147 
   2148 static xmlChar *
   2149 xmlSchemaFormatNodeForError(xmlChar ** msg,
   2150 			    xmlSchemaAbstractCtxtPtr actxt,
   2151 			    xmlNodePtr node)
   2152 {
   2153     xmlChar *str = NULL;
   2154 
   2155     *msg = NULL;
   2156     if ((node != NULL) &&
   2157 	(node->type != XML_ELEMENT_NODE) &&
   2158 	(node->type != XML_ATTRIBUTE_NODE))
   2159     {
   2160 	/*
   2161 	* Don't try to format other nodes than element and
   2162 	* attribute nodes.
   2163 	* Play save and return an empty string.
   2164 	*/
   2165 	*msg = xmlStrdup(BAD_CAST "");
   2166 	return(*msg);
   2167     }
   2168     if (node != NULL) {
   2169 	/*
   2170 	* Work on tree nodes.
   2171 	*/
   2172 	if (node->type == XML_ATTRIBUTE_NODE) {
   2173 	    xmlNodePtr elem = node->parent;
   2174 
   2175 	    *msg = xmlStrdup(BAD_CAST "Element '");
   2176 	    if (elem->ns != NULL)
   2177 		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2178 		    elem->ns->href, elem->name));
   2179 	    else
   2180 		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2181 		    NULL, elem->name));
   2182 	    FREE_AND_NULL(str);
   2183 	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
   2184 	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
   2185 	} else {
   2186 	    *msg = xmlStrdup(BAD_CAST "Element '");
   2187 	}
   2188 	if (node->ns != NULL)
   2189 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2190 	    node->ns->href, node->name));
   2191 	else
   2192 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2193 	    NULL, node->name));
   2194 	FREE_AND_NULL(str);
   2195 	*msg = xmlStrcat(*msg, BAD_CAST "': ");
   2196     } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
   2197 	xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
   2198 	/*
   2199 	* Work on node infos.
   2200 	*/
   2201 	if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
   2202 	    xmlSchemaNodeInfoPtr ielem =
   2203 		vctxt->elemInfos[vctxt->depth];
   2204 
   2205 	    *msg = xmlStrdup(BAD_CAST "Element '");
   2206 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2207 		ielem->nsName, ielem->localName));
   2208 	    FREE_AND_NULL(str);
   2209 	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
   2210 	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
   2211 	} else {
   2212 	    *msg = xmlStrdup(BAD_CAST "Element '");
   2213 	}
   2214 	*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2215 	    vctxt->inode->nsName, vctxt->inode->localName));
   2216 	FREE_AND_NULL(str);
   2217 	*msg = xmlStrcat(*msg, BAD_CAST "': ");
   2218     } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
   2219 	/*
   2220 	* Hmm, no node while parsing?
   2221 	* Return an empty string, in case NULL will break something.
   2222 	*/
   2223 	*msg = xmlStrdup(BAD_CAST "");
   2224     } else {
   2225 	TODO
   2226 	return (NULL);
   2227     }
   2228     /*
   2229     * VAL TODO: The output of the given schema component is currently
   2230     * disabled.
   2231     */
   2232 #if 0
   2233     if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
   2234 	*msg = xmlStrcat(*msg, BAD_CAST " [");
   2235 	*msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
   2236 	    NULL, type, NULL, 0));
   2237 	FREE_AND_NULL(str)
   2238 	*msg = xmlStrcat(*msg, BAD_CAST "]");
   2239     }
   2240 #endif
   2241     return (*msg);
   2242 }
   2243 
   2244 static void
   2245 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
   2246 		     const char *funcName,
   2247 		     const char *message,
   2248 		     const xmlChar *str1,
   2249 		     const xmlChar *str2)
   2250 {
   2251     xmlChar *msg = NULL;
   2252 
   2253     if (actxt == NULL)
   2254         return;
   2255     msg = xmlStrdup(BAD_CAST "Internal error: ");
   2256     msg = xmlStrcat(msg, BAD_CAST funcName);
   2257     msg = xmlStrcat(msg, BAD_CAST ", ");
   2258     msg = xmlStrcat(msg, BAD_CAST message);
   2259     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2260 
   2261     if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
   2262 	xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL,
   2263 	    (const char *) msg, str1, str2);
   2264 
   2265     else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
   2266 	xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL,
   2267 	    (const char *) msg, str1, str2);
   2268 
   2269     FREE_AND_NULL(msg)
   2270 }
   2271 
   2272 static void
   2273 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
   2274 		     const char *funcName,
   2275 		     const char *message)
   2276 {
   2277     xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
   2278 }
   2279 
   2280 #if 0
   2281 static void
   2282 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
   2283 		     const char *funcName,
   2284 		     const char *message,
   2285 		     const xmlChar *str1,
   2286 		     const xmlChar *str2)
   2287 {
   2288     xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
   2289 	str1, str2);
   2290 }
   2291 #endif
   2292 
   2293 static void
   2294 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
   2295 		   xmlParserErrors error,
   2296 		   xmlNodePtr node,
   2297 		   xmlSchemaBasicItemPtr item,
   2298 		   const char *message,
   2299 		   const xmlChar *str1, const xmlChar *str2,
   2300 		   const xmlChar *str3, const xmlChar *str4)
   2301 {
   2302     xmlChar *msg = NULL;
   2303 
   2304     if ((node == NULL) && (item != NULL) &&
   2305 	(actxt->type == XML_SCHEMA_CTXT_PARSER)) {
   2306 	node = WXS_ITEM_NODE(item);
   2307 	xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
   2308 	msg = xmlStrcat(msg, BAD_CAST ": ");
   2309     } else
   2310 	xmlSchemaFormatNodeForError(&msg, actxt, node);
   2311     msg = xmlStrcat(msg, (const xmlChar *) message);
   2312     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2313     xmlSchemaErr4(actxt, error, node,
   2314 	(const char *) msg, str1, str2, str3, str4);
   2315     FREE_AND_NULL(msg)
   2316 }
   2317 
   2318 static void
   2319 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
   2320 		   xmlParserErrors error,
   2321 		   xmlNodePtr node,
   2322 		   xmlSchemaBasicItemPtr item,
   2323 		   const char *message,
   2324 		   const xmlChar *str1,
   2325 		   const xmlChar *str2)
   2326 {
   2327     xmlSchemaCustomErr4(actxt, error, node, item,
   2328 	message, str1, str2, NULL, NULL);
   2329 }
   2330 
   2331 
   2332 
   2333 static void
   2334 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
   2335 		   xmlParserErrors error,
   2336 		   xmlNodePtr node,
   2337 		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
   2338 		   const char *message,
   2339 		   const xmlChar *str1,
   2340 		   const xmlChar *str2,
   2341 		   const xmlChar *str3)
   2342 {
   2343     xmlChar *msg = NULL;
   2344 
   2345     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2346     msg = xmlStrcat(msg, (const xmlChar *) message);
   2347     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2348 
   2349     /* URGENT TODO: Set the error code to something sane. */
   2350     xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
   2351 	(const char *) msg, str1, str2, str3, NULL);
   2352 
   2353     FREE_AND_NULL(msg)
   2354 }
   2355 
   2356 
   2357 
   2358 static void
   2359 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
   2360 		   xmlParserErrors error,
   2361 		   xmlSchemaPSVIIDCNodePtr idcNode,
   2362 		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
   2363 		   const char *message,
   2364 		   const xmlChar *str1,
   2365 		   const xmlChar *str2)
   2366 {
   2367     xmlChar *msg = NULL, *qname = NULL;
   2368 
   2369     msg = xmlStrdup(BAD_CAST "Element '%s': ");
   2370     msg = xmlStrcat(msg, (const xmlChar *) message);
   2371     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2372     xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
   2373 	error, NULL, idcNode->nodeLine, (const char *) msg,
   2374 	xmlSchemaFormatQName(&qname,
   2375 	    vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
   2376 	    vctxt->nodeQNames->items[idcNode->nodeQNameID]),
   2377 	str1, str2, NULL);
   2378     FREE_AND_NULL(qname);
   2379     FREE_AND_NULL(msg);
   2380 }
   2381 
   2382 static int
   2383 xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
   2384 			   xmlNodePtr node)
   2385 {
   2386     if (node != NULL)
   2387 	return (node->type);
   2388     if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
   2389 	(((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
   2390 	return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
   2391     return (-1);
   2392 }
   2393 
   2394 static int
   2395 xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
   2396 {
   2397     switch (item->type) {
   2398 	case XML_SCHEMA_TYPE_COMPLEX:
   2399 	case XML_SCHEMA_TYPE_SIMPLE:
   2400 	    if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
   2401 		return(1);
   2402 	    break;
   2403 	case XML_SCHEMA_TYPE_GROUP:
   2404 	    return (1);
   2405 	case XML_SCHEMA_TYPE_ELEMENT:
   2406 	    if ( ((xmlSchemaElementPtr) item)->flags &
   2407 		XML_SCHEMAS_ELEM_GLOBAL)
   2408 		return(1);
   2409 	    break;
   2410 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   2411 	    if ( ((xmlSchemaAttributePtr) item)->flags &
   2412 		XML_SCHEMAS_ATTR_GLOBAL)
   2413 		return(1);
   2414 	    break;
   2415 	/* Note that attribute groups are always global. */
   2416 	default:
   2417 	    return(1);
   2418     }
   2419     return (0);
   2420 }
   2421 
   2422 static void
   2423 xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
   2424 		       xmlParserErrors error,
   2425 		       xmlNodePtr node,
   2426 		       const xmlChar *value,
   2427 		       xmlSchemaTypePtr type,
   2428 		       int displayValue)
   2429 {
   2430     xmlChar *msg = NULL;
   2431 
   2432     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2433 
   2434     if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
   2435 	    XML_ATTRIBUTE_NODE))
   2436 	msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
   2437     else
   2438 	msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
   2439 	    "value of ");
   2440 
   2441     if (! xmlSchemaIsGlobalItem(type))
   2442 	msg = xmlStrcat(msg, BAD_CAST "the local ");
   2443     else
   2444 	msg = xmlStrcat(msg, BAD_CAST "the ");
   2445 
   2446     if (WXS_IS_ATOMIC(type))
   2447 	msg = xmlStrcat(msg, BAD_CAST "atomic type");
   2448     else if (WXS_IS_LIST(type))
   2449 	msg = xmlStrcat(msg, BAD_CAST "list type");
   2450     else if (WXS_IS_UNION(type))
   2451 	msg = xmlStrcat(msg, BAD_CAST "union type");
   2452 
   2453     if (xmlSchemaIsGlobalItem(type)) {
   2454 	xmlChar *str = NULL;
   2455 	msg = xmlStrcat(msg, BAD_CAST " '");
   2456 	if (type->builtInType != 0) {
   2457 	    msg = xmlStrcat(msg, BAD_CAST "xs:");
   2458 	    msg = xmlStrcat(msg, type->name);
   2459 	} else
   2460 	    msg = xmlStrcat(msg,
   2461 		xmlSchemaFormatQName(&str,
   2462 		    type->targetNamespace, type->name));
   2463 	msg = xmlStrcat(msg, BAD_CAST "'");
   2464 	FREE_AND_NULL(str);
   2465     }
   2466     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2467     if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
   2468 	    XML_ATTRIBUTE_NODE))
   2469 	xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
   2470     else
   2471 	xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
   2472     FREE_AND_NULL(msg)
   2473 }
   2474 
   2475 static const xmlChar *
   2476 xmlSchemaFormatErrorNodeQName(xmlChar ** str,
   2477 			      xmlSchemaNodeInfoPtr ni,
   2478 			      xmlNodePtr node)
   2479 {
   2480     if (node != NULL) {
   2481 	if (node->ns != NULL)
   2482 	    return (xmlSchemaFormatQName(str, node->ns->href, node->name));
   2483 	else
   2484 	    return (xmlSchemaFormatQName(str, NULL, node->name));
   2485     } else if (ni != NULL)
   2486 	return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
   2487     return (NULL);
   2488 }
   2489 
   2490 static void
   2491 xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
   2492 			xmlParserErrors error,
   2493 			xmlSchemaAttrInfoPtr ni,
   2494 			xmlNodePtr node)
   2495 {
   2496     xmlChar *msg = NULL, *str = NULL;
   2497 
   2498     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2499     msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
   2500     xmlSchemaErr(actxt, error, node, (const char *) msg,
   2501 	xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
   2502 	NULL);
   2503     FREE_AND_NULL(str)
   2504     FREE_AND_NULL(msg)
   2505 }
   2506 
   2507 static void
   2508 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
   2509 		        xmlParserErrors error,
   2510 		        xmlNodePtr node,
   2511 			xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
   2512 			const char *message,
   2513 			int nbval,
   2514 			int nbneg,
   2515 			xmlChar **values)
   2516 {
   2517     xmlChar *str = NULL, *msg = NULL;
   2518     xmlChar *localName, *nsName;
   2519     const xmlChar *cur, *end;
   2520     int i;
   2521 
   2522     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2523     msg = xmlStrcat(msg, (const xmlChar *) message);
   2524     msg = xmlStrcat(msg, BAD_CAST ".");
   2525     /*
   2526     * Note that is does not make sense to report that we have a
   2527     * wildcard here, since the wildcard might be unfolded into
   2528     * multiple transitions.
   2529     */
   2530     if (nbval + nbneg > 0) {
   2531 	if (nbval + nbneg > 1) {
   2532 	    str = xmlStrdup(BAD_CAST " Expected is one of ( ");
   2533 	} else
   2534 	    str = xmlStrdup(BAD_CAST " Expected is ( ");
   2535 	nsName = NULL;
   2536 
   2537 	for (i = 0; i < nbval + nbneg; i++) {
   2538 	    cur = values[i];
   2539 	    if (cur == NULL)
   2540 	        continue;
   2541 	    if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
   2542 	        (cur[3] == ' ')) {
   2543 		cur += 4;
   2544 		str = xmlStrcat(str, BAD_CAST "##other");
   2545 	    }
   2546 	    /*
   2547 	    * Get the local name.
   2548 	    */
   2549 	    localName = NULL;
   2550 
   2551 	    end = cur;
   2552 	    if (*end == '*') {
   2553 		localName = xmlStrdup(BAD_CAST "*");
   2554 		end++;
   2555 	    } else {
   2556 		while ((*end != 0) && (*end != '|'))
   2557 		    end++;
   2558 		localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
   2559 	    }
   2560 	    if (*end != 0) {
   2561 		end++;
   2562 		/*
   2563 		* Skip "*|*" if they come with negated expressions, since
   2564 		* they represent the same negated wildcard.
   2565 		*/
   2566 		if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
   2567 		    /*
   2568 		    * Get the namespace name.
   2569 		    */
   2570 		    cur = end;
   2571 		    if (*end == '*') {
   2572 			nsName = xmlStrdup(BAD_CAST "{*}");
   2573 		    } else {
   2574 			while (*end != 0)
   2575 			    end++;
   2576 
   2577 			if (i >= nbval)
   2578 			    nsName = xmlStrdup(BAD_CAST "{##other:");
   2579 			else
   2580 			    nsName = xmlStrdup(BAD_CAST "{");
   2581 
   2582 			nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
   2583 			nsName = xmlStrcat(nsName, BAD_CAST "}");
   2584 		    }
   2585 		    str = xmlStrcat(str, BAD_CAST nsName);
   2586 		    FREE_AND_NULL(nsName)
   2587 		} else {
   2588 		    FREE_AND_NULL(localName);
   2589 		    continue;
   2590 		}
   2591 	    }
   2592 	    str = xmlStrcat(str, BAD_CAST localName);
   2593 	    FREE_AND_NULL(localName);
   2594 
   2595 	    if (i < nbval + nbneg -1)
   2596 		str = xmlStrcat(str, BAD_CAST ", ");
   2597 	}
   2598 	str = xmlStrcat(str, BAD_CAST " ).\n");
   2599 	msg = xmlStrcat(msg, BAD_CAST str);
   2600 	FREE_AND_NULL(str)
   2601     } else
   2602       msg = xmlStrcat(msg, BAD_CAST "\n");
   2603     xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
   2604     xmlFree(msg);
   2605 }
   2606 
   2607 static void
   2608 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
   2609 		  xmlParserErrors error,
   2610 		  xmlNodePtr node,
   2611 		  const xmlChar *value,
   2612 		  unsigned long length,
   2613 		  xmlSchemaTypePtr type,
   2614 		  xmlSchemaFacetPtr facet,
   2615 		  const char *message,
   2616 		  const xmlChar *str1,
   2617 		  const xmlChar *str2)
   2618 {
   2619     xmlChar *str = NULL, *msg = NULL;
   2620     xmlSchemaTypeType facetType;
   2621     int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
   2622 
   2623     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2624     if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
   2625 	facetType = XML_SCHEMA_FACET_ENUMERATION;
   2626 	/*
   2627 	* If enumerations are validated, one must not expect the
   2628 	* facet to be given.
   2629 	*/
   2630     } else
   2631 	facetType = facet->type;
   2632     msg = xmlStrcat(msg, BAD_CAST "[");
   2633     msg = xmlStrcat(msg, BAD_CAST "facet '");
   2634     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
   2635     msg = xmlStrcat(msg, BAD_CAST "'] ");
   2636     if (message == NULL) {
   2637 	/*
   2638 	* Use a default message.
   2639 	*/
   2640 	if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
   2641 	    (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
   2642 	    (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
   2643 
   2644 	    char len[25], actLen[25];
   2645 
   2646 	    /* FIXME, TODO: What is the max expected string length of the
   2647 	    * this value?
   2648 	    */
   2649 	    if (nodeType == XML_ATTRIBUTE_NODE)
   2650 		msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
   2651 	    else
   2652 		msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
   2653 
   2654 	    snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
   2655 	    snprintf(actLen, 24, "%lu", length);
   2656 
   2657 	    if (facetType == XML_SCHEMA_FACET_LENGTH)
   2658 		msg = xmlStrcat(msg,
   2659 		BAD_CAST "this differs from the allowed length of '%s'.\n");
   2660 	    else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
   2661 		msg = xmlStrcat(msg,
   2662 		BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
   2663 	    else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
   2664 		msg = xmlStrcat(msg,
   2665 		BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
   2666 
   2667 	    if (nodeType == XML_ATTRIBUTE_NODE)
   2668 		xmlSchemaErr3(actxt, error, node, (const char *) msg,
   2669 		    value, (const xmlChar *) actLen, (const xmlChar *) len);
   2670 	    else
   2671 		xmlSchemaErr(actxt, error, node, (const char *) msg,
   2672 		    (const xmlChar *) actLen, (const xmlChar *) len);
   2673 
   2674 	} else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
   2675 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
   2676 		"of the set {%s}.\n");
   2677 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2678 		xmlSchemaFormatFacetEnumSet(actxt, &str, type));
   2679 	} else if (facetType == XML_SCHEMA_FACET_PATTERN) {
   2680 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
   2681 		"by the pattern '%s'.\n");
   2682 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2683 		facet->value);
   2684 	} else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
   2685 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
   2686 		"minimum value allowed ('%s').\n");
   2687 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2688 		facet->value);
   2689 	} else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
   2690 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
   2691 		"maximum value allowed ('%s').\n");
   2692 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2693 		facet->value);
   2694 	} else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
   2695 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
   2696 		"'%s'.\n");
   2697 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2698 		facet->value);
   2699 	} else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
   2700 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
   2701 		"'%s'.\n");
   2702 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2703 		facet->value);
   2704 	} else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
   2705 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
   2706 		"digits than are allowed ('%s').\n");
   2707 	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
   2708 		facet->value);
   2709 	} else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
   2710 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
   2711 		"digits than are allowed ('%s').\n");
   2712 	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
   2713 		facet->value);
   2714 	} else if (nodeType == XML_ATTRIBUTE_NODE) {
   2715 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
   2716 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
   2717 	} else {
   2718 	    msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
   2719 	    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
   2720 	}
   2721     } else {
   2722 	msg = xmlStrcat(msg, (const xmlChar *) message);
   2723 	msg = xmlStrcat(msg, BAD_CAST ".\n");
   2724 	xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
   2725     }
   2726     FREE_AND_NULL(str)
   2727     xmlFree(msg);
   2728 }
   2729 
   2730 #define VERROR(err, type, msg) \
   2731     xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
   2732 
   2733 #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
   2734 
   2735 #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
   2736 #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
   2737 
   2738 #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
   2739 
   2740 
   2741 /**
   2742  * xmlSchemaPMissingAttrErr:
   2743  * @ctxt: the schema validation context
   2744  * @ownerDes: the designation of  the owner
   2745  * @ownerName: the name of the owner
   2746  * @ownerItem: the owner as a schema object
   2747  * @ownerElem: the owner as an element node
   2748  * @node: the parent element node of the missing attribute node
   2749  * @type: the corresponding type of the attribute node
   2750  *
   2751  * Reports an illegal attribute.
   2752  */
   2753 static void
   2754 xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
   2755 			 xmlParserErrors error,
   2756 			 xmlSchemaBasicItemPtr ownerItem,
   2757 			 xmlNodePtr ownerElem,
   2758 			 const char *name,
   2759 			 const char *message)
   2760 {
   2761     xmlChar *des = NULL;
   2762 
   2763     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
   2764 
   2765     if (message != NULL)
   2766 	xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
   2767     else
   2768 	xmlSchemaPErr(ctxt, ownerElem, error,
   2769 	    "%s: The attribute '%s' is required but missing.\n",
   2770 	    BAD_CAST des, BAD_CAST name);
   2771     FREE_AND_NULL(des);
   2772 }
   2773 
   2774 
   2775 /**
   2776  * xmlSchemaPResCompAttrErr:
   2777  * @ctxt: the schema validation context
   2778  * @error: the error code
   2779  * @ownerDes: the designation of  the owner
   2780  * @ownerItem: the owner as a schema object
   2781  * @ownerElem: the owner as an element node
   2782  * @name: the name of the attribute holding the QName
   2783  * @refName: the referenced local name
   2784  * @refURI: the referenced namespace URI
   2785  * @message: optional message
   2786  *
   2787  * Used to report QName attribute values that failed to resolve
   2788  * to schema components.
   2789  */
   2790 static void
   2791 xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
   2792 			 xmlParserErrors error,
   2793 			 xmlSchemaBasicItemPtr ownerItem,
   2794 			 xmlNodePtr ownerElem,
   2795 			 const char *name,
   2796 			 const xmlChar *refName,
   2797 			 const xmlChar *refURI,
   2798 			 xmlSchemaTypeType refType,
   2799 			 const char *refTypeStr)
   2800 {
   2801     xmlChar *des = NULL, *strA = NULL;
   2802 
   2803     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
   2804     if (refTypeStr == NULL)
   2805 	refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
   2806 	xmlSchemaPErrExt(ctxt, ownerElem, error,
   2807 	    NULL, NULL, NULL,
   2808 	    "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
   2809 	    "%s.\n", BAD_CAST des, BAD_CAST name,
   2810 	    xmlSchemaFormatQName(&strA, refURI, refName),
   2811 	    BAD_CAST refTypeStr, NULL);
   2812     FREE_AND_NULL(des)
   2813     FREE_AND_NULL(strA)
   2814 }
   2815 
   2816 /**
   2817  * xmlSchemaPCustomAttrErr:
   2818  * @ctxt: the schema parser context
   2819  * @error: the error code
   2820  * @ownerDes: the designation of the owner
   2821  * @ownerItem: the owner as a schema object
   2822  * @attr: the illegal attribute node
   2823  *
   2824  * Reports an illegal attribute during the parse.
   2825  */
   2826 static void
   2827 xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
   2828 			xmlParserErrors error,
   2829 			xmlChar **ownerDes,
   2830 			xmlSchemaBasicItemPtr ownerItem,
   2831 			xmlAttrPtr attr,
   2832 			const char *msg)
   2833 {
   2834     xmlChar *des = NULL;
   2835 
   2836     if (ownerDes == NULL)
   2837 	xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
   2838     else if (*ownerDes == NULL) {
   2839 	xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
   2840 	des = *ownerDes;
   2841     } else
   2842 	des = *ownerDes;
   2843     if (attr == NULL) {
   2844 	xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
   2845 	    "%s, attribute '%s': %s.\n",
   2846 	    BAD_CAST des, (const xmlChar *) "Unknown",
   2847 	    (const xmlChar *) msg, NULL, NULL);
   2848     } else {
   2849 	xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
   2850 	    "%s, attribute '%s': %s.\n",
   2851 	    BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
   2852     }
   2853     if (ownerDes == NULL)
   2854 	FREE_AND_NULL(des);
   2855 }
   2856 
   2857 /**
   2858  * xmlSchemaPIllegalAttrErr:
   2859  * @ctxt: the schema parser context
   2860  * @error: the error code
   2861  * @ownerDes: the designation of the attribute's owner
   2862  * @ownerItem: the attribute's owner item
   2863  * @attr: the illegal attribute node
   2864  *
   2865  * Reports an illegal attribute during the parse.
   2866  */
   2867 static void
   2868 xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
   2869 			 xmlParserErrors error,
   2870 			 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
   2871 			 xmlAttrPtr attr)
   2872 {
   2873     xmlChar *strA = NULL, *strB = NULL;
   2874 
   2875     xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
   2876     xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
   2877 	"%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
   2878 	xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
   2879 	NULL, NULL);
   2880     FREE_AND_NULL(strA);
   2881     FREE_AND_NULL(strB);
   2882 }
   2883 
   2884 /**
   2885  * xmlSchemaPCustomErr:
   2886  * @ctxt: the schema parser context
   2887  * @error: the error code
   2888  * @itemDes: the designation of the schema item
   2889  * @item: the schema item
   2890  * @itemElem: the node of the schema item
   2891  * @message: the error message
   2892  * @str1: an optional param for the error message
   2893  * @str2: an optional param for the error message
   2894  * @str3: an optional param for the error message
   2895  *
   2896  * Reports an error during parsing.
   2897  */
   2898 static void
   2899 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
   2900 		    xmlParserErrors error,
   2901 		    xmlSchemaBasicItemPtr item,
   2902 		    xmlNodePtr itemElem,
   2903 		    const char *message,
   2904 		    const xmlChar *str1,
   2905 		    const xmlChar *str2,
   2906 		    const xmlChar *str3)
   2907 {
   2908     xmlChar *des = NULL, *msg = NULL;
   2909 
   2910     xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
   2911     msg = xmlStrdup(BAD_CAST "%s: ");
   2912     msg = xmlStrcat(msg, (const xmlChar *) message);
   2913     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2914     if ((itemElem == NULL) && (item != NULL))
   2915 	itemElem = WXS_ITEM_NODE(item);
   2916     xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
   2917 	(const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
   2918     FREE_AND_NULL(des);
   2919     FREE_AND_NULL(msg);
   2920 }
   2921 
   2922 /**
   2923  * xmlSchemaPCustomErr:
   2924  * @ctxt: the schema parser context
   2925  * @error: the error code
   2926  * @itemDes: the designation of the schema item
   2927  * @item: the schema item
   2928  * @itemElem: the node of the schema item
   2929  * @message: the error message
   2930  * @str1: the optional param for the error message
   2931  *
   2932  * Reports an error during parsing.
   2933  */
   2934 static void
   2935 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
   2936 		    xmlParserErrors error,
   2937 		    xmlSchemaBasicItemPtr item,
   2938 		    xmlNodePtr itemElem,
   2939 		    const char *message,
   2940 		    const xmlChar *str1)
   2941 {
   2942     xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
   2943 	str1, NULL, NULL);
   2944 }
   2945 
   2946 /**
   2947  * xmlSchemaPAttrUseErr:
   2948  * @ctxt: the schema parser context
   2949  * @error: the error code
   2950  * @itemDes: the designation of the schema type
   2951  * @item: the schema type
   2952  * @itemElem: the node of the schema type
   2953  * @attr: the invalid schema attribute
   2954  * @message: the error message
   2955  * @str1: the optional param for the error message
   2956  *
   2957  * Reports an attribute use error during parsing.
   2958  */
   2959 static void
   2960 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
   2961 		    xmlParserErrors error,
   2962 		    xmlNodePtr node,
   2963 		    xmlSchemaBasicItemPtr ownerItem,
   2964 		    const xmlSchemaAttributeUsePtr attruse,
   2965 		    const char *message,
   2966 		    const xmlChar *str1, const xmlChar *str2,
   2967 		    const xmlChar *str3,const xmlChar *str4)
   2968 {
   2969     xmlChar *str = NULL, *msg = NULL;
   2970 
   2971     xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
   2972     msg = xmlStrcat(msg, BAD_CAST ", ");
   2973     msg = xmlStrcat(msg,
   2974 	BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
   2975 	WXS_BASIC_CAST attruse, NULL));
   2976     FREE_AND_NULL(str);
   2977     msg = xmlStrcat(msg, BAD_CAST ": ");
   2978     msg = xmlStrcat(msg, (const xmlChar *) message);
   2979     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2980     xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
   2981 	(const char *) msg, str1, str2, str3, str4);
   2982     xmlFree(msg);
   2983 }
   2984 
   2985 /**
   2986  * xmlSchemaPIllegalFacetAtomicErr:
   2987  * @ctxt: the schema parser context
   2988  * @error: the error code
   2989  * @type: the schema type
   2990  * @baseType: the base type of type
   2991  * @facet: the illegal facet
   2992  *
   2993  * Reports an illegal facet for atomic simple types.
   2994  */
   2995 static void
   2996 xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
   2997 			  xmlParserErrors error,
   2998 			  xmlSchemaTypePtr type,
   2999 			  xmlSchemaTypePtr baseType,
   3000 			  xmlSchemaFacetPtr facet)
   3001 {
   3002     xmlChar *des = NULL, *strT = NULL;
   3003 
   3004     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
   3005     xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
   3006 	"%s: The facet '%s' is not allowed on types derived from the "
   3007 	"type %s.\n",
   3008 	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
   3009 	xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
   3010 	NULL, NULL);
   3011     FREE_AND_NULL(des);
   3012     FREE_AND_NULL(strT);
   3013 }
   3014 
   3015 /**
   3016  * xmlSchemaPIllegalFacetListUnionErr:
   3017  * @ctxt: the schema parser context
   3018  * @error: the error code
   3019  * @itemDes: the designation of the schema item involved
   3020  * @item: the schema item involved
   3021  * @facet: the illegal facet
   3022  *
   3023  * Reports an illegal facet for <list> and <union>.
   3024  */
   3025 static void
   3026 xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
   3027 			  xmlParserErrors error,
   3028 			  xmlSchemaTypePtr type,
   3029 			  xmlSchemaFacetPtr facet)
   3030 {
   3031     xmlChar *des = NULL;
   3032 
   3033     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
   3034 	type->node);
   3035     xmlSchemaPErr(ctxt, type->node, error,
   3036 	"%s: The facet '%s' is not allowed.\n",
   3037 	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
   3038     FREE_AND_NULL(des);
   3039 }
   3040 
   3041 /**
   3042  * xmlSchemaPMutualExclAttrErr:
   3043  * @ctxt: the schema validation context
   3044  * @error: the error code
   3045  * @elemDes: the designation of the parent element node
   3046  * @attr: the bad attribute node
   3047  * @type: the corresponding type of the attribute node
   3048  *
   3049  * Reports an illegal attribute.
   3050  */
   3051 static void
   3052 xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
   3053 			 xmlParserErrors error,
   3054 			 xmlSchemaBasicItemPtr ownerItem,
   3055 			 xmlAttrPtr attr,
   3056 			 const char *name1,
   3057 			 const char *name2)
   3058 {
   3059     xmlChar *des = NULL;
   3060 
   3061     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
   3062     xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
   3063 	"%s: The attributes '%s' and '%s' are mutually exclusive.\n",
   3064 	BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
   3065     FREE_AND_NULL(des);
   3066 }
   3067 
   3068 /**
   3069  * xmlSchemaPSimpleTypeErr:
   3070  * @ctxt:  the schema validation context
   3071  * @error: the error code
   3072  * @type: the type specifier
   3073  * @ownerDes: the designation of the owner
   3074  * @ownerItem: the schema object if existent
   3075  * @node: the validated node
   3076  * @value: the validated value
   3077  *
   3078  * Reports a simple type validation error.
   3079  * TODO: Should this report the value of an element as well?
   3080  */
   3081 static void
   3082 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
   3083 			xmlParserErrors error,
   3084 			xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
   3085 			xmlNodePtr node,
   3086 			xmlSchemaTypePtr type,
   3087 			const char *expected,
   3088 			const xmlChar *value,
   3089 			const char *message,
   3090 			const xmlChar *str1,
   3091 			const xmlChar *str2)
   3092 {
   3093     xmlChar *msg = NULL;
   3094 
   3095     xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
   3096     if (message == NULL) {
   3097 	/*
   3098 	* Use default messages.
   3099 	*/
   3100 	if (type != NULL) {
   3101 	    if (node->type == XML_ATTRIBUTE_NODE)
   3102 		msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
   3103 	    else
   3104 		msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
   3105 		"valid value of ");
   3106 	    if (! xmlSchemaIsGlobalItem(type))
   3107 		msg = xmlStrcat(msg, BAD_CAST "the local ");
   3108 	    else
   3109 		msg = xmlStrcat(msg, BAD_CAST "the ");
   3110 
   3111 	    if (WXS_IS_ATOMIC(type))
   3112 		msg = xmlStrcat(msg, BAD_CAST "atomic type");
   3113 	    else if (WXS_IS_LIST(type))
   3114 		msg = xmlStrcat(msg, BAD_CAST "list type");
   3115 	    else if (WXS_IS_UNION(type))
   3116 		msg = xmlStrcat(msg, BAD_CAST "union type");
   3117 
   3118 	    if (xmlSchemaIsGlobalItem(type)) {
   3119 		xmlChar *str = NULL;
   3120 		msg = xmlStrcat(msg, BAD_CAST " '");
   3121 		if (type->builtInType != 0) {
   3122 		    msg = xmlStrcat(msg, BAD_CAST "xs:");
   3123 		    msg = xmlStrcat(msg, type->name);
   3124 		} else
   3125 		    msg = xmlStrcat(msg,
   3126 			xmlSchemaFormatQName(&str,
   3127 			    type->targetNamespace, type->name));
   3128 		msg = xmlStrcat(msg, BAD_CAST "'.");
   3129 		FREE_AND_NULL(str);
   3130 	    }
   3131 	} else {
   3132 	    if (node->type == XML_ATTRIBUTE_NODE)
   3133 		msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
   3134 	    else
   3135 		msg = xmlStrcat(msg, BAD_CAST "The character content is not "
   3136 		"valid.");
   3137 	}
   3138 	if (expected) {
   3139 	    msg = xmlStrcat(msg, BAD_CAST " Expected is '");
   3140 	    msg = xmlStrcat(msg, BAD_CAST expected);
   3141 	    msg = xmlStrcat(msg, BAD_CAST "'.\n");
   3142 	} else
   3143 	    msg = xmlStrcat(msg, BAD_CAST "\n");
   3144 	if (node->type == XML_ATTRIBUTE_NODE)
   3145 	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
   3146 	else
   3147 	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
   3148     } else {
   3149 	msg = xmlStrcat(msg, BAD_CAST message);
   3150 	msg = xmlStrcat(msg, BAD_CAST ".\n");
   3151 	xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
   3152 	     (const char*) msg, str1, str2, NULL, NULL, NULL);
   3153     }
   3154     /* Cleanup. */
   3155     FREE_AND_NULL(msg)
   3156 }
   3157 
   3158 /**
   3159  * xmlSchemaPContentErr:
   3160  * @ctxt: the schema parser context
   3161  * @error: the error code
   3162  * @onwerDes: the designation of the holder of the content
   3163  * @ownerItem: the owner item of the holder of the content
   3164  * @ownerElem: the node of the holder of the content
   3165  * @child: the invalid child node
   3166  * @message: the optional error message
   3167  * @content: the optional string describing the correct content
   3168  *
   3169  * Reports an error concerning the content of a schema element.
   3170  */
   3171 static void
   3172 xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
   3173 		     xmlParserErrors error,
   3174 		     xmlSchemaBasicItemPtr ownerItem,
   3175 		     xmlNodePtr ownerElem,
   3176 		     xmlNodePtr child,
   3177 		     const char *message,
   3178 		     const char *content)
   3179 {
   3180     xmlChar *des = NULL;
   3181 
   3182     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
   3183     if (message != NULL)
   3184 	xmlSchemaPErr2(ctxt, ownerElem, child, error,
   3185 	    "%s: %s.\n",
   3186 	    BAD_CAST des, BAD_CAST message);
   3187     else {
   3188 	if (content != NULL) {
   3189 	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
   3190 		"%s: The content is not valid. Expected is %s.\n",
   3191 		BAD_CAST des, BAD_CAST content);
   3192 	} else {
   3193 	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
   3194 		"%s: The content is not valid.\n",
   3195 		BAD_CAST des, NULL);
   3196 	}
   3197     }
   3198     FREE_AND_NULL(des)
   3199 }
   3200 
   3201 /************************************************************************
   3202  * 									*
   3203  * 			Streamable error functions                      *
   3204  * 									*
   3205  ************************************************************************/
   3206 
   3207 
   3208 
   3209 
   3210 /************************************************************************
   3211  * 									*
   3212  * 			Validation helper functions			*
   3213  * 									*
   3214  ************************************************************************/
   3215 
   3216 
   3217 /************************************************************************
   3218  * 									*
   3219  * 			Allocation functions				*
   3220  * 									*
   3221  ************************************************************************/
   3222 
   3223 /**
   3224  * xmlSchemaNewSchemaForParserCtxt:
   3225  * @ctxt:  a schema validation context
   3226  *
   3227  * Allocate a new Schema structure.
   3228  *
   3229  * Returns the newly allocated structure or NULL in case or error
   3230  */
   3231 static xmlSchemaPtr
   3232 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
   3233 {
   3234     xmlSchemaPtr ret;
   3235 
   3236     ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
   3237     if (ret == NULL) {
   3238         xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
   3239         return (NULL);
   3240     }
   3241     memset(ret, 0, sizeof(xmlSchema));
   3242     ret->dict = ctxt->dict;
   3243     xmlDictReference(ret->dict);
   3244 
   3245     return (ret);
   3246 }
   3247 
   3248 /**
   3249  * xmlSchemaNewFacet:
   3250  *
   3251  * Allocate a new Facet structure.
   3252  *
   3253  * Returns the newly allocated structure or NULL in case or error
   3254  */
   3255 xmlSchemaFacetPtr
   3256 xmlSchemaNewFacet(void)
   3257 {
   3258     xmlSchemaFacetPtr ret;
   3259 
   3260     ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
   3261     if (ret == NULL) {
   3262         return (NULL);
   3263     }
   3264     memset(ret, 0, sizeof(xmlSchemaFacet));
   3265 
   3266     return (ret);
   3267 }
   3268 
   3269 /**
   3270  * xmlSchemaNewAnnot:
   3271  * @ctxt:  a schema validation context
   3272  * @node:  a node
   3273  *
   3274  * Allocate a new annotation structure.
   3275  *
   3276  * Returns the newly allocated structure or NULL in case or error
   3277  */
   3278 static xmlSchemaAnnotPtr
   3279 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
   3280 {
   3281     xmlSchemaAnnotPtr ret;
   3282 
   3283     ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
   3284     if (ret == NULL) {
   3285         xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
   3286         return (NULL);
   3287     }
   3288     memset(ret, 0, sizeof(xmlSchemaAnnot));
   3289     ret->content = node;
   3290     return (ret);
   3291 }
   3292 
   3293 static xmlSchemaItemListPtr
   3294 xmlSchemaItemListCreate(void)
   3295 {
   3296     xmlSchemaItemListPtr ret;
   3297 
   3298     ret = xmlMalloc(sizeof(xmlSchemaItemList));
   3299     if (ret == NULL) {
   3300 	xmlSchemaPErrMemory(NULL,
   3301 	    "allocating an item list structure", NULL);
   3302 	return (NULL);
   3303     }
   3304     memset(ret, 0, sizeof(xmlSchemaItemList));
   3305     return (ret);
   3306 }
   3307 
   3308 static void
   3309 xmlSchemaItemListClear(xmlSchemaItemListPtr list)
   3310 {
   3311     if (list->items != NULL) {
   3312 	xmlFree(list->items);
   3313 	list->items = NULL;
   3314     }
   3315     list->nbItems = 0;
   3316     list->sizeItems = 0;
   3317 }
   3318 
   3319 static int
   3320 xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
   3321 {
   3322     if (list->items == NULL) {
   3323 	list->items = (void **) xmlMalloc(
   3324 	    20 * sizeof(void *));
   3325 	if (list->items == NULL) {
   3326 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
   3327 	    return(-1);
   3328 	}
   3329 	list->sizeItems = 20;
   3330     } else if (list->sizeItems <= list->nbItems) {
   3331 	list->sizeItems *= 2;
   3332 	list->items = (void **) xmlRealloc(list->items,
   3333 	    list->sizeItems * sizeof(void *));
   3334 	if (list->items == NULL) {
   3335 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
   3336 	    list->sizeItems = 0;
   3337 	    return(-1);
   3338 	}
   3339     }
   3340     list->items[list->nbItems++] = item;
   3341     return(0);
   3342 }
   3343 
   3344 static int
   3345 xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
   3346 			 int initialSize,
   3347 			 void *item)
   3348 {
   3349     if (list->items == NULL) {
   3350 	if (initialSize <= 0)
   3351 	    initialSize = 1;
   3352 	list->items = (void **) xmlMalloc(
   3353 	    initialSize * sizeof(void *));
   3354 	if (list->items == NULL) {
   3355 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
   3356 	    return(-1);
   3357 	}
   3358 	list->sizeItems = initialSize;
   3359     } else if (list->sizeItems <= list->nbItems) {
   3360 	list->sizeItems *= 2;
   3361 	list->items = (void **) xmlRealloc(list->items,
   3362 	    list->sizeItems * sizeof(void *));
   3363 	if (list->items == NULL) {
   3364 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
   3365 	    list->sizeItems = 0;
   3366 	    return(-1);
   3367 	}
   3368     }
   3369     list->items[list->nbItems++] = item;
   3370     return(0);
   3371 }
   3372 
   3373 static int
   3374 xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
   3375 {
   3376     if (list->items == NULL) {
   3377 	list->items = (void **) xmlMalloc(
   3378 	    20 * sizeof(void *));
   3379 	if (list->items == NULL) {
   3380 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
   3381 	    return(-1);
   3382 	}
   3383 	list->sizeItems = 20;
   3384     } else if (list->sizeItems <= list->nbItems) {
   3385 	list->sizeItems *= 2;
   3386 	list->items = (void **) xmlRealloc(list->items,
   3387 	    list->sizeItems * sizeof(void *));
   3388 	if (list->items == NULL) {
   3389 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
   3390 	    list->sizeItems = 0;
   3391 	    return(-1);
   3392 	}
   3393     }
   3394     /*
   3395     * Just append if the index is greater/equal than the item count.
   3396     */
   3397     if (idx >= list->nbItems) {
   3398 	list->items[list->nbItems++] = item;
   3399     } else {
   3400 	int i;
   3401 	for (i = list->nbItems; i > idx; i--)
   3402 	    list->items[i] = list->items[i-1];
   3403 	list->items[idx] = item;
   3404 	list->nbItems++;
   3405     }
   3406     return(0);
   3407 }
   3408 
   3409 #if 0 /* enable if ever needed */
   3410 static int
   3411 xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
   3412 			    int initialSize,
   3413 			    void *item,
   3414 			    int idx)
   3415 {
   3416     if (list->items == NULL) {
   3417 	if (initialSize <= 0)
   3418 	    initialSize = 1;
   3419 	list->items = (void **) xmlMalloc(
   3420 	    initialSize * sizeof(void *));
   3421 	if (list->items == NULL) {
   3422 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
   3423 	    return(-1);
   3424 	}
   3425 	list->sizeItems = initialSize;
   3426     } else if (list->sizeItems <= list->nbItems) {
   3427 	list->sizeItems *= 2;
   3428 	list->items = (void **) xmlRealloc(list->items,
   3429 	    list->sizeItems * sizeof(void *));
   3430 	if (list->items == NULL) {
   3431 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
   3432 	    list->sizeItems = 0;
   3433 	    return(-1);
   3434 	}
   3435     }
   3436     /*
   3437     * Just append if the index is greater/equal than the item count.
   3438     */
   3439     if (idx >= list->nbItems) {
   3440 	list->items[list->nbItems++] = item;
   3441     } else {
   3442 	int i;
   3443 	for (i = list->nbItems; i > idx; i--)
   3444 	    list->items[i] = list->items[i-1];
   3445 	list->items[idx] = item;
   3446 	list->nbItems++;
   3447     }
   3448     return(0);
   3449 }
   3450 #endif
   3451 
   3452 static int
   3453 xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
   3454 {
   3455     int i;
   3456     if ((list->items == NULL) || (idx >= list->nbItems)) {
   3457 	xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
   3458 	    "index error.\n");
   3459 	return(-1);
   3460     }
   3461 
   3462     if (list->nbItems == 1) {
   3463 	/* TODO: Really free the list? */
   3464 	xmlFree(list->items);
   3465 	list->items = NULL;
   3466 	list->nbItems = 0;
   3467 	list->sizeItems = 0;
   3468     } else if (list->nbItems -1 == idx) {
   3469 	list->nbItems--;
   3470     } else {
   3471 	for (i = idx; i < list->nbItems -1; i++)
   3472 	    list->items[i] = list->items[i+1];
   3473 	list->nbItems--;
   3474     }
   3475     return(0);
   3476 }
   3477 
   3478 /**
   3479  * xmlSchemaItemListFree:
   3480  * @annot:  a schema type structure
   3481  *
   3482  * Deallocate a annotation structure
   3483  */
   3484 static void
   3485 xmlSchemaItemListFree(xmlSchemaItemListPtr list)
   3486 {
   3487     if (list == NULL)
   3488 	return;
   3489     if (list->items != NULL)
   3490 	xmlFree(list->items);
   3491     xmlFree(list);
   3492 }
   3493 
   3494 static void
   3495 xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
   3496 {
   3497     if (bucket == NULL)
   3498 	return;
   3499     if (bucket->globals != NULL) {
   3500 	xmlSchemaComponentListFree(bucket->globals);
   3501 	xmlSchemaItemListFree(bucket->globals);
   3502     }
   3503     if (bucket->locals != NULL) {
   3504 	xmlSchemaComponentListFree(bucket->locals);
   3505 	xmlSchemaItemListFree(bucket->locals);
   3506     }
   3507     if (bucket->relations != NULL) {
   3508 	xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
   3509 	do {
   3510 	    prev = cur;
   3511 	    cur = cur->next;
   3512 	    xmlFree(prev);
   3513 	} while (cur != NULL);
   3514     }
   3515     if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
   3516 	xmlFreeDoc(bucket->doc);
   3517     }
   3518     if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
   3519 	if (WXS_IMPBUCKET(bucket)->schema != NULL)
   3520 	    xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
   3521     }
   3522     xmlFree(bucket);
   3523 }
   3524 
   3525 static xmlSchemaBucketPtr
   3526 xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
   3527 			 int type, const xmlChar *targetNamespace)
   3528 {
   3529     xmlSchemaBucketPtr ret;
   3530     int size;
   3531     xmlSchemaPtr mainSchema;
   3532 
   3533     if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
   3534 	PERROR_INT("xmlSchemaBucketCreate",
   3535 	    "no main schema on constructor");
   3536 	return(NULL);
   3537     }
   3538     mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
   3539     /* Create the schema bucket. */
   3540     if (WXS_IS_BUCKET_INCREDEF(type))
   3541 	size = sizeof(xmlSchemaInclude);
   3542     else
   3543 	size = sizeof(xmlSchemaImport);
   3544     ret = (xmlSchemaBucketPtr) xmlMalloc(size);
   3545     if (ret == NULL) {
   3546 	xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
   3547 	return(NULL);
   3548     }
   3549     memset(ret, 0, size);
   3550     ret->targetNamespace = targetNamespace;
   3551     ret->type = type;
   3552     ret->globals = xmlSchemaItemListCreate();
   3553     if (ret->globals == NULL) {
   3554 	xmlFree(ret);
   3555 	return(NULL);
   3556     }
   3557     ret->locals = xmlSchemaItemListCreate();
   3558     if (ret->locals == NULL) {
   3559 	xmlFree(ret);
   3560 	return(NULL);
   3561     }
   3562     /*
   3563     * The following will assure that only the first bucket is marked as
   3564     * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
   3565     * For each following import buckets an xmlSchema will be created.
   3566     * An xmlSchema will be created for every distinct targetNamespace.
   3567     * We assign the targetNamespace to the schemata here.
   3568     */
   3569     if (! WXS_HAS_BUCKETS(pctxt)) {
   3570 	if (WXS_IS_BUCKET_INCREDEF(type)) {
   3571 	    PERROR_INT("xmlSchemaBucketCreate",
   3572 		"first bucket but it's an include or redefine");
   3573 	    xmlSchemaBucketFree(ret);
   3574 	    return(NULL);
   3575 	}
   3576 	/* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
   3577 	ret->type = XML_SCHEMA_SCHEMA_MAIN;
   3578 	/* Point to the *main* schema. */
   3579 	WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
   3580 	WXS_IMPBUCKET(ret)->schema = mainSchema;
   3581 	/*
   3582 	* Ensure that the main schema gets a targetNamespace.
   3583 	*/
   3584 	mainSchema->targetNamespace = targetNamespace;
   3585     } else {
   3586 	if (type == XML_SCHEMA_SCHEMA_MAIN) {
   3587 	    PERROR_INT("xmlSchemaBucketCreate",
   3588 		"main bucket but it's not the first one");
   3589 	    xmlSchemaBucketFree(ret);
   3590 	    return(NULL);
   3591 	} else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
   3592 	    /*
   3593 	    * Create a schema for imports and assign the
   3594 	    * targetNamespace.
   3595 	    */
   3596 	    WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
   3597 	    if (WXS_IMPBUCKET(ret)->schema == NULL) {
   3598 		xmlSchemaBucketFree(ret);
   3599 		return(NULL);
   3600 	    }
   3601 	    WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
   3602 	}
   3603     }
   3604     if (WXS_IS_BUCKET_IMPMAIN(type)) {
   3605 	int res;
   3606 	/*
   3607 	* Imports go into the "schemasImports" slot of the main *schema*.
   3608 	* Note that we create an import entry for the main schema as well; i.e.,
   3609 	* even if there's only one schema, we'll get an import.
   3610 	*/
   3611 	if (mainSchema->schemasImports == NULL) {
   3612 	    mainSchema->schemasImports = xmlHashCreateDict(5,
   3613 		WXS_CONSTRUCTOR(pctxt)->dict);
   3614 	    if (mainSchema->schemasImports == NULL) {
   3615 		xmlSchemaBucketFree(ret);
   3616 		return(NULL);
   3617 	    }
   3618 	}
   3619 	if (targetNamespace == NULL)
   3620 	    res = xmlHashAddEntry(mainSchema->schemasImports,
   3621 		XML_SCHEMAS_NO_NAMESPACE, ret);
   3622 	else
   3623 	    res = xmlHashAddEntry(mainSchema->schemasImports,
   3624 		targetNamespace, ret);
   3625 	if (res != 0) {
   3626 	    PERROR_INT("xmlSchemaBucketCreate",
   3627 		"failed to add the schema bucket to the hash");
   3628 	    xmlSchemaBucketFree(ret);
   3629 	    return(NULL);
   3630 	}
   3631     } else {
   3632 	/* Set the @ownerImport of an include bucket. */
   3633 	if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
   3634 	    WXS_INCBUCKET(ret)->ownerImport =
   3635 		WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
   3636 	else
   3637 	    WXS_INCBUCKET(ret)->ownerImport =
   3638 		WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
   3639 
   3640 	/* Includes got into the "includes" slot of the *main* schema. */
   3641 	if (mainSchema->includes == NULL) {
   3642 	    mainSchema->includes = xmlSchemaItemListCreate();
   3643 	    if (mainSchema->includes == NULL) {
   3644 		xmlSchemaBucketFree(ret);
   3645 		return(NULL);
   3646 	    }
   3647 	}
   3648 	xmlSchemaItemListAdd(mainSchema->includes, ret);
   3649     }
   3650     /*
   3651     * Add to list of all buckets; this is used for lookup
   3652     * during schema construction time only.
   3653     */
   3654     if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
   3655 	return(NULL);
   3656     return(ret);
   3657 }
   3658 
   3659 static int
   3660 xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
   3661 {
   3662     if (*list == NULL) {
   3663 	*list = xmlSchemaItemListCreate();
   3664 	if (*list == NULL)
   3665 	    return(-1);
   3666     }
   3667     xmlSchemaItemListAddSize(*list, initialSize, item);
   3668     return(0);
   3669 }
   3670 
   3671 /**
   3672  * xmlSchemaFreeAnnot:
   3673  * @annot:  a schema type structure
   3674  *
   3675  * Deallocate a annotation structure
   3676  */
   3677 static void
   3678 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
   3679 {
   3680     if (annot == NULL)
   3681         return;
   3682     if (annot->next == NULL) {
   3683 	xmlFree(annot);
   3684     } else {
   3685 	xmlSchemaAnnotPtr prev;
   3686 
   3687 	do {
   3688 	    prev = annot;
   3689 	    annot = annot->next;
   3690 	    xmlFree(prev);
   3691 	} while (annot != NULL);
   3692     }
   3693 }
   3694 
   3695 /**
   3696  * xmlSchemaFreeNotation:
   3697  * @schema:  a schema notation structure
   3698  *
   3699  * Deallocate a Schema Notation structure.
   3700  */
   3701 static void
   3702 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
   3703 {
   3704     if (nota == NULL)
   3705         return;
   3706     xmlFree(nota);
   3707 }
   3708 
   3709 /**
   3710  * xmlSchemaFreeAttribute:
   3711  * @attr:  an attribute declaration
   3712  *
   3713  * Deallocates an attribute declaration structure.
   3714  */
   3715 static void
   3716 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
   3717 {
   3718     if (attr == NULL)
   3719         return;
   3720     if (attr->annot != NULL)
   3721 	xmlSchemaFreeAnnot(attr->annot);
   3722     if (attr->defVal != NULL)
   3723 	xmlSchemaFreeValue(attr->defVal);
   3724     xmlFree(attr);
   3725 }
   3726 
   3727 /**
   3728  * xmlSchemaFreeAttributeUse:
   3729  * @use:  an attribute use
   3730  *
   3731  * Deallocates an attribute use structure.
   3732  */
   3733 static void
   3734 xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
   3735 {
   3736     if (use == NULL)
   3737         return;
   3738     if (use->annot != NULL)
   3739 	xmlSchemaFreeAnnot(use->annot);
   3740     if (use->defVal != NULL)
   3741 	xmlSchemaFreeValue(use->defVal);
   3742     xmlFree(use);
   3743 }
   3744 
   3745 /**
   3746  * xmlSchemaFreeAttributeUseProhib:
   3747  * @prohib:  an attribute use prohibition
   3748  *
   3749  * Deallocates an attribute use structure.
   3750  */
   3751 static void
   3752 xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
   3753 {
   3754     if (prohib == NULL)
   3755         return;
   3756     xmlFree(prohib);
   3757 }
   3758 
   3759 /**
   3760  * xmlSchemaFreeWildcardNsSet:
   3761  * set:  a schema wildcard namespace
   3762  *
   3763  * Deallocates a list of wildcard constraint structures.
   3764  */
   3765 static void
   3766 xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
   3767 {
   3768     xmlSchemaWildcardNsPtr next;
   3769 
   3770     while (set != NULL) {
   3771 	next = set->next;
   3772 	xmlFree(set);
   3773 	set = next;
   3774     }
   3775 }
   3776 
   3777 /**
   3778  * xmlSchemaFreeWildcard:
   3779  * @wildcard:  a wildcard structure
   3780  *
   3781  * Deallocates a wildcard structure.
   3782  */
   3783 void
   3784 xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
   3785 {
   3786     if (wildcard == NULL)
   3787         return;
   3788     if (wildcard->annot != NULL)
   3789         xmlSchemaFreeAnnot(wildcard->annot);
   3790     if (wildcard->nsSet != NULL)
   3791 	xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
   3792     if (wildcard->negNsSet != NULL)
   3793 	xmlFree(wildcard->negNsSet);
   3794     xmlFree(wildcard);
   3795 }
   3796 
   3797 /**
   3798  * xmlSchemaFreeAttributeGroup:
   3799  * @schema:  a schema attribute group structure
   3800  *
   3801  * Deallocate a Schema Attribute Group structure.
   3802  */
   3803 static void
   3804 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
   3805 {
   3806     if (attrGr == NULL)
   3807         return;
   3808     if (attrGr->annot != NULL)
   3809         xmlSchemaFreeAnnot(attrGr->annot);
   3810     if (attrGr->attrUses != NULL)
   3811 	xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
   3812     xmlFree(attrGr);
   3813 }
   3814 
   3815 /**
   3816  * xmlSchemaFreeQNameRef:
   3817  * @item: a QName reference structure
   3818  *
   3819  * Deallocatea a QName reference structure.
   3820  */
   3821 static void
   3822 xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
   3823 {
   3824     xmlFree(item);
   3825 }
   3826 
   3827 /**
   3828  * xmlSchemaFreeTypeLinkList:
   3829  * @alink: a type link
   3830  *
   3831  * Deallocate a list of types.
   3832  */
   3833 static void
   3834 xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
   3835 {
   3836     xmlSchemaTypeLinkPtr next;
   3837 
   3838     while (link != NULL) {
   3839 	next = link->next;
   3840 	xmlFree(link);
   3841 	link = next;
   3842     }
   3843 }
   3844 
   3845 static void
   3846 xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
   3847 {
   3848     xmlSchemaIDCStateObjPtr next;
   3849     while (sto != NULL) {
   3850 	next = sto->next;
   3851 	if (sto->history != NULL)
   3852 	    xmlFree(sto->history);
   3853 	if (sto->xpathCtxt != NULL)
   3854 	    xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
   3855 	xmlFree(sto);
   3856 	sto = next;
   3857     }
   3858 }
   3859 
   3860 /**
   3861  * xmlSchemaFreeIDC:
   3862  * @idc: a identity-constraint definition
   3863  *
   3864  * Deallocates an identity-constraint definition.
   3865  */
   3866 static void
   3867 xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
   3868 {
   3869     xmlSchemaIDCSelectPtr cur, prev;
   3870 
   3871     if (idcDef == NULL)
   3872 	return;
   3873     if (idcDef->annot != NULL)
   3874         xmlSchemaFreeAnnot(idcDef->annot);
   3875     /* Selector */
   3876     if (idcDef->selector != NULL) {
   3877 	if (idcDef->selector->xpathComp != NULL)
   3878 	    xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
   3879 	xmlFree(idcDef->selector);
   3880     }
   3881     /* Fields */
   3882     if (idcDef->fields != NULL) {
   3883 	cur = idcDef->fields;
   3884 	do {
   3885 	    prev = cur;
   3886 	    cur = cur->next;
   3887 	    if (prev->xpathComp != NULL)
   3888 		xmlFreePattern((xmlPatternPtr) prev->xpathComp);
   3889 	    xmlFree(prev);
   3890 	} while (cur != NULL);
   3891     }
   3892     xmlFree(idcDef);
   3893 }
   3894 
   3895 /**
   3896  * xmlSchemaFreeElement:
   3897  * @schema:  a schema element structure
   3898  *
   3899  * Deallocate a Schema Element structure.
   3900  */
   3901 static void
   3902 xmlSchemaFreeElement(xmlSchemaElementPtr elem)
   3903 {
   3904     if (elem == NULL)
   3905         return;
   3906     if (elem->annot != NULL)
   3907         xmlSchemaFreeAnnot(elem->annot);
   3908     if (elem->contModel != NULL)
   3909         xmlRegFreeRegexp(elem->contModel);
   3910     if (elem->defVal != NULL)
   3911 	xmlSchemaFreeValue(elem->defVal);
   3912     xmlFree(elem);
   3913 }
   3914 
   3915 /**
   3916  * xmlSchemaFreeFacet:
   3917  * @facet:  a schema facet structure
   3918  *
   3919  * Deallocate a Schema Facet structure.
   3920  */
   3921 void
   3922 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
   3923 {
   3924     if (facet == NULL)
   3925         return;
   3926     if (facet->val != NULL)
   3927         xmlSchemaFreeValue(facet->val);
   3928     if (facet->regexp != NULL)
   3929         xmlRegFreeRegexp(facet->regexp);
   3930     if (facet->annot != NULL)
   3931         xmlSchemaFreeAnnot(facet->annot);
   3932     xmlFree(facet);
   3933 }
   3934 
   3935 /**
   3936  * xmlSchemaFreeType:
   3937  * @type:  a schema type structure
   3938  *
   3939  * Deallocate a Schema Type structure.
   3940  */
   3941 void
   3942 xmlSchemaFreeType(xmlSchemaTypePtr type)
   3943 {
   3944     if (type == NULL)
   3945         return;
   3946     if (type->annot != NULL)
   3947         xmlSchemaFreeAnnot(type->annot);
   3948     if (type->facets != NULL) {
   3949         xmlSchemaFacetPtr facet, next;
   3950 
   3951         facet = type->facets;
   3952         while (facet != NULL) {
   3953             next = facet->next;
   3954             xmlSchemaFreeFacet(facet);
   3955             facet = next;
   3956         }
   3957     }
   3958     if (type->attrUses != NULL)
   3959 	xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
   3960     if (type->memberTypes != NULL)
   3961 	xmlSchemaFreeTypeLinkList(type->memberTypes);
   3962     if (type->facetSet != NULL) {
   3963 	xmlSchemaFacetLinkPtr next, link;
   3964 
   3965 	link = type->facetSet;
   3966 	do {
   3967 	    next = link->next;
   3968 	    xmlFree(link);
   3969 	    link = next;
   3970 	} while (link != NULL);
   3971     }
   3972     if (type->contModel != NULL)
   3973         xmlRegFreeRegexp(type->contModel);
   3974     xmlFree(type);
   3975 }
   3976 
   3977 /**
   3978  * xmlSchemaFreeModelGroupDef:
   3979  * @item:  a schema model group definition
   3980  *
   3981  * Deallocates a schema model group definition.
   3982  */
   3983 static void
   3984 xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
   3985 {
   3986     if (item->annot != NULL)
   3987 	xmlSchemaFreeAnnot(item->annot);
   3988     xmlFree(item);
   3989 }
   3990 
   3991 /**
   3992  * xmlSchemaFreeModelGroup:
   3993  * @item:  a schema model group
   3994  *
   3995  * Deallocates a schema model group structure.
   3996  */
   3997 static void
   3998 xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
   3999 {
   4000     if (item->annot != NULL)
   4001 	xmlSchemaFreeAnnot(item->annot);
   4002     xmlFree(item);
   4003 }
   4004 
   4005 static void
   4006 xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
   4007 {
   4008     if ((list == NULL) || (list->nbItems == 0))
   4009 	return;
   4010     {
   4011 	xmlSchemaTreeItemPtr item;
   4012 	xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
   4013 	int i;
   4014 
   4015 	for (i = 0; i < list->nbItems; i++) {
   4016 	    item = items[i];
   4017 	    if (item == NULL)
   4018 		continue;
   4019 	    switch (item->type) {
   4020 		case XML_SCHEMA_TYPE_SIMPLE:
   4021 		case XML_SCHEMA_TYPE_COMPLEX:
   4022 		    xmlSchemaFreeType((xmlSchemaTypePtr) item);
   4023 		    break;
   4024 		case XML_SCHEMA_TYPE_ATTRIBUTE:
   4025 		    xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
   4026 		    break;
   4027 		case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   4028 		    xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
   4029 		    break;
   4030 		case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
   4031 		    xmlSchemaFreeAttributeUseProhib(
   4032 			(xmlSchemaAttributeUseProhibPtr) item);
   4033 		    break;
   4034 		case XML_SCHEMA_TYPE_ELEMENT:
   4035 		    xmlSchemaFreeElement((xmlSchemaElementPtr) item);
   4036 		    break;
   4037 		case XML_SCHEMA_TYPE_PARTICLE:
   4038 		    if (item->annot != NULL)
   4039 			xmlSchemaFreeAnnot(item->annot);
   4040 		    xmlFree(item);
   4041 		    break;
   4042 		case XML_SCHEMA_TYPE_SEQUENCE:
   4043 		case XML_SCHEMA_TYPE_CHOICE:
   4044 		case XML_SCHEMA_TYPE_ALL:
   4045 		    xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
   4046 		    break;
   4047 		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   4048 		    xmlSchemaFreeAttributeGroup(
   4049 			(xmlSchemaAttributeGroupPtr) item);
   4050 		    break;
   4051 		case XML_SCHEMA_TYPE_GROUP:
   4052 		    xmlSchemaFreeModelGroupDef(
   4053 			(xmlSchemaModelGroupDefPtr) item);
   4054 		    break;
   4055 		case XML_SCHEMA_TYPE_ANY:
   4056 		case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   4057 		    xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
   4058 		    break;
   4059 		case XML_SCHEMA_TYPE_IDC_KEY:
   4060 		case XML_SCHEMA_TYPE_IDC_UNIQUE:
   4061 		case XML_SCHEMA_TYPE_IDC_KEYREF:
   4062 		    xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
   4063 		    break;
   4064 		case XML_SCHEMA_TYPE_NOTATION:
   4065 		    xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
   4066 		    break;
   4067 		case XML_SCHEMA_EXTRA_QNAMEREF:
   4068 		    xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
   4069 		    break;
   4070 		default: {
   4071 		    /* TODO: This should never be hit. */
   4072 		    xmlSchemaPSimpleInternalErr(NULL,
   4073 			"Internal error: xmlSchemaComponentListFree, "
   4074 			"unexpected component type '%s'\n",
   4075 			(const xmlChar *) WXS_ITEM_TYPE_NAME(item));
   4076 			 }
   4077 		    break;
   4078 	    }
   4079 	}
   4080 	list->nbItems = 0;
   4081     }
   4082 }
   4083 
   4084 /**
   4085  * xmlSchemaFree:
   4086  * @schema:  a schema structure
   4087  *
   4088  * Deallocate a Schema structure.
   4089  */
   4090 void
   4091 xmlSchemaFree(xmlSchemaPtr schema)
   4092 {
   4093     if (schema == NULL)
   4094         return;
   4095     /* @volatiles is not used anymore :-/ */
   4096     if (schema->volatiles != NULL)
   4097 	TODO
   4098     /*
   4099     * Note that those slots are not responsible for freeing
   4100     * schema components anymore; this will now be done by
   4101     * the schema buckets.
   4102     */
   4103     if (schema->notaDecl != NULL)
   4104         xmlHashFree(schema->notaDecl, NULL);
   4105     if (schema->attrDecl != NULL)
   4106         xmlHashFree(schema->attrDecl, NULL);
   4107     if (schema->attrgrpDecl != NULL)
   4108         xmlHashFree(schema->attrgrpDecl, NULL);
   4109     if (schema->elemDecl != NULL)
   4110         xmlHashFree(schema->elemDecl, NULL);
   4111     if (schema->typeDecl != NULL)
   4112         xmlHashFree(schema->typeDecl, NULL);
   4113     if (schema->groupDecl != NULL)
   4114         xmlHashFree(schema->groupDecl, NULL);
   4115     if (schema->idcDef != NULL)
   4116         xmlHashFree(schema->idcDef, NULL);
   4117 
   4118     if (schema->schemasImports != NULL)
   4119 	xmlHashFree(schema->schemasImports,
   4120 		    (xmlHashDeallocator) xmlSchemaBucketFree);
   4121     if (schema->includes != NULL) {
   4122 	xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
   4123 	int i;
   4124 	for (i = 0; i < list->nbItems; i++) {
   4125 	    xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
   4126 	}
   4127 	xmlSchemaItemListFree(list);
   4128     }
   4129     if (schema->annot != NULL)
   4130         xmlSchemaFreeAnnot(schema->annot);
   4131     /* Never free the doc here, since this will be done by the buckets. */
   4132 
   4133     xmlDictFree(schema->dict);
   4134     xmlFree(schema);
   4135 }
   4136 
   4137 /************************************************************************
   4138  * 									*
   4139  * 			Debug functions					*
   4140  * 									*
   4141  ************************************************************************/
   4142 
   4143 #ifdef LIBXML_OUTPUT_ENABLED
   4144 
   4145 static void
   4146 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
   4147 
   4148 /**
   4149  * xmlSchemaElementDump:
   4150  * @elem:  an element
   4151  * @output:  the file output
   4152  *
   4153  * Dump the element
   4154  */
   4155 static void
   4156 xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output,
   4157                      const xmlChar * name ATTRIBUTE_UNUSED,
   4158 		     const xmlChar * namespace ATTRIBUTE_UNUSED,
   4159                      const xmlChar * context ATTRIBUTE_UNUSED)
   4160 {
   4161     if (elem == NULL)
   4162         return;
   4163 
   4164 
   4165     fprintf(output, "Element");
   4166     if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
   4167 	fprintf(output, " (global)");
   4168     fprintf(output, ": '%s' ", elem->name);
   4169     if (namespace != NULL)
   4170 	fprintf(output, "ns '%s'", namespace);
   4171     fprintf(output, "\n");
   4172 #if 0
   4173     if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
   4174 	fprintf(output, "  min %d ", elem->minOccurs);
   4175         if (elem->maxOccurs >= UNBOUNDED)
   4176             fprintf(output, "max: unbounded\n");
   4177         else if (elem->maxOccurs != 1)
   4178             fprintf(output, "max: %d\n", elem->maxOccurs);
   4179         else
   4180             fprintf(output, "\n");
   4181     }
   4182 #endif
   4183     /*
   4184     * Misc other properties.
   4185     */
   4186     if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
   4187 	(elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
   4188 	(elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
   4189 	(elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
   4190 	fprintf(output, "  props: ");
   4191 	if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
   4192 	    fprintf(output, "[fixed] ");
   4193 	if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
   4194 	    fprintf(output, "[default] ");
   4195 	if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
   4196 	    fprintf(output, "[abstract] ");
   4197 	if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
   4198 	    fprintf(output, "[nillable] ");
   4199 	fprintf(output, "\n");
   4200     }
   4201     /*
   4202     * Default/fixed value.
   4203     */
   4204     if (elem->value != NULL)
   4205 	fprintf(output, "  value: '%s'\n", elem->value);
   4206     /*
   4207     * Type.
   4208     */
   4209     if (elem->namedType != NULL) {
   4210 	fprintf(output, "  type: '%s' ", elem->namedType);
   4211 	if (elem->namedTypeNs != NULL)
   4212 	    fprintf(output, "ns '%s'\n", elem->namedTypeNs);
   4213 	else
   4214 	    fprintf(output, "\n");
   4215     } else if (elem->subtypes != NULL) {
   4216 	/*
   4217 	* Dump local types.
   4218 	*/
   4219 	xmlSchemaTypeDump(elem->subtypes, output);
   4220     }
   4221     /*
   4222     * Substitution group.
   4223     */
   4224     if (elem->substGroup != NULL) {
   4225 	fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
   4226 	if (elem->substGroupNs != NULL)
   4227 	    fprintf(output, "ns '%s'\n", elem->substGroupNs);
   4228 	else
   4229 	    fprintf(output, "\n");
   4230     }
   4231 }
   4232 
   4233 /**
   4234  * xmlSchemaAnnotDump:
   4235  * @output:  the file output
   4236  * @annot:  a annotation
   4237  *
   4238  * Dump the annotation
   4239  */
   4240 static void
   4241 xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
   4242 {
   4243     xmlChar *content;
   4244 
   4245     if (annot == NULL)
   4246         return;
   4247 
   4248     content = xmlNodeGetContent(annot->content);
   4249     if (content != NULL) {
   4250         fprintf(output, "  Annot: %s\n", content);
   4251         xmlFree(content);
   4252     } else
   4253         fprintf(output, "  Annot: empty\n");
   4254 }
   4255 
   4256 /**
   4257  * xmlSchemaContentModelDump:
   4258  * @particle: the schema particle
   4259  * @output: the file output
   4260  * @depth: the depth used for intentation
   4261  *
   4262  * Dump a SchemaType structure
   4263  */
   4264 static void
   4265 xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
   4266 {
   4267     xmlChar *str = NULL;
   4268     xmlSchemaTreeItemPtr term;
   4269     char shift[100];
   4270     int i;
   4271 
   4272     if (particle == NULL)
   4273 	return;
   4274     for (i = 0;((i < depth) && (i < 25));i++)
   4275         shift[2 * i] = shift[2 * i + 1] = ' ';
   4276     shift[2 * i] = shift[2 * i + 1] = 0;
   4277     fprintf(output, "%s", shift);
   4278     if (particle->children == NULL) {
   4279 	fprintf(output, "MISSING particle term\n");
   4280 	return;
   4281     }
   4282     term = particle->children;
   4283     if (term == NULL) {
   4284 	fprintf(output, "(NULL)");
   4285     } else {
   4286 	switch (term->type) {
   4287 	    case XML_SCHEMA_TYPE_ELEMENT:
   4288 		fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
   4289 		    ((xmlSchemaElementPtr)term)->targetNamespace,
   4290 		    ((xmlSchemaElementPtr)term)->name));
   4291 		FREE_AND_NULL(str);
   4292 		break;
   4293 	    case XML_SCHEMA_TYPE_SEQUENCE:
   4294 		fprintf(output, "SEQUENCE");
   4295 		break;
   4296 	    case XML_SCHEMA_TYPE_CHOICE:
   4297 		fprintf(output, "CHOICE");
   4298 		break;
   4299 	    case XML_SCHEMA_TYPE_ALL:
   4300 		fprintf(output, "ALL");
   4301 		break;
   4302 	    case XML_SCHEMA_TYPE_ANY:
   4303 		fprintf(output, "ANY");
   4304 		break;
   4305 	    default:
   4306 		fprintf(output, "UNKNOWN\n");
   4307 		return;
   4308 	}
   4309     }
   4310     if (particle->minOccurs != 1)
   4311 	fprintf(output, " min: %d", particle->minOccurs);
   4312     if (particle->maxOccurs >= UNBOUNDED)
   4313 	fprintf(output, " max: unbounded");
   4314     else if (particle->maxOccurs != 1)
   4315 	fprintf(output, " max: %d", particle->maxOccurs);
   4316     fprintf(output, "\n");
   4317     if (term &&
   4318 	((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
   4319 	 (term->type == XML_SCHEMA_TYPE_CHOICE) ||
   4320 	 (term->type == XML_SCHEMA_TYPE_ALL)) &&
   4321 	 (term->children != NULL)) {
   4322 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
   4323 	    output, depth +1);
   4324     }
   4325     if (particle->next != NULL)
   4326 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
   4327 		output, depth);
   4328 }
   4329 
   4330 /**
   4331  * xmlSchemaAttrUsesDump:
   4332  * @uses:  attribute uses list
   4333  * @output:  the file output
   4334  *
   4335  * Dumps a list of attribute use components.
   4336  */
   4337 static void
   4338 xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
   4339 {
   4340     xmlSchemaAttributeUsePtr use;
   4341     xmlSchemaAttributeUseProhibPtr prohib;
   4342     xmlSchemaQNameRefPtr ref;
   4343     const xmlChar *name, *tns;
   4344     xmlChar *str = NULL;
   4345     int i;
   4346 
   4347     if ((uses == NULL) || (uses->nbItems == 0))
   4348         return;
   4349 
   4350     fprintf(output, "  attributes:\n");
   4351     for (i = 0; i < uses->nbItems; i++) {
   4352 	use = uses->items[i];
   4353 	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
   4354 	    fprintf(output, "  [prohibition] ");
   4355 	    prohib = (xmlSchemaAttributeUseProhibPtr) use;
   4356 	    name = prohib->name;
   4357 	    tns = prohib->targetNamespace;
   4358 	} else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
   4359 	    fprintf(output, "  [reference] ");
   4360 	    ref = (xmlSchemaQNameRefPtr) use;
   4361 	    name = ref->name;
   4362 	    tns = ref->targetNamespace;
   4363 	} else {
   4364 	    fprintf(output, "  [use] ");
   4365 	    name = WXS_ATTRUSE_DECL_NAME(use);
   4366 	    tns = WXS_ATTRUSE_DECL_TNS(use);
   4367 	}
   4368 	fprintf(output, "'%s'\n",
   4369 	    (const char *) xmlSchemaFormatQName(&str, tns, name));
   4370 	FREE_AND_NULL(str);
   4371     }
   4372 }
   4373 
   4374 /**
   4375  * xmlSchemaTypeDump:
   4376  * @output:  the file output
   4377  * @type:  a type structure
   4378  *
   4379  * Dump a SchemaType structure
   4380  */
   4381 static void
   4382 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
   4383 {
   4384     if (type == NULL) {
   4385         fprintf(output, "Type: NULL\n");
   4386         return;
   4387     }
   4388     fprintf(output, "Type: ");
   4389     if (type->name != NULL)
   4390         fprintf(output, "'%s' ", type->name);
   4391     else
   4392         fprintf(output, "(no name) ");
   4393     if (type->targetNamespace != NULL)
   4394 	fprintf(output, "ns '%s' ", type->targetNamespace);
   4395     switch (type->type) {
   4396         case XML_SCHEMA_TYPE_BASIC:
   4397             fprintf(output, "[basic] ");
   4398             break;
   4399         case XML_SCHEMA_TYPE_SIMPLE:
   4400             fprintf(output, "[simple] ");
   4401             break;
   4402         case XML_SCHEMA_TYPE_COMPLEX:
   4403             fprintf(output, "[complex] ");
   4404             break;
   4405         case XML_SCHEMA_TYPE_SEQUENCE:
   4406             fprintf(output, "[sequence] ");
   4407             break;
   4408         case XML_SCHEMA_TYPE_CHOICE:
   4409             fprintf(output, "[choice] ");
   4410             break;
   4411         case XML_SCHEMA_TYPE_ALL:
   4412             fprintf(output, "[all] ");
   4413             break;
   4414         case XML_SCHEMA_TYPE_UR:
   4415             fprintf(output, "[ur] ");
   4416             break;
   4417         case XML_SCHEMA_TYPE_RESTRICTION:
   4418             fprintf(output, "[restriction] ");
   4419             break;
   4420         case XML_SCHEMA_TYPE_EXTENSION:
   4421             fprintf(output, "[extension] ");
   4422             break;
   4423         default:
   4424             fprintf(output, "[unknown type %d] ", type->type);
   4425             break;
   4426     }
   4427     fprintf(output, "content: ");
   4428     switch (type->contentType) {
   4429         case XML_SCHEMA_CONTENT_UNKNOWN:
   4430             fprintf(output, "[unknown] ");
   4431             break;
   4432         case XML_SCHEMA_CONTENT_EMPTY:
   4433             fprintf(output, "[empty] ");
   4434             break;
   4435         case XML_SCHEMA_CONTENT_ELEMENTS:
   4436             fprintf(output, "[element] ");
   4437             break;
   4438         case XML_SCHEMA_CONTENT_MIXED:
   4439             fprintf(output, "[mixed] ");
   4440             break;
   4441         case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
   4442 	/* not used. */
   4443             break;
   4444         case XML_SCHEMA_CONTENT_BASIC:
   4445             fprintf(output, "[basic] ");
   4446             break;
   4447         case XML_SCHEMA_CONTENT_SIMPLE:
   4448             fprintf(output, "[simple] ");
   4449             break;
   4450         case XML_SCHEMA_CONTENT_ANY:
   4451             fprintf(output, "[any] ");
   4452             break;
   4453     }
   4454     fprintf(output, "\n");
   4455     if (type->base != NULL) {
   4456         fprintf(output, "  base type: '%s'", type->base);
   4457 	if (type->baseNs != NULL)
   4458 	    fprintf(output, " ns '%s'\n", type->baseNs);
   4459 	else
   4460 	    fprintf(output, "\n");
   4461     }
   4462     if (type->attrUses != NULL)
   4463 	xmlSchemaAttrUsesDump(type->attrUses, output);
   4464     if (type->annot != NULL)
   4465         xmlSchemaAnnotDump(output, type->annot);
   4466 #ifdef DUMP_CONTENT_MODEL
   4467     if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
   4468 	(type->subtypes != NULL)) {
   4469 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
   4470 	    output, 1);
   4471     }
   4472 #endif
   4473 }
   4474 
   4475 /**
   4476  * xmlSchemaDump:
   4477  * @output:  the file output
   4478  * @schema:  a schema structure
   4479  *
   4480  * Dump a Schema structure.
   4481  */
   4482 void
   4483 xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
   4484 {
   4485     if (output == NULL)
   4486         return;
   4487     if (schema == NULL) {
   4488         fprintf(output, "Schemas: NULL\n");
   4489         return;
   4490     }
   4491     fprintf(output, "Schemas: ");
   4492     if (schema->name != NULL)
   4493         fprintf(output, "%s, ", schema->name);
   4494     else
   4495         fprintf(output, "no name, ");
   4496     if (schema->targetNamespace != NULL)
   4497         fprintf(output, "%s", (const char *) schema->targetNamespace);
   4498     else
   4499         fprintf(output, "no target namespace");
   4500     fprintf(output, "\n");
   4501     if (schema->annot != NULL)
   4502         xmlSchemaAnnotDump(output, schema->annot);
   4503     xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump,
   4504                 output);
   4505     xmlHashScanFull(schema->elemDecl,
   4506                     (xmlHashScannerFull) xmlSchemaElementDump, output);
   4507 }
   4508 
   4509 #ifdef DEBUG_IDC_NODE_TABLE
   4510 /**
   4511  * xmlSchemaDebugDumpIDCTable:
   4512  * @vctxt: the WXS validation context
   4513  *
   4514  * Displays the current IDC table for debug purposes.
   4515  */
   4516 static void
   4517 xmlSchemaDebugDumpIDCTable(FILE * output,
   4518 			   const xmlChar *namespaceName,
   4519 			   const xmlChar *localName,
   4520 			   xmlSchemaPSVIIDCBindingPtr bind)
   4521 {
   4522     xmlChar *str = NULL;
   4523     const xmlChar *value;
   4524     xmlSchemaPSVIIDCNodePtr tab;
   4525     xmlSchemaPSVIIDCKeyPtr key;
   4526     int i, j, res;
   4527 
   4528     fprintf(output, "IDC: TABLES on '%s'\n",
   4529 	xmlSchemaFormatQName(&str, namespaceName, localName));
   4530     FREE_AND_NULL(str)
   4531 
   4532     if (bind == NULL)
   4533 	return;
   4534     do {
   4535 	fprintf(output, "IDC:   BINDING '%s' (%d)\n",
   4536 	    xmlSchemaGetComponentQName(&str,
   4537 		bind->definition), bind->nbNodes);
   4538 	FREE_AND_NULL(str)
   4539 	for (i = 0; i < bind->nbNodes; i++) {
   4540 	    tab = bind->nodeTable[i];
   4541 	    fprintf(output, "         ( ");
   4542 	    for (j = 0; j < bind->definition->nbFields; j++) {
   4543 		key = tab->keys[j];
   4544 		if ((key != NULL) && (key->val != NULL)) {
   4545 		    res = xmlSchemaGetCanonValue(key->val, &value);
   4546 		    if (res >= 0)
   4547 			fprintf(output, "'%s' ", value);
   4548 		    else
   4549 			fprintf(output, "CANON-VALUE-FAILED ");
   4550 		    if (res == 0)
   4551 			FREE_AND_NULL(value)
   4552 		} else if (key != NULL)
   4553 		    fprintf(output, "(no val), ");
   4554 		else
   4555 		    fprintf(output, "(key missing), ");
   4556 	    }
   4557 	    fprintf(output, ")\n");
   4558 	}
   4559 	if (bind->dupls && bind->dupls->nbItems) {
   4560 	    fprintf(output, "IDC:     dupls (%d):\n", bind->dupls->nbItems);
   4561 	    for (i = 0; i < bind->dupls->nbItems; i++) {
   4562 		tab = bind->dupls->items[i];
   4563 		fprintf(output, "         ( ");
   4564 		for (j = 0; j < bind->definition->nbFields; j++) {
   4565 		    key = tab->keys[j];
   4566 		    if ((key != NULL) && (key->val != NULL)) {
   4567 			res = xmlSchemaGetCanonValue(key->val, &value);
   4568 			if (res >= 0)
   4569 			    fprintf(output, "'%s' ", value);
   4570 			else
   4571 			    fprintf(output, "CANON-VALUE-FAILED ");
   4572 			if (res == 0)
   4573 			    FREE_AND_NULL(value)
   4574 		    } else if (key != NULL)
   4575 		    fprintf(output, "(no val), ");
   4576 			else
   4577 			    fprintf(output, "(key missing), ");
   4578 		}
   4579 		fprintf(output, ")\n");
   4580 	    }
   4581 	}
   4582 	bind = bind->next;
   4583     } while (bind != NULL);
   4584 }
   4585 #endif /* DEBUG_IDC */
   4586 #endif /* LIBXML_OUTPUT_ENABLED */
   4587 
   4588 /************************************************************************
   4589  *									*
   4590  * 			Utilities					*
   4591  *									*
   4592  ************************************************************************/
   4593 
   4594 /**
   4595  * xmlSchemaGetPropNode:
   4596  * @node: the element node
   4597  * @name: the name of the attribute
   4598  *
   4599  * Seeks an attribute with a name of @name in
   4600  * no namespace.
   4601  *
   4602  * Returns the attribute or NULL if not present.
   4603  */
   4604 static xmlAttrPtr
   4605 xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
   4606 {
   4607     xmlAttrPtr prop;
   4608 
   4609     if ((node == NULL) || (name == NULL))
   4610 	return(NULL);
   4611     prop = node->properties;
   4612     while (prop != NULL) {
   4613         if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
   4614 	    return(prop);
   4615 	prop = prop->next;
   4616     }
   4617     return (NULL);
   4618 }
   4619 
   4620 /**
   4621  * xmlSchemaGetPropNodeNs:
   4622  * @node: the element node
   4623  * @uri: the uri
   4624  * @name: the name of the attribute
   4625  *
   4626  * Seeks an attribute with a local name of @name and
   4627  * a namespace URI of @uri.
   4628  *
   4629  * Returns the attribute or NULL if not present.
   4630  */
   4631 static xmlAttrPtr
   4632 xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
   4633 {
   4634     xmlAttrPtr prop;
   4635 
   4636     if ((node == NULL) || (name == NULL))
   4637 	return(NULL);
   4638     prop = node->properties;
   4639     while (prop != NULL) {
   4640 	if ((prop->ns != NULL) &&
   4641 	    xmlStrEqual(prop->name, BAD_CAST name) &&
   4642 	    xmlStrEqual(prop->ns->href, BAD_CAST uri))
   4643 	    return(prop);
   4644 	prop = prop->next;
   4645     }
   4646     return (NULL);
   4647 }
   4648 
   4649 static const xmlChar *
   4650 xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
   4651 {
   4652     xmlChar *val;
   4653     const xmlChar *ret;
   4654 
   4655     val = xmlNodeGetContent(node);
   4656     if (val == NULL)
   4657 	val = xmlStrdup((xmlChar *)"");
   4658     ret = xmlDictLookup(ctxt->dict, val, -1);
   4659     xmlFree(val);
   4660     return(ret);
   4661 }
   4662 
   4663 static const xmlChar *
   4664 xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
   4665 {
   4666     return((const xmlChar*) xmlNodeGetContent(node));
   4667 }
   4668 
   4669 /**
   4670  * xmlSchemaGetProp:
   4671  * @ctxt: the parser context
   4672  * @node: the node
   4673  * @name: the property name
   4674  *
   4675  * Read a attribute value and internalize the string
   4676  *
   4677  * Returns the string or NULL if not present.
   4678  */
   4679 static const xmlChar *
   4680 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
   4681                  const char *name)
   4682 {
   4683     xmlChar *val;
   4684     const xmlChar *ret;
   4685 
   4686     val = xmlGetNoNsProp(node, BAD_CAST name);
   4687     if (val == NULL)
   4688         return(NULL);
   4689     ret = xmlDictLookup(ctxt->dict, val, -1);
   4690     xmlFree(val);
   4691     return(ret);
   4692 }
   4693 
   4694 /************************************************************************
   4695  * 									*
   4696  * 			Parsing functions				*
   4697  * 									*
   4698  ************************************************************************/
   4699 
   4700 #define WXS_FIND_GLOBAL_ITEM(slot)			\
   4701     if (xmlStrEqual(nsName, schema->targetNamespace)) { \
   4702 	ret = xmlHashLookup(schema->slot, name); \
   4703 	if (ret != NULL) goto exit; \
   4704     } \
   4705     if (xmlHashSize(schema->schemasImports) > 1) { \
   4706 	xmlSchemaImportPtr import; \
   4707 	if (nsName == NULL) \
   4708 	    import = xmlHashLookup(schema->schemasImports, \
   4709 		XML_SCHEMAS_NO_NAMESPACE); \
   4710 	else \
   4711 	    import = xmlHashLookup(schema->schemasImports, nsName); \
   4712 	if (import == NULL) \
   4713 	    goto exit; \
   4714 	ret = xmlHashLookup(import->schema->slot, name); \
   4715     }
   4716 
   4717 /**
   4718  * xmlSchemaGetElem:
   4719  * @schema:  the schema context
   4720  * @name:  the element name
   4721  * @ns:  the element namespace
   4722  *
   4723  * Lookup a global element declaration in the schema.
   4724  *
   4725  * Returns the element declaration or NULL if not found.
   4726  */
   4727 static xmlSchemaElementPtr
   4728 xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
   4729                  const xmlChar * nsName)
   4730 {
   4731     xmlSchemaElementPtr ret = NULL;
   4732 
   4733     if ((name == NULL) || (schema == NULL))
   4734         return(NULL);
   4735     if (schema != NULL) {
   4736 	WXS_FIND_GLOBAL_ITEM(elemDecl)
   4737     }
   4738 exit:
   4739 #ifdef DEBUG
   4740     if (ret == NULL) {
   4741         if (nsName == NULL)
   4742             fprintf(stderr, "Unable to lookup element decl. %s", name);
   4743         else
   4744             fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
   4745                     nsName);
   4746     }
   4747 #endif
   4748     return (ret);
   4749 }
   4750 
   4751 /**
   4752  * xmlSchemaGetType:
   4753  * @schema:  the main schema
   4754  * @name:  the type's name
   4755  * nsName:  the type's namespace
   4756  *
   4757  * Lookup a type in the schemas or the predefined types
   4758  *
   4759  * Returns the group definition or NULL if not found.
   4760  */
   4761 static xmlSchemaTypePtr
   4762 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
   4763                  const xmlChar * nsName)
   4764 {
   4765     xmlSchemaTypePtr ret = NULL;
   4766 
   4767     if (name == NULL)
   4768         return (NULL);
   4769     /* First try the built-in types. */
   4770     if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
   4771 	ret = xmlSchemaGetPredefinedType(name, nsName);
   4772 	if (ret != NULL)
   4773 	    goto exit;
   4774 	/*
   4775 	* Note that we try the parsed schemas as well here
   4776 	* since one might have parsed the S4S, which contain more
   4777 	* than the built-in types.
   4778 	* TODO: Can we optimize this?
   4779 	*/
   4780     }
   4781     if (schema != NULL) {
   4782 	WXS_FIND_GLOBAL_ITEM(typeDecl)
   4783     }
   4784 exit:
   4785 
   4786 #ifdef DEBUG
   4787     if (ret == NULL) {
   4788         if (nsName == NULL)
   4789             fprintf(stderr, "Unable to lookup type %s", name);
   4790         else
   4791             fprintf(stderr, "Unable to lookup type %s:%s", name,
   4792                     nsName);
   4793     }
   4794 #endif
   4795     return (ret);
   4796 }
   4797 
   4798 /**
   4799  * xmlSchemaGetAttributeDecl:
   4800  * @schema:  the context of the schema
   4801  * @name:  the name of the attribute
   4802  * @ns:  the target namespace of the attribute
   4803  *
   4804  * Lookup a an attribute in the schema or imported schemas
   4805  *
   4806  * Returns the attribute declaration or NULL if not found.
   4807  */
   4808 static xmlSchemaAttributePtr
   4809 xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
   4810                  const xmlChar * nsName)
   4811 {
   4812     xmlSchemaAttributePtr ret = NULL;
   4813 
   4814     if ((name == NULL) || (schema == NULL))
   4815         return (NULL);
   4816     if (schema != NULL) {
   4817 	WXS_FIND_GLOBAL_ITEM(attrDecl)
   4818     }
   4819 exit:
   4820 #ifdef DEBUG
   4821     if (ret == NULL) {
   4822         if (nsName == NULL)
   4823             fprintf(stderr, "Unable to lookup attribute %s", name);
   4824         else
   4825             fprintf(stderr, "Unable to lookup attribute %s:%s", name,
   4826                     nsName);
   4827     }
   4828 #endif
   4829     return (ret);
   4830 }
   4831 
   4832 /**
   4833  * xmlSchemaGetAttributeGroup:
   4834  * @schema:  the context of the schema
   4835  * @name:  the name of the attribute group
   4836  * @ns:  the target namespace of the attribute group
   4837  *
   4838  * Lookup a an attribute group in the schema or imported schemas
   4839  *
   4840  * Returns the attribute group definition or NULL if not found.
   4841  */
   4842 static xmlSchemaAttributeGroupPtr
   4843 xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
   4844                  const xmlChar * nsName)
   4845 {
   4846     xmlSchemaAttributeGroupPtr ret = NULL;
   4847 
   4848     if ((name == NULL) || (schema == NULL))
   4849         return (NULL);
   4850     if (schema != NULL) {
   4851 	WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
   4852     }
   4853 exit:
   4854     /* TODO:
   4855     if ((ret != NULL) && (ret->redef != NULL)) {
   4856 	* Return the last redefinition. *
   4857 	ret = ret->redef;
   4858     }
   4859     */
   4860 #ifdef DEBUG
   4861     if (ret == NULL) {
   4862         if (nsName == NULL)
   4863             fprintf(stderr, "Unable to lookup attribute group %s", name);
   4864         else
   4865             fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
   4866                     nsName);
   4867     }
   4868 #endif
   4869     return (ret);
   4870 }
   4871 
   4872 /**
   4873  * xmlSchemaGetGroup:
   4874  * @schema:  the context of the schema
   4875  * @name:  the name of the group
   4876  * @ns:  the target namespace of the group
   4877  *
   4878  * Lookup a group in the schema or imported schemas
   4879  *
   4880  * Returns the group definition or NULL if not found.
   4881  */
   4882 static xmlSchemaModelGroupDefPtr
   4883 xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
   4884                  const xmlChar * nsName)
   4885 {
   4886     xmlSchemaModelGroupDefPtr ret = NULL;
   4887 
   4888     if ((name == NULL) || (schema == NULL))
   4889         return (NULL);
   4890     if (schema != NULL) {
   4891 	WXS_FIND_GLOBAL_ITEM(groupDecl)
   4892     }
   4893 exit:
   4894 
   4895 #ifdef DEBUG
   4896     if (ret == NULL) {
   4897         if (nsName == NULL)
   4898             fprintf(stderr, "Unable to lookup group %s", name);
   4899         else
   4900             fprintf(stderr, "Unable to lookup group %s:%s", name,
   4901                     nsName);
   4902     }
   4903 #endif
   4904     return (ret);
   4905 }
   4906 
   4907 static xmlSchemaNotationPtr
   4908 xmlSchemaGetNotation(xmlSchemaPtr schema,
   4909 		     const xmlChar *name,
   4910 		     const xmlChar *nsName)
   4911 {
   4912     xmlSchemaNotationPtr ret = NULL;
   4913 
   4914     if ((name == NULL) || (schema == NULL))
   4915         return (NULL);
   4916     if (schema != NULL) {
   4917 	WXS_FIND_GLOBAL_ITEM(notaDecl)
   4918     }
   4919 exit:
   4920     return (ret);
   4921 }
   4922 
   4923 static xmlSchemaIDCPtr
   4924 xmlSchemaGetIDC(xmlSchemaPtr schema,
   4925 		const xmlChar *name,
   4926 		const xmlChar *nsName)
   4927 {
   4928     xmlSchemaIDCPtr ret = NULL;
   4929 
   4930     if ((name == NULL) || (schema == NULL))
   4931         return (NULL);
   4932     if (schema != NULL) {
   4933 	WXS_FIND_GLOBAL_ITEM(idcDef)
   4934     }
   4935 exit:
   4936     return (ret);
   4937 }
   4938 
   4939 /**
   4940  * xmlSchemaGetNamedComponent:
   4941  * @schema:  the schema
   4942  * @name:  the name of the group
   4943  * @ns:  the target namespace of the group
   4944  *
   4945  * Lookup a group in the schema or imported schemas
   4946  *
   4947  * Returns the group definition or NULL if not found.
   4948  */
   4949 static xmlSchemaBasicItemPtr
   4950 xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
   4951 			   xmlSchemaTypeType itemType,
   4952 			   const xmlChar *name,
   4953 			   const xmlChar *targetNs)
   4954 {
   4955     switch (itemType) {
   4956 	case XML_SCHEMA_TYPE_GROUP:
   4957 	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
   4958 		name, targetNs));
   4959 	case XML_SCHEMA_TYPE_ELEMENT:
   4960 	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
   4961 		name, targetNs));
   4962 	default:
   4963 	    TODO
   4964 	    return (NULL);
   4965     }
   4966 }
   4967 
   4968 /************************************************************************
   4969  * 									*
   4970  * 			Parsing functions				*
   4971  * 									*
   4972  ************************************************************************/
   4973 
   4974 #define IS_BLANK_NODE(n)						\
   4975     (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
   4976 
   4977 /**
   4978  * xmlSchemaIsBlank:
   4979  * @str:  a string
   4980  * @len: the length of the string or -1
   4981  *
   4982  * Check if a string is ignorable
   4983  *
   4984  * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
   4985  */
   4986 static int
   4987 xmlSchemaIsBlank(xmlChar * str, int len)
   4988 {
   4989     if (str == NULL)
   4990         return (1);
   4991     if (len < 0) {
   4992 	while (*str != 0) {
   4993 	    if (!(IS_BLANK_CH(*str)))
   4994 		return (0);
   4995 	    str++;
   4996 	}
   4997     } else while ((*str != 0) && (len != 0)) {
   4998 	if (!(IS_BLANK_CH(*str)))
   4999 	    return (0);
   5000 	str++;
   5001 	len--;
   5002     }
   5003 
   5004     return (1);
   5005 }
   5006 
   5007 #define WXS_COMP_NAME(c, t) ((t) (c))->name
   5008 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
   5009 /*
   5010 * xmlSchemaFindRedefCompInGraph:
   5011 * ATTENTION TODO: This uses pointer comp. for strings.
   5012 */
   5013 static xmlSchemaBasicItemPtr
   5014 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
   5015 			      xmlSchemaTypeType type,
   5016 			      const xmlChar *name,
   5017 			      const xmlChar *nsName)
   5018 {
   5019     xmlSchemaBasicItemPtr ret;
   5020     int i;
   5021 
   5022     if ((bucket == NULL) || (name == NULL))
   5023 	return(NULL);
   5024     if ((bucket->globals == NULL) ||
   5025 	(bucket->globals->nbItems == 0))
   5026 	goto subschemas;
   5027     /*
   5028     * Search in global components.
   5029     */
   5030     for (i = 0; i < bucket->globals->nbItems; i++) {
   5031 	ret = bucket->globals->items[i];
   5032 	if (ret->type == type) {
   5033 	    switch (type) {
   5034 		case XML_SCHEMA_TYPE_COMPLEX:
   5035 		case XML_SCHEMA_TYPE_SIMPLE:
   5036 		    if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
   5037 			(WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
   5038 			nsName))
   5039 		    {
   5040 			return(ret);
   5041 		    }
   5042 		    break;
   5043 		case XML_SCHEMA_TYPE_GROUP:
   5044 		    if ((WXS_COMP_NAME(ret,
   5045 			    xmlSchemaModelGroupDefPtr) == name) &&
   5046 			(WXS_COMP_TNS(ret,
   5047 			    xmlSchemaModelGroupDefPtr) == nsName))
   5048 		    {
   5049 			return(ret);
   5050 		    }
   5051 		    break;
   5052 		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   5053 		    if ((WXS_COMP_NAME(ret,
   5054 			    xmlSchemaAttributeGroupPtr) == name) &&
   5055 			(WXS_COMP_TNS(ret,
   5056 			    xmlSchemaAttributeGroupPtr) == nsName))
   5057 		    {
   5058 			return(ret);
   5059 		    }
   5060 		    break;
   5061 		default:
   5062 		    /* Should not be hit. */
   5063 		    return(NULL);
   5064 	    }
   5065 	}
   5066     }
   5067 subschemas:
   5068     /*
   5069     * Process imported/included schemas.
   5070     */
   5071     if (bucket->relations != NULL) {
   5072 	xmlSchemaSchemaRelationPtr rel = bucket->relations;
   5073 
   5074 	/*
   5075 	* TODO: Marking the bucket will not avoid multiple searches
   5076 	* in the same schema, but avoids at least circularity.
   5077 	*/
   5078 	bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
   5079 	do {
   5080 	    if ((rel->bucket != NULL) &&
   5081 		((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
   5082 		ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
   5083 		    type, name, nsName);
   5084 		if (ret != NULL)
   5085 		    return(ret);
   5086 	    }
   5087 	    rel = rel->next;
   5088 	} while (rel != NULL);
   5089 	 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
   5090     }
   5091     return(NULL);
   5092 }
   5093 
   5094 /**
   5095  * xmlSchemaAddNotation:
   5096  * @ctxt:  a schema parser context
   5097  * @schema:  the schema being built
   5098  * @name:  the item name
   5099  *
   5100  * Add an XML schema annotation declaration
   5101  * *WARNING* this interface is highly subject to change
   5102  *
   5103  * Returns the new struture or NULL in case of error
   5104  */
   5105 static xmlSchemaNotationPtr
   5106 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5107                      const xmlChar *name, const xmlChar *nsName,
   5108 		     xmlNodePtr node ATTRIBUTE_UNUSED)
   5109 {
   5110     xmlSchemaNotationPtr ret = NULL;
   5111 
   5112     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
   5113         return (NULL);
   5114 
   5115     ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
   5116     if (ret == NULL) {
   5117         xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
   5118         return (NULL);
   5119     }
   5120     memset(ret, 0, sizeof(xmlSchemaNotation));
   5121     ret->type = XML_SCHEMA_TYPE_NOTATION;
   5122     ret->name = name;
   5123     ret->targetNamespace = nsName;
   5124     /* TODO: do we need the node to be set?
   5125     * ret->node = node;*/
   5126     WXS_ADD_GLOBAL(ctxt, ret);
   5127     return (ret);
   5128 }
   5129 
   5130 /**
   5131  * xmlSchemaAddAttribute:
   5132  * @ctxt:  a schema parser context
   5133  * @schema:  the schema being built
   5134  * @name:  the item name
   5135  * @namespace:  the namespace
   5136  *
   5137  * Add an XML schema Attrribute declaration
   5138  * *WARNING* this interface is highly subject to change
   5139  *
   5140  * Returns the new struture or NULL in case of error
   5141  */
   5142 static xmlSchemaAttributePtr
   5143 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5144                       const xmlChar * name, const xmlChar * nsName,
   5145 		      xmlNodePtr node, int topLevel)
   5146 {
   5147     xmlSchemaAttributePtr ret = NULL;
   5148 
   5149     if ((ctxt == NULL) || (schema == NULL))
   5150         return (NULL);
   5151 
   5152     ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
   5153     if (ret == NULL) {
   5154         xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
   5155         return (NULL);
   5156     }
   5157     memset(ret, 0, sizeof(xmlSchemaAttribute));
   5158     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
   5159     ret->node = node;
   5160     ret->name = name;
   5161     ret->targetNamespace = nsName;
   5162 
   5163     if (topLevel)
   5164 	WXS_ADD_GLOBAL(ctxt, ret);
   5165     else
   5166 	WXS_ADD_LOCAL(ctxt, ret);
   5167     WXS_ADD_PENDING(ctxt, ret);
   5168     return (ret);
   5169 }
   5170 
   5171 /**
   5172  * xmlSchemaAddAttributeUse:
   5173  * @ctxt:  a schema parser context
   5174  * @schema:  the schema being built
   5175  * @name:  the item name
   5176  * @namespace:  the namespace
   5177  *
   5178  * Add an XML schema Attrribute declaration
   5179  * *WARNING* this interface is highly subject to change
   5180  *
   5181  * Returns the new struture or NULL in case of error
   5182  */
   5183 static xmlSchemaAttributeUsePtr
   5184 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
   5185 			 xmlNodePtr node)
   5186 {
   5187     xmlSchemaAttributeUsePtr ret = NULL;
   5188 
   5189     if (pctxt == NULL)
   5190         return (NULL);
   5191 
   5192     ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
   5193     if (ret == NULL) {
   5194         xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
   5195         return (NULL);
   5196     }
   5197     memset(ret, 0, sizeof(xmlSchemaAttributeUse));
   5198     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
   5199     ret->node = node;
   5200 
   5201     WXS_ADD_LOCAL(pctxt, ret);
   5202     return (ret);
   5203 }
   5204 
   5205 /*
   5206 * xmlSchemaAddRedef:
   5207 *
   5208 * Adds a redefinition information. This is used at a later stage to:
   5209 * resolve references to the redefined components and to check constraints.
   5210 */
   5211 static xmlSchemaRedefPtr
   5212 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
   5213 		  xmlSchemaBucketPtr targetBucket,
   5214 		  void *item,
   5215 		  const xmlChar *refName,
   5216 		  const xmlChar *refTargetNs)
   5217 {
   5218     xmlSchemaRedefPtr ret;
   5219 
   5220     ret = (xmlSchemaRedefPtr)
   5221 	xmlMalloc(sizeof(xmlSchemaRedef));
   5222     if (ret == NULL) {
   5223 	xmlSchemaPErrMemory(pctxt,
   5224 	    "allocating redefinition info", NULL);
   5225 	return (NULL);
   5226     }
   5227     memset(ret, 0, sizeof(xmlSchemaRedef));
   5228     ret->item = item;
   5229     ret->targetBucket = targetBucket;
   5230     ret->refName = refName;
   5231     ret->refTargetNs = refTargetNs;
   5232     if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
   5233 	WXS_CONSTRUCTOR(pctxt)->redefs = ret;
   5234     else
   5235 	WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
   5236     WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
   5237 
   5238     return (ret);
   5239 }
   5240 
   5241 /**
   5242  * xmlSchemaAddAttributeGroupDefinition:
   5243  * @ctxt:  a schema parser context
   5244  * @schema:  the schema being built
   5245  * @name:  the item name
   5246  * @nsName:  the target namespace
   5247  * @node: the corresponding node
   5248  *
   5249  * Add an XML schema Attrribute Group definition.
   5250  *
   5251  * Returns the new struture or NULL in case of error
   5252  */
   5253 static xmlSchemaAttributeGroupPtr
   5254 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
   5255                            xmlSchemaPtr schema ATTRIBUTE_UNUSED,
   5256 			   const xmlChar *name,
   5257 			   const xmlChar *nsName,
   5258 			   xmlNodePtr node)
   5259 {
   5260     xmlSchemaAttributeGroupPtr ret = NULL;
   5261 
   5262     if ((pctxt == NULL) || (name == NULL))
   5263         return (NULL);
   5264 
   5265     ret = (xmlSchemaAttributeGroupPtr)
   5266         xmlMalloc(sizeof(xmlSchemaAttributeGroup));
   5267     if (ret == NULL) {
   5268 	xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
   5269 	return (NULL);
   5270     }
   5271     memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
   5272     ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
   5273     ret->name = name;
   5274     ret->targetNamespace = nsName;
   5275     ret->node = node;
   5276 
   5277     /* TODO: Remove the flag. */
   5278     ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
   5279     if (pctxt->isRedefine) {
   5280 	pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
   5281 	    ret, name, nsName);
   5282 	if (pctxt->redef == NULL) {
   5283 	    xmlFree(ret);
   5284 	    return(NULL);
   5285 	}
   5286 	pctxt->redefCounter = 0;
   5287     }
   5288     WXS_ADD_GLOBAL(pctxt, ret);
   5289     WXS_ADD_PENDING(pctxt, ret);
   5290     return (ret);
   5291 }
   5292 
   5293 /**
   5294  * xmlSchemaAddElement:
   5295  * @ctxt:  a schema parser context
   5296  * @schema:  the schema being built
   5297  * @name:  the type name
   5298  * @namespace:  the type namespace
   5299  *
   5300  * Add an XML schema Element declaration
   5301  * *WARNING* this interface is highly subject to change
   5302  *
   5303  * Returns the new struture or NULL in case of error
   5304  */
   5305 static xmlSchemaElementPtr
   5306 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
   5307                     const xmlChar * name, const xmlChar * nsName,
   5308 		    xmlNodePtr node, int topLevel)
   5309 {
   5310     xmlSchemaElementPtr ret = NULL;
   5311 
   5312     if ((ctxt == NULL) || (name == NULL))
   5313         return (NULL);
   5314 
   5315     ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
   5316     if (ret == NULL) {
   5317         xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
   5318         return (NULL);
   5319     }
   5320     memset(ret, 0, sizeof(xmlSchemaElement));
   5321     ret->type = XML_SCHEMA_TYPE_ELEMENT;
   5322     ret->name = name;
   5323     ret->targetNamespace = nsName;
   5324     ret->node = node;
   5325 
   5326     if (topLevel)
   5327 	WXS_ADD_GLOBAL(ctxt, ret);
   5328     else
   5329 	WXS_ADD_LOCAL(ctxt, ret);
   5330     WXS_ADD_PENDING(ctxt, ret);
   5331     return (ret);
   5332 }
   5333 
   5334 /**
   5335  * xmlSchemaAddType:
   5336  * @ctxt:  a schema parser context
   5337  * @schema:  the schema being built
   5338  * @name:  the item name
   5339  * @namespace:  the namespace
   5340  *
   5341  * Add an XML schema item
   5342  * *WARNING* this interface is highly subject to change
   5343  *
   5344  * Returns the new struture or NULL in case of error
   5345  */
   5346 static xmlSchemaTypePtr
   5347 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5348 		 xmlSchemaTypeType type,
   5349                  const xmlChar * name, const xmlChar * nsName,
   5350 		 xmlNodePtr node, int topLevel)
   5351 {
   5352     xmlSchemaTypePtr ret = NULL;
   5353 
   5354     if ((ctxt == NULL) || (schema == NULL))
   5355         return (NULL);
   5356 
   5357     ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
   5358     if (ret == NULL) {
   5359         xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
   5360         return (NULL);
   5361     }
   5362     memset(ret, 0, sizeof(xmlSchemaType));
   5363     ret->type = type;
   5364     ret->name = name;
   5365     ret->targetNamespace = nsName;
   5366     ret->node = node;
   5367     if (topLevel) {
   5368 	if (ctxt->isRedefine) {
   5369 	    ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
   5370 		ret, name, nsName);
   5371 	    if (ctxt->redef == NULL) {
   5372 		xmlFree(ret);
   5373 		return(NULL);
   5374 	    }
   5375 	    ctxt->redefCounter = 0;
   5376 	}
   5377 	WXS_ADD_GLOBAL(ctxt, ret);
   5378     } else
   5379 	WXS_ADD_LOCAL(ctxt, ret);
   5380     WXS_ADD_PENDING(ctxt, ret);
   5381     return (ret);
   5382 }
   5383 
   5384 static xmlSchemaQNameRefPtr
   5385 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
   5386 		     xmlSchemaTypeType refType,
   5387 		     const xmlChar *refName,
   5388 		     const xmlChar *refNs)
   5389 {
   5390     xmlSchemaQNameRefPtr ret;
   5391 
   5392     ret = (xmlSchemaQNameRefPtr)
   5393 	xmlMalloc(sizeof(xmlSchemaQNameRef));
   5394     if (ret == NULL) {
   5395 	xmlSchemaPErrMemory(pctxt,
   5396 	    "allocating QName reference item", NULL);
   5397 	return (NULL);
   5398     }
   5399     ret->node = NULL;
   5400     ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
   5401     ret->name = refName;
   5402     ret->targetNamespace = refNs;
   5403     ret->item = NULL;
   5404     ret->itemType = refType;
   5405     /*
   5406     * Store the reference item in the schema.
   5407     */
   5408     WXS_ADD_LOCAL(pctxt, ret);
   5409     return (ret);
   5410 }
   5411 
   5412 static xmlSchemaAttributeUseProhibPtr
   5413 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
   5414 {
   5415     xmlSchemaAttributeUseProhibPtr ret;
   5416 
   5417     ret = (xmlSchemaAttributeUseProhibPtr)
   5418 	xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
   5419     if (ret == NULL) {
   5420 	xmlSchemaPErrMemory(pctxt,
   5421 	    "allocating attribute use prohibition", NULL);
   5422 	return (NULL);
   5423     }
   5424     memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
   5425     ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
   5426     WXS_ADD_LOCAL(pctxt, ret);
   5427     return (ret);
   5428 }
   5429 
   5430 
   5431 /**
   5432  * xmlSchemaAddModelGroup:
   5433  * @ctxt:  a schema parser context
   5434  * @schema:  the schema being built
   5435  * @type: the "compositor" type of the model group
   5436  * @node: the node in the schema doc
   5437  *
   5438  * Adds a schema model group
   5439  * *WARNING* this interface is highly subject to change
   5440  *
   5441  * Returns the new struture or NULL in case of error
   5442  */
   5443 static xmlSchemaModelGroupPtr
   5444 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
   5445 		       xmlSchemaPtr schema,
   5446 		       xmlSchemaTypeType type,
   5447 		       xmlNodePtr node)
   5448 {
   5449     xmlSchemaModelGroupPtr ret = NULL;
   5450 
   5451     if ((ctxt == NULL) || (schema == NULL))
   5452         return (NULL);
   5453 
   5454     ret = (xmlSchemaModelGroupPtr)
   5455 	xmlMalloc(sizeof(xmlSchemaModelGroup));
   5456     if (ret == NULL) {
   5457 	xmlSchemaPErrMemory(ctxt, "allocating model group component",
   5458 	    NULL);
   5459 	return (NULL);
   5460     }
   5461     memset(ret, 0, sizeof(xmlSchemaModelGroup));
   5462     ret->type = type;
   5463     ret->node = node;
   5464     WXS_ADD_LOCAL(ctxt, ret);
   5465     if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
   5466 	(type == XML_SCHEMA_TYPE_CHOICE))
   5467 	WXS_ADD_PENDING(ctxt, ret);
   5468     return (ret);
   5469 }
   5470 
   5471 
   5472 /**
   5473  * xmlSchemaAddParticle:
   5474  * @ctxt:  a schema parser context
   5475  * @schema:  the schema being built
   5476  * @node: the corresponding node in the schema doc
   5477  * @min: the minOccurs
   5478  * @max: the maxOccurs
   5479  *
   5480  * Adds an XML schema particle component.
   5481  * *WARNING* this interface is highly subject to change
   5482  *
   5483  * Returns the new struture or NULL in case of error
   5484  */
   5485 static xmlSchemaParticlePtr
   5486 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
   5487 		     xmlNodePtr node, int min, int max)
   5488 {
   5489     xmlSchemaParticlePtr ret = NULL;
   5490     if (ctxt == NULL)
   5491         return (NULL);
   5492 
   5493 #ifdef DEBUG
   5494     fprintf(stderr, "Adding particle component\n");
   5495 #endif
   5496     ret = (xmlSchemaParticlePtr)
   5497 	xmlMalloc(sizeof(xmlSchemaParticle));
   5498     if (ret == NULL) {
   5499 	xmlSchemaPErrMemory(ctxt, "allocating particle component",
   5500 	    NULL);
   5501 	return (NULL);
   5502     }
   5503     ret->type = XML_SCHEMA_TYPE_PARTICLE;
   5504     ret->annot = NULL;
   5505     ret->node = node;
   5506     ret->minOccurs = min;
   5507     ret->maxOccurs = max;
   5508     ret->next = NULL;
   5509     ret->children = NULL;
   5510 
   5511     WXS_ADD_LOCAL(ctxt, ret);
   5512     /*
   5513     * Note that addition to pending components will be done locally
   5514     * to the specific parsing function, since the most particles
   5515     * need not to be fixed up (i.e. the reference to be resolved).
   5516     * REMOVED: WXS_ADD_PENDING(ctxt, ret);
   5517     */
   5518     return (ret);
   5519 }
   5520 
   5521 /**
   5522  * xmlSchemaAddModelGroupDefinition:
   5523  * @ctxt:  a schema validation context
   5524  * @schema:  the schema being built
   5525  * @name:  the group name
   5526  *
   5527  * Add an XML schema Group definition
   5528  *
   5529  * Returns the new struture or NULL in case of error
   5530  */
   5531 static xmlSchemaModelGroupDefPtr
   5532 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
   5533 				 xmlSchemaPtr schema,
   5534 				 const xmlChar *name,
   5535 				 const xmlChar *nsName,
   5536 				 xmlNodePtr node)
   5537 {
   5538     xmlSchemaModelGroupDefPtr ret = NULL;
   5539 
   5540     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
   5541         return (NULL);
   5542 
   5543     ret = (xmlSchemaModelGroupDefPtr)
   5544 	xmlMalloc(sizeof(xmlSchemaModelGroupDef));
   5545     if (ret == NULL) {
   5546         xmlSchemaPErrMemory(ctxt, "adding group", NULL);
   5547         return (NULL);
   5548     }
   5549     memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
   5550     ret->name = name;
   5551     ret->type = XML_SCHEMA_TYPE_GROUP;
   5552     ret->node = node;
   5553     ret->targetNamespace = nsName;
   5554 
   5555     if (ctxt->isRedefine) {
   5556 	ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
   5557 	    ret, name, nsName);
   5558 	if (ctxt->redef == NULL) {
   5559 	    xmlFree(ret);
   5560 	    return(NULL);
   5561 	}
   5562 	ctxt->redefCounter = 0;
   5563     }
   5564     WXS_ADD_GLOBAL(ctxt, ret);
   5565     WXS_ADD_PENDING(ctxt, ret);
   5566     return (ret);
   5567 }
   5568 
   5569 /**
   5570  * xmlSchemaNewWildcardNs:
   5571  * @ctxt:  a schema validation context
   5572  *
   5573  * Creates a new wildcard namespace constraint.
   5574  *
   5575  * Returns the new struture or NULL in case of error
   5576  */
   5577 static xmlSchemaWildcardNsPtr
   5578 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
   5579 {
   5580     xmlSchemaWildcardNsPtr ret;
   5581 
   5582     ret = (xmlSchemaWildcardNsPtr)
   5583 	xmlMalloc(sizeof(xmlSchemaWildcardNs));
   5584     if (ret == NULL) {
   5585 	xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
   5586 	return (NULL);
   5587     }
   5588     ret->value = NULL;
   5589     ret->next = NULL;
   5590     return (ret);
   5591 }
   5592 
   5593 static xmlSchemaIDCPtr
   5594 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5595                   const xmlChar *name, const xmlChar *nsName,
   5596 		  int category, xmlNodePtr node)
   5597 {
   5598     xmlSchemaIDCPtr ret = NULL;
   5599 
   5600     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
   5601         return (NULL);
   5602 
   5603     ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
   5604     if (ret == NULL) {
   5605         xmlSchemaPErrMemory(ctxt,
   5606 	    "allocating an identity-constraint definition", NULL);
   5607         return (NULL);
   5608     }
   5609     memset(ret, 0, sizeof(xmlSchemaIDC));
   5610     /* The target namespace of the parent element declaration. */
   5611     ret->targetNamespace = nsName;
   5612     ret->name = name;
   5613     ret->type = category;
   5614     ret->node = node;
   5615 
   5616     WXS_ADD_GLOBAL(ctxt, ret);
   5617     /*
   5618     * Only keyrefs need to be fixup up.
   5619     */
   5620     if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
   5621 	WXS_ADD_PENDING(ctxt, ret);
   5622     return (ret);
   5623 }
   5624 
   5625 /**
   5626  * xmlSchemaAddWildcard:
   5627  * @ctxt:  a schema validation context
   5628  * @schema: a schema
   5629  *
   5630  * Adds a wildcard.
   5631  * It corresponds to a xsd:anyAttribute and xsd:any.
   5632  *
   5633  * Returns the new struture or NULL in case of error
   5634  */
   5635 static xmlSchemaWildcardPtr
   5636 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5637 		     xmlSchemaTypeType type, xmlNodePtr node)
   5638 {
   5639     xmlSchemaWildcardPtr ret = NULL;
   5640 
   5641     if ((ctxt == NULL) || (schema == NULL))
   5642         return (NULL);
   5643 
   5644     ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
   5645     if (ret == NULL) {
   5646         xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
   5647         return (NULL);
   5648     }
   5649     memset(ret, 0, sizeof(xmlSchemaWildcard));
   5650     ret->type = type;
   5651     ret->node = node;
   5652     WXS_ADD_LOCAL(ctxt, ret);
   5653     return (ret);
   5654 }
   5655 
   5656 static void
   5657 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
   5658 {
   5659     if (group == NULL)
   5660 	return;
   5661     if (group->members != NULL)
   5662 	xmlSchemaItemListFree(group->members);
   5663     xmlFree(group);
   5664 }
   5665 
   5666 static xmlSchemaSubstGroupPtr
   5667 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
   5668 		       xmlSchemaElementPtr head)
   5669 {
   5670     xmlSchemaSubstGroupPtr ret;
   5671 
   5672     /* Init subst group hash. */
   5673     if (WXS_SUBST_GROUPS(pctxt) == NULL) {
   5674 	WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
   5675 	if (WXS_SUBST_GROUPS(pctxt) == NULL)
   5676 	    return(NULL);
   5677     }
   5678     /* Create a new substitution group. */
   5679     ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
   5680     if (ret == NULL) {
   5681 	xmlSchemaPErrMemory(NULL,
   5682 	    "allocating a substitution group container", NULL);
   5683 	return(NULL);
   5684     }
   5685     memset(ret, 0, sizeof(xmlSchemaSubstGroup));
   5686     ret->head = head;
   5687     /* Create list of members. */
   5688     ret->members = xmlSchemaItemListCreate();
   5689     if (ret->members == NULL) {
   5690 	xmlSchemaSubstGroupFree(ret);
   5691 	return(NULL);
   5692     }
   5693     /* Add subst group to hash. */
   5694     if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
   5695 	head->name, head->targetNamespace, ret) != 0) {
   5696 	PERROR_INT("xmlSchemaSubstGroupAdd",
   5697 	    "failed to add a new substitution container");
   5698 	xmlSchemaSubstGroupFree(ret);
   5699 	return(NULL);
   5700     }
   5701     return(ret);
   5702 }
   5703 
   5704 static xmlSchemaSubstGroupPtr
   5705 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
   5706 		       xmlSchemaElementPtr head)
   5707 {
   5708     if (WXS_SUBST_GROUPS(pctxt) == NULL)
   5709 	return(NULL);
   5710     return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
   5711 	head->name, head->targetNamespace));
   5712 
   5713 }
   5714 
   5715 /**
   5716  * xmlSchemaAddElementSubstitutionMember:
   5717  * @pctxt:  a schema parser context
   5718  * @head:  the head of the substitution group
   5719  * @member: the new member of the substitution group
   5720  *
   5721  * Allocate a new annotation structure.
   5722  *
   5723  * Returns the newly allocated structure or NULL in case or error
   5724  */
   5725 static int
   5726 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
   5727 				      xmlSchemaElementPtr head,
   5728 				      xmlSchemaElementPtr member)
   5729 {
   5730     xmlSchemaSubstGroupPtr substGroup = NULL;
   5731 
   5732     if ((pctxt == NULL) || (head == NULL) || (member == NULL))
   5733 	return (-1);
   5734 
   5735     substGroup = xmlSchemaSubstGroupGet(pctxt, head);
   5736     if (substGroup == NULL)
   5737 	substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
   5738     if (substGroup == NULL)
   5739 	return(-1);
   5740     if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
   5741 	return(-1);
   5742     return(0);
   5743 }
   5744 
   5745 /************************************************************************
   5746  * 									*
   5747  *		Utilities for parsing					*
   5748  * 									*
   5749  ************************************************************************/
   5750 
   5751 /**
   5752  * xmlSchemaPValAttrNodeQNameValue:
   5753  * @ctxt:  a schema parser context
   5754  * @schema: the schema context
   5755  * @ownerDes: the designation of the parent element
   5756  * @ownerItem: the parent as a schema object
   5757  * @value:  the QName value
   5758  * @local: the resulting local part if found, the attribute value otherwise
   5759  * @uri:  the resulting namespace URI if found
   5760  *
   5761  * Extracts the local name and the URI of a QName value and validates it.
   5762  * This one is intended to be used on attribute values that
   5763  * should resolve to schema components.
   5764  *
   5765  * Returns 0, in case the QName is valid, a positive error code
   5766  * if not valid and -1 if an internal error occurs.
   5767  */
   5768 static int
   5769 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
   5770 				       xmlSchemaPtr schema,
   5771 				       xmlSchemaBasicItemPtr ownerItem,
   5772 				       xmlAttrPtr attr,
   5773 				       const xmlChar *value,
   5774 				       const xmlChar **uri,
   5775 				       const xmlChar **local)
   5776 {
   5777     const xmlChar *pref;
   5778     xmlNsPtr ns;
   5779     int len, ret;
   5780 
   5781     *uri = NULL;
   5782     *local = NULL;
   5783     ret = xmlValidateQName(value, 1);
   5784     if (ret > 0) {
   5785 	xmlSchemaPSimpleTypeErr(ctxt,
   5786 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5787 	    ownerItem, (xmlNodePtr) attr,
   5788 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
   5789 	    NULL, value, NULL, NULL, NULL);
   5790 	*local = value;
   5791 	return (ctxt->err);
   5792     } else if (ret < 0)
   5793 	return (-1);
   5794 
   5795     if (!strchr((char *) value, ':')) {
   5796 	ns = xmlSearchNs(attr->doc, attr->parent, NULL);
   5797 	if (ns)
   5798 	    *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
   5799 	else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
   5800 	    /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
   5801 	    * parser context. */
   5802 	    /*
   5803 	    * This one takes care of included schemas with no
   5804 	    * target namespace.
   5805 	    */
   5806 	    *uri = ctxt->targetNamespace;
   5807 	}
   5808 	*local = xmlDictLookup(ctxt->dict, value, -1);
   5809 	return (0);
   5810     }
   5811     /*
   5812     * At this point xmlSplitQName3 has to return a local name.
   5813     */
   5814     *local = xmlSplitQName3(value, &len);
   5815     *local = xmlDictLookup(ctxt->dict, *local, -1);
   5816     pref = xmlDictLookup(ctxt->dict, value, len);
   5817     ns = xmlSearchNs(attr->doc, attr->parent, pref);
   5818     if (ns == NULL) {
   5819 	xmlSchemaPSimpleTypeErr(ctxt,
   5820 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5821 	    ownerItem, (xmlNodePtr) attr,
   5822 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
   5823 	    "The value '%s' of simple type 'xs:QName' has no "
   5824 	    "corresponding namespace declaration in scope", value, NULL);
   5825 	return (ctxt->err);
   5826     } else {
   5827         *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
   5828     }
   5829     return (0);
   5830 }
   5831 
   5832 /**
   5833  * xmlSchemaPValAttrNodeQName:
   5834  * @ctxt:  a schema parser context
   5835  * @schema: the schema context
   5836  * @ownerDes: the designation of the owner element
   5837  * @ownerItem: the owner as a schema object
   5838  * @attr:  the attribute node
   5839  * @local: the resulting local part if found, the attribute value otherwise
   5840  * @uri:  the resulting namespace URI if found
   5841  *
   5842  * Extracts and validates the QName of an attribute value.
   5843  * This one is intended to be used on attribute values that
   5844  * should resolve to schema components.
   5845  *
   5846  * Returns 0, in case the QName is valid, a positive error code
   5847  * if not valid and -1 if an internal error occurs.
   5848  */
   5849 static int
   5850 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
   5851 				       xmlSchemaPtr schema,
   5852 				       xmlSchemaBasicItemPtr ownerItem,
   5853 				       xmlAttrPtr attr,
   5854 				       const xmlChar **uri,
   5855 				       const xmlChar **local)
   5856 {
   5857     const xmlChar *value;
   5858 
   5859     value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   5860     return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
   5861 	ownerItem, attr, value, uri, local));
   5862 }
   5863 
   5864 /**
   5865  * xmlSchemaPValAttrQName:
   5866  * @ctxt:  a schema parser context
   5867  * @schema: the schema context
   5868  * @ownerDes: the designation of the parent element
   5869  * @ownerItem: the owner as a schema object
   5870  * @ownerElem:  the parent node of the attribute
   5871  * @name:  the name of the attribute
   5872  * @local: the resulting local part if found, the attribute value otherwise
   5873  * @uri:  the resulting namespace URI if found
   5874  *
   5875  * Extracts and validates the QName of an attribute value.
   5876  *
   5877  * Returns 0, in case the QName is valid, a positive error code
   5878  * if not valid and -1 if an internal error occurs.
   5879  */
   5880 static int
   5881 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
   5882 				   xmlSchemaPtr schema,
   5883 				   xmlSchemaBasicItemPtr ownerItem,
   5884 				   xmlNodePtr ownerElem,
   5885 				   const char *name,
   5886 				   const xmlChar **uri,
   5887 				   const xmlChar **local)
   5888 {
   5889     xmlAttrPtr attr;
   5890 
   5891     attr = xmlSchemaGetPropNode(ownerElem, name);
   5892     if (attr == NULL) {
   5893 	*local = NULL;
   5894 	*uri = NULL;
   5895 	return (0);
   5896     }
   5897     return (xmlSchemaPValAttrNodeQName(ctxt, schema,
   5898 	ownerItem, attr, uri, local));
   5899 }
   5900 
   5901 /**
   5902  * xmlSchemaPValAttrID:
   5903  * @ctxt:  a schema parser context
   5904  * @schema: the schema context
   5905  * @ownerDes: the designation of the parent element
   5906  * @ownerItem: the owner as a schema object
   5907  * @ownerElem:  the parent node of the attribute
   5908  * @name:  the name of the attribute
   5909  *
   5910  * Extracts and validates the ID of an attribute value.
   5911  *
   5912  * Returns 0, in case the ID is valid, a positive error code
   5913  * if not valid and -1 if an internal error occurs.
   5914  */
   5915 static int
   5916 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
   5917 {
   5918     int ret;
   5919     const xmlChar *value;
   5920 
   5921     if (attr == NULL)
   5922 	return(0);
   5923     value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
   5924     ret = xmlValidateNCName(value, 1);
   5925     if (ret == 0) {
   5926 	/*
   5927 	* NOTE: the IDness might have already be declared in the DTD
   5928 	*/
   5929 	if (attr->atype != XML_ATTRIBUTE_ID) {
   5930 	    xmlIDPtr res;
   5931 	    xmlChar *strip;
   5932 
   5933 	    /*
   5934 	    * TODO: Use xmlSchemaStrip here; it's not exported at this
   5935 	    * moment.
   5936 	    */
   5937 	    strip = xmlSchemaCollapseString(value);
   5938 	    if (strip != NULL) {
   5939 		xmlFree((xmlChar *) value);
   5940 		value = strip;
   5941 	    }
   5942     	    res = xmlAddID(NULL, attr->doc, value, attr);
   5943 	    if (res == NULL) {
   5944 		ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   5945 		xmlSchemaPSimpleTypeErr(ctxt,
   5946 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5947 		    NULL, (xmlNodePtr) attr,
   5948 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
   5949 		    NULL, NULL, "Duplicate value '%s' of simple "
   5950 		    "type 'xs:ID'", value, NULL);
   5951 	    } else
   5952 		attr->atype = XML_ATTRIBUTE_ID;
   5953 	}
   5954     } else if (ret > 0) {
   5955 	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   5956 	xmlSchemaPSimpleTypeErr(ctxt,
   5957 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5958 	    NULL, (xmlNodePtr) attr,
   5959 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
   5960 	    NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
   5961 	    "not a valid 'xs:NCName'",
   5962 	    value, NULL);
   5963     }
   5964     if (value != NULL)
   5965 	xmlFree((xmlChar *)value);
   5966 
   5967     return (ret);
   5968 }
   5969 
   5970 static int
   5971 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
   5972 		    xmlNodePtr ownerElem,
   5973 		    const xmlChar *name)
   5974 {
   5975     xmlAttrPtr attr;
   5976 
   5977     attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
   5978     if (attr == NULL)
   5979 	return(0);
   5980     return(xmlSchemaPValAttrNodeID(ctxt, attr));
   5981 
   5982 }
   5983 
   5984 /**
   5985  * xmlGetMaxOccurs:
   5986  * @ctxt:  a schema validation context
   5987  * @node:  a subtree containing XML Schema informations
   5988  *
   5989  * Get the maxOccurs property
   5990  *
   5991  * Returns the default if not found, or the value
   5992  */
   5993 static int
   5994 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
   5995 		int min, int max, int def, const char *expected)
   5996 {
   5997     const xmlChar *val, *cur;
   5998     int ret = 0;
   5999     xmlAttrPtr attr;
   6000 
   6001     attr = xmlSchemaGetPropNode(node, "maxOccurs");
   6002     if (attr == NULL)
   6003 	return (def);
   6004     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6005 
   6006     if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
   6007 	if (max != UNBOUNDED) {
   6008 	    xmlSchemaPSimpleTypeErr(ctxt,
   6009 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6010 		/* XML_SCHEMAP_INVALID_MINOCCURS, */
   6011 		NULL, (xmlNodePtr) attr, NULL, expected,
   6012 		val, NULL, NULL, NULL);
   6013 	    return (def);
   6014 	} else
   6015 	    return (UNBOUNDED);  /* encoding it with -1 might be another option */
   6016     }
   6017 
   6018     cur = val;
   6019     while (IS_BLANK_CH(*cur))
   6020         cur++;
   6021     if (*cur == 0) {
   6022         xmlSchemaPSimpleTypeErr(ctxt,
   6023 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6024 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6025 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6026 	    val, NULL, NULL, NULL);
   6027 	return (def);
   6028     }
   6029     while ((*cur >= '0') && (*cur <= '9')) {
   6030         ret = ret * 10 + (*cur - '0');
   6031         cur++;
   6032     }
   6033     while (IS_BLANK_CH(*cur))
   6034         cur++;
   6035     /*
   6036     * TODO: Restrict the maximal value to Integer.
   6037     */
   6038     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
   6039 	xmlSchemaPSimpleTypeErr(ctxt,
   6040 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6041 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6042 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6043 	    val, NULL, NULL, NULL);
   6044         return (def);
   6045     }
   6046     return (ret);
   6047 }
   6048 
   6049 /**
   6050  * xmlGetMinOccurs:
   6051  * @ctxt:  a schema validation context
   6052  * @node:  a subtree containing XML Schema informations
   6053  *
   6054  * Get the minOccurs property
   6055  *
   6056  * Returns the default if not found, or the value
   6057  */
   6058 static int
   6059 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
   6060 		int min, int max, int def, const char *expected)
   6061 {
   6062     const xmlChar *val, *cur;
   6063     int ret = 0;
   6064     xmlAttrPtr attr;
   6065 
   6066     attr = xmlSchemaGetPropNode(node, "minOccurs");
   6067     if (attr == NULL)
   6068 	return (def);
   6069     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6070     cur = val;
   6071     while (IS_BLANK_CH(*cur))
   6072         cur++;
   6073     if (*cur == 0) {
   6074         xmlSchemaPSimpleTypeErr(ctxt,
   6075 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6076 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6077 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6078 	    val, NULL, NULL, NULL);
   6079         return (def);
   6080     }
   6081     while ((*cur >= '0') && (*cur <= '9')) {
   6082         ret = ret * 10 + (*cur - '0');
   6083         cur++;
   6084     }
   6085     while (IS_BLANK_CH(*cur))
   6086         cur++;
   6087     /*
   6088     * TODO: Restrict the maximal value to Integer.
   6089     */
   6090     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
   6091 	xmlSchemaPSimpleTypeErr(ctxt,
   6092 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6093 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6094 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6095 	    val, NULL, NULL, NULL);
   6096         return (def);
   6097     }
   6098     return (ret);
   6099 }
   6100 
   6101 /**
   6102  * xmlSchemaPGetBoolNodeValue:
   6103  * @ctxt:  a schema validation context
   6104  * @ownerDes:  owner designation
   6105  * @ownerItem:  the owner as a schema item
   6106  * @node: the node holding the value
   6107  *
   6108  * Converts a boolean string value into 1 or 0.
   6109  *
   6110  * Returns 0 or 1.
   6111  */
   6112 static int
   6113 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
   6114 			   xmlSchemaBasicItemPtr ownerItem,
   6115 			   xmlNodePtr node)
   6116 {
   6117     xmlChar *value = NULL;
   6118     int res = 0;
   6119 
   6120     value = xmlNodeGetContent(node);
   6121     /*
   6122     * 3.2.2.1 Lexical representation
   6123     * An instance of a datatype that is defined as boolean
   6124     * can have the following legal literals {true, false, 1, 0}.
   6125     */
   6126     if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
   6127         res = 1;
   6128     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
   6129         res = 0;
   6130     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
   6131 	res = 1;
   6132     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
   6133         res = 0;
   6134     else {
   6135         xmlSchemaPSimpleTypeErr(ctxt,
   6136 	    XML_SCHEMAP_INVALID_BOOLEAN,
   6137 	    ownerItem, node,
   6138 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
   6139 	    NULL, BAD_CAST value,
   6140 	    NULL, NULL, NULL);
   6141     }
   6142     if (value != NULL)
   6143 	xmlFree(value);
   6144     return (res);
   6145 }
   6146 
   6147 /**
   6148  * xmlGetBooleanProp:
   6149  * @ctxt:  a schema validation context
   6150  * @node:  a subtree containing XML Schema informations
   6151  * @name:  the attribute name
   6152  * @def:  the default value
   6153  *
   6154  * Evaluate if a boolean property is set
   6155  *
   6156  * Returns the default if not found, 0 if found to be false,
   6157  * 1 if found to be true
   6158  */
   6159 static int
   6160 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
   6161 		  xmlNodePtr node,
   6162                   const char *name, int def)
   6163 {
   6164     const xmlChar *val;
   6165 
   6166     val = xmlSchemaGetProp(ctxt, node, name);
   6167     if (val == NULL)
   6168         return (def);
   6169     /*
   6170     * 3.2.2.1 Lexical representation
   6171     * An instance of a datatype that is defined as boolean
   6172     * can have the following legal literals {true, false, 1, 0}.
   6173     */
   6174     if (xmlStrEqual(val, BAD_CAST "true"))
   6175         def = 1;
   6176     else if (xmlStrEqual(val, BAD_CAST "false"))
   6177         def = 0;
   6178     else if (xmlStrEqual(val, BAD_CAST "1"))
   6179 	def = 1;
   6180     else if (xmlStrEqual(val, BAD_CAST "0"))
   6181         def = 0;
   6182     else {
   6183         xmlSchemaPSimpleTypeErr(ctxt,
   6184 	    XML_SCHEMAP_INVALID_BOOLEAN,
   6185 	    NULL,
   6186 	    (xmlNodePtr) xmlSchemaGetPropNode(node, name),
   6187 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
   6188 	    NULL, val, NULL, NULL, NULL);
   6189     }
   6190     return (def);
   6191 }
   6192 
   6193 /************************************************************************
   6194  * 									*
   6195  *		Shema extraction from an Infoset			*
   6196  * 									*
   6197  ************************************************************************/
   6198 static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
   6199                                                  ctxt, xmlSchemaPtr schema,
   6200                                                  xmlNodePtr node,
   6201 						 int topLevel);
   6202 static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
   6203                                                   ctxt,
   6204                                                   xmlSchemaPtr schema,
   6205                                                   xmlNodePtr node,
   6206 						  int topLevel);
   6207 static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
   6208                                                   ctxt,
   6209                                                   xmlSchemaPtr schema,
   6210                                                   xmlNodePtr node,
   6211 						  xmlSchemaTypeType parentType);
   6212 static xmlSchemaBasicItemPtr
   6213 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
   6214 			     xmlSchemaPtr schema,
   6215 			     xmlNodePtr node,
   6216 			     xmlSchemaItemListPtr uses,
   6217 			     int parentType);
   6218 static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
   6219                                            xmlSchemaPtr schema,
   6220                                            xmlNodePtr node);
   6221 static xmlSchemaWildcardPtr
   6222 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
   6223                            xmlSchemaPtr schema, xmlNodePtr node);
   6224 
   6225 /**
   6226  * xmlSchemaPValAttrNodeValue:
   6227  *
   6228  * @ctxt:  a schema parser context
   6229  * @ownerDes: the designation of the parent element
   6230  * @ownerItem: the schema object owner if existent
   6231  * @attr:  the schema attribute node being validated
   6232  * @value: the value
   6233  * @type: the built-in type to be validated against
   6234  *
   6235  * Validates a value against the given built-in type.
   6236  * This one is intended to be used internally for validation
   6237  * of schema attribute values during parsing of the schema.
   6238  *
   6239  * Returns 0 if the value is valid, a positive error code
   6240  * number otherwise and -1 in case of an internal or API error.
   6241  */
   6242 static int
   6243 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
   6244 			   xmlSchemaBasicItemPtr ownerItem,
   6245 			   xmlAttrPtr attr,
   6246 			   const xmlChar *value,
   6247 			   xmlSchemaTypePtr type)
   6248 {
   6249 
   6250     int ret = 0;
   6251 
   6252     /*
   6253     * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
   6254     * one is really meant to be used internally, so better not.
   6255     */
   6256     if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
   6257 	return (-1);
   6258     if (type->type != XML_SCHEMA_TYPE_BASIC) {
   6259 	PERROR_INT("xmlSchemaPValAttrNodeValue",
   6260 	    "the given type is not a built-in type");
   6261 	return (-1);
   6262     }
   6263     switch (type->builtInType) {
   6264 	case XML_SCHEMAS_NCNAME:
   6265 	case XML_SCHEMAS_QNAME:
   6266 	case XML_SCHEMAS_ANYURI:
   6267 	case XML_SCHEMAS_TOKEN:
   6268 	case XML_SCHEMAS_LANGUAGE:
   6269 	    ret = xmlSchemaValPredefTypeNode(type, value, NULL,
   6270 		(xmlNodePtr) attr);
   6271 	    break;
   6272 	default: {
   6273 	    PERROR_INT("xmlSchemaPValAttrNodeValue",
   6274 		"validation using the given type is not supported while "
   6275 		"parsing a schema");
   6276 	    return (-1);
   6277 	}
   6278     }
   6279     /*
   6280     * TODO: Should we use the S4S error codes instead?
   6281     */
   6282     if (ret < 0) {
   6283 	PERROR_INT("xmlSchemaPValAttrNodeValue",
   6284 	    "failed to validate a schema attribute value");
   6285 	return (-1);
   6286     } else if (ret > 0) {
   6287 	if (WXS_IS_LIST(type))
   6288 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   6289 	else
   6290 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
   6291 	xmlSchemaPSimpleTypeErr(pctxt,
   6292 	    ret, ownerItem, (xmlNodePtr) attr,
   6293 	    type, NULL, value, NULL, NULL, NULL);
   6294     }
   6295     return (ret);
   6296 }
   6297 
   6298 /**
   6299  * xmlSchemaPValAttrNode:
   6300  *
   6301  * @ctxt:  a schema parser context
   6302  * @ownerDes: the designation of the parent element
   6303  * @ownerItem: the schema object owner if existent
   6304  * @attr:  the schema attribute node being validated
   6305  * @type: the built-in type to be validated against
   6306  * @value: the resulting value if any
   6307  *
   6308  * Extracts and validates a value against the given built-in type.
   6309  * This one is intended to be used internally for validation
   6310  * of schema attribute values during parsing of the schema.
   6311  *
   6312  * Returns 0 if the value is valid, a positive error code
   6313  * number otherwise and -1 in case of an internal or API error.
   6314  */
   6315 static int
   6316 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
   6317 			   xmlSchemaBasicItemPtr ownerItem,
   6318 			   xmlAttrPtr attr,
   6319 			   xmlSchemaTypePtr type,
   6320 			   const xmlChar **value)
   6321 {
   6322     const xmlChar *val;
   6323 
   6324     if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
   6325 	return (-1);
   6326 
   6327     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6328     if (value != NULL)
   6329 	*value = val;
   6330 
   6331     return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
   6332 	val, type));
   6333 }
   6334 
   6335 /**
   6336  * xmlSchemaPValAttr:
   6337  *
   6338  * @ctxt:  a schema parser context
   6339  * @node: the element node of the attribute
   6340  * @ownerDes: the designation of the parent element
   6341  * @ownerItem: the schema object owner if existent
   6342  * @ownerElem: the owner element node
   6343  * @name:  the name of the schema attribute node
   6344  * @type: the built-in type to be validated against
   6345  * @value: the resulting value if any
   6346  *
   6347  * Extracts and validates a value against the given built-in type.
   6348  * This one is intended to be used internally for validation
   6349  * of schema attribute values during parsing of the schema.
   6350  *
   6351  * Returns 0 if the value is valid, a positive error code
   6352  * number otherwise and -1 in case of an internal or API error.
   6353  */
   6354 static int
   6355 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
   6356 		       xmlSchemaBasicItemPtr ownerItem,
   6357 		       xmlNodePtr ownerElem,
   6358 		       const char *name,
   6359 		       xmlSchemaTypePtr type,
   6360 		       const xmlChar **value)
   6361 {
   6362     xmlAttrPtr attr;
   6363 
   6364     if ((ctxt == NULL) || (type == NULL)) {
   6365 	if (value != NULL)
   6366 	    *value = NULL;
   6367 	return (-1);
   6368     }
   6369     if (type->type != XML_SCHEMA_TYPE_BASIC) {
   6370 	if (value != NULL)
   6371 	    *value = NULL;
   6372 	xmlSchemaPErr(ctxt, ownerElem,
   6373 	    XML_SCHEMAP_INTERNAL,
   6374 	    "Internal error: xmlSchemaPValAttr, the given "
   6375 	    "type '%s' is not a built-in type.\n",
   6376 	    type->name, NULL);
   6377 	return (-1);
   6378     }
   6379     attr = xmlSchemaGetPropNode(ownerElem, name);
   6380     if (attr == NULL) {
   6381 	if (value != NULL)
   6382 	    *value = NULL;
   6383 	return (0);
   6384     }
   6385     return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
   6386 	type, value));
   6387 }
   6388 
   6389 static int
   6390 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
   6391 		  xmlSchemaPtr schema ATTRIBUTE_UNUSED,
   6392 		  xmlNodePtr node,
   6393 		  xmlAttrPtr attr,
   6394 		  const xmlChar *namespaceName)
   6395 {
   6396     /* TODO: Pointer comparison instead? */
   6397     if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
   6398 	return (0);
   6399     if (xmlStrEqual(xmlSchemaNs, namespaceName))
   6400 	return (0);
   6401     /*
   6402     * Check if the referenced namespace was <import>ed.
   6403     */
   6404     if (WXS_BUCKET(pctxt)->relations != NULL) {
   6405 	xmlSchemaSchemaRelationPtr rel;
   6406 
   6407 	rel = WXS_BUCKET(pctxt)->relations;
   6408 	do {
   6409 	    if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
   6410 		xmlStrEqual(namespaceName, rel->importNamespace))
   6411 		return (0);
   6412 	    rel = rel->next;
   6413 	} while (rel != NULL);
   6414     }
   6415     /*
   6416     * No matching <import>ed namespace found.
   6417     */
   6418     {
   6419 	xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
   6420 
   6421 	if (namespaceName == NULL)
   6422 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   6423 		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
   6424 		"References from this schema to components in no "
   6425 		"namespace are not allowed, since not indicated by an "
   6426 		"import statement", NULL, NULL);
   6427 	else
   6428 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   6429 		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
   6430 		"References from this schema to components in the "
   6431 		"namespace '%s' are not allowed, since not indicated by an "
   6432 		"import statement", namespaceName, NULL);
   6433     }
   6434     return (XML_SCHEMAP_SRC_RESOLVE);
   6435 }
   6436 
   6437 /**
   6438  * xmlSchemaParseLocalAttributes:
   6439  * @ctxt:  a schema validation context
   6440  * @schema:  the schema being built
   6441  * @node:  a subtree containing XML Schema informations
   6442  * @type:  the hosting type where the attributes will be anchored
   6443  *
   6444  * Parses attribute uses and attribute declarations and
   6445  * attribute group references.
   6446  */
   6447 static int
   6448 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6449                         xmlNodePtr *child, xmlSchemaItemListPtr *list,
   6450 			int parentType, int *hasRefs)
   6451 {
   6452     void *item;
   6453 
   6454     while ((IS_SCHEMA((*child), "attribute")) ||
   6455            (IS_SCHEMA((*child), "attributeGroup"))) {
   6456         if (IS_SCHEMA((*child), "attribute")) {
   6457 	    item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
   6458 		*list, parentType);
   6459         } else {
   6460             item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
   6461 	    if ((item != NULL) && (hasRefs != NULL))
   6462 		*hasRefs = 1;
   6463         }
   6464 	if (item != NULL) {
   6465 	    if (*list == NULL) {
   6466 		/* TODO: Customize grow factor. */
   6467 		*list = xmlSchemaItemListCreate();
   6468 		if (*list == NULL)
   6469 		    return(-1);
   6470 	    }
   6471 	    if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
   6472 		return(-1);
   6473 	}
   6474         *child = (*child)->next;
   6475     }
   6476     return (0);
   6477 }
   6478 
   6479 /**
   6480  * xmlSchemaParseAnnotation:
   6481  * @ctxt:  a schema validation context
   6482  * @schema:  the schema being built
   6483  * @node:  a subtree containing XML Schema informations
   6484  *
   6485  * parse a XML schema Attrribute declaration
   6486  * *WARNING* this interface is highly subject to change
   6487  *
   6488  * Returns -1 in case of error, 0 if the declaration is improper and
   6489  *         1 in case of success.
   6490  */
   6491 static xmlSchemaAnnotPtr
   6492 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
   6493 {
   6494     xmlSchemaAnnotPtr ret;
   6495     xmlNodePtr child = NULL;
   6496     xmlAttrPtr attr;
   6497     int barked = 0;
   6498 
   6499     /*
   6500     * INFO: S4S completed.
   6501     */
   6502     /*
   6503     * id = ID
   6504     * {any attributes with non-schema namespace . . .}>
   6505     * Content: (appinfo | documentation)*
   6506     */
   6507     if ((ctxt == NULL) || (node == NULL))
   6508         return (NULL);
   6509     if (needed)
   6510 	ret = xmlSchemaNewAnnot(ctxt, node);
   6511     else
   6512 	ret = NULL;
   6513     attr = node->properties;
   6514     while (attr != NULL) {
   6515 	if (((attr->ns == NULL) &&
   6516 	    (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
   6517 	    ((attr->ns != NULL) &&
   6518 	    xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
   6519 
   6520 	    xmlSchemaPIllegalAttrErr(ctxt,
   6521 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6522 	}
   6523 	attr = attr->next;
   6524     }
   6525     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   6526     /*
   6527     * And now for the children...
   6528     */
   6529     child = node->children;
   6530     while (child != NULL) {
   6531 	if (IS_SCHEMA(child, "appinfo")) {
   6532 	    /* TODO: make available the content of "appinfo". */
   6533 	    /*
   6534 	    * source = anyURI
   6535 	    * {any attributes with non-schema namespace . . .}>
   6536 	    * Content: ({any})*
   6537 	    */
   6538 	    attr = child->properties;
   6539 	    while (attr != NULL) {
   6540 		if (((attr->ns == NULL) &&
   6541 		     (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
   6542 		     ((attr->ns != NULL) &&
   6543 		      xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
   6544 
   6545 		    xmlSchemaPIllegalAttrErr(ctxt,
   6546 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6547 		}
   6548 		attr = attr->next;
   6549 	    }
   6550 	    xmlSchemaPValAttr(ctxt, NULL, child, "source",
   6551 		xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
   6552 	    child = child->next;
   6553 	} else if (IS_SCHEMA(child, "documentation")) {
   6554 	    /* TODO: make available the content of "documentation". */
   6555 	    /*
   6556 	    * source = anyURI
   6557 	    * {any attributes with non-schema namespace . . .}>
   6558 	    * Content: ({any})*
   6559 	    */
   6560 	    attr = child->properties;
   6561 	    while (attr != NULL) {
   6562 		if (attr->ns == NULL) {
   6563 		    if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
   6564 			xmlSchemaPIllegalAttrErr(ctxt,
   6565 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6566 		    }
   6567 		} else {
   6568 		    if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
   6569 			(xmlStrEqual(attr->name, BAD_CAST "lang") &&
   6570 			(!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
   6571 
   6572 			xmlSchemaPIllegalAttrErr(ctxt,
   6573 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6574 		    }
   6575 		}
   6576 		attr = attr->next;
   6577 	    }
   6578 	    /*
   6579 	    * Attribute "xml:lang".
   6580 	    */
   6581 	    attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
   6582 	    if (attr != NULL)
   6583 		xmlSchemaPValAttrNode(ctxt, NULL, attr,
   6584 		xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
   6585 	    child = child->next;
   6586 	} else {
   6587 	    if (!barked)
   6588 		xmlSchemaPContentErr(ctxt,
   6589 		    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   6590 		    NULL, node, child, NULL, "(appinfo | documentation)*");
   6591 	    barked = 1;
   6592 	    child = child->next;
   6593 	}
   6594     }
   6595 
   6596     return (ret);
   6597 }
   6598 
   6599 /**
   6600  * xmlSchemaParseFacet:
   6601  * @ctxt:  a schema validation context
   6602  * @schema:  the schema being built
   6603  * @node:  a subtree containing XML Schema informations
   6604  *
   6605  * parse a XML schema Facet declaration
   6606  * *WARNING* this interface is highly subject to change
   6607  *
   6608  * Returns the new type structure or NULL in case of error
   6609  */
   6610 static xmlSchemaFacetPtr
   6611 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6612                     xmlNodePtr node)
   6613 {
   6614     xmlSchemaFacetPtr facet;
   6615     xmlNodePtr child = NULL;
   6616     const xmlChar *value;
   6617 
   6618     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   6619         return (NULL);
   6620 
   6621     facet = xmlSchemaNewFacet();
   6622     if (facet == NULL) {
   6623         xmlSchemaPErrMemory(ctxt, "allocating facet", node);
   6624         return (NULL);
   6625     }
   6626     facet->node = node;
   6627     value = xmlSchemaGetProp(ctxt, node, "value");
   6628     if (value == NULL) {
   6629         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
   6630                        "Facet %s has no value\n", node->name, NULL);
   6631         xmlSchemaFreeFacet(facet);
   6632         return (NULL);
   6633     }
   6634     if (IS_SCHEMA(node, "minInclusive")) {
   6635         facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
   6636     } else if (IS_SCHEMA(node, "minExclusive")) {
   6637         facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
   6638     } else if (IS_SCHEMA(node, "maxInclusive")) {
   6639         facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
   6640     } else if (IS_SCHEMA(node, "maxExclusive")) {
   6641         facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
   6642     } else if (IS_SCHEMA(node, "totalDigits")) {
   6643         facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
   6644     } else if (IS_SCHEMA(node, "fractionDigits")) {
   6645         facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
   6646     } else if (IS_SCHEMA(node, "pattern")) {
   6647         facet->type = XML_SCHEMA_FACET_PATTERN;
   6648     } else if (IS_SCHEMA(node, "enumeration")) {
   6649         facet->type = XML_SCHEMA_FACET_ENUMERATION;
   6650     } else if (IS_SCHEMA(node, "whiteSpace")) {
   6651         facet->type = XML_SCHEMA_FACET_WHITESPACE;
   6652     } else if (IS_SCHEMA(node, "length")) {
   6653         facet->type = XML_SCHEMA_FACET_LENGTH;
   6654     } else if (IS_SCHEMA(node, "maxLength")) {
   6655         facet->type = XML_SCHEMA_FACET_MAXLENGTH;
   6656     } else if (IS_SCHEMA(node, "minLength")) {
   6657         facet->type = XML_SCHEMA_FACET_MINLENGTH;
   6658     } else {
   6659         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
   6660                        "Unknown facet type %s\n", node->name, NULL);
   6661         xmlSchemaFreeFacet(facet);
   6662         return (NULL);
   6663     }
   6664     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   6665     facet->value = value;
   6666     if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
   6667 	(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
   6668 	const xmlChar *fixed;
   6669 
   6670 	fixed = xmlSchemaGetProp(ctxt, node, "fixed");
   6671 	if (fixed != NULL) {
   6672 	    if (xmlStrEqual(fixed, BAD_CAST "true"))
   6673 		facet->fixed = 1;
   6674 	}
   6675     }
   6676     child = node->children;
   6677 
   6678     if (IS_SCHEMA(child, "annotation")) {
   6679         facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   6680         child = child->next;
   6681     }
   6682     if (child != NULL) {
   6683         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
   6684                        "Facet %s has unexpected child content\n",
   6685                        node->name, NULL);
   6686     }
   6687     return (facet);
   6688 }
   6689 
   6690 /**
   6691  * xmlSchemaParseWildcardNs:
   6692  * @ctxt:  a schema parser context
   6693  * @wildc:  the wildcard, already created
   6694  * @node:  a subtree containing XML Schema informations
   6695  *
   6696  * Parses the attribute "processContents" and "namespace"
   6697  * of a xsd:anyAttribute and xsd:any.
   6698  * *WARNING* this interface is highly subject to change
   6699  *
   6700  * Returns 0 if everything goes fine, a positive error code
   6701  * if something is not valid and -1 if an internal error occurs.
   6702  */
   6703 static int
   6704 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
   6705 			 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
   6706 			 xmlSchemaWildcardPtr wildc,
   6707 			 xmlNodePtr node)
   6708 {
   6709     const xmlChar *pc, *ns, *dictnsItem;
   6710     int ret = 0;
   6711     xmlChar *nsItem;
   6712     xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
   6713     xmlAttrPtr attr;
   6714 
   6715     pc = xmlSchemaGetProp(ctxt, node, "processContents");
   6716     if ((pc == NULL)
   6717         || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
   6718         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
   6719     } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
   6720         wildc->processContents = XML_SCHEMAS_ANY_SKIP;
   6721     } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
   6722         wildc->processContents = XML_SCHEMAS_ANY_LAX;
   6723     } else {
   6724         xmlSchemaPSimpleTypeErr(ctxt,
   6725 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6726 	    NULL, node,
   6727 	    NULL, "(strict | skip | lax)", pc,
   6728 	    NULL, NULL, NULL);
   6729         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
   6730 	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   6731     }
   6732     /*
   6733      * Build the namespace constraints.
   6734      */
   6735     attr = xmlSchemaGetPropNode(node, "namespace");
   6736     ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6737     if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
   6738 	wildc->any = 1;
   6739     else if (xmlStrEqual(ns, BAD_CAST "##other")) {
   6740 	wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   6741 	if (wildc->negNsSet == NULL) {
   6742 	    return (-1);
   6743 	}
   6744 	wildc->negNsSet->value = ctxt->targetNamespace;
   6745     } else {
   6746 	const xmlChar *end, *cur;
   6747 
   6748 	cur = ns;
   6749 	do {
   6750 	    while (IS_BLANK_CH(*cur))
   6751 		cur++;
   6752 	    end = cur;
   6753 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   6754 		end++;
   6755 	    if (end == cur)
   6756 		break;
   6757 	    nsItem = xmlStrndup(cur, end - cur);
   6758 	    if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
   6759 		    (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
   6760 		xmlSchemaPSimpleTypeErr(ctxt,
   6761 		    XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
   6762 		    NULL, (xmlNodePtr) attr,
   6763 		    NULL,
   6764 		    "((##any | ##other) | List of (xs:anyURI | "
   6765 		    "(##targetNamespace | ##local)))",
   6766 		    nsItem, NULL, NULL, NULL);
   6767 		ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
   6768 	    } else {
   6769 		if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
   6770 		    dictnsItem = ctxt->targetNamespace;
   6771 		} else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
   6772 		    dictnsItem = NULL;
   6773 		} else {
   6774 		    /*
   6775 		    * Validate the item (anyURI).
   6776 		    */
   6777 		    xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
   6778 			nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
   6779 		    dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
   6780 		}
   6781 		/*
   6782 		* Avoid dublicate namespaces.
   6783 		*/
   6784 		tmp = wildc->nsSet;
   6785 		while (tmp != NULL) {
   6786 		    if (dictnsItem == tmp->value)
   6787 			break;
   6788 		    tmp = tmp->next;
   6789 		}
   6790 		if (tmp == NULL) {
   6791 		    tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
   6792 		    if (tmp == NULL) {
   6793 			xmlFree(nsItem);
   6794 			return (-1);
   6795 		    }
   6796 		    tmp->value = dictnsItem;
   6797 		    tmp->next = NULL;
   6798 		    if (wildc->nsSet == NULL)
   6799 			wildc->nsSet = tmp;
   6800 		    else if (lastNs != NULL)
   6801 			lastNs->next = tmp;
   6802 		    lastNs = tmp;
   6803 		}
   6804 
   6805 	    }
   6806 	    xmlFree(nsItem);
   6807 	    cur = end;
   6808 	} while (*cur != 0);
   6809     }
   6810     return (ret);
   6811 }
   6812 
   6813 static int
   6814 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
   6815 				 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
   6816 				 xmlNodePtr node,
   6817 				 int minOccurs,
   6818 				 int maxOccurs) {
   6819 
   6820     if ((maxOccurs == 0) && ( minOccurs == 0))
   6821 	return (0);
   6822     if (maxOccurs != UNBOUNDED) {
   6823 	/*
   6824 	* TODO: Maybe we should better not create the particle,
   6825 	* if min/max is invalid, since it could confuse the build of the
   6826 	* content model.
   6827 	*/
   6828 	/*
   6829 	* 3.9.6 Schema Component Constraint: Particle Correct
   6830 	*
   6831 	*/
   6832 	if (maxOccurs < 1) {
   6833 	    /*
   6834 	    * 2.2 {max occurs} must be greater than or equal to 1.
   6835 	    */
   6836 	    xmlSchemaPCustomAttrErr(ctxt,
   6837 		XML_SCHEMAP_P_PROPS_CORRECT_2_2,
   6838 		NULL, NULL,
   6839 		xmlSchemaGetPropNode(node, "maxOccurs"),
   6840 		"The value must be greater than or equal to 1");
   6841 	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
   6842 	} else if (minOccurs > maxOccurs) {
   6843 	    /*
   6844 	    * 2.1 {min occurs} must not be greater than {max occurs}.
   6845 	    */
   6846 	    xmlSchemaPCustomAttrErr(ctxt,
   6847 		XML_SCHEMAP_P_PROPS_CORRECT_2_1,
   6848 		NULL, NULL,
   6849 		xmlSchemaGetPropNode(node, "minOccurs"),
   6850 		"The value must not be greater than the value of 'maxOccurs'");
   6851 	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
   6852 	}
   6853     }
   6854     return (0);
   6855 }
   6856 
   6857 /**
   6858  * xmlSchemaParseAny:
   6859  * @ctxt:  a schema validation context
   6860  * @schema:  the schema being built
   6861  * @node:  a subtree containing XML Schema informations
   6862  *
   6863  * Parsea a XML schema <any> element. A particle and wildcard
   6864  * will be created (except if minOccurs==maxOccurs==0, in this case
   6865  * nothing will be created).
   6866  * *WARNING* this interface is highly subject to change
   6867  *
   6868  * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
   6869  */
   6870 static xmlSchemaParticlePtr
   6871 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6872                   xmlNodePtr node)
   6873 {
   6874     xmlSchemaParticlePtr particle;
   6875     xmlNodePtr child = NULL;
   6876     xmlSchemaWildcardPtr wild;
   6877     int min, max;
   6878     xmlAttrPtr attr;
   6879     xmlSchemaAnnotPtr annot = NULL;
   6880 
   6881     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   6882         return (NULL);
   6883     /*
   6884     * Check for illegal attributes.
   6885     */
   6886     attr = node->properties;
   6887     while (attr != NULL) {
   6888 	if (attr->ns == NULL) {
   6889 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   6890 		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
   6891 		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
   6892 	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
   6893 		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
   6894 		xmlSchemaPIllegalAttrErr(ctxt,
   6895 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6896 	    }
   6897 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   6898 	    xmlSchemaPIllegalAttrErr(ctxt,
   6899 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6900 	}
   6901 	attr = attr->next;
   6902     }
   6903     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   6904     /*
   6905     * minOccurs/maxOccurs.
   6906     */
   6907     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
   6908 	"(xs:nonNegativeInteger | unbounded)");
   6909     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
   6910 	"xs:nonNegativeInteger");
   6911     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
   6912     /*
   6913     * Create & parse the wildcard.
   6914     */
   6915     wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
   6916     if (wild == NULL)
   6917 	return (NULL);
   6918     xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
   6919     /*
   6920     * And now for the children...
   6921     */
   6922     child = node->children;
   6923     if (IS_SCHEMA(child, "annotation")) {
   6924         annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   6925         child = child->next;
   6926     }
   6927     if (child != NULL) {
   6928 	xmlSchemaPContentErr(ctxt,
   6929 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   6930 	    NULL, node, child,
   6931 	    NULL, "(annotation?)");
   6932     }
   6933     /*
   6934     * No component if minOccurs==maxOccurs==0.
   6935     */
   6936     if ((min == 0) && (max == 0)) {
   6937 	/* Don't free the wildcard, since it's already on the list. */
   6938 	return (NULL);
   6939     }
   6940     /*
   6941     * Create the particle.
   6942     */
   6943     particle = xmlSchemaAddParticle(ctxt, node, min, max);
   6944     if (particle == NULL)
   6945         return (NULL);
   6946     particle->annot = annot;
   6947     particle->children = (xmlSchemaTreeItemPtr) wild;
   6948 
   6949     return (particle);
   6950 }
   6951 
   6952 /**
   6953  * xmlSchemaParseNotation:
   6954  * @ctxt:  a schema validation context
   6955  * @schema:  the schema being built
   6956  * @node:  a subtree containing XML Schema informations
   6957  *
   6958  * parse a XML schema Notation declaration
   6959  *
   6960  * Returns the new structure or NULL in case of error
   6961  */
   6962 static xmlSchemaNotationPtr
   6963 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6964                        xmlNodePtr node)
   6965 {
   6966     const xmlChar *name;
   6967     xmlSchemaNotationPtr ret;
   6968     xmlNodePtr child = NULL;
   6969 
   6970     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   6971         return (NULL);
   6972     name = xmlSchemaGetProp(ctxt, node, "name");
   6973     if (name == NULL) {
   6974         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
   6975                        "Notation has no name\n", NULL, NULL);
   6976         return (NULL);
   6977     }
   6978     ret = xmlSchemaAddNotation(ctxt, schema, name,
   6979 	ctxt->targetNamespace, node);
   6980     if (ret == NULL)
   6981         return (NULL);
   6982     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   6983 
   6984     child = node->children;
   6985     if (IS_SCHEMA(child, "annotation")) {
   6986         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   6987         child = child->next;
   6988     }
   6989     if (child != NULL) {
   6990 	xmlSchemaPContentErr(ctxt,
   6991 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   6992 	    NULL, node, child,
   6993 	    NULL, "(annotation?)");
   6994     }
   6995 
   6996     return (ret);
   6997 }
   6998 
   6999 /**
   7000  * xmlSchemaParseAnyAttribute:
   7001  * @ctxt:  a schema validation context
   7002  * @schema:  the schema being built
   7003  * @node:  a subtree containing XML Schema informations
   7004  *
   7005  * parse a XML schema AnyAttrribute declaration
   7006  * *WARNING* this interface is highly subject to change
   7007  *
   7008  * Returns a wildcard or NULL.
   7009  */
   7010 static xmlSchemaWildcardPtr
   7011 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
   7012                            xmlSchemaPtr schema, xmlNodePtr node)
   7013 {
   7014     xmlSchemaWildcardPtr ret;
   7015     xmlNodePtr child = NULL;
   7016     xmlAttrPtr attr;
   7017 
   7018     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   7019         return (NULL);
   7020 
   7021     ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
   7022 	node);
   7023     if (ret == NULL) {
   7024         return (NULL);
   7025     }
   7026     /*
   7027     * Check for illegal attributes.
   7028     */
   7029     attr = node->properties;
   7030     while (attr != NULL) {
   7031 	if (attr->ns == NULL) {
   7032 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   7033 	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
   7034 		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
   7035 		xmlSchemaPIllegalAttrErr(ctxt,
   7036 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7037 	    }
   7038 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7039 	    xmlSchemaPIllegalAttrErr(ctxt,
   7040 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7041 	}
   7042 	attr = attr->next;
   7043     }
   7044     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   7045     /*
   7046     * Parse the namespace list.
   7047     */
   7048     if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
   7049 	return (NULL);
   7050     /*
   7051     * And now for the children...
   7052     */
   7053     child = node->children;
   7054     if (IS_SCHEMA(child, "annotation")) {
   7055         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   7056         child = child->next;
   7057     }
   7058     if (child != NULL) {
   7059 	xmlSchemaPContentErr(ctxt,
   7060 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7061 	    NULL, node, child,
   7062 	    NULL, "(annotation?)");
   7063     }
   7064 
   7065     return (ret);
   7066 }
   7067 
   7068 
   7069 /**
   7070  * xmlSchemaParseAttribute:
   7071  * @ctxt:  a schema validation context
   7072  * @schema:  the schema being built
   7073  * @node:  a subtree containing XML Schema informations
   7074  *
   7075  * parse a XML schema Attrribute declaration
   7076  * *WARNING* this interface is highly subject to change
   7077  *
   7078  * Returns the attribute declaration.
   7079  */
   7080 static xmlSchemaBasicItemPtr
   7081 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
   7082 			     xmlSchemaPtr schema,
   7083 			     xmlNodePtr node,
   7084 			     xmlSchemaItemListPtr uses,
   7085 			     int parentType)
   7086 {
   7087     const xmlChar *attrValue, *name = NULL, *ns = NULL;
   7088     xmlSchemaAttributeUsePtr use = NULL;
   7089     xmlNodePtr child = NULL;
   7090     xmlAttrPtr attr;
   7091     const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
   7092     int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
   7093     int	nberrors, hasForm = 0, defValueType = 0;
   7094 
   7095 #define WXS_ATTR_DEF_VAL_DEFAULT 1
   7096 #define WXS_ATTR_DEF_VAL_FIXED 2
   7097 
   7098     /*
   7099      * 3.2.3 Constraints on XML Representations of Attribute Declarations
   7100      */
   7101 
   7102     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7103         return (NULL);
   7104     attr = xmlSchemaGetPropNode(node, "ref");
   7105     if (attr != NULL) {
   7106 	if (xmlSchemaPValAttrNodeQName(pctxt, schema,
   7107 	    NULL, attr, &tmpNs, &tmpName) != 0) {
   7108 	    return (NULL);
   7109 	}
   7110 	if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
   7111 	    return(NULL);
   7112 	isRef = 1;
   7113     }
   7114     nberrors = pctxt->nberrors;
   7115     /*
   7116     * Check for illegal attributes.
   7117     */
   7118     attr = node->properties;
   7119     while (attr != NULL) {
   7120 	if (attr->ns == NULL) {
   7121 	    if (isRef) {
   7122 		if (xmlStrEqual(attr->name, BAD_CAST "id")) {
   7123 		    xmlSchemaPValAttrNodeID(pctxt, attr);
   7124 		    goto attr_next;
   7125 		} else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
   7126 		    goto attr_next;
   7127 		}
   7128 	    } else {
   7129 		if (xmlStrEqual(attr->name, BAD_CAST "name")) {
   7130 		    goto attr_next;
   7131 		} else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
   7132 		    xmlSchemaPValAttrNodeID(pctxt, attr);
   7133 		    goto attr_next;
   7134 		} else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
   7135 		    xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
   7136 			attr, &tmpNs, &tmpName);
   7137 		    goto attr_next;
   7138 		} else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
   7139 		    /*
   7140 		    * Evaluate the target namespace
   7141 		    */
   7142 		    hasForm = 1;
   7143 		    attrValue = xmlSchemaGetNodeContent(pctxt,
   7144 			(xmlNodePtr) attr);
   7145 		    if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
   7146 			ns = pctxt->targetNamespace;
   7147 		    } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
   7148 		    {
   7149 			xmlSchemaPSimpleTypeErr(pctxt,
   7150 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   7151 			    NULL, (xmlNodePtr) attr,
   7152 			    NULL, "(qualified | unqualified)",
   7153 			    attrValue, NULL, NULL, NULL);
   7154 		    }
   7155 		    goto attr_next;
   7156 		}
   7157 	    }
   7158 	    if (xmlStrEqual(attr->name, BAD_CAST "use")) {
   7159 
   7160 		attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7161 		/* TODO: Maybe we need to normalize the value beforehand. */
   7162 		if (xmlStrEqual(attrValue, BAD_CAST "optional"))
   7163 		    occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
   7164 		else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
   7165 		    occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
   7166 		else if (xmlStrEqual(attrValue, BAD_CAST "required"))
   7167 		    occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
   7168 		else {
   7169 		    xmlSchemaPSimpleTypeErr(pctxt,
   7170 			XML_SCHEMAP_INVALID_ATTR_USE,
   7171 			NULL, (xmlNodePtr) attr,
   7172 			NULL, "(optional | prohibited | required)",
   7173 			attrValue, NULL, NULL, NULL);
   7174 		}
   7175 		goto attr_next;
   7176 	    } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
   7177 		/*
   7178 		* 3.2.3 : 1
   7179 		* default and fixed must not both be present.
   7180 		*/
   7181 		if (defValue) {
   7182 		    xmlSchemaPMutualExclAttrErr(pctxt,
   7183 			XML_SCHEMAP_SRC_ATTRIBUTE_1,
   7184 			NULL, attr, "default", "fixed");
   7185 		} else {
   7186 		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7187 		    defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
   7188 		}
   7189 		goto attr_next;
   7190 	    } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
   7191 		/*
   7192 		* 3.2.3 : 1
   7193 		* default and fixed must not both be present.
   7194 		*/
   7195 		if (defValue) {
   7196 		    xmlSchemaPMutualExclAttrErr(pctxt,
   7197 			XML_SCHEMAP_SRC_ATTRIBUTE_1,
   7198 			NULL, attr, "default", "fixed");
   7199 		} else {
   7200 		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7201 		    defValueType = WXS_ATTR_DEF_VAL_FIXED;
   7202 		}
   7203 		goto attr_next;
   7204 	    }
   7205 	} else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
   7206 	    goto attr_next;
   7207 
   7208 	xmlSchemaPIllegalAttrErr(pctxt,
   7209 	    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7210 
   7211 attr_next:
   7212 	attr = attr->next;
   7213     }
   7214     /*
   7215     * 3.2.3 : 2
   7216     * If default and use are both present, use must have
   7217     * the actual value optional.
   7218     */
   7219     if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
   7220 	(occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
   7221 	xmlSchemaPSimpleTypeErr(pctxt,
   7222 	    XML_SCHEMAP_SRC_ATTRIBUTE_2,
   7223 	    NULL, node, NULL,
   7224 	    "(optional | prohibited | required)", NULL,
   7225 	    "The value of the attribute 'use' must be 'optional' "
   7226 	    "if the attribute 'default' is present",
   7227 	    NULL, NULL);
   7228     }
   7229     /*
   7230     * We want correct attributes.
   7231     */
   7232     if (nberrors != pctxt->nberrors)
   7233 	return(NULL);
   7234     if (! isRef) {
   7235 	xmlSchemaAttributePtr attrDecl;
   7236 
   7237 	/* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
   7238 	if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
   7239 	    ns = pctxt->targetNamespace;
   7240 	/*
   7241 	* 3.2.6 Schema Component Constraint: xsi: Not Allowed
   7242 	* TODO: Move this to the component layer.
   7243 	*/
   7244 	if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
   7245 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   7246 		XML_SCHEMAP_NO_XSI,
   7247 		node, NULL,
   7248 		"The target namespace must not match '%s'",
   7249 		xmlSchemaInstanceNs, NULL);
   7250 	}
   7251 	attr = xmlSchemaGetPropNode(node, "name");
   7252 	if (attr == NULL) {
   7253 	    xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
   7254 		NULL, node, "name", NULL);
   7255 	    return (NULL);
   7256 	}
   7257 	if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
   7258 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   7259 	    return (NULL);
   7260 	}
   7261 	/*
   7262 	* 3.2.6 Schema Component Constraint: xmlns Not Allowed
   7263 	* TODO: Move this to the component layer.
   7264 	*/
   7265 	if (xmlStrEqual(name, BAD_CAST "xmlns")) {
   7266 	    xmlSchemaPSimpleTypeErr(pctxt,
   7267 		XML_SCHEMAP_NO_XMLNS,
   7268 		NULL, (xmlNodePtr) attr,
   7269 		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
   7270 		"The value of the attribute must not match 'xmlns'",
   7271 		NULL, NULL);
   7272 	    return (NULL);
   7273 	}
   7274 	if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
   7275 	    goto check_children;
   7276 	/*
   7277 	* Create the attribute use component.
   7278 	*/
   7279 	use = xmlSchemaAddAttributeUse(pctxt, node);
   7280 	if (use == NULL)
   7281 	    return(NULL);
   7282 	use->occurs = occurs;
   7283 	/*
   7284 	* Create the attribute declaration.
   7285 	*/
   7286 	attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
   7287 	if (attrDecl == NULL)
   7288 	    return (NULL);
   7289 	if (tmpName != NULL) {
   7290 	    attrDecl->typeName = tmpName;
   7291 	    attrDecl->typeNs = tmpNs;
   7292 	}
   7293 	use->attrDecl = attrDecl;
   7294 	/*
   7295 	* Value constraint.
   7296 	*/
   7297 	if (defValue != NULL) {
   7298 	    attrDecl->defValue = defValue;
   7299 	    if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
   7300 		attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
   7301 	}
   7302     } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
   7303 	xmlSchemaQNameRefPtr ref;
   7304 
   7305 	/*
   7306 	* Create the attribute use component.
   7307 	*/
   7308 	use = xmlSchemaAddAttributeUse(pctxt, node);
   7309 	if (use == NULL)
   7310 	    return(NULL);
   7311 	/*
   7312 	* We need to resolve the reference at later stage.
   7313 	*/
   7314 	WXS_ADD_PENDING(pctxt, use);
   7315 	use->occurs = occurs;
   7316 	/*
   7317 	* Create a QName reference to the attribute declaration.
   7318 	*/
   7319 	ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
   7320 	    tmpName, tmpNs);
   7321 	if (ref == NULL)
   7322 	    return(NULL);
   7323 	/*
   7324 	* Assign the reference. This will be substituted for the
   7325 	* referenced attribute declaration when the QName is resolved.
   7326 	*/
   7327 	use->attrDecl = WXS_ATTR_CAST ref;
   7328 	/*
   7329 	* Value constraint.
   7330 	*/
   7331 	if (defValue != NULL)
   7332 	    use->defValue = defValue;
   7333 	    if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
   7334 		use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
   7335     }
   7336 
   7337 check_children:
   7338     /*
   7339     * And now for the children...
   7340     */
   7341     child = node->children;
   7342     if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
   7343 	xmlSchemaAttributeUseProhibPtr prohib;
   7344 
   7345 	if (IS_SCHEMA(child, "annotation")) {
   7346 	    xmlSchemaParseAnnotation(pctxt, child, 0);
   7347 	    child = child->next;
   7348 	}
   7349 	if (child != NULL) {
   7350 	    xmlSchemaPContentErr(pctxt,
   7351 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7352 		NULL, node, child, NULL,
   7353 		"(annotation?)");
   7354 	}
   7355 	/*
   7356 	* Check for pointlessness of attribute prohibitions.
   7357 	*/
   7358 	if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
   7359 	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   7360 		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   7361 		node, NULL,
   7362 		"Skipping attribute use prohibition, since it is "
   7363 		"pointless inside an <attributeGroup>",
   7364 		NULL, NULL, NULL);
   7365 	    return(NULL);
   7366 	} else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
   7367 	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   7368 		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   7369 		node, NULL,
   7370 		"Skipping attribute use prohibition, since it is "
   7371 		"pointless when extending a type",
   7372 		NULL, NULL, NULL);
   7373 	    return(NULL);
   7374 	}
   7375 	if (! isRef) {
   7376 	    tmpName = name;
   7377 	    tmpNs = ns;
   7378 	}
   7379 	/*
   7380 	* Check for duplicate attribute prohibitions.
   7381 	*/
   7382 	if (uses) {
   7383 	    int i;
   7384 
   7385 	    for (i = 0; i < uses->nbItems; i++) {
   7386 		use = uses->items[i];
   7387 		if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
   7388 		    (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
   7389 		    (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
   7390 		{
   7391 		    xmlChar *str = NULL;
   7392 
   7393 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   7394 			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   7395 			node, NULL,
   7396 			"Skipping duplicate attribute use prohibition '%s'",
   7397 			xmlSchemaFormatQName(&str, tmpNs, tmpName),
   7398 			NULL, NULL);
   7399 		    FREE_AND_NULL(str)
   7400 		    return(NULL);
   7401 		}
   7402 	    }
   7403 	}
   7404 	/*
   7405 	* Create the attribute prohibition helper component.
   7406 	*/
   7407 	prohib = xmlSchemaAddAttributeUseProhib(pctxt);
   7408 	if (prohib == NULL)
   7409 	    return(NULL);
   7410 	prohib->node = node;
   7411 	prohib->name = tmpName;
   7412 	prohib->targetNamespace = tmpNs;
   7413 	if (isRef) {
   7414 	    /*
   7415 	    * We need at least to resolve to the attribute declaration.
   7416 	    */
   7417 	    WXS_ADD_PENDING(pctxt, prohib);
   7418 	}
   7419 	return(WXS_BASIC_CAST prohib);
   7420     } else {
   7421 	if (IS_SCHEMA(child, "annotation")) {
   7422 	    /*
   7423 	    * TODO: Should this go into the attr decl?
   7424 	    */
   7425 	    use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
   7426 	    child = child->next;
   7427 	}
   7428 	if (isRef) {
   7429 	    if (child != NULL) {
   7430 		if (IS_SCHEMA(child, "simpleType"))
   7431 		    /*
   7432 		    * 3.2.3 : 3.2
   7433 		    * If ref is present, then all of <simpleType>,
   7434 		    * form and type must be absent.
   7435 		    */
   7436 		    xmlSchemaPContentErr(pctxt,
   7437 			XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
   7438 			NULL, node, child, NULL,
   7439 			"(annotation?)");
   7440 		else
   7441 		    xmlSchemaPContentErr(pctxt,
   7442 			XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7443 			NULL, node, child, NULL,
   7444 			"(annotation?)");
   7445 	    }
   7446 	} else {
   7447 	    if (IS_SCHEMA(child, "simpleType")) {
   7448 		if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
   7449 		    /*
   7450 		    * 3.2.3 : 4
   7451 		    * type and <simpleType> must not both be present.
   7452 		    */
   7453 		    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
   7454 			NULL, node, child,
   7455 			"The attribute 'type' and the <simpleType> child "
   7456 			"are mutually exclusive", NULL);
   7457 		} else
   7458 		    WXS_ATTRUSE_TYPEDEF(use) =
   7459 			xmlSchemaParseSimpleType(pctxt, schema, child, 0);
   7460 		child = child->next;
   7461 	    }
   7462 	    if (child != NULL)
   7463 		xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7464 		NULL, node, child, NULL,
   7465 		"(annotation?, simpleType?)");
   7466 	}
   7467     }
   7468     return (WXS_BASIC_CAST use);
   7469 }
   7470 
   7471 
   7472 static xmlSchemaAttributePtr
   7473 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
   7474 			      xmlSchemaPtr schema,
   7475 			      xmlNodePtr node)
   7476 {
   7477     const xmlChar *attrValue;
   7478     xmlSchemaAttributePtr ret;
   7479     xmlNodePtr child = NULL;
   7480     xmlAttrPtr attr;
   7481 
   7482     /*
   7483      * Note that the w3c spec assumes the schema to be validated with schema
   7484      * for schemas beforehand.
   7485      *
   7486      * 3.2.3 Constraints on XML Representations of Attribute Declarations
   7487      */
   7488     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7489         return (NULL);
   7490     /*
   7491     * 3.2.3 : 3.1
   7492     * One of ref or name must be present, but not both
   7493     */
   7494     attr = xmlSchemaGetPropNode(node, "name");
   7495     if (attr == NULL) {
   7496 	xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
   7497 	    NULL, node, "name", NULL);
   7498 	return (NULL);
   7499     }
   7500     if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
   7501 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
   7502 	return (NULL);
   7503     }
   7504     /*
   7505     * 3.2.6 Schema Component Constraint: xmlns Not Allowed
   7506     * TODO: Move this to the component layer.
   7507     */
   7508     if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
   7509 	xmlSchemaPSimpleTypeErr(pctxt,
   7510 	    XML_SCHEMAP_NO_XMLNS,
   7511 	    NULL, (xmlNodePtr) attr,
   7512 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
   7513 	    "The value of the attribute must not match 'xmlns'",
   7514 	    NULL, NULL);
   7515 	return (NULL);
   7516     }
   7517     /*
   7518     * 3.2.6 Schema Component Constraint: xsi: Not Allowed
   7519     * TODO: Move this to the component layer.
   7520     *       Or better leave it here and add it to the component layer
   7521     *       if we have a schema construction API.
   7522     */
   7523     if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
   7524 	xmlSchemaCustomErr(ACTXT_CAST pctxt,
   7525 	    XML_SCHEMAP_NO_XSI, node, NULL,
   7526 	    "The target namespace must not match '%s'",
   7527 	    xmlSchemaInstanceNs, NULL);
   7528     }
   7529 
   7530     ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
   7531 	pctxt->targetNamespace, node, 1);
   7532     if (ret == NULL)
   7533 	return (NULL);
   7534     ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
   7535 
   7536     /*
   7537     * Check for illegal attributes.
   7538     */
   7539     attr = node->properties;
   7540     while (attr != NULL) {
   7541 	if (attr->ns == NULL) {
   7542 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   7543 		(!xmlStrEqual(attr->name, BAD_CAST "default")) &&
   7544 		(!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
   7545 		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   7546 		(!xmlStrEqual(attr->name, BAD_CAST "type")))
   7547 	    {
   7548 		xmlSchemaPIllegalAttrErr(pctxt,
   7549 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7550 	    }
   7551 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7552 	    xmlSchemaPIllegalAttrErr(pctxt,
   7553 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7554 	}
   7555 	attr = attr->next;
   7556     }
   7557     xmlSchemaPValAttrQName(pctxt, schema, NULL,
   7558 	node, "type", &ret->typeNs, &ret->typeName);
   7559 
   7560     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   7561     /*
   7562     * Attribute "fixed".
   7563     */
   7564     ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
   7565     if (ret->defValue != NULL)
   7566 	ret->flags |= XML_SCHEMAS_ATTR_FIXED;
   7567     /*
   7568     * Attribute "default".
   7569     */
   7570     attr = xmlSchemaGetPropNode(node, "default");
   7571     if (attr != NULL) {
   7572 	/*
   7573 	* 3.2.3 : 1
   7574 	* default and fixed must not both be present.
   7575 	*/
   7576 	if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
   7577 	    xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
   7578 		WXS_BASIC_CAST ret, attr, "default", "fixed");
   7579 	} else
   7580 	    ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7581     }
   7582     /*
   7583     * And now for the children...
   7584     */
   7585     child = node->children;
   7586     if (IS_SCHEMA(child, "annotation")) {
   7587         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
   7588         child = child->next;
   7589     }
   7590     if (IS_SCHEMA(child, "simpleType")) {
   7591 	if (ret->typeName != NULL) {
   7592 	    /*
   7593 	    * 3.2.3 : 4
   7594 	    * type and <simpleType> must not both be present.
   7595 	    */
   7596 	    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
   7597 		NULL, node, child,
   7598 		"The attribute 'type' and the <simpleType> child "
   7599 		"are mutually exclusive", NULL);
   7600 	} else
   7601 	    ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
   7602 	child = child->next;
   7603     }
   7604     if (child != NULL)
   7605 	xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7606 	    NULL, node, child, NULL,
   7607 	    "(annotation?, simpleType?)");
   7608 
   7609     return (ret);
   7610 }
   7611 
   7612 /**
   7613  * xmlSchemaParseAttributeGroupRef:
   7614  * @ctxt:  a schema validation context
   7615  * @schema:  the schema being built
   7616  * @node:  a subtree containing XML Schema informations
   7617  *
   7618  * Parse an attribute group definition reference.
   7619  * Note that a reference to an attribute group does not
   7620  * correspond to any component at all.
   7621  * *WARNING* this interface is highly subject to change
   7622  *
   7623  * Returns the attribute group or NULL in case of error.
   7624  */
   7625 static xmlSchemaQNameRefPtr
   7626 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
   7627 				xmlSchemaPtr schema,
   7628 				xmlNodePtr node)
   7629 {
   7630     xmlSchemaQNameRefPtr ret;
   7631     xmlNodePtr child = NULL;
   7632     xmlAttrPtr attr;
   7633     const xmlChar *refNs = NULL, *ref = NULL;
   7634 
   7635     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7636         return (NULL);
   7637 
   7638     attr = xmlSchemaGetPropNode(node, "ref");
   7639     if (attr == NULL) {
   7640 	xmlSchemaPMissingAttrErr(pctxt,
   7641 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   7642 	    NULL, node, "ref", NULL);
   7643 	return (NULL);
   7644     }
   7645     xmlSchemaPValAttrNodeQName(pctxt, schema,
   7646 	NULL, attr, &refNs, &ref);
   7647     if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
   7648 	return(NULL);
   7649 
   7650     /*
   7651     * Check for illegal attributes.
   7652     */
   7653     attr = node->properties;
   7654     while (attr != NULL) {
   7655 	if (attr->ns == NULL) {
   7656 	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
   7657 		(!xmlStrEqual(attr->name, BAD_CAST "id")))
   7658 	    {
   7659 		xmlSchemaPIllegalAttrErr(pctxt,
   7660 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7661 	    }
   7662 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7663 	    xmlSchemaPIllegalAttrErr(pctxt,
   7664 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7665 	}
   7666 	attr = attr->next;
   7667     }
   7668     /* Attribute ID */
   7669     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   7670 
   7671     /*
   7672     * And now for the children...
   7673     */
   7674     child = node->children;
   7675     if (IS_SCHEMA(child, "annotation")) {
   7676 	/*
   7677 	* TODO: We do not have a place to store the annotation, do we?
   7678 	*/
   7679         xmlSchemaParseAnnotation(pctxt, child, 0);
   7680         child = child->next;
   7681     }
   7682     if (child != NULL) {
   7683 	xmlSchemaPContentErr(pctxt,
   7684 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7685 	    NULL, node, child, NULL,
   7686 	    "(annotation?)");
   7687     }
   7688 
   7689     /*
   7690     * Handle attribute group redefinitions.
   7691     */
   7692     if (pctxt->isRedefine && pctxt->redef &&
   7693 	(pctxt->redef->item->type ==
   7694 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
   7695 	(ref == pctxt->redef->refName) &&
   7696 	(refNs == pctxt->redef->refTargetNs))
   7697     {
   7698 	/*
   7699 	* SPEC src-redefine:
   7700 	* (7.1) "If it has an <attributeGroup> among its contents
   7701 	* the actual value of whose ref [attribute] is the same
   7702 	* as the actual value of its own name attribute plus
   7703 	* target namespace, then it must have exactly one such group."
   7704 	*/
   7705 	if (pctxt->redefCounter != 0) {
   7706 	    xmlChar *str = NULL;
   7707 
   7708 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   7709 		XML_SCHEMAP_SRC_REDEFINE, node, NULL,
   7710 		"The redefining attribute group definition "
   7711 		"'%s' must not contain more than one "
   7712 		"reference to the redefined definition",
   7713 		xmlSchemaFormatQName(&str, refNs, ref), NULL);
   7714 	    FREE_AND_NULL(str);
   7715 	    return(NULL);
   7716 	}
   7717 	pctxt->redefCounter++;
   7718 	/*
   7719 	* URGENT TODO: How to ensure that the reference will not be
   7720 	* handled by the normal component resolution mechanism?
   7721 	*/
   7722 	ret = xmlSchemaNewQNameRef(pctxt,
   7723 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
   7724 	if (ret == NULL)
   7725 	    return(NULL);
   7726 	ret->node = node;
   7727 	pctxt->redef->reference = WXS_BASIC_CAST ret;
   7728     } else {
   7729 	/*
   7730 	* Create a QName-reference helper component. We will substitute this
   7731 	* component for the attribute uses of the referenced attribute group
   7732 	* definition.
   7733 	*/
   7734 	ret = xmlSchemaNewQNameRef(pctxt,
   7735 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
   7736 	if (ret == NULL)
   7737 	    return(NULL);
   7738 	ret->node = node;
   7739 	/* Add to pending items, to be able to resolve the reference. */
   7740 	WXS_ADD_PENDING(pctxt, ret);
   7741     }
   7742     return (ret);
   7743 }
   7744 
   7745 /**
   7746  * xmlSchemaParseAttributeGroupDefinition:
   7747  * @pctxt:  a schema validation context
   7748  * @schema:  the schema being built
   7749  * @node:  a subtree containing XML Schema informations
   7750  *
   7751  * parse a XML schema Attribute Group declaration
   7752  * *WARNING* this interface is highly subject to change
   7753  *
   7754  * Returns the attribute group definition or NULL in case of error.
   7755  */
   7756 static xmlSchemaAttributeGroupPtr
   7757 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
   7758 				       xmlSchemaPtr schema,
   7759 				       xmlNodePtr node)
   7760 {
   7761     const xmlChar *name;
   7762     xmlSchemaAttributeGroupPtr ret;
   7763     xmlNodePtr child = NULL;
   7764     xmlAttrPtr attr;
   7765     int hasRefs = 0;
   7766 
   7767     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7768         return (NULL);
   7769 
   7770     attr = xmlSchemaGetPropNode(node, "name");
   7771     if (attr == NULL) {
   7772 	xmlSchemaPMissingAttrErr(pctxt,
   7773 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   7774 	    NULL, node, "name", NULL);
   7775 	return (NULL);
   7776     }
   7777     /*
   7778     * The name is crucial, exit if invalid.
   7779     */
   7780     if (xmlSchemaPValAttrNode(pctxt,
   7781 	NULL, attr,
   7782 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   7783 	return (NULL);
   7784     }
   7785     ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
   7786 	name, pctxt->targetNamespace, node);
   7787     if (ret == NULL)
   7788 	return (NULL);
   7789     /*
   7790     * Check for illegal attributes.
   7791     */
   7792     attr = node->properties;
   7793     while (attr != NULL) {
   7794 	if (attr->ns == NULL) {
   7795 	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   7796 		(!xmlStrEqual(attr->name, BAD_CAST "id")))
   7797 	    {
   7798 		xmlSchemaPIllegalAttrErr(pctxt,
   7799 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7800 	    }
   7801 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7802 	    xmlSchemaPIllegalAttrErr(pctxt,
   7803 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7804 	}
   7805 	attr = attr->next;
   7806     }
   7807     /* Attribute ID */
   7808     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   7809     /*
   7810     * And now for the children...
   7811     */
   7812     child = node->children;
   7813     if (IS_SCHEMA(child, "annotation")) {
   7814         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
   7815         child = child->next;
   7816     }
   7817     /*
   7818     * Parse contained attribute decls/refs.
   7819     */
   7820     if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
   7821 	(xmlSchemaItemListPtr *) &(ret->attrUses),
   7822 	XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
   7823 	return(NULL);
   7824     if (hasRefs)
   7825 	ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
   7826     /*
   7827     * Parse the attribute wildcard.
   7828     */
   7829     if (IS_SCHEMA(child, "anyAttribute")) {
   7830 	ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
   7831 	    schema, child);
   7832 	child = child->next;
   7833     }
   7834     if (child != NULL) {
   7835 	xmlSchemaPContentErr(pctxt,
   7836 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7837 	    NULL, node, child, NULL,
   7838 	    "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
   7839     }
   7840     return (ret);
   7841 }
   7842 
   7843 /**
   7844  * xmlSchemaPValAttrFormDefault:
   7845  * @value:  the value
   7846  * @flags: the flags to be modified
   7847  * @flagQualified: the specific flag for "qualified"
   7848  *
   7849  * Returns 0 if the value is valid, 1 otherwise.
   7850  */
   7851 static int
   7852 xmlSchemaPValAttrFormDefault(const xmlChar *value,
   7853 			     int *flags,
   7854 			     int flagQualified)
   7855 {
   7856     if (xmlStrEqual(value, BAD_CAST "qualified")) {
   7857 	if  ((*flags & flagQualified) == 0)
   7858 	    *flags |= flagQualified;
   7859     } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
   7860 	return (1);
   7861 
   7862     return (0);
   7863 }
   7864 
   7865 /**
   7866  * xmlSchemaPValAttrBlockFinal:
   7867  * @value:  the value
   7868  * @flags: the flags to be modified
   7869  * @flagAll: the specific flag for "#all"
   7870  * @flagExtension: the specific flag for "extension"
   7871  * @flagRestriction: the specific flag for "restriction"
   7872  * @flagSubstitution: the specific flag for "substitution"
   7873  * @flagList: the specific flag for "list"
   7874  * @flagUnion: the specific flag for "union"
   7875  *
   7876  * Validates the value of the attribute "final" and "block". The value
   7877  * is converted into the specified flag values and returned in @flags.
   7878  *
   7879  * Returns 0 if the value is valid, 1 otherwise.
   7880  */
   7881 
   7882 static int
   7883 xmlSchemaPValAttrBlockFinal(const xmlChar *value,
   7884 			    int *flags,
   7885 			    int flagAll,
   7886 			    int flagExtension,
   7887 			    int flagRestriction,
   7888 			    int flagSubstitution,
   7889 			    int flagList,
   7890 			    int flagUnion)
   7891 {
   7892     int ret = 0;
   7893 
   7894     /*
   7895     * TODO: This does not check for dublicate entries.
   7896     */
   7897     if ((flags == NULL) || (value == NULL))
   7898 	return (-1);
   7899     if (value[0] == 0)
   7900 	return (0);
   7901     if (xmlStrEqual(value, BAD_CAST "#all")) {
   7902 	if (flagAll != -1)
   7903 	    *flags |= flagAll;
   7904 	else {
   7905 	    if (flagExtension != -1)
   7906 		*flags |= flagExtension;
   7907 	    if (flagRestriction != -1)
   7908 		*flags |= flagRestriction;
   7909 	    if (flagSubstitution != -1)
   7910 		*flags |= flagSubstitution;
   7911 	    if (flagList != -1)
   7912 		*flags |= flagList;
   7913 	    if (flagUnion != -1)
   7914 		*flags |= flagUnion;
   7915 	}
   7916     } else {
   7917 	const xmlChar *end, *cur = value;
   7918 	xmlChar *item;
   7919 
   7920 	do {
   7921 	    while (IS_BLANK_CH(*cur))
   7922 		cur++;
   7923 	    end = cur;
   7924 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   7925 		end++;
   7926 	    if (end == cur)
   7927 		break;
   7928 	    item = xmlStrndup(cur, end - cur);
   7929 	    if (xmlStrEqual(item, BAD_CAST "extension")) {
   7930 		if (flagExtension != -1) {
   7931 		    if ((*flags & flagExtension) == 0)
   7932 			*flags |= flagExtension;
   7933 		} else
   7934 		    ret = 1;
   7935 	    } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
   7936 		if (flagRestriction != -1) {
   7937 		    if ((*flags & flagRestriction) == 0)
   7938 			*flags |= flagRestriction;
   7939 		} else
   7940 		    ret = 1;
   7941 	    } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
   7942 		if (flagSubstitution != -1) {
   7943 		    if ((*flags & flagSubstitution) == 0)
   7944 			*flags |= flagSubstitution;
   7945 		} else
   7946 		    ret = 1;
   7947 	    } else if (xmlStrEqual(item, BAD_CAST "list")) {
   7948 		if (flagList != -1) {
   7949 		    if ((*flags & flagList) == 0)
   7950 			*flags |= flagList;
   7951 		} else
   7952 		    ret = 1;
   7953 	    } else if (xmlStrEqual(item, BAD_CAST "union")) {
   7954 		if (flagUnion != -1) {
   7955 		    if ((*flags & flagUnion) == 0)
   7956 			*flags |= flagUnion;
   7957 		} else
   7958 		    ret = 1;
   7959 	    } else
   7960 		ret = 1;
   7961 	    if (item != NULL)
   7962 		xmlFree(item);
   7963 	    cur = end;
   7964 	} while ((ret == 0) && (*cur != 0));
   7965     }
   7966 
   7967     return (ret);
   7968 }
   7969 
   7970 static int
   7971 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
   7972 			     xmlSchemaIDCPtr idc,
   7973 			     xmlSchemaIDCSelectPtr selector,
   7974 			     xmlAttrPtr attr,
   7975 			     int isField)
   7976 {
   7977     xmlNodePtr node;
   7978 
   7979     /*
   7980     * c-selector-xpath:
   7981     * Schema Component Constraint: Selector Value OK
   7982     *
   7983     * TODO: 1 The {selector} must be a valid XPath expression, as defined
   7984     * in [XPath].
   7985     */
   7986     if (selector == NULL) {
   7987 	xmlSchemaPErr(ctxt, idc->node,
   7988 	    XML_SCHEMAP_INTERNAL,
   7989 	    "Internal error: xmlSchemaCheckCSelectorXPath, "
   7990 	    "the selector is not specified.\n", NULL, NULL);
   7991 	return (-1);
   7992     }
   7993     if (attr == NULL)
   7994 	node = idc->node;
   7995     else
   7996 	node = (xmlNodePtr) attr;
   7997     if (selector->xpath == NULL) {
   7998 	xmlSchemaPCustomErr(ctxt,
   7999 	    /* TODO: Adjust error code. */
   8000 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8001 	    NULL, node,
   8002 	    "The XPath expression of the selector is not valid", NULL);
   8003 	return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
   8004     } else {
   8005 	const xmlChar **nsArray = NULL;
   8006 	xmlNsPtr *nsList = NULL;
   8007 	/*
   8008 	* Compile the XPath expression.
   8009 	*/
   8010 	/*
   8011 	* TODO: We need the array of in-scope namespaces for compilation.
   8012 	* TODO: Call xmlPatterncompile with different options for selector/
   8013 	* field.
   8014 	*/
   8015 	if (attr == NULL)
   8016 	    nsList = NULL;
   8017 	else
   8018 	    nsList = xmlGetNsList(attr->doc, attr->parent);
   8019 	/*
   8020 	* Build an array of prefixes and namespaces.
   8021 	*/
   8022 	if (nsList != NULL) {
   8023 	    int i, count = 0;
   8024 
   8025 	    for (i = 0; nsList[i] != NULL; i++)
   8026 		count++;
   8027 
   8028 	    nsArray = (const xmlChar **) xmlMalloc(
   8029 		(count * 2 + 1) * sizeof(const xmlChar *));
   8030 	    if (nsArray == NULL) {
   8031 		xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
   8032 		    NULL);
   8033 		xmlFree(nsList);
   8034 		return (-1);
   8035 	    }
   8036 	    for (i = 0; i < count; i++) {
   8037 		nsArray[2 * i] = nsList[i]->href;
   8038 		nsArray[2 * i + 1] = nsList[i]->prefix;
   8039 	    }
   8040 	    nsArray[count * 2] = NULL;
   8041 	    xmlFree(nsList);
   8042 	}
   8043 	/*
   8044 	* TODO: Differentiate between "selector" and "field".
   8045 	*/
   8046 	if (isField)
   8047 	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
   8048 		NULL, XML_PATTERN_XSFIELD, nsArray);
   8049 	else
   8050 	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
   8051 		NULL, XML_PATTERN_XSSEL, nsArray);
   8052 	if (nsArray != NULL)
   8053 	    xmlFree((xmlChar **) nsArray);
   8054 
   8055 	if (selector->xpathComp == NULL) {
   8056 	    xmlSchemaPCustomErr(ctxt,
   8057 		/* TODO: Adjust error code? */
   8058 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8059 		NULL, node,
   8060 		"The XPath expression '%s' could not be "
   8061 		"compiled", selector->xpath);
   8062 	    return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
   8063 	}
   8064     }
   8065     return (0);
   8066 }
   8067 
   8068 #define ADD_ANNOTATION(annot)   \
   8069     xmlSchemaAnnotPtr cur = item->annot; \
   8070     if (item->annot == NULL) {  \
   8071 	item->annot = annot;    \
   8072 	return (annot);         \
   8073     }                           \
   8074     cur = item->annot;          \
   8075     if (cur->next != NULL) {    \
   8076 	cur = cur->next;	\
   8077     }                           \
   8078     cur->next = annot;
   8079 
   8080 /**
   8081  * xmlSchemaAssignAnnotation:
   8082  * @item: the schema component
   8083  * @annot: the annotation
   8084  *
   8085  * Adds the annotation to the given schema component.
   8086  *
   8087  * Returns the given annotaion.
   8088  */
   8089 static xmlSchemaAnnotPtr
   8090 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
   8091 		       xmlSchemaAnnotPtr annot)
   8092 {
   8093     if ((annItem == NULL) || (annot == NULL))
   8094 	return (NULL);
   8095     switch (annItem->type) {
   8096 	case XML_SCHEMA_TYPE_ELEMENT: {
   8097 		xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
   8098 		ADD_ANNOTATION(annot)
   8099 	    }
   8100 	    break;
   8101 	case XML_SCHEMA_TYPE_ATTRIBUTE: {
   8102 		xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
   8103 		ADD_ANNOTATION(annot)
   8104 	    }
   8105 	    break;
   8106 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   8107 	case XML_SCHEMA_TYPE_ANY: {
   8108 		xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
   8109 		ADD_ANNOTATION(annot)
   8110 	    }
   8111 	    break;
   8112 	case XML_SCHEMA_TYPE_PARTICLE:
   8113 	case XML_SCHEMA_TYPE_IDC_KEY:
   8114 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   8115 	case XML_SCHEMA_TYPE_IDC_UNIQUE: {
   8116 		xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
   8117 		ADD_ANNOTATION(annot)
   8118 	    }
   8119 	    break;
   8120 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
   8121 		xmlSchemaAttributeGroupPtr item =
   8122 		    (xmlSchemaAttributeGroupPtr) annItem;
   8123 		ADD_ANNOTATION(annot)
   8124 	    }
   8125 	    break;
   8126 	case XML_SCHEMA_TYPE_NOTATION: {
   8127 		xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
   8128 		ADD_ANNOTATION(annot)
   8129 	    }
   8130 	    break;
   8131 	case XML_SCHEMA_FACET_MININCLUSIVE:
   8132 	case XML_SCHEMA_FACET_MINEXCLUSIVE:
   8133 	case XML_SCHEMA_FACET_MAXINCLUSIVE:
   8134 	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   8135 	case XML_SCHEMA_FACET_TOTALDIGITS:
   8136 	case XML_SCHEMA_FACET_FRACTIONDIGITS:
   8137 	case XML_SCHEMA_FACET_PATTERN:
   8138 	case XML_SCHEMA_FACET_ENUMERATION:
   8139 	case XML_SCHEMA_FACET_WHITESPACE:
   8140 	case XML_SCHEMA_FACET_LENGTH:
   8141 	case XML_SCHEMA_FACET_MAXLENGTH:
   8142 	case XML_SCHEMA_FACET_MINLENGTH: {
   8143 		xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
   8144 		ADD_ANNOTATION(annot)
   8145 	    }
   8146 	    break;
   8147 	case XML_SCHEMA_TYPE_SIMPLE:
   8148 	case XML_SCHEMA_TYPE_COMPLEX: {
   8149 		xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
   8150 		ADD_ANNOTATION(annot)
   8151 	    }
   8152 	    break;
   8153 	case XML_SCHEMA_TYPE_GROUP: {
   8154 		xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
   8155 		ADD_ANNOTATION(annot)
   8156 	    }
   8157 	    break;
   8158 	case XML_SCHEMA_TYPE_SEQUENCE:
   8159 	case XML_SCHEMA_TYPE_CHOICE:
   8160 	case XML_SCHEMA_TYPE_ALL: {
   8161 		xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
   8162 		ADD_ANNOTATION(annot)
   8163 	    }
   8164 	    break;
   8165 	default:
   8166 	     xmlSchemaPCustomErr(NULL,
   8167 		XML_SCHEMAP_INTERNAL,
   8168 		NULL, NULL,
   8169 		"Internal error: xmlSchemaAddAnnotation, "
   8170 		"The item is not a annotated schema component", NULL);
   8171 	     break;
   8172     }
   8173     return (annot);
   8174 }
   8175 
   8176 /**
   8177  * xmlSchemaParseIDCSelectorAndField:
   8178  * @ctxt:  a schema validation context
   8179  * @schema:  the schema being built
   8180  * @node:  a subtree containing XML Schema informations
   8181  *
   8182  * Parses a XML Schema identity-contraint definition's
   8183  * <selector> and <field> elements.
   8184  *
   8185  * Returns the parsed identity-constraint definition.
   8186  */
   8187 static xmlSchemaIDCSelectPtr
   8188 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
   8189 			  xmlSchemaIDCPtr idc,
   8190 			  xmlNodePtr node,
   8191 			  int isField)
   8192 {
   8193     xmlSchemaIDCSelectPtr item;
   8194     xmlNodePtr child = NULL;
   8195     xmlAttrPtr attr;
   8196 
   8197     /*
   8198     * Check for illegal attributes.
   8199     */
   8200     attr = node->properties;
   8201     while (attr != NULL) {
   8202 	if (attr->ns == NULL) {
   8203 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8204 		(!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
   8205 		xmlSchemaPIllegalAttrErr(ctxt,
   8206 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8207 	    }
   8208 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8209 	    xmlSchemaPIllegalAttrErr(ctxt,
   8210 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8211 	}
   8212 	attr = attr->next;
   8213     }
   8214     /*
   8215     * Create the item.
   8216     */
   8217     item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
   8218     if (item == NULL) {
   8219         xmlSchemaPErrMemory(ctxt,
   8220 	    "allocating a 'selector' of an identity-constraint definition",
   8221 	    NULL);
   8222         return (NULL);
   8223     }
   8224     memset(item, 0, sizeof(xmlSchemaIDCSelect));
   8225     /*
   8226     * Attribute "xpath" (mandatory).
   8227     */
   8228     attr = xmlSchemaGetPropNode(node, "xpath");
   8229     if (attr == NULL) {
   8230     	xmlSchemaPMissingAttrErr(ctxt,
   8231 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   8232 	    NULL, node,
   8233 	    "name", NULL);
   8234     } else {
   8235 	item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8236 	/*
   8237 	* URGENT TODO: "field"s have an other syntax than "selector"s.
   8238 	*/
   8239 
   8240 	if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
   8241 	    isField) == -1) {
   8242 	    xmlSchemaPErr(ctxt,
   8243 		(xmlNodePtr) attr,
   8244 		XML_SCHEMAP_INTERNAL,
   8245 		"Internal error: xmlSchemaParseIDCSelectorAndField, "
   8246 		"validating the XPath expression of a IDC selector.\n",
   8247 		NULL, NULL);
   8248 	}
   8249 
   8250     }
   8251     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8252     /*
   8253     * And now for the children...
   8254     */
   8255     child = node->children;
   8256     if (IS_SCHEMA(child, "annotation")) {
   8257 	/*
   8258 	* Add the annotation to the parent IDC.
   8259 	*/
   8260 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
   8261 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   8262 	child = child->next;
   8263     }
   8264     if (child != NULL) {
   8265 	xmlSchemaPContentErr(ctxt,
   8266 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8267 	    NULL, node, child,
   8268 	    NULL, "(annotation?)");
   8269     }
   8270 
   8271     return (item);
   8272 }
   8273 
   8274 /**
   8275  * xmlSchemaParseIDC:
   8276  * @ctxt:  a schema validation context
   8277  * @schema:  the schema being built
   8278  * @node:  a subtree containing XML Schema informations
   8279  *
   8280  * Parses a XML Schema identity-contraint definition.
   8281  *
   8282  * Returns the parsed identity-constraint definition.
   8283  */
   8284 static xmlSchemaIDCPtr
   8285 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
   8286 		  xmlSchemaPtr schema,
   8287 		  xmlNodePtr node,
   8288 		  xmlSchemaTypeType idcCategory,
   8289 		  const xmlChar *targetNamespace)
   8290 {
   8291     xmlSchemaIDCPtr item = NULL;
   8292     xmlNodePtr child = NULL;
   8293     xmlAttrPtr attr;
   8294     const xmlChar *name = NULL;
   8295     xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
   8296 
   8297     /*
   8298     * Check for illegal attributes.
   8299     */
   8300     attr = node->properties;
   8301     while (attr != NULL) {
   8302 	if (attr->ns == NULL) {
   8303 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8304 		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   8305 		((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
   8306 		 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
   8307 		xmlSchemaPIllegalAttrErr(ctxt,
   8308 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8309 	    }
   8310 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8311 	    xmlSchemaPIllegalAttrErr(ctxt,
   8312 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8313 	}
   8314 	attr = attr->next;
   8315     }
   8316     /*
   8317     * Attribute "name" (mandatory).
   8318     */
   8319     attr = xmlSchemaGetPropNode(node, "name");
   8320     if (attr == NULL) {
   8321 	xmlSchemaPMissingAttrErr(ctxt,
   8322 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   8323 	    NULL, node,
   8324 	    "name", NULL);
   8325 	return (NULL);
   8326     } else if (xmlSchemaPValAttrNode(ctxt,
   8327 	NULL, attr,
   8328 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   8329 	return (NULL);
   8330     }
   8331     /* Create the component. */
   8332     item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
   8333 	idcCategory, node);
   8334     if (item == NULL)
   8335 	return(NULL);
   8336 
   8337     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8338     if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
   8339 	/*
   8340 	* Attribute "refer" (mandatory).
   8341 	*/
   8342 	attr = xmlSchemaGetPropNode(node, "refer");
   8343 	if (attr == NULL) {
   8344 	    xmlSchemaPMissingAttrErr(ctxt,
   8345 		XML_SCHEMAP_S4S_ATTR_MISSING,
   8346 		NULL, node,
   8347 		"refer", NULL);
   8348 	} else {
   8349 	    /*
   8350 	    * Create a reference item.
   8351 	    */
   8352 	    item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
   8353 		NULL, NULL);
   8354 	    if (item->ref == NULL)
   8355 		return (NULL);
   8356 	    xmlSchemaPValAttrNodeQName(ctxt, schema,
   8357 		NULL, attr,
   8358 		&(item->ref->targetNamespace),
   8359 		&(item->ref->name));
   8360 	    xmlSchemaCheckReference(ctxt, schema, node, attr,
   8361 		item->ref->targetNamespace);
   8362 	}
   8363     }
   8364     /*
   8365     * And now for the children...
   8366     */
   8367     child = node->children;
   8368     if (IS_SCHEMA(child, "annotation")) {
   8369 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   8370 	child = child->next;
   8371     }
   8372     if (child == NULL) {
   8373 	xmlSchemaPContentErr(ctxt,
   8374 		XML_SCHEMAP_S4S_ELEM_MISSING,
   8375 		NULL, node, child,
   8376 		"A child element is missing",
   8377 		"(annotation?, (selector, field+))");
   8378     }
   8379     /*
   8380     * Child element <selector>.
   8381     */
   8382     if (IS_SCHEMA(child, "selector")) {
   8383 	item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
   8384 	    item, child, 0);
   8385 	child = child->next;
   8386 	/*
   8387 	* Child elements <field>.
   8388 	*/
   8389 	if (IS_SCHEMA(child, "field")) {
   8390 	    do {
   8391 		field = xmlSchemaParseIDCSelectorAndField(ctxt,
   8392 		    item, child, 1);
   8393 		if (field != NULL) {
   8394 		    field->index = item->nbFields;
   8395 		    item->nbFields++;
   8396 		    if (lastField != NULL)
   8397 			lastField->next = field;
   8398 		    else
   8399 			item->fields = field;
   8400 		    lastField = field;
   8401 		}
   8402 		child = child->next;
   8403 	    } while (IS_SCHEMA(child, "field"));
   8404 	} else {
   8405 	    xmlSchemaPContentErr(ctxt,
   8406 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8407 		NULL, node, child,
   8408 		NULL, "(annotation?, (selector, field+))");
   8409 	}
   8410     }
   8411     if (child != NULL) {
   8412 	xmlSchemaPContentErr(ctxt,
   8413 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8414 	    NULL, node, child,
   8415 	    NULL, "(annotation?, (selector, field+))");
   8416     }
   8417 
   8418     return (item);
   8419 }
   8420 
   8421 /**
   8422  * xmlSchemaParseElement:
   8423  * @ctxt:  a schema validation context
   8424  * @schema:  the schema being built
   8425  * @node:  a subtree containing XML Schema informations
   8426  * @topLevel: indicates if this is global declaration
   8427  *
   8428  * Parses a XML schema element declaration.
   8429  * *WARNING* this interface is highly subject to change
   8430  *
   8431  * Returns the element declaration or a particle; NULL in case
   8432  * of an error or if the particle has minOccurs==maxOccurs==0.
   8433  */
   8434 static xmlSchemaBasicItemPtr
   8435 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   8436                       xmlNodePtr node, int *isElemRef, int topLevel)
   8437 {
   8438     xmlSchemaElementPtr decl = NULL;
   8439     xmlSchemaParticlePtr particle = NULL;
   8440     xmlSchemaAnnotPtr annot = NULL;
   8441     xmlNodePtr child = NULL;
   8442     xmlAttrPtr attr, nameAttr;
   8443     int min, max, isRef = 0;
   8444     xmlChar *des = NULL;
   8445 
   8446     /* 3.3.3 Constraints on XML Representations of Element Declarations */
   8447     /* TODO: Complete implementation of 3.3.6 */
   8448 
   8449     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   8450         return (NULL);
   8451 
   8452     if (isElemRef != NULL)
   8453 	*isElemRef = 0;
   8454     /*
   8455     * If we get a "ref" attribute on a local <element> we will assume it's
   8456     * a reference - even if there's a "name" attribute; this seems to be more
   8457     * robust.
   8458     */
   8459     nameAttr = xmlSchemaGetPropNode(node, "name");
   8460     attr = xmlSchemaGetPropNode(node, "ref");
   8461     if ((topLevel) || (attr == NULL)) {
   8462 	if (nameAttr == NULL) {
   8463 	    xmlSchemaPMissingAttrErr(ctxt,
   8464 		XML_SCHEMAP_S4S_ATTR_MISSING,
   8465 		NULL, node, "name", NULL);
   8466 	    return (NULL);
   8467 	}
   8468     } else
   8469 	isRef = 1;
   8470 
   8471     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8472     child = node->children;
   8473     if (IS_SCHEMA(child, "annotation")) {
   8474 	annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   8475 	child = child->next;
   8476     }
   8477     /*
   8478     * Skip particle part if a global declaration.
   8479     */
   8480     if (topLevel)
   8481 	goto declaration_part;
   8482     /*
   8483     * The particle part ==================================================
   8484     */
   8485     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
   8486     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
   8487     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
   8488     particle = xmlSchemaAddParticle(ctxt, node, min, max);
   8489     if (particle == NULL)
   8490 	goto return_null;
   8491 
   8492     /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
   8493 
   8494     if (isRef) {
   8495 	const xmlChar *refNs = NULL, *ref = NULL;
   8496 	xmlSchemaQNameRefPtr refer = NULL;
   8497 	/*
   8498 	* The reference part =============================================
   8499 	*/
   8500 	if (isElemRef != NULL)
   8501 	    *isElemRef = 1;
   8502 
   8503 	xmlSchemaPValAttrNodeQName(ctxt, schema,
   8504 	    NULL, attr, &refNs, &ref);
   8505 	xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
   8506 	/*
   8507 	* SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
   8508 	*/
   8509 	if (nameAttr != NULL) {
   8510 	    xmlSchemaPMutualExclAttrErr(ctxt,
   8511 		XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
   8512 	}
   8513 	/*
   8514 	* Check for illegal attributes.
   8515 	*/
   8516 	attr = node->properties;
   8517 	while (attr != NULL) {
   8518 	    if (attr->ns == NULL) {
   8519 		if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
   8520 		    xmlStrEqual(attr->name, BAD_CAST "name") ||
   8521 		    xmlStrEqual(attr->name, BAD_CAST "id") ||
   8522 		    xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
   8523 		    xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
   8524 		{
   8525 		    attr = attr->next;
   8526 		    continue;
   8527 		} else {
   8528 		    /* SPEC (3.3.3 : 2.2) */
   8529 		    xmlSchemaPCustomAttrErr(ctxt,
   8530 			XML_SCHEMAP_SRC_ELEMENT_2_2,
   8531 			NULL, NULL, attr,
   8532 			"Only the attributes 'minOccurs', 'maxOccurs' and "
   8533 			"'id' are allowed in addition to 'ref'");
   8534 		    break;
   8535 		}
   8536 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8537 		xmlSchemaPIllegalAttrErr(ctxt,
   8538 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8539 	    }
   8540 	    attr = attr->next;
   8541 	}
   8542 	/*
   8543 	* No children except <annotation> expected.
   8544 	*/
   8545 	if (child != NULL) {
   8546 	    xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8547 		NULL, node, child, NULL, "(annotation?)");
   8548 	}
   8549 	if ((min == 0) && (max == 0))
   8550 	    goto return_null;
   8551 	/*
   8552 	* Create the reference item and attach it to the particle.
   8553 	*/
   8554 	refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
   8555 	    ref, refNs);
   8556 	if (refer == NULL)
   8557 	    goto return_null;
   8558 	particle->children = (xmlSchemaTreeItemPtr) refer;
   8559 	particle->annot = annot;
   8560 	/*
   8561 	* Add the particle to pending components, since the reference
   8562 	* need to be resolved.
   8563 	*/
   8564 	WXS_ADD_PENDING(ctxt, particle);
   8565 	return ((xmlSchemaBasicItemPtr) particle);
   8566     }
   8567     /*
   8568     * The declaration part ===============================================
   8569     */
   8570 declaration_part:
   8571     {
   8572 	const xmlChar *ns = NULL, *fixed, *name, *attrValue;
   8573 	xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
   8574 
   8575 	if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
   8576 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
   8577 	    goto return_null;
   8578 	/*
   8579 	* Evaluate the target namespace.
   8580 	*/
   8581 	if (topLevel) {
   8582 	    ns = ctxt->targetNamespace;
   8583 	} else {
   8584 	    attr = xmlSchemaGetPropNode(node, "form");
   8585 	    if (attr != NULL) {
   8586 		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8587 		if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
   8588 		    ns = ctxt->targetNamespace;
   8589 		} else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
   8590 		    xmlSchemaPSimpleTypeErr(ctxt,
   8591 			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8592 			NULL, (xmlNodePtr) attr,
   8593 			NULL, "(qualified | unqualified)",
   8594 			attrValue, NULL, NULL, NULL);
   8595 		}
   8596 	    } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
   8597 		ns = ctxt->targetNamespace;
   8598 	}
   8599 	decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
   8600 	if (decl == NULL) {
   8601 	    goto return_null;
   8602 	}
   8603 	/*
   8604 	* Check for illegal attributes.
   8605 	*/
   8606 	attr = node->properties;
   8607 	while (attr != NULL) {
   8608 	    if (attr->ns == NULL) {
   8609 		if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   8610 		    (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
   8611 		    (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8612 		    (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
   8613 		    (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
   8614 		    (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
   8615 		    (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
   8616 		{
   8617 		    if (topLevel == 0) {
   8618 			if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
   8619 			    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
   8620 			    (!xmlStrEqual(attr->name, BAD_CAST "form")))
   8621 			{
   8622 			    xmlSchemaPIllegalAttrErr(ctxt,
   8623 				XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8624 			}
   8625 		    } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
   8626 			(!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
   8627 			(!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
   8628 
   8629 			xmlSchemaPIllegalAttrErr(ctxt,
   8630 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8631 		    }
   8632 		}
   8633 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8634 
   8635 		xmlSchemaPIllegalAttrErr(ctxt,
   8636 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8637 	    }
   8638 	    attr = attr->next;
   8639 	}
   8640 	/*
   8641 	* Extract/validate attributes.
   8642 	*/
   8643 	if (topLevel) {
   8644 	    /*
   8645 	    * Process top attributes of global element declarations here.
   8646 	    */
   8647 	    decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
   8648 	    decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
   8649 	    xmlSchemaPValAttrQName(ctxt, schema,
   8650 		NULL, node, "substitutionGroup",
   8651 		&(decl->substGroupNs), &(decl->substGroup));
   8652 	    if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
   8653 		decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
   8654 	    /*
   8655 	    * Attribute "final".
   8656 	    */
   8657 	    attr = xmlSchemaGetPropNode(node, "final");
   8658 	    if (attr == NULL) {
   8659 		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
   8660 		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
   8661 		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   8662 		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
   8663 	    } else {
   8664 		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8665 		if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
   8666 		    -1,
   8667 		    XML_SCHEMAS_ELEM_FINAL_EXTENSION,
   8668 		    XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
   8669 		    xmlSchemaPSimpleTypeErr(ctxt,
   8670 			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8671 			NULL, (xmlNodePtr) attr,
   8672 			NULL, "(#all | List of (extension | restriction))",
   8673 			attrValue, NULL, NULL, NULL);
   8674 		}
   8675 	    }
   8676 	}
   8677 	/*
   8678 	* Attribute "block".
   8679 	*/
   8680 	attr = xmlSchemaGetPropNode(node, "block");
   8681 	if (attr == NULL) {
   8682 	    /*
   8683 	    * Apply default "block" values.
   8684 	    */
   8685 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
   8686 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
   8687 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
   8688 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
   8689 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
   8690 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
   8691 	} else {
   8692 	    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8693 	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
   8694 		-1,
   8695 		XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
   8696 		XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
   8697 		XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
   8698 		xmlSchemaPSimpleTypeErr(ctxt,
   8699 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8700 		    NULL, (xmlNodePtr) attr,
   8701 		    NULL, "(#all | List of (extension | "
   8702 		    "restriction | substitution))", attrValue,
   8703 		    NULL, NULL, NULL);
   8704 	    }
   8705 	}
   8706 	if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
   8707 	    decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
   8708 
   8709 	attr = xmlSchemaGetPropNode(node, "type");
   8710 	if (attr != NULL) {
   8711 	    xmlSchemaPValAttrNodeQName(ctxt, schema,
   8712 		NULL, attr,
   8713 		&(decl->namedTypeNs), &(decl->namedType));
   8714 	    xmlSchemaCheckReference(ctxt, schema, node,
   8715 		attr, decl->namedTypeNs);
   8716 	}
   8717 	decl->value = xmlSchemaGetProp(ctxt, node, "default");
   8718 	attr = xmlSchemaGetPropNode(node, "fixed");
   8719 	if (attr != NULL) {
   8720 	    fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8721 	    if (decl->value != NULL) {
   8722 		/*
   8723 		* 3.3.3 : 1
   8724 		* default and fixed must not both be present.
   8725 		*/
   8726 		xmlSchemaPMutualExclAttrErr(ctxt,
   8727 		    XML_SCHEMAP_SRC_ELEMENT_1,
   8728 		    NULL, attr, "default", "fixed");
   8729 	    } else {
   8730 		decl->flags |= XML_SCHEMAS_ELEM_FIXED;
   8731 		decl->value = fixed;
   8732 	    }
   8733 	}
   8734 	/*
   8735 	* And now for the children...
   8736 	*/
   8737 	if (IS_SCHEMA(child, "complexType")) {
   8738 	    /*
   8739 	    * 3.3.3 : 3
   8740 	    * "type" and either <simpleType> or <complexType> are mutually
   8741 	    * exclusive
   8742 	    */
   8743 	    if (decl->namedType != NULL) {
   8744 		xmlSchemaPContentErr(ctxt,
   8745 		    XML_SCHEMAP_SRC_ELEMENT_3,
   8746 		    NULL, node, child,
   8747 		    "The attribute 'type' and the <complexType> child are "
   8748 		    "mutually exclusive", NULL);
   8749 	    } else
   8750 		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
   8751 	    child = child->next;
   8752 	} else if (IS_SCHEMA(child, "simpleType")) {
   8753 	    /*
   8754 	    * 3.3.3 : 3
   8755 	    * "type" and either <simpleType> or <complexType> are
   8756 	    * mutually exclusive
   8757 	    */
   8758 	    if (decl->namedType != NULL) {
   8759 		xmlSchemaPContentErr(ctxt,
   8760 		    XML_SCHEMAP_SRC_ELEMENT_3,
   8761 		    NULL, node, child,
   8762 		    "The attribute 'type' and the <simpleType> child are "
   8763 		    "mutually exclusive", NULL);
   8764 	    } else
   8765 		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   8766 	    child = child->next;
   8767 	}
   8768 	while ((IS_SCHEMA(child, "unique")) ||
   8769 	    (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
   8770 	    if (IS_SCHEMA(child, "unique")) {
   8771 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
   8772 		    XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
   8773 	    } else if (IS_SCHEMA(child, "key")) {
   8774 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
   8775 		    XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
   8776 	    } else if (IS_SCHEMA(child, "keyref")) {
   8777 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
   8778 		    XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
   8779 	    }
   8780 	    if (lastIDC != NULL)
   8781 		lastIDC->next = curIDC;
   8782 	    else
   8783 		decl->idcs = (void *) curIDC;
   8784 	    lastIDC = curIDC;
   8785 	    child = child->next;
   8786 	}
   8787 	if (child != NULL) {
   8788 	    xmlSchemaPContentErr(ctxt,
   8789 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8790 		NULL, node, child,
   8791 		NULL, "(annotation?, ((simpleType | complexType)?, "
   8792 		"(unique | key | keyref)*))");
   8793 	}
   8794 	decl->annot = annot;
   8795     }
   8796     /*
   8797     * NOTE: Element Declaration Representation OK 4. will be checked at a
   8798     * different layer.
   8799     */
   8800     FREE_AND_NULL(des)
   8801     if (topLevel)
   8802 	return ((xmlSchemaBasicItemPtr) decl);
   8803     else {
   8804 	particle->children = (xmlSchemaTreeItemPtr) decl;
   8805 	return ((xmlSchemaBasicItemPtr) particle);
   8806     }
   8807 
   8808 return_null:
   8809     FREE_AND_NULL(des);
   8810     if (annot != NULL) {
   8811 	if (particle != NULL)
   8812 	    particle->annot = NULL;
   8813 	if (decl != NULL)
   8814 	    decl->annot = NULL;
   8815 	xmlSchemaFreeAnnot(annot);
   8816     }
   8817     return (NULL);
   8818 }
   8819 
   8820 /**
   8821  * xmlSchemaParseUnion:
   8822  * @ctxt:  a schema validation context
   8823  * @schema:  the schema being built
   8824  * @node:  a subtree containing XML Schema informations
   8825  *
   8826  * parse a XML schema Union definition
   8827  * *WARNING* this interface is highly subject to change
   8828  *
   8829  * Returns -1 in case of internal error, 0 in case of success and a positive
   8830  * error code otherwise.
   8831  */
   8832 static int
   8833 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   8834                     xmlNodePtr node)
   8835 {
   8836     xmlSchemaTypePtr type;
   8837     xmlNodePtr child = NULL;
   8838     xmlAttrPtr attr;
   8839     const xmlChar *cur = NULL;
   8840 
   8841     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   8842         return (-1);
   8843     /* Not a component, don't create it. */
   8844     type = ctxt->ctxtType;
   8845     /*
   8846     * Mark the simple type as being of variety "union".
   8847     */
   8848     type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
   8849     /*
   8850     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
   8851     * then the simple ur-type definition."
   8852     */
   8853     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
   8854     /*
   8855     * Check for illegal attributes.
   8856     */
   8857     attr = node->properties;
   8858     while (attr != NULL) {
   8859 	if (attr->ns == NULL) {
   8860 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8861 		(!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
   8862 		xmlSchemaPIllegalAttrErr(ctxt,
   8863 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8864 	    }
   8865 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8866 	    xmlSchemaPIllegalAttrErr(ctxt,
   8867 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8868 	}
   8869 	attr = attr->next;
   8870     }
   8871     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8872     /*
   8873     * Attribute "memberTypes". This is a list of QNames.
   8874     * TODO: Check the value to contain anything.
   8875     */
   8876     attr = xmlSchemaGetPropNode(node, "memberTypes");
   8877     if (attr != NULL) {
   8878 	const xmlChar *end;
   8879 	xmlChar *tmp;
   8880 	const xmlChar *localName, *nsName;
   8881 	xmlSchemaTypeLinkPtr link, lastLink = NULL;
   8882 	xmlSchemaQNameRefPtr ref;
   8883 
   8884 	cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8885 	type->base = cur;
   8886 	do {
   8887 	    while (IS_BLANK_CH(*cur))
   8888 		cur++;
   8889 	    end = cur;
   8890 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   8891 		end++;
   8892 	    if (end == cur)
   8893 		break;
   8894 	    tmp = xmlStrndup(cur, end - cur);
   8895 	    if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
   8896 		NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
   8897 		/*
   8898 		* Create the member type link.
   8899 		*/
   8900 		link = (xmlSchemaTypeLinkPtr)
   8901 		    xmlMalloc(sizeof(xmlSchemaTypeLink));
   8902 		if (link == NULL) {
   8903 		    xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
   8904 			"allocating a type link", NULL);
   8905 		    return (-1);
   8906 		}
   8907 		link->type = NULL;
   8908 		link->next = NULL;
   8909 		if (lastLink == NULL)
   8910 		    type->memberTypes = link;
   8911 		else
   8912 		    lastLink->next = link;
   8913 		lastLink = link;
   8914 		/*
   8915 		* Create a reference item.
   8916 		*/
   8917 		ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
   8918 		    localName, nsName);
   8919 		if (ref == NULL) {
   8920 		    FREE_AND_NULL(tmp)
   8921 		    return (-1);
   8922 		}
   8923 		/*
   8924 		* Assign the reference to the link, it will be resolved
   8925 		* later during fixup of the union simple type.
   8926 		*/
   8927 		link->type = (xmlSchemaTypePtr) ref;
   8928 	    }
   8929 	    FREE_AND_NULL(tmp)
   8930 	    cur = end;
   8931 	} while (*cur != 0);
   8932 
   8933     }
   8934     /*
   8935     * And now for the children...
   8936     */
   8937     child = node->children;
   8938     if (IS_SCHEMA(child, "annotation")) {
   8939 	/*
   8940 	* Add the annotation to the simple type ancestor.
   8941 	*/
   8942 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   8943 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   8944         child = child->next;
   8945     }
   8946     if (IS_SCHEMA(child, "simpleType")) {
   8947 	xmlSchemaTypePtr subtype, last = NULL;
   8948 
   8949 	/*
   8950 	* Anchor the member types in the "subtypes" field of the
   8951 	* simple type.
   8952 	*/
   8953 	while (IS_SCHEMA(child, "simpleType")) {
   8954 	    subtype = (xmlSchemaTypePtr)
   8955 		xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   8956 	    if (subtype != NULL) {
   8957 		if (last == NULL) {
   8958 		    type->subtypes = subtype;
   8959 		    last = subtype;
   8960 		} else {
   8961 		    last->next = subtype;
   8962 		    last = subtype;
   8963 		}
   8964 		last->next = NULL;
   8965 	    }
   8966 	    child = child->next;
   8967 	}
   8968     }
   8969     if (child != NULL) {
   8970 	xmlSchemaPContentErr(ctxt,
   8971 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8972 	    NULL, node, child, NULL, "(annotation?, simpleType*)");
   8973     }
   8974     if ((attr == NULL) && (type->subtypes == NULL)) {
   8975 	 /*
   8976 	* src-union-memberTypes-or-simpleTypes
   8977 	* Either the memberTypes [attribute] of the <union> element must
   8978 	* be non-empty or there must be at least one simpleType [child].
   8979 	*/
   8980 	xmlSchemaPCustomErr(ctxt,
   8981 	    XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
   8982 	    NULL, node,
   8983 	    "Either the attribute 'memberTypes' or "
   8984 	    "at least one <simpleType> child must be present", NULL);
   8985     }
   8986     return (0);
   8987 }
   8988 
   8989 /**
   8990  * xmlSchemaParseList:
   8991  * @ctxt:  a schema validation context
   8992  * @schema:  the schema being built
   8993  * @node:  a subtree containing XML Schema informations
   8994  *
   8995  * parse a XML schema List definition
   8996  * *WARNING* this interface is highly subject to change
   8997  *
   8998  * Returns -1 in case of error, 0 if the declaration is improper and
   8999  *         1 in case of success.
   9000  */
   9001 static xmlSchemaTypePtr
   9002 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   9003                    xmlNodePtr node)
   9004 {
   9005     xmlSchemaTypePtr type;
   9006     xmlNodePtr child = NULL;
   9007     xmlAttrPtr attr;
   9008 
   9009     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9010         return (NULL);
   9011     /* Not a component, don't create it. */
   9012     type = ctxt->ctxtType;
   9013     /*
   9014     * Mark the type as being of variety "list".
   9015     */
   9016     type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
   9017     /*
   9018     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
   9019     * then the simple ur-type definition."
   9020     */
   9021     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
   9022     /*
   9023     * Check for illegal attributes.
   9024     */
   9025     attr = node->properties;
   9026     while (attr != NULL) {
   9027 	if (attr->ns == NULL) {
   9028 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   9029 		(!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
   9030 		xmlSchemaPIllegalAttrErr(ctxt,
   9031 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9032 	    }
   9033 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9034 	    xmlSchemaPIllegalAttrErr(ctxt,
   9035 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9036 	}
   9037 	attr = attr->next;
   9038     }
   9039 
   9040     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9041 
   9042     /*
   9043     * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
   9044     * fields for holding the reference to the itemType.
   9045     *
   9046     * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
   9047     * the "ref" fields.
   9048     */
   9049     xmlSchemaPValAttrQName(ctxt, schema, NULL,
   9050 	node, "itemType", &(type->baseNs), &(type->base));
   9051     /*
   9052     * And now for the children...
   9053     */
   9054     child = node->children;
   9055     if (IS_SCHEMA(child, "annotation")) {
   9056 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   9057 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   9058         child = child->next;
   9059     }
   9060     if (IS_SCHEMA(child, "simpleType")) {
   9061 	/*
   9062 	* src-list-itemType-or-simpleType
   9063 	* Either the itemType [attribute] or the <simpleType> [child] of
   9064 	* the <list> element must be present, but not both.
   9065 	*/
   9066 	if (type->base != NULL) {
   9067 	    xmlSchemaPCustomErr(ctxt,
   9068 		XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   9069 		NULL, node,
   9070 		"The attribute 'itemType' and the <simpleType> child "
   9071 		"are mutually exclusive", NULL);
   9072 	} else {
   9073 	    type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   9074 	}
   9075         child = child->next;
   9076     } else if (type->base == NULL) {
   9077 	xmlSchemaPCustomErr(ctxt,
   9078 	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   9079 	    NULL, node,
   9080 	    "Either the attribute 'itemType' or the <simpleType> child "
   9081 	    "must be present", NULL);
   9082     }
   9083     if (child != NULL) {
   9084 	xmlSchemaPContentErr(ctxt,
   9085 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9086 	    NULL, node, child, NULL, "(annotation?, simpleType?)");
   9087     }
   9088     if ((type->base == NULL) &&
   9089 	(type->subtypes == NULL) &&
   9090 	(xmlSchemaGetPropNode(node, "itemType") == NULL)) {
   9091 	xmlSchemaPCustomErr(ctxt,
   9092 	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   9093 	    NULL, node,
   9094 	    "Either the attribute 'itemType' or the <simpleType> child "
   9095 	    "must be present", NULL);
   9096     }
   9097     return (NULL);
   9098 }
   9099 
   9100 /**
   9101  * xmlSchemaParseSimpleType:
   9102  * @ctxt:  a schema validation context
   9103  * @schema:  the schema being built
   9104  * @node:  a subtree containing XML Schema informations
   9105  *
   9106  * parse a XML schema Simple Type definition
   9107  * *WARNING* this interface is highly subject to change
   9108  *
   9109  * Returns -1 in case of error, 0 if the declaration is improper and
   9110  * 1 in case of success.
   9111  */
   9112 static xmlSchemaTypePtr
   9113 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   9114                          xmlNodePtr node, int topLevel)
   9115 {
   9116     xmlSchemaTypePtr type, oldCtxtType;
   9117     xmlNodePtr child = NULL;
   9118     const xmlChar *attrValue = NULL;
   9119     xmlAttrPtr attr;
   9120     int hasRestriction = 0;
   9121 
   9122     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9123         return (NULL);
   9124 
   9125     if (topLevel) {
   9126 	attr = xmlSchemaGetPropNode(node, "name");
   9127 	if (attr == NULL) {
   9128 	    xmlSchemaPMissingAttrErr(ctxt,
   9129 		XML_SCHEMAP_S4S_ATTR_MISSING,
   9130 		NULL, node,
   9131 		"name", NULL);
   9132 	    return (NULL);
   9133 	} else {
   9134 	    if (xmlSchemaPValAttrNode(ctxt,
   9135 		NULL, attr,
   9136 		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
   9137 		return (NULL);
   9138 	    /*
   9139 	    * Skip built-in types.
   9140 	    */
   9141 	    if (ctxt->isS4S) {
   9142 		xmlSchemaTypePtr biType;
   9143 
   9144 		if (ctxt->isRedefine) {
   9145 		    /*
   9146 		    * REDEFINE: Disallow redefinition of built-in-types.
   9147 		    * TODO: It seems that the spec does not say anything
   9148 		    * about this case.
   9149 		    */
   9150 		    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   9151 			NULL, node,
   9152 			"Redefinition of built-in simple types is not "
   9153 			"supported", NULL);
   9154 		    return(NULL);
   9155 		}
   9156 		biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
   9157 		if (biType != NULL)
   9158 		    return (biType);
   9159 	    }
   9160 	}
   9161     }
   9162     /*
   9163     * TargetNamespace:
   9164     * SPEC "The actual value of the targetNamespace [attribute]
   9165     * of the <schema> ancestor element information item if present,
   9166     * otherwise absent.
   9167     */
   9168     if (topLevel == 0) {
   9169 #ifdef ENABLE_NAMED_LOCALS
   9170         char buf[40];
   9171 #endif
   9172 	/*
   9173 	* Parse as local simple type definition.
   9174 	*/
   9175 #ifdef ENABLE_NAMED_LOCALS
   9176         snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
   9177 	type = xmlSchemaAddType(ctxt, schema,
   9178 	    XML_SCHEMA_TYPE_SIMPLE,
   9179 	    xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
   9180 	    ctxt->targetNamespace, node, 0);
   9181 #else
   9182 	type = xmlSchemaAddType(ctxt, schema,
   9183 	    XML_SCHEMA_TYPE_SIMPLE,
   9184 	    NULL, ctxt->targetNamespace, node, 0);
   9185 #endif
   9186 	if (type == NULL)
   9187 	    return (NULL);
   9188 	type->type = XML_SCHEMA_TYPE_SIMPLE;
   9189 	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   9190 	/*
   9191 	* Check for illegal attributes.
   9192 	*/
   9193 	attr = node->properties;
   9194 	while (attr != NULL) {
   9195 	    if (attr->ns == NULL) {
   9196 		if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
   9197 		    xmlSchemaPIllegalAttrErr(ctxt,
   9198 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9199 		}
   9200 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9201 		    xmlSchemaPIllegalAttrErr(ctxt,
   9202 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9203 	    }
   9204 	    attr = attr->next;
   9205 	}
   9206     } else {
   9207 	/*
   9208 	* Parse as global simple type definition.
   9209 	*
   9210 	* Note that attrValue is the value of the attribute "name" here.
   9211 	*/
   9212 	type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
   9213 	    attrValue, ctxt->targetNamespace, node, 1);
   9214 	if (type == NULL)
   9215 	    return (NULL);
   9216 	type->type = XML_SCHEMA_TYPE_SIMPLE;
   9217 	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   9218 	type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
   9219 	/*
   9220 	* Check for illegal attributes.
   9221 	*/
   9222 	attr = node->properties;
   9223 	while (attr != NULL) {
   9224 	    if (attr->ns == NULL) {
   9225 		if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   9226 		    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   9227 		    (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
   9228 		    xmlSchemaPIllegalAttrErr(ctxt,
   9229 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9230 		}
   9231 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9232 		xmlSchemaPIllegalAttrErr(ctxt,
   9233 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9234 	    }
   9235 	    attr = attr->next;
   9236 	}
   9237 	/*
   9238 	* Attribute "final".
   9239 	*/
   9240 	attr = xmlSchemaGetPropNode(node, "final");
   9241 	if (attr == NULL) {
   9242 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   9243 		type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
   9244 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
   9245 		type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
   9246 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
   9247 		type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
   9248 	} else {
   9249 	    attrValue = xmlSchemaGetProp(ctxt, node, "final");
   9250 	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
   9251 		-1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
   9252 		XML_SCHEMAS_TYPE_FINAL_LIST,
   9253 		XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
   9254 
   9255 		xmlSchemaPSimpleTypeErr(ctxt,
   9256 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   9257 		    WXS_BASIC_CAST type, (xmlNodePtr) attr,
   9258 		    NULL, "(#all | List of (list | union | restriction)",
   9259 		    attrValue, NULL, NULL, NULL);
   9260 	    }
   9261 	}
   9262     }
   9263     type->targetNamespace = ctxt->targetNamespace;
   9264     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9265     /*
   9266     * And now for the children...
   9267     */
   9268     oldCtxtType = ctxt->ctxtType;
   9269 
   9270     ctxt->ctxtType = type;
   9271 
   9272     child = node->children;
   9273     if (IS_SCHEMA(child, "annotation")) {
   9274         type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9275         child = child->next;
   9276     }
   9277     if (child == NULL) {
   9278 	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
   9279 	    NULL, node, child, NULL,
   9280 	    "(annotation?, (restriction | list | union))");
   9281     } else if (IS_SCHEMA(child, "restriction")) {
   9282         xmlSchemaParseRestriction(ctxt, schema, child,
   9283 	    XML_SCHEMA_TYPE_SIMPLE);
   9284 	hasRestriction = 1;
   9285         child = child->next;
   9286     } else if (IS_SCHEMA(child, "list")) {
   9287         xmlSchemaParseList(ctxt, schema, child);
   9288         child = child->next;
   9289     } else if (IS_SCHEMA(child, "union")) {
   9290         xmlSchemaParseUnion(ctxt, schema, child);
   9291         child = child->next;
   9292     }
   9293     if (child != NULL) {
   9294 	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9295 	    NULL, node, child, NULL,
   9296 	    "(annotation?, (restriction | list | union))");
   9297     }
   9298     /*
   9299     * REDEFINE: SPEC src-redefine (5)
   9300     * "Within the [children], each <simpleType> must have a
   9301     * <restriction> among its [children] ... the actual value of whose
   9302     * base [attribute] must be the same as the actual value of its own
   9303     * name attribute plus target namespace;"
   9304     */
   9305     if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
   9306 	xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   9307 	    NULL, node, "This is a redefinition, thus the "
   9308 	    "<simpleType> must have a <restriction> child", NULL);
   9309     }
   9310 
   9311     ctxt->ctxtType = oldCtxtType;
   9312     return (type);
   9313 }
   9314 
   9315 /**
   9316  * xmlSchemaParseModelGroupDefRef:
   9317  * @ctxt:  the parser context
   9318  * @schema: the schema being built
   9319  * @node:  the node
   9320  *
   9321  * Parses a reference to a model group definition.
   9322  *
   9323  * We will return a particle component with a qname-component or
   9324  * NULL in case of an error.
   9325  */
   9326 static xmlSchemaTreeItemPtr
   9327 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
   9328 			       xmlSchemaPtr schema,
   9329 			       xmlNodePtr node)
   9330 {
   9331     xmlSchemaParticlePtr item;
   9332     xmlNodePtr child = NULL;
   9333     xmlAttrPtr attr;
   9334     const xmlChar *ref = NULL, *refNs = NULL;
   9335     int min, max;
   9336 
   9337     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9338         return (NULL);
   9339 
   9340     attr = xmlSchemaGetPropNode(node, "ref");
   9341     if (attr == NULL) {
   9342 	xmlSchemaPMissingAttrErr(ctxt,
   9343 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   9344 	    NULL, node, "ref", NULL);
   9345 	return (NULL);
   9346     } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
   9347 	attr, &refNs, &ref) != 0) {
   9348 	return (NULL);
   9349     }
   9350     xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
   9351     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
   9352     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
   9353 	"(xs:nonNegativeInteger | unbounded)");
   9354     /*
   9355     * Check for illegal attributes.
   9356     */
   9357     attr = node->properties;
   9358     while (attr != NULL) {
   9359 	if (attr->ns == NULL) {
   9360 	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
   9361 		(!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   9362 		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
   9363 		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
   9364 		xmlSchemaPIllegalAttrErr(ctxt,
   9365 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9366 	    }
   9367 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9368 	    xmlSchemaPIllegalAttrErr(ctxt,
   9369 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9370 	}
   9371 	attr = attr->next;
   9372     }
   9373     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9374     item = xmlSchemaAddParticle(ctxt, node, min, max);
   9375     if (item == NULL)
   9376 	return (NULL);
   9377     /*
   9378     * Create a qname-reference and set as the term; it will be substituted
   9379     * for the model group after the reference has been resolved.
   9380     */
   9381     item->children = (xmlSchemaTreeItemPtr)
   9382 	xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
   9383     xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
   9384     /*
   9385     * And now for the children...
   9386     */
   9387     child = node->children;
   9388     /* TODO: Is annotation even allowed for a model group reference? */
   9389     if (IS_SCHEMA(child, "annotation")) {
   9390 	/*
   9391 	* TODO: What to do exactly with the annotation?
   9392 	*/
   9393 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9394 	child = child->next;
   9395     }
   9396     if (child != NULL) {
   9397 	xmlSchemaPContentErr(ctxt,
   9398 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9399 	    NULL, node, child, NULL,
   9400 	    "(annotation?)");
   9401     }
   9402     /*
   9403     * Corresponds to no component at all if minOccurs==maxOccurs==0.
   9404     */
   9405     if ((min == 0) && (max == 0))
   9406 	return (NULL);
   9407 
   9408     return ((xmlSchemaTreeItemPtr) item);
   9409 }
   9410 
   9411 /**
   9412  * xmlSchemaParseModelGroupDefinition:
   9413  * @ctxt:  a schema validation context
   9414  * @schema:  the schema being built
   9415  * @node:  a subtree containing XML Schema informations
   9416  *
   9417  * Parses a XML schema model group definition.
   9418  *
   9419  * Note that the contraint src-redefine (6.2) can't be applied until
   9420  * references have been resolved. So we will do this at the
   9421  * component fixup level.
   9422  *
   9423  * *WARNING* this interface is highly subject to change
   9424  *
   9425  * Returns -1 in case of error, 0 if the declaration is improper and
   9426  *         1 in case of success.
   9427  */
   9428 static xmlSchemaModelGroupDefPtr
   9429 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
   9430 				   xmlSchemaPtr schema,
   9431 				   xmlNodePtr node)
   9432 {
   9433     xmlSchemaModelGroupDefPtr item;
   9434     xmlNodePtr child = NULL;
   9435     xmlAttrPtr attr;
   9436     const xmlChar *name;
   9437 
   9438     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9439         return (NULL);
   9440 
   9441     attr = xmlSchemaGetPropNode(node, "name");
   9442     if (attr == NULL) {
   9443 	xmlSchemaPMissingAttrErr(ctxt,
   9444 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   9445 	    NULL, node,
   9446 	    "name", NULL);
   9447 	return (NULL);
   9448     } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
   9449 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   9450 	return (NULL);
   9451     }
   9452     item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
   9453 	ctxt->targetNamespace, node);
   9454     if (item == NULL)
   9455 	return (NULL);
   9456     /*
   9457     * Check for illegal attributes.
   9458     */
   9459     attr = node->properties;
   9460     while (attr != NULL) {
   9461 	if (attr->ns == NULL) {
   9462 	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   9463 		(!xmlStrEqual(attr->name, BAD_CAST "id"))) {
   9464 		xmlSchemaPIllegalAttrErr(ctxt,
   9465 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9466 	    }
   9467 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9468 	    xmlSchemaPIllegalAttrErr(ctxt,
   9469 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9470 	}
   9471 	attr = attr->next;
   9472     }
   9473     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9474     /*
   9475     * And now for the children...
   9476     */
   9477     child = node->children;
   9478     if (IS_SCHEMA(child, "annotation")) {
   9479 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9480 	child = child->next;
   9481     }
   9482     if (IS_SCHEMA(child, "all")) {
   9483 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
   9484 	    XML_SCHEMA_TYPE_ALL, 0);
   9485 	child = child->next;
   9486     } else if (IS_SCHEMA(child, "choice")) {
   9487 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
   9488 	    XML_SCHEMA_TYPE_CHOICE, 0);
   9489 	child = child->next;
   9490     } else if (IS_SCHEMA(child, "sequence")) {
   9491 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
   9492 	    XML_SCHEMA_TYPE_SEQUENCE, 0);
   9493 	child = child->next;
   9494     }
   9495 
   9496 
   9497 
   9498     if (child != NULL) {
   9499 	xmlSchemaPContentErr(ctxt,
   9500 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9501 	    NULL, node, child, NULL,
   9502 	    "(annotation?, (all | choice | sequence)?)");
   9503     }
   9504     return (item);
   9505 }
   9506 
   9507 /**
   9508  * xmlSchemaCleanupDoc:
   9509  * @ctxt:  a schema validation context
   9510  * @node:  the root of the document.
   9511  *
   9512  * removes unwanted nodes in a schemas document tree
   9513  */
   9514 static void
   9515 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
   9516 {
   9517     xmlNodePtr delete, cur;
   9518 
   9519     if ((ctxt == NULL) || (root == NULL)) return;
   9520 
   9521     /*
   9522      * Remove all the blank text nodes
   9523      */
   9524     delete = NULL;
   9525     cur = root;
   9526     while (cur != NULL) {
   9527         if (delete != NULL) {
   9528             xmlUnlinkNode(delete);
   9529             xmlFreeNode(delete);
   9530             delete = NULL;
   9531         }
   9532         if (cur->type == XML_TEXT_NODE) {
   9533             if (IS_BLANK_NODE(cur)) {
   9534                 if (xmlNodeGetSpacePreserve(cur) != 1) {
   9535                     delete = cur;
   9536                 }
   9537             }
   9538         } else if ((cur->type != XML_ELEMENT_NODE) &&
   9539                    (cur->type != XML_CDATA_SECTION_NODE)) {
   9540             delete = cur;
   9541             goto skip_children;
   9542         }
   9543 
   9544         /*
   9545          * Skip to next node
   9546          */
   9547         if (cur->children != NULL) {
   9548             if ((cur->children->type != XML_ENTITY_DECL) &&
   9549                 (cur->children->type != XML_ENTITY_REF_NODE) &&
   9550                 (cur->children->type != XML_ENTITY_NODE)) {
   9551                 cur = cur->children;
   9552                 continue;
   9553             }
   9554         }
   9555       skip_children:
   9556         if (cur->next != NULL) {
   9557             cur = cur->next;
   9558             continue;
   9559         }
   9560 
   9561         do {
   9562             cur = cur->parent;
   9563             if (cur == NULL)
   9564                 break;
   9565             if (cur == root) {
   9566                 cur = NULL;
   9567                 break;
   9568             }
   9569             if (cur->next != NULL) {
   9570                 cur = cur->next;
   9571                 break;
   9572             }
   9573         } while (cur != NULL);
   9574     }
   9575     if (delete != NULL) {
   9576         xmlUnlinkNode(delete);
   9577         xmlFreeNode(delete);
   9578         delete = NULL;
   9579     }
   9580 }
   9581 
   9582 
   9583 static void
   9584 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
   9585 {
   9586     if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
   9587 	schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
   9588 
   9589     if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
   9590 	schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
   9591 
   9592     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
   9593 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
   9594     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   9595 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
   9596     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
   9597 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
   9598     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
   9599 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
   9600 
   9601     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
   9602 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
   9603     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
   9604 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
   9605     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
   9606 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
   9607 }
   9608 
   9609 static int
   9610 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
   9611 			     xmlSchemaPtr schema,
   9612 			     xmlNodePtr node)
   9613 {
   9614     xmlAttrPtr attr;
   9615     const xmlChar *val;
   9616     int res = 0, oldErrs = ctxt->nberrors;
   9617 
   9618     /*
   9619     * Those flags should be moved to the parser context flags,
   9620     * since they are not visible at the component level. I.e.
   9621     * they are used if processing schema *documents* only.
   9622     */
   9623     res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9624     HFAILURE;
   9625 
   9626     /*
   9627     * Since the version is of type xs:token, we won't bother to
   9628     * check it.
   9629     */
   9630     /* REMOVED:
   9631     attr = xmlSchemaGetPropNode(node, "version");
   9632     if (attr != NULL) {
   9633 	res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
   9634 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
   9635 	HFAILURE;
   9636     }
   9637     */
   9638     attr = xmlSchemaGetPropNode(node, "targetNamespace");
   9639     if (attr != NULL) {
   9640 	res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
   9641 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
   9642 	HFAILURE;
   9643 	if (res != 0) {
   9644 	    ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   9645 	    goto exit;
   9646 	}
   9647     }
   9648     attr = xmlSchemaGetPropNode(node, "elementFormDefault");
   9649     if (attr != NULL) {
   9650 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9651 	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
   9652 	    XML_SCHEMAS_QUALIF_ELEM);
   9653 	HFAILURE;
   9654 	if (res != 0) {
   9655 	    xmlSchemaPSimpleTypeErr(ctxt,
   9656 		XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
   9657 		NULL, (xmlNodePtr) attr, NULL,
   9658 		"(qualified | unqualified)", val, NULL, NULL, NULL);
   9659 	}
   9660     }
   9661     attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
   9662     if (attr != NULL) {
   9663 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9664 	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
   9665 	    XML_SCHEMAS_QUALIF_ATTR);
   9666 	HFAILURE;
   9667 	if (res != 0) {
   9668 	    xmlSchemaPSimpleTypeErr(ctxt,
   9669 		XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
   9670 		NULL, (xmlNodePtr) attr, NULL,
   9671 		"(qualified | unqualified)", val, NULL, NULL, NULL);
   9672 	}
   9673     }
   9674     attr = xmlSchemaGetPropNode(node, "finalDefault");
   9675     if (attr != NULL) {
   9676 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9677 	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
   9678 	    XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
   9679 	    XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
   9680 	    -1,
   9681 	    XML_SCHEMAS_FINAL_DEFAULT_LIST,
   9682 	    XML_SCHEMAS_FINAL_DEFAULT_UNION);
   9683 	HFAILURE;
   9684 	if (res != 0) {
   9685 	    xmlSchemaPSimpleTypeErr(ctxt,
   9686 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   9687 		NULL, (xmlNodePtr) attr, NULL,
   9688 		"(#all | List of (extension | restriction | list | union))",
   9689 		val, NULL, NULL, NULL);
   9690 	}
   9691     }
   9692     attr = xmlSchemaGetPropNode(node, "blockDefault");
   9693     if (attr != NULL) {
   9694 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9695 	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
   9696 	    XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
   9697 	    XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
   9698 	    XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
   9699 	HFAILURE;
   9700 	if (res != 0) {
   9701 	    xmlSchemaPSimpleTypeErr(ctxt,
   9702 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   9703 		NULL, (xmlNodePtr) attr, NULL,
   9704 		"(#all | List of (extension | restriction | substitution))",
   9705 		val, NULL, NULL, NULL);
   9706 	}
   9707     }
   9708 
   9709 exit:
   9710     if (oldErrs != ctxt->nberrors)
   9711 	res = ctxt->err;
   9712     return(res);
   9713 exit_failure:
   9714     return(-1);
   9715 }
   9716 
   9717 /**
   9718  * xmlSchemaParseSchemaTopLevel:
   9719  * @ctxt:  a schema validation context
   9720  * @schema:  the schemas
   9721  * @nodes:  the list of top level nodes
   9722  *
   9723  * Returns the internal XML Schema structure built from the resource or
   9724  *         NULL in case of error
   9725  */
   9726 static int
   9727 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
   9728                              xmlSchemaPtr schema, xmlNodePtr nodes)
   9729 {
   9730     xmlNodePtr child;
   9731     xmlSchemaAnnotPtr annot;
   9732     int res = 0, oldErrs, tmpOldErrs;
   9733 
   9734     if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
   9735         return(-1);
   9736 
   9737     oldErrs = ctxt->nberrors;
   9738     child = nodes;
   9739     while ((IS_SCHEMA(child, "include")) ||
   9740 	   (IS_SCHEMA(child, "import")) ||
   9741 	   (IS_SCHEMA(child, "redefine")) ||
   9742 	   (IS_SCHEMA(child, "annotation"))) {
   9743 	if (IS_SCHEMA(child, "annotation")) {
   9744 	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9745 	    if (schema->annot == NULL)
   9746 		schema->annot = annot;
   9747 	    else
   9748 		xmlSchemaFreeAnnot(annot);
   9749 	} else if (IS_SCHEMA(child, "import")) {
   9750 	    tmpOldErrs = ctxt->nberrors;
   9751 	    res = xmlSchemaParseImport(ctxt, schema, child);
   9752 	    HFAILURE;
   9753 	    HSTOP(ctxt);
   9754 	    if (tmpOldErrs != ctxt->nberrors)
   9755 		goto exit;
   9756 	} else if (IS_SCHEMA(child, "include")) {
   9757 	    tmpOldErrs = ctxt->nberrors;
   9758 	    res = xmlSchemaParseInclude(ctxt, schema, child);
   9759 	    HFAILURE;
   9760 	    HSTOP(ctxt);
   9761 	    if (tmpOldErrs != ctxt->nberrors)
   9762 		goto exit;
   9763 	} else if (IS_SCHEMA(child, "redefine")) {
   9764 	    tmpOldErrs = ctxt->nberrors;
   9765 	    res = xmlSchemaParseRedefine(ctxt, schema, child);
   9766 	    HFAILURE;
   9767 	    HSTOP(ctxt);
   9768 	    if (tmpOldErrs != ctxt->nberrors)
   9769 		goto exit;
   9770 	}
   9771 	child = child->next;
   9772     }
   9773     /*
   9774     * URGENT TODO: Change the functions to return int results.
   9775     * We need especially to catch internal errors.
   9776     */
   9777     while (child != NULL) {
   9778 	if (IS_SCHEMA(child, "complexType")) {
   9779 	    xmlSchemaParseComplexType(ctxt, schema, child, 1);
   9780 	    child = child->next;
   9781 	} else if (IS_SCHEMA(child, "simpleType")) {
   9782 	    xmlSchemaParseSimpleType(ctxt, schema, child, 1);
   9783 	    child = child->next;
   9784 	} else if (IS_SCHEMA(child, "element")) {
   9785 	    xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
   9786 	    child = child->next;
   9787 	} else if (IS_SCHEMA(child, "attribute")) {
   9788 	    xmlSchemaParseGlobalAttribute(ctxt, schema, child);
   9789 	    child = child->next;
   9790 	} else if (IS_SCHEMA(child, "attributeGroup")) {
   9791 	    xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
   9792 	    child = child->next;
   9793 	} else if (IS_SCHEMA(child, "group")) {
   9794 	    xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
   9795 	    child = child->next;
   9796 	} else if (IS_SCHEMA(child, "notation")) {
   9797 	    xmlSchemaParseNotation(ctxt, schema, child);
   9798 	    child = child->next;
   9799 	} else {
   9800 	    xmlSchemaPContentErr(ctxt,
   9801 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9802 		NULL, child->parent, child,
   9803 		NULL, "((include | import | redefine | annotation)*, "
   9804 		"(((simpleType | complexType | group | attributeGroup) "
   9805 		"| element | attribute | notation), annotation*)*)");
   9806 	    child = child->next;
   9807 	}
   9808 	while (IS_SCHEMA(child, "annotation")) {
   9809 	    /*
   9810 	    * TODO: We should add all annotations.
   9811 	    */
   9812 	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9813 	    if (schema->annot == NULL)
   9814 		schema->annot = annot;
   9815 	    else
   9816 		xmlSchemaFreeAnnot(annot);
   9817 	    child = child->next;
   9818 	}
   9819     }
   9820 exit:
   9821     ctxt->ctxtType = NULL;
   9822     if (oldErrs != ctxt->nberrors)
   9823 	res = ctxt->err;
   9824     return(res);
   9825 exit_failure:
   9826     return(-1);
   9827 }
   9828 
   9829 static xmlSchemaSchemaRelationPtr
   9830 xmlSchemaSchemaRelationCreate(void)
   9831 {
   9832     xmlSchemaSchemaRelationPtr ret;
   9833 
   9834     ret = (xmlSchemaSchemaRelationPtr)
   9835 	xmlMalloc(sizeof(xmlSchemaSchemaRelation));
   9836     if (ret == NULL) {
   9837 	xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
   9838 	return(NULL);
   9839     }
   9840     memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
   9841     return(ret);
   9842 }
   9843 
   9844 #if 0
   9845 static void
   9846 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
   9847 {
   9848     xmlFree(rel);
   9849 }
   9850 #endif
   9851 
   9852 static void
   9853 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
   9854 {
   9855     xmlSchemaRedefPtr prev;
   9856 
   9857     while (redef != NULL) {
   9858 	prev = redef;
   9859 	redef = redef->next;
   9860 	xmlFree(prev);
   9861     }
   9862 }
   9863 
   9864 static void
   9865 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
   9866 {
   9867     /*
   9868     * After the construction context has been freed, there will be
   9869     * no schema graph available any more. Only the schema buckets
   9870     * will stay alive, which are put into the "schemasImports" and
   9871     * "includes" slots of the xmlSchema.
   9872     */
   9873     if (con->buckets != NULL)
   9874 	xmlSchemaItemListFree(con->buckets);
   9875     if (con->pending != NULL)
   9876 	xmlSchemaItemListFree(con->pending);
   9877     if (con->substGroups != NULL)
   9878 	xmlHashFree(con->substGroups,
   9879 	    (xmlHashDeallocator) xmlSchemaSubstGroupFree);
   9880     if (con->redefs != NULL)
   9881 	xmlSchemaRedefListFree(con->redefs);
   9882     if (con->dict != NULL)
   9883 	xmlDictFree(con->dict);
   9884     xmlFree(con);
   9885 }
   9886 
   9887 static xmlSchemaConstructionCtxtPtr
   9888 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
   9889 {
   9890     xmlSchemaConstructionCtxtPtr ret;
   9891 
   9892     ret = (xmlSchemaConstructionCtxtPtr)
   9893 	xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
   9894     if (ret == NULL) {
   9895         xmlSchemaPErrMemory(NULL,
   9896 	    "allocating schema construction context", NULL);
   9897         return (NULL);
   9898     }
   9899     memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
   9900 
   9901     ret->buckets = xmlSchemaItemListCreate();
   9902     if (ret->buckets == NULL) {
   9903 	xmlSchemaPErrMemory(NULL,
   9904 	    "allocating list of schema buckets", NULL);
   9905 	xmlFree(ret);
   9906         return (NULL);
   9907     }
   9908     ret->pending = xmlSchemaItemListCreate();
   9909     if (ret->pending == NULL) {
   9910 	xmlSchemaPErrMemory(NULL,
   9911 	    "allocating list of pending global components", NULL);
   9912 	xmlSchemaConstructionCtxtFree(ret);
   9913         return (NULL);
   9914     }
   9915     ret->dict = dict;
   9916     xmlDictReference(dict);
   9917     return(ret);
   9918 }
   9919 
   9920 static xmlSchemaParserCtxtPtr
   9921 xmlSchemaParserCtxtCreate(void)
   9922 {
   9923     xmlSchemaParserCtxtPtr ret;
   9924 
   9925     ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
   9926     if (ret == NULL) {
   9927         xmlSchemaPErrMemory(NULL, "allocating schema parser context",
   9928                             NULL);
   9929         return (NULL);
   9930     }
   9931     memset(ret, 0, sizeof(xmlSchemaParserCtxt));
   9932     ret->type = XML_SCHEMA_CTXT_PARSER;
   9933     ret->attrProhibs = xmlSchemaItemListCreate();
   9934     if (ret->attrProhibs == NULL) {
   9935 	xmlFree(ret);
   9936 	return(NULL);
   9937     }
   9938     return(ret);
   9939 }
   9940 
   9941 /**
   9942  * xmlSchemaNewParserCtxtUseDict:
   9943  * @URL:  the location of the schema
   9944  * @dict: the dictionary to be used
   9945  *
   9946  * Create an XML Schemas parse context for that file/resource expected
   9947  * to contain an XML Schemas file.
   9948  *
   9949  * Returns the parser context or NULL in case of error
   9950  */
   9951 static xmlSchemaParserCtxtPtr
   9952 xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
   9953 {
   9954     xmlSchemaParserCtxtPtr ret;
   9955 
   9956     ret = xmlSchemaParserCtxtCreate();
   9957     if (ret == NULL)
   9958         return (NULL);
   9959     ret->dict = dict;
   9960     xmlDictReference(dict);
   9961     if (URL != NULL)
   9962 	ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
   9963     return (ret);
   9964 }
   9965 
   9966 static int
   9967 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
   9968 {
   9969     if (vctxt->pctxt == NULL) {
   9970         if (vctxt->schema != NULL)
   9971 	    vctxt->pctxt =
   9972 		xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
   9973 	else
   9974 	    vctxt->pctxt = xmlSchemaNewParserCtxt("*");
   9975 	if (vctxt->pctxt == NULL) {
   9976 	    VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
   9977 		"failed to create a temp. parser context");
   9978 	    return (-1);
   9979 	}
   9980 	/* TODO: Pass user data. */
   9981 	xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
   9982 	    vctxt->warning, vctxt->errCtxt);
   9983 	xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
   9984 	    vctxt->errCtxt);
   9985     }
   9986     return (0);
   9987 }
   9988 
   9989 /**
   9990  * xmlSchemaGetSchemaBucket:
   9991  * @pctxt: the schema parser context
   9992  * @schemaLocation: the URI of the schema document
   9993  *
   9994  * Returns a schema bucket if it was already parsed.
   9995  *
   9996  * Returns a schema bucket if it was already parsed from
   9997  *         @schemaLocation, NULL otherwise.
   9998  */
   9999 static xmlSchemaBucketPtr
   10000 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
   10001 			    const xmlChar *schemaLocation)
   10002 {
   10003     xmlSchemaBucketPtr cur;
   10004     xmlSchemaItemListPtr list;
   10005 
   10006     list = pctxt->constructor->buckets;
   10007     if (list->nbItems == 0)
   10008 	return(NULL);
   10009     else {
   10010 	int i;
   10011 	for (i = 0; i < list->nbItems; i++) {
   10012 	    cur = (xmlSchemaBucketPtr) list->items[i];
   10013 	    /* Pointer comparison! */
   10014 	    if (cur->schemaLocation == schemaLocation)
   10015 		return(cur);
   10016 	}
   10017     }
   10018     return(NULL);
   10019 }
   10020 
   10021 static xmlSchemaBucketPtr
   10022 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
   10023 				     const xmlChar *schemaLocation,
   10024 				     const xmlChar *targetNamespace)
   10025 {
   10026     xmlSchemaBucketPtr cur;
   10027     xmlSchemaItemListPtr list;
   10028 
   10029     list = pctxt->constructor->buckets;
   10030     if (list->nbItems == 0)
   10031 	return(NULL);
   10032     else {
   10033 	int i;
   10034 	for (i = 0; i < list->nbItems; i++) {
   10035 	    cur = (xmlSchemaBucketPtr) list->items[i];
   10036 	    /* Pointer comparison! */
   10037 	    if ((cur->origTargetNamespace == NULL) &&
   10038 		(cur->schemaLocation == schemaLocation) &&
   10039 		(cur->targetNamespace == targetNamespace))
   10040 		return(cur);
   10041 	}
   10042     }
   10043     return(NULL);
   10044 }
   10045 
   10046 
   10047 #define IS_BAD_SCHEMA_DOC(b) \
   10048     (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
   10049 
   10050 static xmlSchemaBucketPtr
   10051 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
   10052 				 const xmlChar *targetNamespace,
   10053 				 int imported)
   10054 {
   10055     xmlSchemaBucketPtr cur;
   10056     xmlSchemaItemListPtr list;
   10057 
   10058     list = pctxt->constructor->buckets;
   10059     if (list->nbItems == 0)
   10060 	return(NULL);
   10061     else {
   10062 	int i;
   10063 	for (i = 0; i < list->nbItems; i++) {
   10064 	    cur = (xmlSchemaBucketPtr) list->items[i];
   10065 	    if ((! IS_BAD_SCHEMA_DOC(cur)) &&
   10066 		(cur->origTargetNamespace == targetNamespace) &&
   10067 		((imported && cur->imported) ||
   10068 		 ((!imported) && (!cur->imported))))
   10069 		return(cur);
   10070 	}
   10071     }
   10072     return(NULL);
   10073 }
   10074 
   10075 static int
   10076 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
   10077 		     xmlSchemaPtr schema,
   10078 		     xmlSchemaBucketPtr bucket)
   10079 {
   10080     int oldFlags;
   10081     xmlDocPtr oldDoc;
   10082     xmlNodePtr node;
   10083     int ret, oldErrs;
   10084     xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
   10085 
   10086     /*
   10087     * Save old values; reset the *main* schema.
   10088     * URGENT TODO: This is not good; move the per-document information
   10089     * to the parser. Get rid of passing the main schema to the
   10090     * parsing functions.
   10091     */
   10092     oldFlags = schema->flags;
   10093     oldDoc = schema->doc;
   10094     if (schema->flags != 0)
   10095 	xmlSchemaClearSchemaDefaults(schema);
   10096     schema->doc = bucket->doc;
   10097     pctxt->schema = schema;
   10098     /*
   10099     * Keep the current target namespace on the parser *not* on the
   10100     * main schema.
   10101     */
   10102     pctxt->targetNamespace = bucket->targetNamespace;
   10103     WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
   10104 
   10105     if ((bucket->targetNamespace != NULL) &&
   10106 	xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
   10107 	/*
   10108 	* We are parsing the schema for schemas!
   10109 	*/
   10110 	pctxt->isS4S = 1;
   10111     }
   10112     /* Mark it as parsed, even if parsing fails. */
   10113     bucket->parsed++;
   10114     /* Compile the schema doc. */
   10115     node = xmlDocGetRootElement(bucket->doc);
   10116     ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
   10117     if (ret != 0)
   10118 	goto exit;
   10119     /* An empty schema; just get out. */
   10120     if (node->children == NULL)
   10121 	goto exit;
   10122     oldErrs = pctxt->nberrors;
   10123     ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
   10124     if (ret != 0)
   10125 	goto exit;
   10126     /*
   10127     * TODO: Not nice, but I'm not 100% sure we will get always an error
   10128     * as a result of the obove functions; so better rely on pctxt->err
   10129     * as well.
   10130     */
   10131     if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
   10132 	ret = pctxt->err;
   10133 	goto exit;
   10134     }
   10135 
   10136 exit:
   10137     WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
   10138     /* Restore schema values. */
   10139     schema->doc = oldDoc;
   10140     schema->flags = oldFlags;
   10141     return(ret);
   10142 }
   10143 
   10144 static int
   10145 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
   10146 		     xmlSchemaPtr schema,
   10147 		     xmlSchemaBucketPtr bucket)
   10148 {
   10149     xmlSchemaParserCtxtPtr newpctxt;
   10150     int res = 0;
   10151 
   10152     if (bucket == NULL)
   10153 	return(0);
   10154     if (bucket->parsed) {
   10155 	PERROR_INT("xmlSchemaParseNewDoc",
   10156 	    "reparsing a schema doc");
   10157 	return(-1);
   10158     }
   10159     if (bucket->doc == NULL) {
   10160 	PERROR_INT("xmlSchemaParseNewDoc",
   10161 	    "parsing a schema doc, but there's no doc");
   10162 	return(-1);
   10163     }
   10164     if (pctxt->constructor == NULL) {
   10165 	PERROR_INT("xmlSchemaParseNewDoc",
   10166 	    "no constructor");
   10167 	return(-1);
   10168     }
   10169     /* Create and init the temporary parser context. */
   10170     newpctxt = xmlSchemaNewParserCtxtUseDict(
   10171 	(const char *) bucket->schemaLocation, pctxt->dict);
   10172     if (newpctxt == NULL)
   10173 	return(-1);
   10174     newpctxt->constructor = pctxt->constructor;
   10175     /*
   10176     * TODO: Can we avoid that the parser knows about the main schema?
   10177     * It would be better if he knows about the current schema bucket
   10178     * only.
   10179     */
   10180     newpctxt->schema = schema;
   10181     xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
   10182 	pctxt->errCtxt);
   10183     xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
   10184 	pctxt->errCtxt);
   10185     newpctxt->counter = pctxt->counter;
   10186 
   10187 
   10188     res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
   10189 
   10190     /* Channel back errors and cleanup the temporary parser context. */
   10191     if (res != 0)
   10192 	pctxt->err = res;
   10193     pctxt->nberrors += newpctxt->nberrors;
   10194     pctxt->counter = newpctxt->counter;
   10195     newpctxt->constructor = NULL;
   10196     /* Free the parser context. */
   10197     xmlSchemaFreeParserCtxt(newpctxt);
   10198     return(res);
   10199 }
   10200 
   10201 static void
   10202 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
   10203 				xmlSchemaSchemaRelationPtr rel)
   10204 {
   10205     xmlSchemaSchemaRelationPtr cur = bucket->relations;
   10206 
   10207     if (cur == NULL) {
   10208 	bucket->relations = rel;
   10209 	return;
   10210     }
   10211     while (cur->next != NULL)
   10212 	cur = cur->next;
   10213     cur->next = rel;
   10214 }
   10215 
   10216 
   10217 static const xmlChar *
   10218 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
   10219 			  xmlNodePtr ctxtNode)
   10220 {
   10221     /*
   10222     * Build an absolue location URI.
   10223     */
   10224     if (location != NULL) {
   10225 	if (ctxtNode == NULL)
   10226 	    return(location);
   10227 	else {
   10228 	    xmlChar *base, *URI;
   10229 	    const xmlChar *ret = NULL;
   10230 
   10231 	    base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
   10232 	    if (base == NULL) {
   10233 		URI = xmlBuildURI(location, ctxtNode->doc->URL);
   10234 	    } else {
   10235 		URI = xmlBuildURI(location, base);
   10236 		xmlFree(base);
   10237 	    }
   10238 	    if (URI != NULL) {
   10239 		ret = xmlDictLookup(dict, URI, -1);
   10240 		xmlFree(URI);
   10241 		return(ret);
   10242 	    }
   10243 	}
   10244     }
   10245     return(NULL);
   10246 }
   10247 
   10248 
   10249 
   10250 /**
   10251  * xmlSchemaAddSchemaDoc:
   10252  * @pctxt:  a schema validation context
   10253  * @schema:  the schema being built
   10254  * @node:  a subtree containing XML Schema informations
   10255  *
   10256  * Parse an included (and to-be-redefined) XML schema document.
   10257  *
   10258  * Returns 0 on success, a positive error code on errors and
   10259  *         -1 in case of an internal or API error.
   10260  */
   10261 
   10262 static int
   10263 xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
   10264 		int type, /* import or include or redefine */
   10265 		const xmlChar *schemaLocation,
   10266 		xmlDocPtr schemaDoc,
   10267 		const char *schemaBuffer,
   10268 		int schemaBufferLen,
   10269 		xmlNodePtr invokingNode,
   10270 		const xmlChar *sourceTargetNamespace,
   10271 		const xmlChar *importNamespace,
   10272 		xmlSchemaBucketPtr *bucket)
   10273 {
   10274     const xmlChar *targetNamespace = NULL;
   10275     xmlSchemaSchemaRelationPtr relation = NULL;
   10276     xmlDocPtr doc = NULL;
   10277     int res = 0, err = 0, located = 0, preserveDoc = 0;
   10278     xmlSchemaBucketPtr bkt = NULL;
   10279 
   10280     if (bucket != NULL)
   10281 	*bucket = NULL;
   10282 
   10283     switch (type) {
   10284 	case XML_SCHEMA_SCHEMA_IMPORT:
   10285 	case XML_SCHEMA_SCHEMA_MAIN:
   10286 	    err = XML_SCHEMAP_SRC_IMPORT;
   10287 	    break;
   10288 	case XML_SCHEMA_SCHEMA_INCLUDE:
   10289 	    err = XML_SCHEMAP_SRC_INCLUDE;
   10290 	    break;
   10291 	case XML_SCHEMA_SCHEMA_REDEFINE:
   10292 	    err = XML_SCHEMAP_SRC_REDEFINE;
   10293 	    break;
   10294     }
   10295 
   10296 
   10297     /* Special handling for the main schema:
   10298     * skip the location and relation logic and just parse the doc.
   10299     * We need just a bucket to be returned in this case.
   10300     */
   10301     if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
   10302 	goto doc_load;
   10303 
   10304     /* Note that we expect the location to be an absulute URI. */
   10305     if (schemaLocation != NULL) {
   10306 	bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
   10307 	if ((bkt != NULL) &&
   10308 	    (pctxt->constructor->bucket == bkt)) {
   10309 	    /* Report self-imports/inclusions/redefinitions. */
   10310 
   10311 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
   10312 		invokingNode, NULL,
   10313 		"The schema must not import/include/redefine itself",
   10314 		NULL, NULL);
   10315 	    goto exit;
   10316 	}
   10317     }
   10318     /*
   10319     * Create a relation for the graph of schemas.
   10320     */
   10321     relation = xmlSchemaSchemaRelationCreate();
   10322     if (relation == NULL)
   10323 	return(-1);
   10324     xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
   10325 	relation);
   10326     relation->type = type;
   10327 
   10328     /*
   10329     * Save the namespace import information.
   10330     */
   10331     if (WXS_IS_BUCKET_IMPMAIN(type)) {
   10332 	relation->importNamespace = importNamespace;
   10333 	if (schemaLocation == NULL) {
   10334 	    /*
   10335 	    * No location; this is just an import of the namespace.
   10336 	    * Note that we don't assign a bucket to the relation
   10337 	    * in this case.
   10338 	    */
   10339 	    goto exit;
   10340 	}
   10341 	targetNamespace = importNamespace;
   10342     }
   10343 
   10344     /* Did we already fetch the doc? */
   10345     if (bkt != NULL) {
   10346 	if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
   10347 	    /*
   10348 	    * We included/redefined and then try to import a schema,
   10349 	    * but the new location provided for import was different.
   10350 	    */
   10351 	    if (schemaLocation == NULL)
   10352 		schemaLocation = BAD_CAST "in_memory_buffer";
   10353 	    if (!xmlStrEqual(schemaLocation,
   10354 		bkt->schemaLocation)) {
   10355 		xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
   10356 		    invokingNode, NULL,
   10357 		    "The schema document '%s' cannot be imported, since "
   10358 		    "it was already included or redefined",
   10359 		    schemaLocation, NULL);
   10360 		goto exit;
   10361 	    }
   10362 	} else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
   10363 	    /*
   10364 	    * We imported and then try to include/redefine a schema,
   10365 	    * but the new location provided for the include/redefine
   10366 	    * was different.
   10367 	    */
   10368 	    if (schemaLocation == NULL)
   10369 		schemaLocation = BAD_CAST "in_memory_buffer";
   10370 	    if (!xmlStrEqual(schemaLocation,
   10371 		bkt->schemaLocation)) {
   10372 		xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
   10373 		    invokingNode, NULL,
   10374 		    "The schema document '%s' cannot be included or "
   10375 		    "redefined, since it was already imported",
   10376 		    schemaLocation, NULL);
   10377 		goto exit;
   10378 	    }
   10379 	}
   10380     }
   10381 
   10382     if (WXS_IS_BUCKET_IMPMAIN(type)) {
   10383 	/*
   10384 	* Given that the schemaLocation [attribute] is only a hint, it is open
   10385 	* to applications to ignore all but the first <import> for a given
   10386 	* namespace, regardless of the actual value of schemaLocation, but
   10387 	* such a strategy risks missing useful information when new
   10388 	* schemaLocations are offered.
   10389 	*
   10390 	* We will use the first <import> that comes with a location.
   10391 	* Further <import>s *with* a location, will result in an error.
   10392 	* TODO: Better would be to just report a warning here, but
   10393 	* we'll try it this way until someone complains.
   10394 	*
   10395 	* Schema Document Location Strategy:
   10396 	* 3 Based on the namespace name, identify an existing schema document,
   10397 	* either as a resource which is an XML document or a <schema> element
   10398 	* information item, in some local schema repository;
   10399 	* 5 Attempt to resolve the namespace name to locate such a resource.
   10400 	*
   10401 	* NOTE: (3) and (5) are not supported.
   10402 	*/
   10403 	if (bkt != NULL) {
   10404 	    relation->bucket = bkt;
   10405 	    goto exit;
   10406 	}
   10407 	bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
   10408 	    importNamespace, 1);
   10409 
   10410 	if (bkt != NULL) {
   10411 	    relation->bucket = bkt;
   10412 	    if (bkt->schemaLocation == NULL) {
   10413 		/* First given location of the schema; load the doc. */
   10414 		bkt->schemaLocation = schemaLocation;
   10415 	    } else {
   10416 		if (!xmlStrEqual(schemaLocation,
   10417 		    bkt->schemaLocation)) {
   10418 		    /*
   10419 		    * Additional location given; just skip it.
   10420 		    * URGENT TODO: We should report a warning here.
   10421 		    * res = XML_SCHEMAP_SRC_IMPORT;
   10422 		    */
   10423 		    if (schemaLocation == NULL)
   10424 			schemaLocation = BAD_CAST "in_memory_buffer";
   10425 
   10426 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   10427 			XML_SCHEMAP_WARN_SKIP_SCHEMA,
   10428 			invokingNode, NULL,
   10429 			"Skipping import of schema located at '%s' for the "
   10430 			"namespace '%s', since this namespace was already "
   10431 			"imported with the schema located at '%s'",
   10432 			schemaLocation, importNamespace, bkt->schemaLocation);
   10433 		}
   10434 		goto exit;
   10435 	    }
   10436 	}
   10437 	/*
   10438 	* No bucket + first location: load the doc and create a
   10439 	* bucket.
   10440 	*/
   10441     } else {
   10442 	/* <include> and <redefine> */
   10443 	if (bkt != NULL) {
   10444 
   10445 	    if ((bkt->origTargetNamespace == NULL) &&
   10446 		(bkt->targetNamespace != sourceTargetNamespace)) {
   10447 		xmlSchemaBucketPtr chamel;
   10448 
   10449 		/*
   10450 		* Chameleon include/redefine: skip loading only if it was
   10451 		* aleady build for the targetNamespace of the including
   10452 		* schema.
   10453 		*/
   10454 		/*
   10455 		* URGENT TODO: If the schema is a chameleon-include then copy
   10456 		* the components into the including schema and modify the
   10457 		* targetNamespace of those components, do nothing otherwise.
   10458 		* NOTE: This is currently worked-around by compiling the
   10459 		* chameleon for every destinct including targetNamespace; thus
   10460 		* not performant at the moment.
   10461 		* TODO: Check when the namespace in wildcards for chameleons
   10462 		* needs to be converted: before we built wildcard intersections
   10463 		* or after.
   10464 		*   Answer: after!
   10465 		*/
   10466 		chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
   10467 		    schemaLocation, sourceTargetNamespace);
   10468 		if (chamel != NULL) {
   10469 		    /* A fitting chameleon was already parsed; NOP. */
   10470 		    relation->bucket = chamel;
   10471 		    goto exit;
   10472 		}
   10473 		/*
   10474 		* We need to parse the chameleon again for a different
   10475 		* targetNamespace.
   10476 		* CHAMELEON TODO: Optimize this by only parsing the
   10477 		* chameleon once, and then copying the components to
   10478 		* the new targetNamespace.
   10479 		*/
   10480 		bkt = NULL;
   10481 	    } else {
   10482 		relation->bucket = bkt;
   10483 		goto exit;
   10484 	    }
   10485 	}
   10486     }
   10487     if ((bkt != NULL) && (bkt->doc != NULL)) {
   10488 	PERROR_INT("xmlSchemaAddSchemaDoc",
   10489 	    "trying to load a schema doc, but a doc is already "
   10490 	    "assigned to the schema bucket");
   10491 	goto exit_failure;
   10492     }
   10493 
   10494 doc_load:
   10495     /*
   10496     * Load the document.
   10497     */
   10498     if (schemaDoc != NULL) {
   10499 	doc = schemaDoc;
   10500 	/* Don' free this one, since it was provided by the caller. */
   10501 	preserveDoc = 1;
   10502 	/* TODO: Does the context or the doc hold the location? */
   10503 	if (schemaDoc->URL != NULL)
   10504 	    schemaLocation = xmlDictLookup(pctxt->dict,
   10505 		schemaDoc->URL, -1);
   10506         else
   10507 	    schemaLocation = BAD_CAST "in_memory_buffer";
   10508     } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
   10509 	xmlParserCtxtPtr parserCtxt;
   10510 
   10511 	parserCtxt = xmlNewParserCtxt();
   10512 	if (parserCtxt == NULL) {
   10513 	    xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
   10514 		"allocating a parser context", NULL);
   10515 	    goto exit_failure;
   10516 	}
   10517 	if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
   10518 	    /*
   10519 	    * TODO: Do we have to burden the schema parser dict with all
   10520 	    * the content of the schema doc?
   10521 	    */
   10522 	    xmlDictFree(parserCtxt->dict);
   10523 	    parserCtxt->dict = pctxt->dict;
   10524 	    xmlDictReference(parserCtxt->dict);
   10525 	}
   10526 	if (schemaLocation != NULL) {
   10527 	    /* Parse from file. */
   10528 	    doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
   10529 		NULL, SCHEMAS_PARSE_OPTIONS);
   10530 	} else if (schemaBuffer != NULL) {
   10531 	    /* Parse from memory buffer. */
   10532 	    doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
   10533 		NULL, NULL, SCHEMAS_PARSE_OPTIONS);
   10534 	    schemaLocation = BAD_CAST "in_memory_buffer";
   10535 	    if (doc != NULL)
   10536 		doc->URL = xmlStrdup(schemaLocation);
   10537 	}
   10538 	/*
   10539 	* For <import>:
   10540 	* 2.1 The referent is (a fragment of) a resource which is an
   10541 	* XML document (see clause 1.1), which in turn corresponds to
   10542 	* a <schema> element information item in a well-formed information
   10543 	* set, which in turn corresponds to a valid schema.
   10544 	* TODO: (2.1) fragments of XML documents are not supported.
   10545 	*
   10546 	* 2.2 The referent is a <schema> element information item in
   10547 	* a well-formed information set, which in turn corresponds
   10548 	* to a valid schema.
   10549 	* TODO: (2.2) is not supported.
   10550 	*/
   10551 	if (doc == NULL) {
   10552 	    xmlErrorPtr lerr;
   10553 	    lerr = xmlGetLastError();
   10554 	    /*
   10555 	    * Check if this a parser error, or if the document could
   10556 	    * just not be located.
   10557 	    * TODO: Try to find specific error codes to react only on
   10558 	    * localisation failures.
   10559 	    */
   10560 	    if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
   10561 		/*
   10562 		* We assume a parser error here.
   10563 		*/
   10564 		located = 1;
   10565 		/* TODO: Error code ?? */
   10566 		res = XML_SCHEMAP_SRC_IMPORT_2_1;
   10567 		xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
   10568 		    invokingNode, NULL,
   10569 		    "Failed to parse the XML resource '%s'",
   10570 		    schemaLocation, NULL);
   10571 	    }
   10572 	}
   10573 	xmlFreeParserCtxt(parserCtxt);
   10574 	if ((doc == NULL) && located)
   10575 	    goto exit_error;
   10576     } else {
   10577 	xmlSchemaPErr(pctxt, NULL,
   10578 	    XML_SCHEMAP_NOTHING_TO_PARSE,
   10579 	    "No information for parsing was provided with the "
   10580 	    "given schema parser context.\n",
   10581 	    NULL, NULL);
   10582 	goto exit_failure;
   10583     }
   10584     /*
   10585     * Preprocess the document.
   10586     */
   10587     if (doc != NULL) {
   10588 	xmlNodePtr docElem = NULL;
   10589 
   10590 	located = 1;
   10591 	docElem = xmlDocGetRootElement(doc);
   10592 	if (docElem == NULL) {
   10593 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
   10594 		invokingNode, NULL,
   10595 		"The document '%s' has no document element",
   10596 		schemaLocation, NULL);
   10597 	    goto exit_error;
   10598 	}
   10599 	/*
   10600 	* Remove all the blank text nodes.
   10601 	*/
   10602 	xmlSchemaCleanupDoc(pctxt, docElem);
   10603 	/*
   10604 	* Check the schema's top level element.
   10605 	*/
   10606 	if (!IS_SCHEMA(docElem, "schema")) {
   10607 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
   10608 		invokingNode, NULL,
   10609 		"The XML document '%s' is not a schema document",
   10610 		schemaLocation, NULL);
   10611 	    goto exit_error;
   10612 	}
   10613 	/*
   10614 	* Note that we don't apply a type check for the
   10615 	* targetNamespace value here.
   10616 	*/
   10617 	targetNamespace = xmlSchemaGetProp(pctxt, docElem,
   10618 	    "targetNamespace");
   10619     }
   10620 
   10621 /* after_doc_loading: */
   10622     if ((bkt == NULL) && located) {
   10623 	/* Only create a bucket if the schema was located. */
   10624         bkt = xmlSchemaBucketCreate(pctxt, type,
   10625 	    targetNamespace);
   10626 	if (bkt == NULL)
   10627 	    goto exit_failure;
   10628     }
   10629     if (bkt != NULL) {
   10630 	bkt->schemaLocation = schemaLocation;
   10631 	bkt->located = located;
   10632 	if (doc != NULL) {
   10633 	    bkt->doc = doc;
   10634 	    bkt->targetNamespace = targetNamespace;
   10635 	    bkt->origTargetNamespace = targetNamespace;
   10636 	    if (preserveDoc)
   10637 		bkt->preserveDoc = 1;
   10638 	}
   10639 	if (WXS_IS_BUCKET_IMPMAIN(type))
   10640 	    bkt->imported++;
   10641 	    /*
   10642 	    * Add it to the graph of schemas.
   10643 	    */
   10644 	if (relation != NULL)
   10645 	    relation->bucket = bkt;
   10646     }
   10647 
   10648 exit:
   10649     /*
   10650     * Return the bucket explicitely; this is needed for the
   10651     * main schema.
   10652     */
   10653     if (bucket != NULL)
   10654 	*bucket = bkt;
   10655     return (0);
   10656 
   10657 exit_error:
   10658     if ((doc != NULL) && (! preserveDoc)) {
   10659 	xmlFreeDoc(doc);
   10660 	if (bkt != NULL)
   10661 	    bkt->doc = NULL;
   10662     }
   10663     return(pctxt->err);
   10664 
   10665 exit_failure:
   10666     if ((doc != NULL) && (! preserveDoc)) {
   10667 	xmlFreeDoc(doc);
   10668 	if (bkt != NULL)
   10669 	    bkt->doc = NULL;
   10670     }
   10671     return (-1);
   10672 }
   10673 
   10674 /**
   10675  * xmlSchemaParseImport:
   10676  * @ctxt:  a schema validation context
   10677  * @schema:  the schema being built
   10678  * @node:  a subtree containing XML Schema informations
   10679  *
   10680  * parse a XML schema Import definition
   10681  * *WARNING* this interface is highly subject to change
   10682  *
   10683  * Returns 0 in case of success, a positive error code if
   10684  * not valid and -1 in case of an internal error.
   10685  */
   10686 static int
   10687 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
   10688                      xmlNodePtr node)
   10689 {
   10690     xmlNodePtr child;
   10691     const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
   10692     const xmlChar *thisTargetNamespace;
   10693     xmlAttrPtr attr;
   10694     int ret = 0;
   10695     xmlSchemaBucketPtr bucket = NULL;
   10696 
   10697     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   10698         return (-1);
   10699 
   10700     /*
   10701     * Check for illegal attributes.
   10702     */
   10703     attr = node->properties;
   10704     while (attr != NULL) {
   10705 	if (attr->ns == NULL) {
   10706 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   10707 		(!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
   10708 		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
   10709 		xmlSchemaPIllegalAttrErr(pctxt,
   10710 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10711 	    }
   10712 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   10713 	    xmlSchemaPIllegalAttrErr(pctxt,
   10714 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10715 	}
   10716 	attr = attr->next;
   10717     }
   10718     /*
   10719     * Extract and validate attributes.
   10720     */
   10721     if (xmlSchemaPValAttr(pctxt, NULL, node,
   10722 	"namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10723 	&namespaceName) != 0) {
   10724 	xmlSchemaPSimpleTypeErr(pctxt,
   10725 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   10726 	    NULL, node,
   10727 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10728 	    NULL, namespaceName, NULL, NULL, NULL);
   10729 	return (pctxt->err);
   10730     }
   10731 
   10732     if (xmlSchemaPValAttr(pctxt, NULL, node,
   10733 	"schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10734 	&schemaLocation) != 0) {
   10735 	xmlSchemaPSimpleTypeErr(pctxt,
   10736 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   10737 	    NULL, node,
   10738 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10739 	    NULL, namespaceName, NULL, NULL, NULL);
   10740 	return (pctxt->err);
   10741     }
   10742     /*
   10743     * And now for the children...
   10744     */
   10745     child = node->children;
   10746     if (IS_SCHEMA(child, "annotation")) {
   10747         /*
   10748          * the annotation here is simply discarded ...
   10749 	 * TODO: really?
   10750          */
   10751         child = child->next;
   10752     }
   10753     if (child != NULL) {
   10754 	xmlSchemaPContentErr(pctxt,
   10755 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   10756 	    NULL, node, child, NULL,
   10757 	    "(annotation?)");
   10758     }
   10759     /*
   10760     * Apply additional constraints.
   10761     *
   10762     * Note that it is important to use the original @targetNamespace
   10763     * (or none at all), to rule out imports of schemas _with_ a
   10764     * @targetNamespace if the importing schema is a chameleon schema
   10765     * (with no @targetNamespace).
   10766     */
   10767     thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
   10768     if (namespaceName != NULL) {
   10769 	/*
   10770 	* 1.1 If the namespace [attribute] is present, then its actual value
   10771 	* must not match the actual value of the enclosing <schema>'s
   10772 	* targetNamespace [attribute].
   10773 	*/
   10774 	if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
   10775 	    xmlSchemaPCustomErr(pctxt,
   10776 		XML_SCHEMAP_SRC_IMPORT_1_1,
   10777 		NULL, node,
   10778 		"The value of the attribute 'namespace' must not match "
   10779 		"the target namespace '%s' of the importing schema",
   10780 		thisTargetNamespace);
   10781 	    return (pctxt->err);
   10782 	}
   10783     } else {
   10784 	/*
   10785 	* 1.2 If the namespace [attribute] is not present, then the enclosing
   10786 	* <schema> must have a targetNamespace [attribute].
   10787 	*/
   10788 	if (thisTargetNamespace == NULL) {
   10789 	    xmlSchemaPCustomErr(pctxt,
   10790 		XML_SCHEMAP_SRC_IMPORT_1_2,
   10791 		NULL, node,
   10792 		"The attribute 'namespace' must be existent if "
   10793 		"the importing schema has no target namespace",
   10794 		NULL);
   10795 	    return (pctxt->err);
   10796 	}
   10797     }
   10798     /*
   10799     * Locate and acquire the schema document.
   10800     */
   10801     if (schemaLocation != NULL)
   10802 	schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
   10803 	    schemaLocation, node);
   10804     ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
   10805 	schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
   10806 	namespaceName, &bucket);
   10807 
   10808     if (ret != 0)
   10809 	return(ret);
   10810 
   10811     /*
   10812     * For <import>: "It is *not* an error for the application
   10813     * schema reference strategy to fail."
   10814     * So just don't parse if no schema document was found.
   10815     * Note that we will get no bucket if the schema could not be
   10816     * located or if there was no schemaLocation.
   10817     */
   10818     if ((bucket == NULL) && (schemaLocation != NULL)) {
   10819 	xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   10820 	    XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
   10821 	    node, NULL,
   10822 	    "Failed to locate a schema at location '%s'. "
   10823 	    "Skipping the import", schemaLocation, NULL, NULL);
   10824     }
   10825 
   10826     if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
   10827 	ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
   10828     }
   10829 
   10830     return (ret);
   10831 }
   10832 
   10833 static int
   10834 xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
   10835 				     xmlSchemaPtr schema,
   10836 				     xmlNodePtr node,
   10837 				     xmlChar **schemaLocation,
   10838 				     int type)
   10839 {
   10840     xmlAttrPtr attr;
   10841 
   10842     if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
   10843 	(schemaLocation == NULL))
   10844         return (-1);
   10845 
   10846     *schemaLocation = NULL;
   10847     /*
   10848     * Check for illegal attributes.
   10849     * Applies for both <include> and <redefine>.
   10850     */
   10851     attr = node->properties;
   10852     while (attr != NULL) {
   10853 	if (attr->ns == NULL) {
   10854 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   10855 		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
   10856 		xmlSchemaPIllegalAttrErr(pctxt,
   10857 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10858 	    }
   10859 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   10860 	    xmlSchemaPIllegalAttrErr(pctxt,
   10861 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10862 	}
   10863 	attr = attr->next;
   10864     }
   10865     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   10866     /*
   10867     * Preliminary step, extract the URI-Reference and make an URI
   10868     * from the base.
   10869     */
   10870     /*
   10871     * Attribute "schemaLocation" is mandatory.
   10872     */
   10873     attr = xmlSchemaGetPropNode(node, "schemaLocation");
   10874     if (attr != NULL) {
   10875         xmlChar *base = NULL;
   10876         xmlChar *uri = NULL;
   10877 
   10878 	if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
   10879 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10880 	    (const xmlChar **) schemaLocation) != 0)
   10881 	    goto exit_error;
   10882 	base = xmlNodeGetBase(node->doc, node);
   10883 	if (base == NULL) {
   10884 	    uri = xmlBuildURI(*schemaLocation, node->doc->URL);
   10885 	} else {
   10886 	    uri = xmlBuildURI(*schemaLocation, base);
   10887 	    xmlFree(base);
   10888 	}
   10889 	if (uri == NULL) {
   10890 	    PERROR_INT("xmlSchemaParseIncludeOrRedefine",
   10891 		"could not build an URI from the schemaLocation")
   10892 	    goto exit_failure;
   10893 	}
   10894 	(*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
   10895 	xmlFree(uri);
   10896     } else {
   10897 	xmlSchemaPMissingAttrErr(pctxt,
   10898 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   10899 	    NULL, node, "schemaLocation", NULL);
   10900 	goto exit_error;
   10901     }
   10902     /*
   10903     * Report self-inclusion and self-redefinition.
   10904     */
   10905     if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
   10906 	if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
   10907 	    xmlSchemaPCustomErr(pctxt,
   10908 		XML_SCHEMAP_SRC_REDEFINE,
   10909 		NULL, node,
   10910 		"The schema document '%s' cannot redefine itself.",
   10911 		*schemaLocation);
   10912 	} else {
   10913 	    xmlSchemaPCustomErr(pctxt,
   10914 		XML_SCHEMAP_SRC_INCLUDE,
   10915 		NULL, node,
   10916 		"The schema document '%s' cannot include itself.",
   10917 		*schemaLocation);
   10918 	}
   10919 	goto exit_error;
   10920     }
   10921 
   10922     return(0);
   10923 exit_error:
   10924     return(pctxt->err);
   10925 exit_failure:
   10926     return(-1);
   10927 }
   10928 
   10929 static int
   10930 xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
   10931 				xmlSchemaPtr schema,
   10932 				xmlNodePtr node,
   10933 				int type)
   10934 {
   10935     xmlNodePtr child = NULL;
   10936     const xmlChar *schemaLocation = NULL;
   10937     int res = 0; /* hasRedefinitions = 0 */
   10938     int isChameleon = 0, wasChameleon = 0;
   10939     xmlSchemaBucketPtr bucket = NULL;
   10940 
   10941     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   10942         return (-1);
   10943 
   10944     /*
   10945     * Parse attributes. Note that the returned schemaLocation will
   10946     * be already converted to an absolute URI.
   10947     */
   10948     res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
   10949 	node, (xmlChar **) (&schemaLocation), type);
   10950     if (res != 0)
   10951 	return(res);
   10952     /*
   10953     * Load and add the schema document.
   10954     */
   10955     res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
   10956 	NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
   10957     if (res != 0)
   10958 	return(res);
   10959     /*
   10960     * If we get no schema bucket back, then this means that the schema
   10961     * document could not be located or was broken XML or was not
   10962     * a schema document.
   10963     */
   10964     if ((bucket == NULL) || (bucket->doc == NULL)) {
   10965 	if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
   10966 	    /*
   10967 	    * WARNING for <include>:
   10968 	    * We will raise an error if the schema cannot be located
   10969 	    * for inclusions, since the that was the feedback from the
   10970 	    * schema people. I.e. the following spec piece will *not* be
   10971 	    * satisfied:
   10972 	    * SPEC src-include: "It is not an error for the actual value of the
   10973 	    * schemaLocation [attribute] to fail to resolve it all, in which
   10974 	    * case no corresponding inclusion is performed.
   10975 	    * So do we need a warning report here?"
   10976 	    */
   10977 	    res = XML_SCHEMAP_SRC_INCLUDE;
   10978 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
   10979 		node, NULL,
   10980 		"Failed to load the document '%s' for inclusion",
   10981 		schemaLocation, NULL);
   10982 	} else {
   10983 	    /*
   10984 	    * NOTE: This was changed to raise an error even if no redefinitions
   10985 	    * are specified.
   10986 	    *
   10987 	    * SPEC src-redefine (1)
   10988 	    * "If there are any element information items among the [children]
   10989 	    * other than <annotation> then the actual value of the
   10990 	    * schemaLocation [attribute] must successfully resolve."
   10991 	    * TODO: Ask the WG if a the location has always to resolve
   10992 	    * here as well!
   10993 	    */
   10994 	    res = XML_SCHEMAP_SRC_REDEFINE;
   10995 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
   10996 		node, NULL,
   10997 		"Failed to load the document '%s' for redefinition",
   10998 		schemaLocation, NULL);
   10999 	}
   11000     } else {
   11001 	/*
   11002 	* Check targetNamespace sanity before parsing the new schema.
   11003 	* TODO: Note that we won't check further content if the
   11004 	* targetNamespace was bad.
   11005 	*/
   11006 	if (bucket->origTargetNamespace != NULL) {
   11007 	    /*
   11008 	    * SPEC src-include (2.1)
   11009 	    * "SII has a targetNamespace [attribute], and its actual
   11010 	    * value is identical to the actual value of the targetNamespace
   11011 	    * [attribute] of SII (which must have such an [attribute])."
   11012 	    */
   11013 	    if (pctxt->targetNamespace == NULL) {
   11014 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   11015 		    XML_SCHEMAP_SRC_INCLUDE,
   11016 		    node, NULL,
   11017 		    "The target namespace of the included/redefined schema "
   11018 		    "'%s' has to be absent, since the including/redefining "
   11019 		    "schema has no target namespace",
   11020 		    schemaLocation, NULL);
   11021 		goto exit_error;
   11022 	    } else if (!xmlStrEqual(bucket->origTargetNamespace,
   11023 		pctxt->targetNamespace)) {
   11024 		/* TODO: Change error function. */
   11025 		xmlSchemaPCustomErrExt(pctxt,
   11026 		    XML_SCHEMAP_SRC_INCLUDE,
   11027 		    NULL, node,
   11028 		    "The target namespace '%s' of the included/redefined "
   11029 		    "schema '%s' differs from '%s' of the "
   11030 		    "including/redefining schema",
   11031 		    bucket->origTargetNamespace, schemaLocation,
   11032 		    pctxt->targetNamespace);
   11033 		goto exit_error;
   11034 	    }
   11035 	} else if (pctxt->targetNamespace != NULL) {
   11036 	    /*
   11037 	    * Chameleons: the original target namespace will
   11038 	    * differ from the resulting namespace.
   11039 	    */
   11040 	    isChameleon = 1;
   11041 	    if (bucket->parsed &&
   11042 		bucket->origTargetNamespace != NULL) {
   11043 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   11044 		    XML_SCHEMAP_SRC_INCLUDE,
   11045 		    node, NULL,
   11046 		    "The target namespace of the included/redefined schema "
   11047 		    "'%s' has to be absent or the same as the "
   11048 		    "including/redefining schema's target namespace",
   11049 		    schemaLocation, NULL);
   11050 		goto exit_error;
   11051 	    }
   11052 	    bucket->targetNamespace = pctxt->targetNamespace;
   11053 	}
   11054     }
   11055     /*
   11056     * Parse the schema.
   11057     */
   11058     if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
   11059 	if (isChameleon) {
   11060 	    /* TODO: Get rid of this flag on the schema itself. */
   11061 	    if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
   11062 		schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
   11063 	    } else
   11064 		wasChameleon = 1;
   11065 	}
   11066 	xmlSchemaParseNewDoc(pctxt, schema, bucket);
   11067 	/* Restore chameleon flag. */
   11068 	if (isChameleon && (!wasChameleon))
   11069 	    schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
   11070     }
   11071     /*
   11072     * And now for the children...
   11073     */
   11074     child = node->children;
   11075     if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
   11076 	/*
   11077 	* Parse (simpleType | complexType | group | attributeGroup))*
   11078 	*/
   11079 	pctxt->redefined = bucket;
   11080 	/*
   11081 	* How to proceed if the redefined schema was not located?
   11082 	*/
   11083 	pctxt->isRedefine = 1;
   11084 	while (IS_SCHEMA(child, "annotation") ||
   11085 	    IS_SCHEMA(child, "simpleType") ||
   11086 	    IS_SCHEMA(child, "complexType") ||
   11087 	    IS_SCHEMA(child, "group") ||
   11088 	    IS_SCHEMA(child, "attributeGroup")) {
   11089 	    if (IS_SCHEMA(child, "annotation")) {
   11090 		/*
   11091 		* TODO: discard or not?
   11092 		*/
   11093 	    } else if (IS_SCHEMA(child, "simpleType")) {
   11094 		xmlSchemaParseSimpleType(pctxt, schema, child, 1);
   11095 	    } else if (IS_SCHEMA(child, "complexType")) {
   11096 		xmlSchemaParseComplexType(pctxt, schema, child, 1);
   11097 		/* hasRedefinitions = 1; */
   11098 	    } else if (IS_SCHEMA(child, "group")) {
   11099 		/* hasRedefinitions = 1; */
   11100 		xmlSchemaParseModelGroupDefinition(pctxt,
   11101 		    schema, child);
   11102 	    } else if (IS_SCHEMA(child, "attributeGroup")) {
   11103 		/* hasRedefinitions = 1; */
   11104 		xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
   11105 		    child);
   11106 	    }
   11107 	    child = child->next;
   11108 	}
   11109 	pctxt->redefined = NULL;
   11110 	pctxt->isRedefine = 0;
   11111     } else {
   11112 	if (IS_SCHEMA(child, "annotation")) {
   11113 	    /*
   11114 	    * TODO: discard or not?
   11115 	    */
   11116 	    child = child->next;
   11117 	}
   11118     }
   11119     if (child != NULL) {
   11120 	res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
   11121 	if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
   11122 	    xmlSchemaPContentErr(pctxt, res,
   11123 		NULL, node, child, NULL,
   11124 		"(annotation | (simpleType | complexType | group | attributeGroup))*");
   11125 	} else {
   11126 	     xmlSchemaPContentErr(pctxt, res,
   11127 		NULL, node, child, NULL,
   11128 		"(annotation?)");
   11129 	}
   11130     }
   11131     return(res);
   11132 
   11133 exit_error:
   11134     return(pctxt->err);
   11135 }
   11136 
   11137 static int
   11138 xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
   11139                        xmlNodePtr node)
   11140 {
   11141     int res;
   11142 #ifndef ENABLE_REDEFINE
   11143     TODO
   11144     return(0);
   11145 #endif
   11146     res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
   11147 	XML_SCHEMA_SCHEMA_REDEFINE);
   11148     if (res != 0)
   11149 	return(res);
   11150     return(0);
   11151 }
   11152 
   11153 static int
   11154 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
   11155                        xmlNodePtr node)
   11156 {
   11157     int res;
   11158 
   11159     res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
   11160 	XML_SCHEMA_SCHEMA_INCLUDE);
   11161     if (res != 0)
   11162 	return(res);
   11163     return(0);
   11164 }
   11165 
   11166 /**
   11167  * xmlSchemaParseModelGroup:
   11168  * @ctxt:  a schema validation context
   11169  * @schema:  the schema being built
   11170  * @node:  a subtree containing XML Schema informations
   11171  * @type: the "compositor" type
   11172  * @particleNeeded: if a a model group with a particle
   11173  *
   11174  * parse a XML schema Sequence definition.
   11175  * Applies parts of:
   11176  *   Schema Representation Constraint:
   11177  *     Redefinition Constraints and Semantics (src-redefine)
   11178  *     (6.1), (6.1.1), (6.1.2)
   11179  *
   11180  *   Schema Component Constraint:
   11181  *     All Group Limited (cos-all-limited) (2)
   11182  *     TODO: Actually this should go to component-level checks,
   11183  *     but is done here due to performance. Move it to an other layer
   11184  *     is schema construction via an API is implemented.
   11185  *
   11186  * *WARNING* this interface is highly subject to change
   11187  *
   11188  * Returns -1 in case of error, 0 if the declaration is improper and
   11189  *         1 in case of success.
   11190  */
   11191 static xmlSchemaTreeItemPtr
   11192 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   11193 			 xmlNodePtr node, xmlSchemaTypeType type,
   11194 			 int withParticle)
   11195 {
   11196     xmlSchemaModelGroupPtr item;
   11197     xmlSchemaParticlePtr particle = NULL;
   11198     xmlNodePtr child = NULL;
   11199     xmlAttrPtr attr;
   11200     int min = 1, max = 1, isElemRef, hasRefs = 0;
   11201 
   11202     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   11203         return (NULL);
   11204     /*
   11205     * Create a model group with the given compositor.
   11206     */
   11207     item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
   11208     if (item == NULL)
   11209 	return (NULL);
   11210 
   11211     if (withParticle) {
   11212 	if (type == XML_SCHEMA_TYPE_ALL) {
   11213 	    min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
   11214 	    max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
   11215 	} else {
   11216 	    /* choice + sequence */
   11217 	    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
   11218 	    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
   11219 		"(xs:nonNegativeInteger | unbounded)");
   11220 	}
   11221 	xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
   11222 	/*
   11223 	* Create a particle
   11224 	*/
   11225 	particle = xmlSchemaAddParticle(ctxt, node, min, max);
   11226 	if (particle == NULL)
   11227 	    return (NULL);
   11228 	particle->children = (xmlSchemaTreeItemPtr) item;
   11229 	/*
   11230 	* Check for illegal attributes.
   11231 	*/
   11232 	attr = node->properties;
   11233 	while (attr != NULL) {
   11234 	    if (attr->ns == NULL) {
   11235 		if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   11236 		    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
   11237 		    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
   11238 		    xmlSchemaPIllegalAttrErr(ctxt,
   11239 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11240 		}
   11241 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11242 		xmlSchemaPIllegalAttrErr(ctxt,
   11243 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11244 	    }
   11245 	    attr = attr->next;
   11246 	}
   11247     } else {
   11248 	/*
   11249 	* Check for illegal attributes.
   11250 	*/
   11251 	attr = node->properties;
   11252 	while (attr != NULL) {
   11253 	    if (attr->ns == NULL) {
   11254 		if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
   11255 		    xmlSchemaPIllegalAttrErr(ctxt,
   11256 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11257 		}
   11258 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11259 		xmlSchemaPIllegalAttrErr(ctxt,
   11260 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11261 	    }
   11262 	    attr = attr->next;
   11263 	}
   11264     }
   11265 
   11266     /*
   11267     * Extract and validate attributes.
   11268     */
   11269     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   11270     /*
   11271     * And now for the children...
   11272     */
   11273     child = node->children;
   11274     if (IS_SCHEMA(child, "annotation")) {
   11275         item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   11276         child = child->next;
   11277     }
   11278     if (type == XML_SCHEMA_TYPE_ALL) {
   11279 	xmlSchemaParticlePtr part, last = NULL;
   11280 
   11281 	while (IS_SCHEMA(child, "element")) {
   11282 	    part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
   11283 		schema, child, &isElemRef, 0);
   11284 	    /*
   11285 	    * SPEC cos-all-limited (2)
   11286 	    * "The {max occurs} of all the particles in the {particles}
   11287 	    * of the ('all') group must be 0 or 1.
   11288 	    */
   11289 	    if (part != NULL) {
   11290 		if (isElemRef)
   11291 		    hasRefs++;
   11292 		if (part->minOccurs > 1) {
   11293 		    xmlSchemaPCustomErr(ctxt,
   11294 			XML_SCHEMAP_COS_ALL_LIMITED,
   11295 			NULL, child,
   11296 			"Invalid value for minOccurs (must be 0 or 1)",
   11297 			NULL);
   11298 		    /* Reset to 1. */
   11299 		    part->minOccurs = 1;
   11300 		}
   11301 		if (part->maxOccurs > 1) {
   11302 		    xmlSchemaPCustomErr(ctxt,
   11303 			XML_SCHEMAP_COS_ALL_LIMITED,
   11304 			NULL, child,
   11305 			"Invalid value for maxOccurs (must be 0 or 1)",
   11306 			NULL);
   11307 		    /* Reset to 1. */
   11308 		    part->maxOccurs = 1;
   11309 		}
   11310 		if (last == NULL)
   11311 		    item->children = (xmlSchemaTreeItemPtr) part;
   11312 		else
   11313 		    last->next = (xmlSchemaTreeItemPtr) part;
   11314 		last = part;
   11315 	    }
   11316 	    child = child->next;
   11317 	}
   11318 	if (child != NULL) {
   11319 	    xmlSchemaPContentErr(ctxt,
   11320 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11321 		NULL, node, child, NULL,
   11322 		"(annotation?, (annotation?, element*)");
   11323 	}
   11324     } else {
   11325 	/* choice + sequence */
   11326 	xmlSchemaTreeItemPtr part = NULL, last = NULL;
   11327 
   11328 	while ((IS_SCHEMA(child, "element")) ||
   11329 	    (IS_SCHEMA(child, "group")) ||
   11330 	    (IS_SCHEMA(child, "any")) ||
   11331 	    (IS_SCHEMA(child, "choice")) ||
   11332 	    (IS_SCHEMA(child, "sequence"))) {
   11333 
   11334 	    if (IS_SCHEMA(child, "element")) {
   11335 		part = (xmlSchemaTreeItemPtr)
   11336 		    xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
   11337 		if (part && isElemRef)
   11338 		    hasRefs++;
   11339 	    } else if (IS_SCHEMA(child, "group")) {
   11340 		part =
   11341 		    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
   11342 		if (part != NULL)
   11343 		    hasRefs++;
   11344 		/*
   11345 		* Handle redefinitions.
   11346 		*/
   11347 		if (ctxt->isRedefine && ctxt->redef &&
   11348 		    (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
   11349 		    part && part->children)
   11350 		{
   11351 		    if ((xmlSchemaGetQNameRefName(part->children) ==
   11352 			    ctxt->redef->refName) &&
   11353 			(xmlSchemaGetQNameRefTargetNs(part->children) ==
   11354 			    ctxt->redef->refTargetNs))
   11355 		    {
   11356 			/*
   11357 			* SPEC src-redefine:
   11358 			* (6.1) "If it has a <group> among its contents at
   11359 			* some level the actual value of whose ref
   11360 			* [attribute] is the same as the actual value of
   11361 			* its own name attribute plus target namespace, then
   11362 			* all of the following must be true:"
   11363 			* (6.1.1) "It must have exactly one such group."
   11364 			*/
   11365 			if (ctxt->redefCounter != 0) {
   11366 			    xmlChar *str = NULL;
   11367 
   11368 			    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   11369 				XML_SCHEMAP_SRC_REDEFINE, child, NULL,
   11370 				"The redefining model group definition "
   11371 				"'%s' must not contain more than one "
   11372 				"reference to the redefined definition",
   11373 				xmlSchemaFormatQName(&str,
   11374 				    ctxt->redef->refTargetNs,
   11375 				    ctxt->redef->refName),
   11376 				NULL);
   11377 			    FREE_AND_NULL(str)
   11378 			    part = NULL;
   11379 			} else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
   11380 			    ((WXS_PARTICLE(part))->maxOccurs != 1))
   11381 			{
   11382 			    xmlChar *str = NULL;
   11383 			    /*
   11384 			    * SPEC src-redefine:
   11385 			    * (6.1.2) "The actual value of both that
   11386 			    * group's minOccurs and maxOccurs [attribute]
   11387 			    * must be 1 (or absent).
   11388 			    */
   11389 			    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   11390 				XML_SCHEMAP_SRC_REDEFINE, child, NULL,
   11391 				"The redefining model group definition "
   11392 				"'%s' must not contain a reference to the "
   11393 				"redefined definition with a "
   11394 				"maxOccurs/minOccurs other than 1",
   11395 				xmlSchemaFormatQName(&str,
   11396 				    ctxt->redef->refTargetNs,
   11397 				    ctxt->redef->refName),
   11398 				NULL);
   11399 			    FREE_AND_NULL(str)
   11400 			    part = NULL;
   11401 			}
   11402 			ctxt->redef->reference = WXS_BASIC_CAST part;
   11403 			ctxt->redefCounter++;
   11404 		    }
   11405 		}
   11406 	    } else if (IS_SCHEMA(child, "any")) {
   11407 		part = (xmlSchemaTreeItemPtr)
   11408 		    xmlSchemaParseAny(ctxt, schema, child);
   11409 	    } else if (IS_SCHEMA(child, "choice")) {
   11410 		part = xmlSchemaParseModelGroup(ctxt, schema, child,
   11411 		    XML_SCHEMA_TYPE_CHOICE, 1);
   11412 	    } else if (IS_SCHEMA(child, "sequence")) {
   11413 		part = xmlSchemaParseModelGroup(ctxt, schema, child,
   11414 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
   11415 	    }
   11416 	    if (part != NULL) {
   11417 		if (last == NULL)
   11418 		    item->children = part;
   11419 		else
   11420 		    last->next = part;
   11421 		last = part;
   11422 	    }
   11423 	    child = child->next;
   11424 	}
   11425 	if (child != NULL) {
   11426 	    xmlSchemaPContentErr(ctxt,
   11427 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11428 		NULL, node, child, NULL,
   11429 		"(annotation?, (element | group | choice | sequence | any)*)");
   11430 	}
   11431     }
   11432     if ((max == 0) && (min == 0))
   11433 	return (NULL);
   11434     if (hasRefs) {
   11435 	/*
   11436 	* We need to resolve references.
   11437 	*/
   11438 	WXS_ADD_PENDING(ctxt, item);
   11439     }
   11440     if (withParticle)
   11441 	return ((xmlSchemaTreeItemPtr) particle);
   11442     else
   11443 	return ((xmlSchemaTreeItemPtr) item);
   11444 }
   11445 
   11446 /**
   11447  * xmlSchemaParseRestriction:
   11448  * @ctxt:  a schema validation context
   11449  * @schema:  the schema being built
   11450  * @node:  a subtree containing XML Schema informations
   11451  *
   11452  * parse a XML schema Restriction definition
   11453  * *WARNING* this interface is highly subject to change
   11454  *
   11455  * Returns the type definition or NULL in case of error
   11456  */
   11457 static xmlSchemaTypePtr
   11458 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   11459                           xmlNodePtr node, xmlSchemaTypeType parentType)
   11460 {
   11461     xmlSchemaTypePtr type;
   11462     xmlNodePtr child = NULL;
   11463     xmlAttrPtr attr;
   11464 
   11465     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   11466         return (NULL);
   11467     /* Not a component, don't create it. */
   11468     type = ctxt->ctxtType;
   11469     type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
   11470 
   11471     /*
   11472     * Check for illegal attributes.
   11473     */
   11474     attr = node->properties;
   11475     while (attr != NULL) {
   11476 	if (attr->ns == NULL) {
   11477 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   11478 		(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
   11479 		xmlSchemaPIllegalAttrErr(ctxt,
   11480 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11481 	    }
   11482 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11483 	    xmlSchemaPIllegalAttrErr(ctxt,
   11484 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11485 	}
   11486 	attr = attr->next;
   11487     }
   11488     /*
   11489     * Extract and validate attributes.
   11490     */
   11491     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   11492     /*
   11493     * Attribute
   11494     */
   11495     /*
   11496     * Extract the base type. The "base" attribute is mandatory if inside
   11497     * a complex type or if redefining.
   11498     *
   11499     * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
   11500     * among its [children]), the simple type definition which is
   11501     * the {content type} of the type definition resolved to by
   11502     * the actual value of the base [attribute]"
   11503     */
   11504     if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
   11505 	&(type->baseNs), &(type->base)) == 0)
   11506     {
   11507 	if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
   11508 	    xmlSchemaPMissingAttrErr(ctxt,
   11509 		XML_SCHEMAP_S4S_ATTR_MISSING,
   11510 		NULL, node, "base", NULL);
   11511 	} else if ((ctxt->isRedefine) &&
   11512 	    (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
   11513 	{
   11514 	    if (type->base == NULL) {
   11515 		xmlSchemaPMissingAttrErr(ctxt,
   11516 		    XML_SCHEMAP_S4S_ATTR_MISSING,
   11517 		    NULL, node, "base", NULL);
   11518 	    } else if ((! xmlStrEqual(type->base, type->name)) ||
   11519 		(! xmlStrEqual(type->baseNs, type->targetNamespace)))
   11520 	    {
   11521 		xmlChar *str1 = NULL, *str2 = NULL;
   11522 		/*
   11523 		* REDEFINE: SPEC src-redefine (5)
   11524 		* "Within the [children], each <simpleType> must have a
   11525 		* <restriction> among its [children] ... the actual value of
   11526 		* whose base [attribute] must be the same as the actual value
   11527 		* of its own name attribute plus target namespace;"
   11528 		*/
   11529 		xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   11530 		    NULL, node, "This is a redefinition, but the QName "
   11531 		    "value '%s' of the 'base' attribute does not match the "
   11532 		    "type's designation '%s'",
   11533 		    xmlSchemaFormatQName(&str1, type->baseNs, type->base),
   11534 		    xmlSchemaFormatQName(&str2, type->targetNamespace,
   11535 			type->name), NULL);
   11536 		FREE_AND_NULL(str1);
   11537 		FREE_AND_NULL(str2);
   11538 		/* Avoid confusion and erase the values. */
   11539 		type->base = NULL;
   11540 		type->baseNs = NULL;
   11541 	    }
   11542 	}
   11543     }
   11544     /*
   11545     * And now for the children...
   11546     */
   11547     child = node->children;
   11548     if (IS_SCHEMA(child, "annotation")) {
   11549 	/*
   11550 	* Add the annotation to the simple type ancestor.
   11551 	*/
   11552 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   11553 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   11554         child = child->next;
   11555     }
   11556     if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
   11557 	/*
   11558 	* Corresponds to <simpleType><restriction><simpleType>.
   11559 	*/
   11560 	if (IS_SCHEMA(child, "simpleType")) {
   11561 	    if (type->base != NULL) {
   11562 		/*
   11563 		* src-restriction-base-or-simpleType
   11564 		* Either the base [attribute] or the simpleType [child] of the
   11565 		* <restriction> element must be present, but not both.
   11566 		*/
   11567 		xmlSchemaPContentErr(ctxt,
   11568 		    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
   11569 		    NULL, node, child,
   11570 		    "The attribute 'base' and the <simpleType> child are "
   11571 		    "mutually exclusive", NULL);
   11572 	    } else {
   11573 		type->baseType = (xmlSchemaTypePtr)
   11574 		    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   11575 	    }
   11576 	    child = child->next;
   11577 	} else if (type->base == NULL) {
   11578 	    xmlSchemaPContentErr(ctxt,
   11579 		XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
   11580 		NULL, node, child,
   11581 		"Either the attribute 'base' or a <simpleType> child "
   11582 		"must be present", NULL);
   11583 	}
   11584     } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
   11585 	/*
   11586 	* Corresponds to <complexType><complexContent><restriction>...
   11587 	* followed by:
   11588 	*
   11589 	* Model groups <all>, <choice> and <sequence>.
   11590 	*/
   11591 	if (IS_SCHEMA(child, "all")) {
   11592 	    type->subtypes = (xmlSchemaTypePtr)
   11593 		xmlSchemaParseModelGroup(ctxt, schema, child,
   11594 		    XML_SCHEMA_TYPE_ALL, 1);
   11595 	    child = child->next;
   11596 	} else if (IS_SCHEMA(child, "choice")) {
   11597 	    type->subtypes = (xmlSchemaTypePtr)
   11598 		xmlSchemaParseModelGroup(ctxt,
   11599 		    schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
   11600 	    child = child->next;
   11601 	} else if (IS_SCHEMA(child, "sequence")) {
   11602 	    type->subtypes = (xmlSchemaTypePtr)
   11603 		xmlSchemaParseModelGroup(ctxt, schema, child,
   11604 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
   11605 	    child = child->next;
   11606 	/*
   11607 	* Model group reference <group>.
   11608 	*/
   11609 	} else if (IS_SCHEMA(child, "group")) {
   11610 	    type->subtypes = (xmlSchemaTypePtr)
   11611 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
   11612 	    /*
   11613 	    * Note that the reference will be resolved in
   11614 	    * xmlSchemaResolveTypeReferences();
   11615 	    */
   11616 	    child = child->next;
   11617 	}
   11618     } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
   11619 	/*
   11620 	* Corresponds to <complexType><simpleContent><restriction>...
   11621 	*
   11622 	* "1.1 the simple type definition corresponding to the <simpleType>
   11623 	* among the [children] of <restriction> if there is one;"
   11624 	*/
   11625 	if (IS_SCHEMA(child, "simpleType")) {
   11626 	    /*
   11627 	    * We will store the to-be-restricted simple type in
   11628 	    * type->contentTypeDef *temporarily*.
   11629 	    */
   11630 	    type->contentTypeDef = (xmlSchemaTypePtr)
   11631 		xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   11632 	    if ( type->contentTypeDef == NULL)
   11633 		return (NULL);
   11634 	    child = child->next;
   11635 	}
   11636     }
   11637 
   11638     if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
   11639 	(parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
   11640 	xmlSchemaFacetPtr facet, lastfacet = NULL;
   11641 	/*
   11642 	* Corresponds to <complexType><simpleContent><restriction>...
   11643 	* <simpleType><restriction>...
   11644 	*/
   11645 
   11646 	/*
   11647 	* Add the facets to the simple type ancestor.
   11648 	*/
   11649 	/*
   11650 	* TODO: Datatypes: 4.1.3 Constraints on XML Representation of
   11651 	* Simple Type Definition Schema Representation Constraint:
   11652 	* *Single Facet Value*
   11653 	*/
   11654 	while ((IS_SCHEMA(child, "minInclusive")) ||
   11655 	    (IS_SCHEMA(child, "minExclusive")) ||
   11656 	    (IS_SCHEMA(child, "maxInclusive")) ||
   11657 	    (IS_SCHEMA(child, "maxExclusive")) ||
   11658 	    (IS_SCHEMA(child, "totalDigits")) ||
   11659 	    (IS_SCHEMA(child, "fractionDigits")) ||
   11660 	    (IS_SCHEMA(child, "pattern")) ||
   11661 	    (IS_SCHEMA(child, "enumeration")) ||
   11662 	    (IS_SCHEMA(child, "whiteSpace")) ||
   11663 	    (IS_SCHEMA(child, "length")) ||
   11664 	    (IS_SCHEMA(child, "maxLength")) ||
   11665 	    (IS_SCHEMA(child, "minLength"))) {
   11666 	    facet = xmlSchemaParseFacet(ctxt, schema, child);
   11667 	    if (facet != NULL) {
   11668 		if (lastfacet == NULL)
   11669 		    type->facets = facet;
   11670 		else
   11671 		    lastfacet->next = facet;
   11672 		lastfacet = facet;
   11673 		lastfacet->next = NULL;
   11674 	    }
   11675 	    child = child->next;
   11676 	}
   11677 	/*
   11678 	* Create links for derivation and validation.
   11679 	*/
   11680 	if (type->facets != NULL) {
   11681 	    xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
   11682 
   11683 	    facet = type->facets;
   11684 	    do {
   11685 		facetLink = (xmlSchemaFacetLinkPtr)
   11686 		    xmlMalloc(sizeof(xmlSchemaFacetLink));
   11687 		if (facetLink == NULL) {
   11688 		    xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
   11689 		    xmlFree(facetLink);
   11690 		    return (NULL);
   11691 		}
   11692 		facetLink->facet = facet;
   11693 		facetLink->next = NULL;
   11694 		if (lastFacetLink == NULL)
   11695 		    type->facetSet = facetLink;
   11696 		else
   11697 		    lastFacetLink->next = facetLink;
   11698 		lastFacetLink = facetLink;
   11699 		facet = facet->next;
   11700 	    } while (facet != NULL);
   11701 	}
   11702     }
   11703     if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
   11704 	/*
   11705 	* Attribute uses/declarations.
   11706 	*/
   11707 	if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
   11708 	    (xmlSchemaItemListPtr *) &(type->attrUses),
   11709 	    XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
   11710 	    return(NULL);
   11711 	/*
   11712 	* Attribute wildcard.
   11713 	*/
   11714 	if (IS_SCHEMA(child, "anyAttribute")) {
   11715 	    type->attributeWildcard =
   11716 		xmlSchemaParseAnyAttribute(ctxt, schema, child);
   11717 	    child = child->next;
   11718 	}
   11719     }
   11720     if (child != NULL) {
   11721 	if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
   11722 	    xmlSchemaPContentErr(ctxt,
   11723 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11724 		NULL, node, child, NULL,
   11725 		"annotation?, (group | all | choice | sequence)?, "
   11726 		"((attribute | attributeGroup)*, anyAttribute?))");
   11727 	} else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
   11728 	     xmlSchemaPContentErr(ctxt,
   11729 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11730 		NULL, node, child, NULL,
   11731 		"(annotation?, (simpleType?, (minExclusive | minInclusive | "
   11732 		"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
   11733 		"length | minLength | maxLength | enumeration | whiteSpace | "
   11734 		"pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
   11735 	} else {
   11736 	    /* Simple type */
   11737 	    xmlSchemaPContentErr(ctxt,
   11738 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11739 		NULL, node, child, NULL,
   11740 		"(annotation?, (simpleType?, (minExclusive | minInclusive | "
   11741 		"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
   11742 		"length | minLength | maxLength | enumeration | whiteSpace | "
   11743 		"pattern)*))");
   11744 	}
   11745     }
   11746     return (NULL);
   11747 }
   11748 
   11749 /**
   11750  * xmlSchemaParseExtension:
   11751  * @ctxt:  a schema validation context
   11752  * @schema:  the schema being built
   11753  * @node:  a subtree containing XML Schema informations
   11754  *
   11755  * Parses an <extension>, which is found inside a
   11756  * <simpleContent> or <complexContent>.
   11757  * *WARNING* this interface is highly subject to change.
   11758  *
   11759  * TODO: Returns the type definition or NULL in case of error
   11760  */
   11761 static xmlSchemaTypePtr
   11762 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   11763                         xmlNodePtr node, xmlSchemaTypeType parentType)
   11764 {
   11765     xmlSchemaTypePtr type;
   11766     xmlNodePtr child = NULL;
   11767     xmlAttrPtr attr;
   11768 
   11769     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   11770         return (NULL);
   11771     /* Not a component, don't create it. */
   11772     type = ctxt->ctxtType;
   11773     type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
   11774 
   11775     /*
   11776     * Check for illegal attributes.
   11777     */
   11778     attr = node->properties;
   11779     while (attr != NULL) {
   11780 	if (attr->ns == NULL) {
   11781 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   11782 		(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
   11783 		xmlSchemaPIllegalAttrErr(ctxt,
   11784 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11785 	    }
   11786 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11787 	    xmlSchemaPIllegalAttrErr(ctxt,
   11788 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11789 	}
   11790 	attr = attr->next;
   11791     }
   11792 
   11793     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   11794 
   11795     /*
   11796     * Attribute "base" - mandatory.
   11797     */
   11798     if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
   11799 	"base", &(type->baseNs), &(type->base)) == 0) &&
   11800 	(type->base == NULL)) {
   11801 	xmlSchemaPMissingAttrErr(ctxt,
   11802 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   11803 	    NULL, node, "base", NULL);
   11804     }
   11805     /*
   11806     * And now for the children...
   11807     */
   11808     child = node->children;
   11809     if (IS_SCHEMA(child, "annotation")) {
   11810 	/*
   11811 	* Add the annotation to the type ancestor.
   11812 	*/
   11813 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   11814 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   11815         child = child->next;
   11816     }
   11817     if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
   11818 	/*
   11819 	* Corresponds to <complexType><complexContent><extension>... and:
   11820 	*
   11821 	* Model groups <all>, <choice>, <sequence> and <group>.
   11822 	*/
   11823 	if (IS_SCHEMA(child, "all")) {
   11824 	    type->subtypes = (xmlSchemaTypePtr)
   11825 		xmlSchemaParseModelGroup(ctxt, schema,
   11826 		    child, XML_SCHEMA_TYPE_ALL, 1);
   11827 	    child = child->next;
   11828 	} else if (IS_SCHEMA(child, "choice")) {
   11829 	    type->subtypes = (xmlSchemaTypePtr)
   11830 		xmlSchemaParseModelGroup(ctxt, schema,
   11831 		    child, XML_SCHEMA_TYPE_CHOICE, 1);
   11832 	    child = child->next;
   11833 	} else if (IS_SCHEMA(child, "sequence")) {
   11834 	    type->subtypes = (xmlSchemaTypePtr)
   11835 		xmlSchemaParseModelGroup(ctxt, schema,
   11836 		child, XML_SCHEMA_TYPE_SEQUENCE, 1);
   11837 	    child = child->next;
   11838 	} else if (IS_SCHEMA(child, "group")) {
   11839 	    type->subtypes = (xmlSchemaTypePtr)
   11840 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
   11841 	    /*
   11842 	    * Note that the reference will be resolved in
   11843 	    * xmlSchemaResolveTypeReferences();
   11844 	    */
   11845 	    child = child->next;
   11846 	}
   11847     }
   11848     if (child != NULL) {
   11849 	/*
   11850 	* Attribute uses/declarations.
   11851 	*/
   11852 	if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
   11853 	    (xmlSchemaItemListPtr *) &(type->attrUses),
   11854 	    XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
   11855 	    return(NULL);
   11856 	/*
   11857 	* Attribute wildcard.
   11858 	*/
   11859 	if (IS_SCHEMA(child, "anyAttribute")) {
   11860 	    ctxt->ctxtType->attributeWildcard =
   11861 		xmlSchemaParseAnyAttribute(ctxt, schema, child);
   11862 	    child = child->next;
   11863 	}
   11864     }
   11865     if (child != NULL) {
   11866 	if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
   11867 	    /* Complex content extension. */
   11868 	    xmlSchemaPContentErr(ctxt,
   11869 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11870 		NULL, node, child, NULL,
   11871 		"(annotation?, ((group | all | choice | sequence)?, "
   11872 		"((attribute | attributeGroup)*, anyAttribute?)))");
   11873 	} else {
   11874 	    /* Simple content extension. */
   11875 	    xmlSchemaPContentErr(ctxt,
   11876 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11877 		NULL, node, child, NULL,
   11878 		"(annotation?, ((attribute | attributeGroup)*, "
   11879 		"anyAttribute?))");
   11880 	}
   11881     }
   11882     return (NULL);
   11883 }
   11884 
   11885 /**
   11886  * xmlSchemaParseSimpleContent:
   11887  * @ctxt:  a schema validation context
   11888  * @schema:  the schema being built
   11889  * @node:  a subtree containing XML Schema informations
   11890  *
   11891  * parse a XML schema SimpleContent definition
   11892  * *WARNING* this interface is highly subject to change
   11893  *
   11894  * Returns the type definition or NULL in case of error
   11895  */
   11896 static int
   11897 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
   11898                             xmlSchemaPtr schema, xmlNodePtr node,
   11899 			    int *hasRestrictionOrExtension)
   11900 {
   11901     xmlSchemaTypePtr type;
   11902     xmlNodePtr child = NULL;
   11903     xmlAttrPtr attr;
   11904 
   11905     if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
   11906 	(hasRestrictionOrExtension == NULL))
   11907         return (-1);
   11908     *hasRestrictionOrExtension = 0;
   11909     /* Not a component, don't create it. */
   11910     type = ctxt->ctxtType;
   11911     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   11912     /*
   11913     * Check for illegal attributes.
   11914     */
   11915     attr = node->properties;
   11916     while (attr != NULL) {
   11917 	if (attr->ns == NULL) {
   11918 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
   11919 		xmlSchemaPIllegalAttrErr(ctxt,
   11920 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11921 	    }
   11922 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11923 	    xmlSchemaPIllegalAttrErr(ctxt,
   11924 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11925 	}
   11926 	attr = attr->next;
   11927     }
   11928 
   11929     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   11930 
   11931     /*
   11932     * And now for the children...
   11933     */
   11934     child = node->children;
   11935     if (IS_SCHEMA(child, "annotation")) {
   11936 	/*
   11937 	* Add the annotation to the complex type ancestor.
   11938 	*/
   11939 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   11940 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   11941         child = child->next;
   11942     }
   11943     if (child == NULL) {
   11944 	xmlSchemaPContentErr(ctxt,
   11945 	    XML_SCHEMAP_S4S_ELEM_MISSING,
   11946 	    NULL, node, NULL, NULL,
   11947 	    "(annotation?, (restriction | extension))");
   11948     }
   11949     if (child == NULL) {
   11950 	xmlSchemaPContentErr(ctxt,
   11951 	    XML_SCHEMAP_S4S_ELEM_MISSING,
   11952 	    NULL, node, NULL, NULL,
   11953 	    "(annotation?, (restriction | extension))");
   11954     }
   11955     if (IS_SCHEMA(child, "restriction")) {
   11956         xmlSchemaParseRestriction(ctxt, schema, child,
   11957 	    XML_SCHEMA_TYPE_SIMPLE_CONTENT);
   11958 	(*hasRestrictionOrExtension) = 1;
   11959         child = child->next;
   11960     } else if (IS_SCHEMA(child, "extension")) {
   11961         xmlSchemaParseExtension(ctxt, schema, child,
   11962 	    XML_SCHEMA_TYPE_SIMPLE_CONTENT);
   11963 	(*hasRestrictionOrExtension) = 1;
   11964         child = child->next;
   11965     }
   11966     if (child != NULL) {
   11967 	xmlSchemaPContentErr(ctxt,
   11968 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11969 	    NULL, node, child, NULL,
   11970 	    "(annotation?, (restriction | extension))");
   11971     }
   11972     return (0);
   11973 }
   11974 
   11975 /**
   11976  * xmlSchemaParseComplexContent:
   11977  * @ctxt:  a schema validation context
   11978  * @schema:  the schema being built
   11979  * @node:  a subtree containing XML Schema informations
   11980  *
   11981  * parse a XML schema ComplexContent definition
   11982  * *WARNING* this interface is highly subject to change
   11983  *
   11984  * Returns the type definition or NULL in case of error
   11985  */
   11986 static int
   11987 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
   11988                              xmlSchemaPtr schema, xmlNodePtr node,
   11989 			     int *hasRestrictionOrExtension)
   11990 {
   11991     xmlSchemaTypePtr type;
   11992     xmlNodePtr child = NULL;
   11993     xmlAttrPtr attr;
   11994 
   11995     if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
   11996 	(hasRestrictionOrExtension == NULL))
   11997         return (-1);
   11998     *hasRestrictionOrExtension = 0;
   11999     /* Not a component, don't create it. */
   12000     type = ctxt->ctxtType;
   12001     /*
   12002     * Check for illegal attributes.
   12003     */
   12004     attr = node->properties;
   12005     while (attr != NULL) {
   12006 	if (attr->ns == NULL) {
   12007 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   12008 		(!xmlStrEqual(attr->name, BAD_CAST "mixed")))
   12009 	    {
   12010 		xmlSchemaPIllegalAttrErr(ctxt,
   12011 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12012 	    }
   12013 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   12014 	    xmlSchemaPIllegalAttrErr(ctxt,
   12015 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12016 	}
   12017 	attr = attr->next;
   12018     }
   12019 
   12020     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   12021 
   12022     /*
   12023     * Set the 'mixed' on the complex type ancestor.
   12024     */
   12025     if (xmlGetBooleanProp(ctxt, node, "mixed", 0))  {
   12026 	if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
   12027 	    type->flags |= XML_SCHEMAS_TYPE_MIXED;
   12028     }
   12029     child = node->children;
   12030     if (IS_SCHEMA(child, "annotation")) {
   12031 	/*
   12032 	* Add the annotation to the complex type ancestor.
   12033 	*/
   12034 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   12035 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   12036         child = child->next;
   12037     }
   12038     if (child == NULL) {
   12039 	xmlSchemaPContentErr(ctxt,
   12040 	    XML_SCHEMAP_S4S_ELEM_MISSING,
   12041 	    NULL, node, NULL,
   12042 	    NULL, "(annotation?, (restriction | extension))");
   12043     }
   12044     if (child == NULL) {
   12045 	xmlSchemaPContentErr(ctxt,
   12046 	    XML_SCHEMAP_S4S_ELEM_MISSING,
   12047 	    NULL, node, NULL,
   12048 	    NULL, "(annotation?, (restriction | extension))");
   12049     }
   12050     if (IS_SCHEMA(child, "restriction")) {
   12051         xmlSchemaParseRestriction(ctxt, schema, child,
   12052 	    XML_SCHEMA_TYPE_COMPLEX_CONTENT);
   12053 	(*hasRestrictionOrExtension) = 1;
   12054         child = child->next;
   12055     } else if (IS_SCHEMA(child, "extension")) {
   12056         xmlSchemaParseExtension(ctxt, schema, child,
   12057 	    XML_SCHEMA_TYPE_COMPLEX_CONTENT);
   12058 	(*hasRestrictionOrExtension) = 1;
   12059         child = child->next;
   12060     }
   12061     if (child != NULL) {
   12062 	xmlSchemaPContentErr(ctxt,
   12063 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   12064 	    NULL, node, child,
   12065 	    NULL, "(annotation?, (restriction | extension))");
   12066     }
   12067     return (0);
   12068 }
   12069 
   12070 /**
   12071  * xmlSchemaParseComplexType:
   12072  * @ctxt:  a schema validation context
   12073  * @schema:  the schema being built
   12074  * @node:  a subtree containing XML Schema informations
   12075  *
   12076  * parse a XML schema Complex Type definition
   12077  * *WARNING* this interface is highly subject to change
   12078  *
   12079  * Returns the type definition or NULL in case of error
   12080  */
   12081 static xmlSchemaTypePtr
   12082 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   12083                           xmlNodePtr node, int topLevel)
   12084 {
   12085     xmlSchemaTypePtr type, ctxtType;
   12086     xmlNodePtr child = NULL;
   12087     const xmlChar *name = NULL;
   12088     xmlAttrPtr attr;
   12089     const xmlChar *attrValue;
   12090 #ifdef ENABLE_NAMED_LOCALS
   12091     char buf[40];
   12092 #endif
   12093     int final = 0, block = 0, hasRestrictionOrExtension = 0;
   12094 
   12095 
   12096     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   12097         return (NULL);
   12098 
   12099     ctxtType = ctxt->ctxtType;
   12100 
   12101     if (topLevel) {
   12102 	attr = xmlSchemaGetPropNode(node, "name");
   12103 	if (attr == NULL) {
   12104 	    xmlSchemaPMissingAttrErr(ctxt,
   12105 		XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
   12106 	    return (NULL);
   12107 	} else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
   12108 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   12109 	    return (NULL);
   12110 	}
   12111     }
   12112 
   12113     if (topLevel == 0) {
   12114 	/*
   12115 	* Parse as local complex type definition.
   12116 	*/
   12117 #ifdef ENABLE_NAMED_LOCALS
   12118         snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
   12119 	type = xmlSchemaAddType(ctxt, schema,
   12120 	    XML_SCHEMA_TYPE_COMPLEX,
   12121 	    xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
   12122 	    ctxt->targetNamespace, node, 0);
   12123 #else
   12124 	type = xmlSchemaAddType(ctxt, schema,
   12125 	    XML_SCHEMA_TYPE_COMPLEX,
   12126 	    NULL, ctxt->targetNamespace, node, 0);
   12127 #endif
   12128 	if (type == NULL)
   12129 	    return (NULL);
   12130 	name = type->name;
   12131 	type->node = node;
   12132 	type->type = XML_SCHEMA_TYPE_COMPLEX;
   12133 	/*
   12134 	* TODO: We need the target namespace.
   12135 	*/
   12136     } else {
   12137 	/*
   12138 	* Parse as global complex type definition.
   12139 	*/
   12140 	type = xmlSchemaAddType(ctxt, schema,
   12141 	    XML_SCHEMA_TYPE_COMPLEX,
   12142 	    name, ctxt->targetNamespace, node, 1);
   12143 	if (type == NULL)
   12144 	    return (NULL);
   12145 	type->node = node;
   12146 	type->type = XML_SCHEMA_TYPE_COMPLEX;
   12147 	type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
   12148     }
   12149     type->targetNamespace = ctxt->targetNamespace;
   12150     /*
   12151     * Handle attributes.
   12152     */
   12153     attr = node->properties;
   12154     while (attr != NULL) {
   12155 	if (attr->ns == NULL) {
   12156 	    if (xmlStrEqual(attr->name, BAD_CAST "id")) {
   12157 		/*
   12158 		* Attribute "id".
   12159 		*/
   12160 		xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   12161 	    } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
   12162 		/*
   12163 		* Attribute "mixed".
   12164 		*/
   12165 		if (xmlSchemaPGetBoolNodeValue(ctxt,
   12166 			NULL, (xmlNodePtr) attr))
   12167 		    type->flags |= XML_SCHEMAS_TYPE_MIXED;
   12168 	    } else if (topLevel) {
   12169 		/*
   12170 		* Attributes of global complex type definitions.
   12171 		*/
   12172 		if (xmlStrEqual(attr->name, BAD_CAST "name")) {
   12173 		    /* Pass. */
   12174 		} else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
   12175 		    /*
   12176 		    * Attribute "abstract".
   12177 		    */
   12178 		    if (xmlSchemaPGetBoolNodeValue(ctxt,
   12179 			    NULL, (xmlNodePtr) attr))
   12180 			type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
   12181 		} else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
   12182 		    /*
   12183 		    * Attribute "final".
   12184 		    */
   12185 		    attrValue = xmlSchemaGetNodeContent(ctxt,
   12186 			(xmlNodePtr) attr);
   12187 		    if (xmlSchemaPValAttrBlockFinal(attrValue,
   12188 			&(type->flags),
   12189 			-1,
   12190 			XML_SCHEMAS_TYPE_FINAL_EXTENSION,
   12191 			XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
   12192 			-1, -1, -1) != 0)
   12193 		    {
   12194 			xmlSchemaPSimpleTypeErr(ctxt,
   12195 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   12196 			    NULL, (xmlNodePtr) attr, NULL,
   12197 			    "(#all | List of (extension | restriction))",
   12198 			    attrValue, NULL, NULL, NULL);
   12199 		    } else
   12200 			final = 1;
   12201 		} else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
   12202 		    /*
   12203 		    * Attribute "block".
   12204 		    */
   12205 		    attrValue = xmlSchemaGetNodeContent(ctxt,
   12206 			(xmlNodePtr) attr);
   12207 		    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
   12208 			-1,
   12209 			XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
   12210 			XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
   12211 			-1, -1, -1) != 0) {
   12212 			xmlSchemaPSimpleTypeErr(ctxt,
   12213 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   12214 			    NULL, (xmlNodePtr) attr, NULL,
   12215 			    "(#all | List of (extension | restriction)) ",
   12216 			    attrValue, NULL, NULL, NULL);
   12217 		    } else
   12218 			block = 1;
   12219 		} else {
   12220 			xmlSchemaPIllegalAttrErr(ctxt,
   12221 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12222 		}
   12223 	    } else {
   12224 		xmlSchemaPIllegalAttrErr(ctxt,
   12225 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12226 	    }
   12227 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   12228 	    xmlSchemaPIllegalAttrErr(ctxt,
   12229 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12230 	}
   12231 	attr = attr->next;
   12232     }
   12233     if (! block) {
   12234 	/*
   12235 	* Apply default "block" values.
   12236 	*/
   12237 	if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
   12238 	    type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
   12239 	if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
   12240 	    type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
   12241     }
   12242     if (! final) {
   12243 	/*
   12244 	* Apply default "block" values.
   12245 	*/
   12246 	if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   12247 	    type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
   12248 	if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
   12249 	    type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
   12250     }
   12251     /*
   12252     * And now for the children...
   12253     */
   12254     child = node->children;
   12255     if (IS_SCHEMA(child, "annotation")) {
   12256         type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   12257         child = child->next;
   12258     }
   12259     ctxt->ctxtType = type;
   12260     if (IS_SCHEMA(child, "simpleContent")) {
   12261 	/*
   12262 	* <complexType><simpleContent>...
   12263 	* 3.4.3 : 2.2
   12264 	* Specifying mixed='true' when the <simpleContent>
   12265 	* alternative is chosen has no effect
   12266 	*/
   12267 	if (type->flags & XML_SCHEMAS_TYPE_MIXED)
   12268 	    type->flags ^= XML_SCHEMAS_TYPE_MIXED;
   12269         xmlSchemaParseSimpleContent(ctxt, schema, child,
   12270 	    &hasRestrictionOrExtension);
   12271         child = child->next;
   12272     } else if (IS_SCHEMA(child, "complexContent")) {
   12273 	/*
   12274 	* <complexType><complexContent>...
   12275 	*/
   12276 	type->contentType = XML_SCHEMA_CONTENT_EMPTY;
   12277         xmlSchemaParseComplexContent(ctxt, schema, child,
   12278 	    &hasRestrictionOrExtension);
   12279         child = child->next;
   12280     } else {
   12281 	/*
   12282 	* E.g <complexType><sequence>... or <complexType><attribute>... etc.
   12283 	*
   12284 	* SPEC
   12285 	* "...the third alternative (neither <simpleContent> nor
   12286 	* <complexContent>) is chosen. This case is understood as shorthand
   12287 	* for complex content restricting the ur-type definition, and the
   12288 	* details of the mappings should be modified as necessary.
   12289 	*/
   12290 	type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
   12291 	type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
   12292 	/*
   12293 	* Parse model groups.
   12294 	*/
   12295         if (IS_SCHEMA(child, "all")) {
   12296             type->subtypes = (xmlSchemaTypePtr)
   12297 		xmlSchemaParseModelGroup(ctxt, schema, child,
   12298 		    XML_SCHEMA_TYPE_ALL, 1);
   12299             child = child->next;
   12300         } else if (IS_SCHEMA(child, "choice")) {
   12301             type->subtypes = (xmlSchemaTypePtr)
   12302 		xmlSchemaParseModelGroup(ctxt, schema, child,
   12303 		    XML_SCHEMA_TYPE_CHOICE, 1);
   12304             child = child->next;
   12305         } else if (IS_SCHEMA(child, "sequence")) {
   12306             type->subtypes = (xmlSchemaTypePtr)
   12307 		xmlSchemaParseModelGroup(ctxt, schema, child,
   12308 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
   12309             child = child->next;
   12310         } else if (IS_SCHEMA(child, "group")) {
   12311             type->subtypes = (xmlSchemaTypePtr)
   12312 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
   12313 	    /*
   12314 	    * Note that the reference will be resolved in
   12315 	    * xmlSchemaResolveTypeReferences();
   12316 	    */
   12317             child = child->next;
   12318         }
   12319 	/*
   12320 	* Parse attribute decls/refs.
   12321 	*/
   12322         if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
   12323 	    (xmlSchemaItemListPtr *) &(type->attrUses),
   12324 	    XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
   12325 	    return(NULL);
   12326 	/*
   12327 	* Parse attribute wildcard.
   12328 	*/
   12329 	if (IS_SCHEMA(child, "anyAttribute")) {
   12330 	    type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
   12331 	    child = child->next;
   12332 	}
   12333     }
   12334     if (child != NULL) {
   12335 	xmlSchemaPContentErr(ctxt,
   12336 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   12337 	    NULL, node, child,
   12338 	    NULL, "(annotation?, (simpleContent | complexContent | "
   12339 	    "((group | all | choice | sequence)?, ((attribute | "
   12340 	    "attributeGroup)*, anyAttribute?))))");
   12341     }
   12342     /*
   12343     * REDEFINE: SPEC src-redefine (5)
   12344     */
   12345     if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
   12346 	xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   12347 	    NULL, node, "This is a redefinition, thus the "
   12348 	    "<complexType> must have a <restriction> or <extension> "
   12349 	    "grand-child", NULL);
   12350     }
   12351     ctxt->ctxtType = ctxtType;
   12352     return (type);
   12353 }
   12354 
   12355 /************************************************************************
   12356  * 									*
   12357  * 			Validating using Schemas			*
   12358  * 									*
   12359  ************************************************************************/
   12360 
   12361 /************************************************************************
   12362  * 									*
   12363  * 			Reading/Writing Schemas				*
   12364  * 									*
   12365  ************************************************************************/
   12366 
   12367 #if 0 /* Will be enabled if it is clear what options are needed. */
   12368 /**
   12369  * xmlSchemaParserCtxtSetOptions:
   12370  * @ctxt:	a schema parser context
   12371  * @options: a combination of xmlSchemaParserOption
   12372  *
   12373  * Sets the options to be used during the parse.
   12374  *
   12375  * Returns 0 in case of success, -1 in case of an
   12376  * API error.
   12377  */
   12378 static int
   12379 xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
   12380 			      int options)
   12381 
   12382 {
   12383     int i;
   12384 
   12385     if (ctxt == NULL)
   12386 	return (-1);
   12387     /*
   12388     * WARNING: Change the start value if adding to the
   12389     * xmlSchemaParseOption.
   12390     */
   12391     for (i = 1; i < (int) sizeof(int) * 8; i++) {
   12392         if (options & 1<<i) {
   12393 	    return (-1);
   12394         }
   12395     }
   12396     ctxt->options = options;
   12397     return (0);
   12398 }
   12399 
   12400 /**
   12401  * xmlSchemaValidCtxtGetOptions:
   12402  * @ctxt: a schema parser context
   12403  *
   12404  * Returns the option combination of the parser context.
   12405  */
   12406 static int
   12407 xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
   12408 
   12409 {
   12410     if (ctxt == NULL)
   12411 	return (-1);
   12412     else
   12413 	return (ctxt->options);
   12414 }
   12415 #endif
   12416 
   12417 /**
   12418  * xmlSchemaNewParserCtxt:
   12419  * @URL:  the location of the schema
   12420  *
   12421  * Create an XML Schemas parse context for that file/resource expected
   12422  * to contain an XML Schemas file.
   12423  *
   12424  * Returns the parser context or NULL in case of error
   12425  */
   12426 xmlSchemaParserCtxtPtr
   12427 xmlSchemaNewParserCtxt(const char *URL)
   12428 {
   12429     xmlSchemaParserCtxtPtr ret;
   12430 
   12431     if (URL == NULL)
   12432         return (NULL);
   12433 
   12434     ret = xmlSchemaParserCtxtCreate();
   12435     if (ret == NULL)
   12436 	return(NULL);
   12437     ret->dict = xmlDictCreate();
   12438     ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
   12439     return (ret);
   12440 }
   12441 
   12442 /**
   12443  * xmlSchemaNewMemParserCtxt:
   12444  * @buffer:  a pointer to a char array containing the schemas
   12445  * @size:  the size of the array
   12446  *
   12447  * Create an XML Schemas parse context for that memory buffer expected
   12448  * to contain an XML Schemas file.
   12449  *
   12450  * Returns the parser context or NULL in case of error
   12451  */
   12452 xmlSchemaParserCtxtPtr
   12453 xmlSchemaNewMemParserCtxt(const char *buffer, int size)
   12454 {
   12455     xmlSchemaParserCtxtPtr ret;
   12456 
   12457     if ((buffer == NULL) || (size <= 0))
   12458         return (NULL);
   12459     ret = xmlSchemaParserCtxtCreate();
   12460     if (ret == NULL)
   12461 	return(NULL);
   12462     ret->buffer = buffer;
   12463     ret->size = size;
   12464     ret->dict = xmlDictCreate();
   12465     return (ret);
   12466 }
   12467 
   12468 /**
   12469  * xmlSchemaNewDocParserCtxt:
   12470  * @doc:  a preparsed document tree
   12471  *
   12472  * Create an XML Schemas parse context for that document.
   12473  * NB. The document may be modified during the parsing process.
   12474  *
   12475  * Returns the parser context or NULL in case of error
   12476  */
   12477 xmlSchemaParserCtxtPtr
   12478 xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
   12479 {
   12480     xmlSchemaParserCtxtPtr ret;
   12481 
   12482     if (doc == NULL)
   12483       return (NULL);
   12484     ret = xmlSchemaParserCtxtCreate();
   12485     if (ret == NULL)
   12486 	return(NULL);
   12487     ret->doc = doc;
   12488     ret->dict = xmlDictCreate();
   12489     /* The application has responsibility for the document */
   12490     ret->preserve = 1;
   12491 
   12492     return (ret);
   12493 }
   12494 
   12495 /**
   12496  * xmlSchemaFreeParserCtxt:
   12497  * @ctxt:  the schema parser context
   12498  *
   12499  * Free the resources associated to the schema parser context
   12500  */
   12501 void
   12502 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
   12503 {
   12504     if (ctxt == NULL)
   12505         return;
   12506     if (ctxt->doc != NULL && !ctxt->preserve)
   12507         xmlFreeDoc(ctxt->doc);
   12508     if (ctxt->vctxt != NULL) {
   12509 	xmlSchemaFreeValidCtxt(ctxt->vctxt);
   12510     }
   12511     if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
   12512 	xmlSchemaConstructionCtxtFree(ctxt->constructor);
   12513 	ctxt->constructor = NULL;
   12514 	ctxt->ownsConstructor = 0;
   12515     }
   12516     if (ctxt->attrProhibs != NULL)
   12517 	xmlSchemaItemListFree(ctxt->attrProhibs);
   12518     xmlDictFree(ctxt->dict);
   12519     xmlFree(ctxt);
   12520 }
   12521 
   12522 /************************************************************************
   12523  *									*
   12524  *			Building the content models			*
   12525  *									*
   12526  ************************************************************************/
   12527 
   12528 /**
   12529  * xmlSchemaBuildContentModelForSubstGroup:
   12530  *
   12531  * Returns 1 if nillable, 0 otherwise
   12532  */
   12533 static int
   12534 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
   12535 	xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
   12536 {
   12537     xmlAutomataStatePtr start, tmp;
   12538     xmlSchemaElementPtr elemDecl, member;
   12539     xmlSchemaSubstGroupPtr substGroup;
   12540     int i;
   12541     int ret = 0;
   12542 
   12543     elemDecl = (xmlSchemaElementPtr) particle->children;
   12544     /*
   12545     * Wrap the substitution group with a CHOICE.
   12546     */
   12547     start = pctxt->state;
   12548     if (end == NULL)
   12549 	end = xmlAutomataNewState(pctxt->am);
   12550     substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
   12551     if (substGroup == NULL) {
   12552 	xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
   12553 	    XML_SCHEMAP_INTERNAL,
   12554 	    "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
   12555 	    "declaration is marked having a subst. group but none "
   12556 	    "available.\n", elemDecl->name, NULL);
   12557 	return(0);
   12558     }
   12559     if (counter >= 0) {
   12560 	/*
   12561 	* NOTE that we put the declaration in, even if it's abstract.
   12562 	* However, an error will be raised during *validation* if an element
   12563 	* information item shall be validated against an abstract element
   12564 	* declaration.
   12565 	*/
   12566 	tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
   12567         xmlAutomataNewTransition2(pctxt->am, tmp, end,
   12568 	            elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12569 	/*
   12570 	* Add subst. group members.
   12571 	*/
   12572 	for (i = 0; i < substGroup->members->nbItems; i++) {
   12573 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
   12574             xmlAutomataNewTransition2(pctxt->am, tmp, end,
   12575 		               member->name, member->targetNamespace, member);
   12576 	}
   12577     } else if (particle->maxOccurs == 1) {
   12578 	/*
   12579 	* NOTE that we put the declaration in, even if it's abstract,
   12580 	*/
   12581 	xmlAutomataNewEpsilon(pctxt->am,
   12582 	    xmlAutomataNewTransition2(pctxt->am,
   12583 	    start, NULL,
   12584 	    elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
   12585 	/*
   12586 	* Add subst. group members.
   12587 	*/
   12588 	for (i = 0; i < substGroup->members->nbItems; i++) {
   12589 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
   12590 	    /*
   12591 	    * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
   12592 	    *  was incorrectly used instead of xmlAutomataNewTransition2()
   12593 	    *  (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
   12594 	    *  section in xmlSchemaBuildAContentModel() ).
   12595 	    * TODO: Check if xmlAutomataNewOnceTrans2() was instead
   12596 	    *  intended for the above "counter" section originally. I.e.,
   12597 	    *  check xs:all with subst-groups.
   12598 	    *
   12599 	    * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
   12600 	    *	               member->name, member->targetNamespace,
   12601 	    *		       1, 1, member);
   12602 	    */
   12603 	    tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
   12604 		member->name, member->targetNamespace, member);
   12605 	    xmlAutomataNewEpsilon(pctxt->am, tmp, end);
   12606 	}
   12607     } else {
   12608 	xmlAutomataStatePtr hop;
   12609 	int maxOccurs = particle->maxOccurs == UNBOUNDED ?
   12610 	    UNBOUNDED : particle->maxOccurs - 1;
   12611 	int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
   12612 
   12613 	counter =
   12614 	    xmlAutomataNewCounter(pctxt->am, minOccurs,
   12615 	    maxOccurs);
   12616 	hop = xmlAutomataNewState(pctxt->am);
   12617 
   12618 	xmlAutomataNewEpsilon(pctxt->am,
   12619 	    xmlAutomataNewTransition2(pctxt->am,
   12620 	    start, NULL,
   12621 	    elemDecl->name, elemDecl->targetNamespace, elemDecl),
   12622 	    hop);
   12623 	/*
   12624 	 * Add subst. group members.
   12625 	 */
   12626 	for (i = 0; i < substGroup->members->nbItems; i++) {
   12627 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
   12628 	    xmlAutomataNewEpsilon(pctxt->am,
   12629 		xmlAutomataNewTransition2(pctxt->am,
   12630 		start, NULL,
   12631 		member->name, member->targetNamespace, member),
   12632 		hop);
   12633 	}
   12634 	xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
   12635 	xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
   12636     }
   12637     if (particle->minOccurs == 0) {
   12638 	xmlAutomataNewEpsilon(pctxt->am, start, end);
   12639         ret = 1;
   12640     }
   12641     pctxt->state = end;
   12642     return(ret);
   12643 }
   12644 
   12645 /**
   12646  * xmlSchemaBuildContentModelForElement:
   12647  *
   12648  * Returns 1 if nillable, 0 otherwise
   12649  */
   12650 static int
   12651 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
   12652 				     xmlSchemaParticlePtr particle)
   12653 {
   12654     int ret = 0;
   12655 
   12656     if (((xmlSchemaElementPtr) particle->children)->flags &
   12657 	XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
   12658 	/*
   12659 	* Substitution groups.
   12660 	*/
   12661 	ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
   12662     } else {
   12663 	xmlSchemaElementPtr elemDecl;
   12664 	xmlAutomataStatePtr start;
   12665 
   12666 	elemDecl = (xmlSchemaElementPtr) particle->children;
   12667 
   12668 	if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
   12669 	    return(0);
   12670 	if (particle->maxOccurs == 1) {
   12671 	    start = ctxt->state;
   12672 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
   12673 		    elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12674 	} else if ((particle->maxOccurs >= UNBOUNDED) &&
   12675 	           (particle->minOccurs < 2)) {
   12676 	    /* Special case. */
   12677 	    start = ctxt->state;
   12678 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
   12679 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12680 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
   12681 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12682 	} else {
   12683 	    int counter;
   12684 	    int maxOccurs = particle->maxOccurs == UNBOUNDED ?
   12685 			    UNBOUNDED : particle->maxOccurs - 1;
   12686 	    int minOccurs = particle->minOccurs < 1 ?
   12687 			    0 : particle->minOccurs - 1;
   12688 
   12689 	    start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
   12690 	    counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
   12691 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
   12692 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12693 	    xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
   12694 	    ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
   12695 		NULL, counter);
   12696 	}
   12697 	if (particle->minOccurs == 0) {
   12698 	    xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
   12699             ret = 1;
   12700         }
   12701     }
   12702     return(ret);
   12703 }
   12704 
   12705 /**
   12706  * xmlSchemaBuildAContentModel:
   12707  * @ctxt:  the schema parser context
   12708  * @particle:  the particle component
   12709  * @name:  the complex type's name whose content is being built
   12710  *
   12711  * Create the automaton for the {content type} of a complex type.
   12712  *
   12713  * Returns 1 if the content is nillable, 0 otherwise
   12714  */
   12715 static int
   12716 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
   12717 			    xmlSchemaParticlePtr particle)
   12718 {
   12719     int ret = 0, tmp2;
   12720 
   12721     if (particle == NULL) {
   12722 	PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
   12723 	return(1);
   12724     }
   12725     if (particle->children == NULL) {
   12726 	/*
   12727 	* Just return in this case. A missing "term" of the particle
   12728 	* might arise due to an invalid "term" component.
   12729 	*/
   12730 	return(1);
   12731     }
   12732 
   12733     switch (particle->children->type) {
   12734 	case XML_SCHEMA_TYPE_ANY: {
   12735 	    xmlAutomataStatePtr start, end;
   12736 	    xmlSchemaWildcardPtr wild;
   12737 	    xmlSchemaWildcardNsPtr ns;
   12738 
   12739 	    wild = (xmlSchemaWildcardPtr) particle->children;
   12740 
   12741 	    start = pctxt->state;
   12742 	    end = xmlAutomataNewState(pctxt->am);
   12743 
   12744 	    if (particle->maxOccurs == 1) {
   12745 		if (wild->any == 1) {
   12746 		    /*
   12747 		    * We need to add both transitions:
   12748 		    *
   12749 		    * 1. the {"*", "*"} for elements in a namespace.
   12750 		    */
   12751 		    pctxt->state =
   12752 			xmlAutomataNewTransition2(pctxt->am,
   12753 			start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
   12754 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
   12755 		    /*
   12756 		    * 2. the {"*"} for elements in no namespace.
   12757 		    */
   12758 		    pctxt->state =
   12759 			xmlAutomataNewTransition2(pctxt->am,
   12760 			start, NULL, BAD_CAST "*", NULL, wild);
   12761 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
   12762 
   12763 		} else if (wild->nsSet != NULL) {
   12764 		    ns = wild->nsSet;
   12765 		    do {
   12766 			pctxt->state = start;
   12767 			pctxt->state = xmlAutomataNewTransition2(pctxt->am,
   12768 			    pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
   12769 			xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
   12770 			ns = ns->next;
   12771 		    } while (ns != NULL);
   12772 
   12773 		} else if (wild->negNsSet != NULL) {
   12774 		    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
   12775 			start, end, BAD_CAST "*", wild->negNsSet->value,
   12776 			wild);
   12777 		}
   12778 	    } else {
   12779 		int counter;
   12780 		xmlAutomataStatePtr hop;
   12781 		int maxOccurs =
   12782 		    particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
   12783                                            particle->maxOccurs - 1;
   12784 		int minOccurs =
   12785 		    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
   12786 
   12787 		counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
   12788 		hop = xmlAutomataNewState(pctxt->am);
   12789 		if (wild->any == 1) {
   12790 		    pctxt->state =
   12791 			xmlAutomataNewTransition2(pctxt->am,
   12792 			start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
   12793 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
   12794 		    pctxt->state =
   12795 			xmlAutomataNewTransition2(pctxt->am,
   12796 			start, NULL, BAD_CAST "*", NULL, wild);
   12797 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
   12798 		} else if (wild->nsSet != NULL) {
   12799 		    ns = wild->nsSet;
   12800 		    do {
   12801 			pctxt->state =
   12802 			    xmlAutomataNewTransition2(pctxt->am,
   12803 				start, NULL, BAD_CAST "*", ns->value, wild);
   12804 			xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
   12805 			ns = ns->next;
   12806 		    } while (ns != NULL);
   12807 
   12808 		} else if (wild->negNsSet != NULL) {
   12809 		    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
   12810 			start, hop, BAD_CAST "*", wild->negNsSet->value,
   12811 			wild);
   12812 		}
   12813 		xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
   12814 		xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
   12815 	    }
   12816 	    if (particle->minOccurs == 0) {
   12817 		xmlAutomataNewEpsilon(pctxt->am, start, end);
   12818                 ret = 1;
   12819 	    }
   12820 	    pctxt->state = end;
   12821             break;
   12822 	}
   12823         case XML_SCHEMA_TYPE_ELEMENT:
   12824 	    ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
   12825 	    break;
   12826         case XML_SCHEMA_TYPE_SEQUENCE:{
   12827             xmlSchemaTreeItemPtr sub;
   12828 
   12829             ret = 1;
   12830             /*
   12831              * If max and min occurances are default (1) then
   12832              * simply iterate over the particles of the <sequence>.
   12833              */
   12834             if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
   12835                 sub = particle->children->children;
   12836 
   12837                 while (sub != NULL) {
   12838                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12839                                         (xmlSchemaParticlePtr) sub);
   12840                     if (tmp2 != 1) ret = 0;
   12841                     sub = sub->next;
   12842                 }
   12843             } else {
   12844                 xmlAutomataStatePtr oldstate = pctxt->state;
   12845 
   12846                 if (particle->maxOccurs >= UNBOUNDED) {
   12847                     if (particle->minOccurs > 1) {
   12848                         xmlAutomataStatePtr tmp;
   12849                         int counter;
   12850 
   12851                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12852                             oldstate, NULL);
   12853                         oldstate = pctxt->state;
   12854 
   12855                         counter = xmlAutomataNewCounter(pctxt->am,
   12856                             particle->minOccurs - 1, UNBOUNDED);
   12857 
   12858                         sub = particle->children->children;
   12859                         while (sub != NULL) {
   12860                             tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12861                                             (xmlSchemaParticlePtr) sub);
   12862                             if (tmp2 != 1) ret = 0;
   12863                             sub = sub->next;
   12864                         }
   12865                         tmp = pctxt->state;
   12866                         xmlAutomataNewCountedTrans(pctxt->am, tmp,
   12867                                                    oldstate, counter);
   12868                         pctxt->state =
   12869                             xmlAutomataNewCounterTrans(pctxt->am, tmp,
   12870                                                        NULL, counter);
   12871                         if (ret == 1)
   12872                             xmlAutomataNewEpsilon(pctxt->am,
   12873                                                 oldstate, pctxt->state);
   12874 
   12875                     } else {
   12876                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12877                             oldstate, NULL);
   12878                         oldstate = pctxt->state;
   12879 
   12880                         sub = particle->children->children;
   12881                         while (sub != NULL) {
   12882                             tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12883                                         (xmlSchemaParticlePtr) sub);
   12884                             if (tmp2 != 1) ret = 0;
   12885                             sub = sub->next;
   12886                         }
   12887                         xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
   12888                                               oldstate);
   12889                         /*
   12890                          * epsilon needed to block previous trans from
   12891                          * being allowed to enter back from another
   12892                          * construct
   12893                          */
   12894                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12895                                             pctxt->state, NULL);
   12896                         if (particle->minOccurs == 0) {
   12897                             xmlAutomataNewEpsilon(pctxt->am,
   12898                                 oldstate, pctxt->state);
   12899                             ret = 1;
   12900                         }
   12901                     }
   12902                 } else if ((particle->maxOccurs > 1)
   12903                            || (particle->minOccurs > 1)) {
   12904                     xmlAutomataStatePtr tmp;
   12905                     int counter;
   12906 
   12907                     pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12908                         oldstate, NULL);
   12909                     oldstate = pctxt->state;
   12910 
   12911                     counter = xmlAutomataNewCounter(pctxt->am,
   12912                         particle->minOccurs - 1,
   12913                         particle->maxOccurs - 1);
   12914 
   12915                     sub = particle->children->children;
   12916                     while (sub != NULL) {
   12917                         tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12918                                         (xmlSchemaParticlePtr) sub);
   12919                         if (tmp2 != 1) ret = 0;
   12920                         sub = sub->next;
   12921                     }
   12922                     tmp = pctxt->state;
   12923                     xmlAutomataNewCountedTrans(pctxt->am,
   12924                         tmp, oldstate, counter);
   12925                     pctxt->state =
   12926                         xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
   12927                                                    counter);
   12928                     if ((particle->minOccurs == 0) || (ret == 1)) {
   12929                         xmlAutomataNewEpsilon(pctxt->am,
   12930                                             oldstate, pctxt->state);
   12931                         ret = 1;
   12932                     }
   12933                 } else {
   12934                     sub = particle->children->children;
   12935                     while (sub != NULL) {
   12936                         tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12937                                         (xmlSchemaParticlePtr) sub);
   12938                         if (tmp2 != 1) ret = 0;
   12939                         sub = sub->next;
   12940                     }
   12941                     if (particle->minOccurs == 0) {
   12942                         xmlAutomataNewEpsilon(pctxt->am, oldstate,
   12943                                               pctxt->state);
   12944                         ret = 1;
   12945                     }
   12946                 }
   12947             }
   12948             break;
   12949         }
   12950         case XML_SCHEMA_TYPE_CHOICE:{
   12951             xmlSchemaTreeItemPtr sub;
   12952             xmlAutomataStatePtr start, end;
   12953 
   12954             ret = 0;
   12955             start = pctxt->state;
   12956             end = xmlAutomataNewState(pctxt->am);
   12957 
   12958             /*
   12959              * iterate over the subtypes and remerge the end with an
   12960              * epsilon transition
   12961              */
   12962             if (particle->maxOccurs == 1) {
   12963                 sub = particle->children->children;
   12964                 while (sub != NULL) {
   12965                     pctxt->state = start;
   12966                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12967                                         (xmlSchemaParticlePtr) sub);
   12968                     if (tmp2 == 1) ret = 1;
   12969                     xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
   12970                     sub = sub->next;
   12971                 }
   12972             } else {
   12973                 int counter;
   12974                 xmlAutomataStatePtr hop, base;
   12975                 int maxOccurs = particle->maxOccurs == UNBOUNDED ?
   12976                     UNBOUNDED : particle->maxOccurs - 1;
   12977                 int minOccurs =
   12978                     particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
   12979 
   12980                 /*
   12981                  * use a counter to keep track of the number of transtions
   12982                  * which went through the choice.
   12983                  */
   12984                 counter =
   12985                     xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
   12986                 hop = xmlAutomataNewState(pctxt->am);
   12987                 base = xmlAutomataNewState(pctxt->am);
   12988 
   12989                 sub = particle->children->children;
   12990                 while (sub != NULL) {
   12991                     pctxt->state = base;
   12992                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12993                                         (xmlSchemaParticlePtr) sub);
   12994                     if (tmp2 == 1) ret = 1;
   12995                     xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
   12996                     sub = sub->next;
   12997                 }
   12998                 xmlAutomataNewEpsilon(pctxt->am, start, base);
   12999                 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
   13000                 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
   13001                 if (ret == 1)
   13002                     xmlAutomataNewEpsilon(pctxt->am, base, end);
   13003             }
   13004             if (particle->minOccurs == 0) {
   13005                 xmlAutomataNewEpsilon(pctxt->am, start, end);
   13006                 ret = 1;
   13007             }
   13008             pctxt->state = end;
   13009             break;
   13010         }
   13011         case XML_SCHEMA_TYPE_ALL:{
   13012             xmlAutomataStatePtr start, tmp;
   13013             xmlSchemaParticlePtr sub;
   13014             xmlSchemaElementPtr elemDecl;
   13015 
   13016             ret = 1;
   13017 
   13018             sub = (xmlSchemaParticlePtr) particle->children->children;
   13019             if (sub == NULL)
   13020                 break;
   13021 
   13022             ret = 0;
   13023 
   13024             start = pctxt->state;
   13025             tmp = xmlAutomataNewState(pctxt->am);
   13026             xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
   13027             pctxt->state = tmp;
   13028             while (sub != NULL) {
   13029                 pctxt->state = tmp;
   13030 
   13031                 elemDecl = (xmlSchemaElementPtr) sub->children;
   13032                 if (elemDecl == NULL) {
   13033                     PERROR_INT("xmlSchemaBuildAContentModel",
   13034                         "<element> particle has no term");
   13035                     return(ret);
   13036                 };
   13037                 /*
   13038                 * NOTE: The {max occurs} of all the particles in the
   13039                 * {particles} of the group must be 0 or 1; this is
   13040                 * already ensured during the parse of the content of
   13041                 * <all>.
   13042                 */
   13043                 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
   13044                     int counter;
   13045 
   13046                     /*
   13047                      * This is an abstract group, we need to share
   13048                      * the same counter for all the element transitions
   13049                      * derived from the group
   13050                      */
   13051                     counter = xmlAutomataNewCounter(pctxt->am,
   13052                                        sub->minOccurs, sub->maxOccurs);
   13053                     xmlSchemaBuildContentModelForSubstGroup(pctxt,
   13054                                        sub, counter, pctxt->state);
   13055                 } else {
   13056                     if ((sub->minOccurs == 1) &&
   13057                         (sub->maxOccurs == 1)) {
   13058                         xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
   13059                                                 pctxt->state,
   13060                                                 elemDecl->name,
   13061                                                 elemDecl->targetNamespace,
   13062                                                 1, 1, elemDecl);
   13063                     } else if ((sub->minOccurs == 0) &&
   13064                         (sub->maxOccurs == 1)) {
   13065 
   13066                         xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
   13067                                                  pctxt->state,
   13068                                                  elemDecl->name,
   13069                                                  elemDecl->targetNamespace,
   13070                                                  0,
   13071                                                  1,
   13072                                                  elemDecl);
   13073                     }
   13074                 }
   13075                 sub = (xmlSchemaParticlePtr) sub->next;
   13076             }
   13077             pctxt->state =
   13078                 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
   13079             if (particle->minOccurs == 0) {
   13080                 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
   13081                 ret = 1;
   13082             }
   13083             break;
   13084         }
   13085 	case XML_SCHEMA_TYPE_GROUP:
   13086 	    /*
   13087 	    * If we hit a model group definition, then this means that
   13088 	    * it was empty, thus was not substituted for the containing
   13089 	    * model group. Just do nothing in this case.
   13090 	    * TODO: But the group should be substituted and not occur at
   13091 	    * all in the content model at this point. Fix this.
   13092 	    */
   13093             ret = 1;
   13094 	    break;
   13095         default:
   13096 	    xmlSchemaInternalErr2(ACTXT_CAST pctxt,
   13097 		"xmlSchemaBuildAContentModel",
   13098 		"found unexpected term of type '%s' in content model",
   13099 		WXS_ITEM_TYPE_NAME(particle->children), NULL);
   13100             return(ret);
   13101     }
   13102     return(ret);
   13103 }
   13104 
   13105 /**
   13106  * xmlSchemaBuildContentModel:
   13107  * @ctxt:  the schema parser context
   13108  * @type:  the complex type definition
   13109  * @name:  the element name
   13110  *
   13111  * Builds the content model of the complex type.
   13112  */
   13113 static void
   13114 xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
   13115 			   xmlSchemaParserCtxtPtr ctxt)
   13116 {
   13117     if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
   13118 	(type->contModel != NULL) ||
   13119 	((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
   13120 	(type->contentType != XML_SCHEMA_CONTENT_MIXED)))
   13121 	return;
   13122 
   13123 #ifdef DEBUG_CONTENT
   13124     xmlGenericError(xmlGenericErrorContext,
   13125                     "Building content model for %s\n", name);
   13126 #endif
   13127     ctxt->am = NULL;
   13128     ctxt->am = xmlNewAutomata();
   13129     if (ctxt->am == NULL) {
   13130         xmlGenericError(xmlGenericErrorContext,
   13131 	    "Cannot create automata for complex type %s\n", type->name);
   13132         return;
   13133     }
   13134     ctxt->state = xmlAutomataGetInitState(ctxt->am);
   13135     /*
   13136     * Build the automaton.
   13137     */
   13138     xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
   13139     xmlAutomataSetFinalState(ctxt->am, ctxt->state);
   13140     type->contModel = xmlAutomataCompile(ctxt->am);
   13141     if (type->contModel == NULL) {
   13142         xmlSchemaPCustomErr(ctxt,
   13143 	    XML_SCHEMAP_INTERNAL,
   13144 	    WXS_BASIC_CAST type, type->node,
   13145 	    "Failed to compile the content model", NULL);
   13146     } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
   13147         xmlSchemaPCustomErr(ctxt,
   13148 	    XML_SCHEMAP_NOT_DETERMINISTIC,
   13149 	    /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
   13150 	    WXS_BASIC_CAST type, type->node,
   13151 	    "The content model is not determinist", NULL);
   13152     } else {
   13153 #ifdef DEBUG_CONTENT_REGEXP
   13154         xmlGenericError(xmlGenericErrorContext,
   13155                         "Content model of %s:\n", type->name);
   13156         xmlRegexpPrint(stderr, type->contModel);
   13157 #endif
   13158     }
   13159     ctxt->state = NULL;
   13160     xmlFreeAutomata(ctxt->am);
   13161     ctxt->am = NULL;
   13162 }
   13163 
   13164 /**
   13165  * xmlSchemaResolveElementReferences:
   13166  * @elem:  the schema element context
   13167  * @ctxt:  the schema parser context
   13168  *
   13169  * Resolves the references of an element declaration
   13170  * or particle, which has an element declaration as it's
   13171  * term.
   13172  */
   13173 static void
   13174 xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
   13175 				  xmlSchemaParserCtxtPtr ctxt)
   13176 {
   13177     if ((ctxt == NULL) || (elemDecl == NULL) ||
   13178 	((elemDecl != NULL) &&
   13179 	(elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
   13180         return;
   13181     elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
   13182 
   13183     if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
   13184 	xmlSchemaTypePtr type;
   13185 
   13186 	/* (type definition) ... otherwise the type definition resolved
   13187 	* to by the actual value of the type [attribute] ...
   13188 	*/
   13189 	type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
   13190 	    elemDecl->namedTypeNs);
   13191 	if (type == NULL) {
   13192 	    xmlSchemaPResCompAttrErr(ctxt,
   13193 		XML_SCHEMAP_SRC_RESOLVE,
   13194 		WXS_BASIC_CAST elemDecl, elemDecl->node,
   13195 		"type", elemDecl->namedType, elemDecl->namedTypeNs,
   13196 		XML_SCHEMA_TYPE_BASIC, "type definition");
   13197 	} else
   13198 	    elemDecl->subtypes = type;
   13199     }
   13200     if (elemDecl->substGroup != NULL) {
   13201 	xmlSchemaElementPtr substHead;
   13202 
   13203 	/*
   13204 	* FIXME TODO: Do we need a new field in _xmlSchemaElement for
   13205 	* substitutionGroup?
   13206 	*/
   13207 	substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
   13208 	    elemDecl->substGroupNs);
   13209 	if (substHead == NULL) {
   13210 	    xmlSchemaPResCompAttrErr(ctxt,
   13211 		XML_SCHEMAP_SRC_RESOLVE,
   13212 		WXS_BASIC_CAST elemDecl, NULL,
   13213 		"substitutionGroup", elemDecl->substGroup,
   13214 		elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
   13215 	} else {
   13216 	    xmlSchemaResolveElementReferences(substHead, ctxt);
   13217 	    /*
   13218 	    * Set the "substitution group affiliation".
   13219 	    * NOTE that now we use the "refDecl" field for this.
   13220 	    */
   13221 	    WXS_SUBST_HEAD(elemDecl) = substHead;
   13222 	    /*
   13223 	    * The type definitions is set to:
   13224 	    * SPEC "...the {type definition} of the element
   13225 	    * declaration resolved to by the actual value
   13226 	    * of the substitutionGroup [attribute], if present"
   13227 	    */
   13228 	    if (elemDecl->subtypes == NULL)
   13229 		elemDecl->subtypes = substHead->subtypes;
   13230 	}
   13231     }
   13232     /*
   13233     * SPEC "The definition of anyType serves as the default type definition
   13234     * for element declarations whose XML representation does not specify one."
   13235     */
   13236     if ((elemDecl->subtypes == NULL) &&
   13237 	(elemDecl->namedType == NULL) &&
   13238 	(elemDecl->substGroup == NULL))
   13239 	elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
   13240 }
   13241 
   13242 /**
   13243  * xmlSchemaResolveUnionMemberTypes:
   13244  * @ctxt:  the schema parser context
   13245  * @type:  the schema simple type definition
   13246  *
   13247  * Checks and builds the "member type definitions" property of the union
   13248  * simple type. This handles part (1), part (2) is done in
   13249  * xmlSchemaFinishMemberTypeDefinitionsProperty()
   13250  *
   13251  * Returns -1 in case of an internal error, 0 otherwise.
   13252  */
   13253 static int
   13254 xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
   13255 				 xmlSchemaTypePtr type)
   13256 {
   13257 
   13258     xmlSchemaTypeLinkPtr link, lastLink, newLink;
   13259     xmlSchemaTypePtr memberType;
   13260 
   13261     /*
   13262     * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
   13263     * define the explicit members as the type definitions resolved
   13264     * to by the items in the actual value of the memberTypes [attribute],
   13265     * if any, followed by the type definitions corresponding to the
   13266     * <simpleType>s among the [children] of <union>, if any."
   13267     */
   13268     /*
   13269     * Resolve references.
   13270     */
   13271     link = type->memberTypes;
   13272     lastLink = NULL;
   13273     while (link != NULL) {
   13274 	const xmlChar *name, *nsName;
   13275 
   13276 	name = ((xmlSchemaQNameRefPtr) link->type)->name;
   13277 	nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
   13278 
   13279 	memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
   13280 	if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
   13281 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
   13282 		WXS_BASIC_CAST type, type->node, "memberTypes",
   13283 		name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
   13284 	    /*
   13285 	    * Remove the member type link.
   13286 	    */
   13287 	    if (lastLink == NULL)
   13288 		type->memberTypes = link->next;
   13289 	    else
   13290 		lastLink->next = link->next;
   13291 	    newLink = link;
   13292 	    link = link->next;
   13293 	    xmlFree(newLink);
   13294 	} else {
   13295 	    link->type = memberType;
   13296 	    lastLink = link;
   13297 	    link = link->next;
   13298 	}
   13299     }
   13300     /*
   13301     * Add local simple types,
   13302     */
   13303     memberType = type->subtypes;
   13304     while (memberType != NULL) {
   13305 	link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
   13306 	if (link == NULL) {
   13307 	    xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
   13308 	    return (-1);
   13309 	}
   13310 	link->type = memberType;
   13311 	link->next = NULL;
   13312 	if (lastLink == NULL)
   13313 	    type->memberTypes = link;
   13314 	else
   13315 	    lastLink->next = link;
   13316 	lastLink = link;
   13317 	memberType = memberType->next;
   13318     }
   13319     return (0);
   13320 }
   13321 
   13322 /**
   13323  * xmlSchemaIsDerivedFromBuiltInType:
   13324  * @ctxt:  the schema parser context
   13325  * @type:  the type definition
   13326  * @valType: the value type
   13327  *
   13328  *
   13329  * Returns 1 if the type has the given value type, or
   13330  * is derived from such a type.
   13331  */
   13332 static int
   13333 xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
   13334 {
   13335     if (type == NULL)
   13336 	return (0);
   13337     if (WXS_IS_COMPLEX(type))
   13338 	return (0);
   13339     if (type->type == XML_SCHEMA_TYPE_BASIC) {
   13340 	if (type->builtInType == valType)
   13341 	    return(1);
   13342 	if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
   13343 	    (type->builtInType == XML_SCHEMAS_ANYTYPE))
   13344 	    return (0);
   13345 	return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
   13346     }
   13347     return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
   13348 }
   13349 
   13350 #if 0
   13351 /**
   13352  * xmlSchemaIsDerivedFromBuiltInType:
   13353  * @ctxt:  the schema parser context
   13354  * @type:  the type definition
   13355  * @valType: the value type
   13356  *
   13357  *
   13358  * Returns 1 if the type has the given value type, or
   13359  * is derived from such a type.
   13360  */
   13361 static int
   13362 xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
   13363 {
   13364     if (type == NULL)
   13365 	return (0);
   13366     if (WXS_IS_COMPLEX(type))
   13367 	return (0);
   13368     if (type->type == XML_SCHEMA_TYPE_BASIC) {
   13369 	if (type->builtInType == valType)
   13370 	    return(1);
   13371 	return (0);
   13372     } else
   13373 	return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
   13374 
   13375     return (0);
   13376 }
   13377 
   13378 static xmlSchemaTypePtr
   13379 xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
   13380 {
   13381     if (type == NULL)
   13382 	return (NULL);
   13383     if (WXS_IS_COMPLEX(type))
   13384 	return (NULL);
   13385     if (type->type == XML_SCHEMA_TYPE_BASIC)
   13386 	return(type);
   13387     return(xmlSchemaQueryBuiltInType(type->subtypes));
   13388 }
   13389 #endif
   13390 
   13391 /**
   13392  * xmlSchemaGetPrimitiveType:
   13393  * @type:  the simpleType definition
   13394  *
   13395  * Returns the primitive type of the given type or
   13396  * NULL in case of error.
   13397  */
   13398 static xmlSchemaTypePtr
   13399 xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
   13400 {
   13401 
   13402     while (type != NULL) {
   13403 	/*
   13404 	* Note that anySimpleType is actually not a primitive type
   13405 	* but we need that here.
   13406 	*/
   13407 	if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
   13408 	   (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
   13409 	    return (type);
   13410 	type = type->baseType;
   13411     }
   13412 
   13413     return (NULL);
   13414 }
   13415 
   13416 #if 0
   13417 /**
   13418  * xmlSchemaGetBuiltInTypeAncestor:
   13419  * @type:  the simpleType definition
   13420  *
   13421  * Returns the primitive type of the given type or
   13422  * NULL in case of error.
   13423  */
   13424 static xmlSchemaTypePtr
   13425 xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
   13426 {
   13427     if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
   13428 	return (0);
   13429     while (type != NULL) {
   13430 	if (type->type == XML_SCHEMA_TYPE_BASIC)
   13431 	    return (type);
   13432 	type = type->baseType;
   13433     }
   13434 
   13435     return (NULL);
   13436 }
   13437 #endif
   13438 
   13439 /**
   13440  * xmlSchemaCloneWildcardNsConstraints:
   13441  * @ctxt:  the schema parser context
   13442  * @dest:  the destination wildcard
   13443  * @source: the source wildcard
   13444  *
   13445  * Clones the namespace constraints of source
   13446  * and assignes them to dest.
   13447  * Returns -1 on internal error, 0 otherwise.
   13448  */
   13449 static int
   13450 xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
   13451 				    xmlSchemaWildcardPtr dest,
   13452 				    xmlSchemaWildcardPtr source)
   13453 {
   13454     xmlSchemaWildcardNsPtr cur, tmp, last;
   13455 
   13456     if ((source == NULL) || (dest == NULL))
   13457 	return(-1);
   13458     dest->any = source->any;
   13459     cur = source->nsSet;
   13460     last = NULL;
   13461     while (cur != NULL) {
   13462 	tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
   13463 	if (tmp == NULL)
   13464 	    return(-1);
   13465 	tmp->value = cur->value;
   13466 	if (last == NULL)
   13467 	    dest->nsSet = tmp;
   13468 	else
   13469 	    last->next = tmp;
   13470 	last = tmp;
   13471 	cur = cur->next;
   13472     }
   13473     if (dest->negNsSet != NULL)
   13474 	xmlSchemaFreeWildcardNsSet(dest->negNsSet);
   13475     if (source->negNsSet != NULL) {
   13476 	dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   13477 	if (dest->negNsSet == NULL)
   13478 	    return(-1);
   13479 	dest->negNsSet->value = source->negNsSet->value;
   13480     } else
   13481 	dest->negNsSet = NULL;
   13482     return(0);
   13483 }
   13484 
   13485 /**
   13486  * xmlSchemaUnionWildcards:
   13487  * @ctxt:  the schema parser context
   13488  * @completeWild:  the first wildcard
   13489  * @curWild: the second wildcard
   13490  *
   13491  * Unions the namespace constraints of the given wildcards.
   13492  * @completeWild will hold the resulting union.
   13493  * Returns a positive error code on failure, -1 in case of an
   13494  * internal error, 0 otherwise.
   13495  */
   13496 static int
   13497 xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
   13498 			    xmlSchemaWildcardPtr completeWild,
   13499 			    xmlSchemaWildcardPtr curWild)
   13500 {
   13501     xmlSchemaWildcardNsPtr cur, curB, tmp;
   13502 
   13503     /*
   13504     * 1 If O1 and O2 are the same value, then that value must be the
   13505     * value.
   13506     */
   13507     if ((completeWild->any == curWild->any) &&
   13508 	((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
   13509 	((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
   13510 
   13511 	if ((completeWild->negNsSet == NULL) ||
   13512 	    (completeWild->negNsSet->value == curWild->negNsSet->value)) {
   13513 
   13514 	    if (completeWild->nsSet != NULL) {
   13515 		int found = 0;
   13516 
   13517 		/*
   13518 		* Check equality of sets.
   13519 		*/
   13520 		cur = completeWild->nsSet;
   13521 		while (cur != NULL) {
   13522 		    found = 0;
   13523 		    curB = curWild->nsSet;
   13524 		    while (curB != NULL) {
   13525 			if (cur->value == curB->value) {
   13526 			    found = 1;
   13527 			    break;
   13528 			}
   13529 			curB = curB->next;
   13530 		    }
   13531 		    if (!found)
   13532 			break;
   13533 		    cur = cur->next;
   13534 		}
   13535 		if (found)
   13536 		    return(0);
   13537 	    } else
   13538 		return(0);
   13539 	}
   13540     }
   13541     /*
   13542     * 2 If either O1 or O2 is any, then any must be the value
   13543     */
   13544     if (completeWild->any != curWild->any) {
   13545 	if (completeWild->any == 0) {
   13546 	    completeWild->any = 1;
   13547 	    if (completeWild->nsSet != NULL) {
   13548 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13549 		completeWild->nsSet = NULL;
   13550 	    }
   13551 	    if (completeWild->negNsSet != NULL) {
   13552 		xmlFree(completeWild->negNsSet);
   13553 		completeWild->negNsSet = NULL;
   13554 	    }
   13555 	}
   13556 	return (0);
   13557     }
   13558     /*
   13559     * 3 If both O1 and O2 are sets of (namespace names or absent),
   13560     * then the union of those sets must be the value.
   13561     */
   13562     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
   13563 	int found;
   13564 	xmlSchemaWildcardNsPtr start;
   13565 
   13566 	cur = curWild->nsSet;
   13567 	start = completeWild->nsSet;
   13568 	while (cur != NULL) {
   13569 	    found = 0;
   13570 	    curB = start;
   13571 	    while (curB != NULL) {
   13572 		if (cur->value == curB->value) {
   13573 		    found = 1;
   13574 		    break;
   13575 		}
   13576 		curB = curB->next;
   13577 	    }
   13578 	    if (!found) {
   13579 		tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
   13580 		if (tmp == NULL)
   13581 		    return (-1);
   13582 		tmp->value = cur->value;
   13583 		tmp->next = completeWild->nsSet;
   13584 		completeWild->nsSet = tmp;
   13585 	    }
   13586 	    cur = cur->next;
   13587 	}
   13588 
   13589 	return(0);
   13590     }
   13591     /*
   13592     * 4 If the two are negations of different values (namespace names
   13593     * or absent), then a pair of not and absent must be the value.
   13594     */
   13595     if ((completeWild->negNsSet != NULL) &&
   13596 	(curWild->negNsSet != NULL) &&
   13597 	(completeWild->negNsSet->value != curWild->negNsSet->value)) {
   13598 	completeWild->negNsSet->value = NULL;
   13599 
   13600 	return(0);
   13601     }
   13602     /*
   13603      * 5.
   13604      */
   13605     if (((completeWild->negNsSet != NULL) &&
   13606 	(completeWild->negNsSet->value != NULL) &&
   13607 	(curWild->nsSet != NULL)) ||
   13608 	((curWild->negNsSet != NULL) &&
   13609 	(curWild->negNsSet->value != NULL) &&
   13610 	(completeWild->nsSet != NULL))) {
   13611 
   13612 	int nsFound, absentFound = 0;
   13613 
   13614 	if (completeWild->nsSet != NULL) {
   13615 	    cur = completeWild->nsSet;
   13616 	    curB = curWild->negNsSet;
   13617 	} else {
   13618 	    cur = curWild->nsSet;
   13619 	    curB = completeWild->negNsSet;
   13620 	}
   13621 	nsFound = 0;
   13622 	while (cur != NULL) {
   13623 	    if (cur->value == NULL)
   13624 		absentFound = 1;
   13625 	    else if (cur->value == curB->value)
   13626 		nsFound = 1;
   13627 	    if (nsFound && absentFound)
   13628 		break;
   13629 	    cur = cur->next;
   13630 	}
   13631 
   13632 	if (nsFound && absentFound) {
   13633 	    /*
   13634 	    * 5.1 If the set S includes both the negated namespace
   13635 	    * name and absent, then any must be the value.
   13636 	    */
   13637 	    completeWild->any = 1;
   13638 	    if (completeWild->nsSet != NULL) {
   13639 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13640 		completeWild->nsSet = NULL;
   13641 	    }
   13642 	    if (completeWild->negNsSet != NULL) {
   13643 		xmlFree(completeWild->negNsSet);
   13644 		completeWild->negNsSet = NULL;
   13645 	    }
   13646 	} else if (nsFound && (!absentFound)) {
   13647 	    /*
   13648 	    * 5.2 If the set S includes the negated namespace name
   13649 	    * but not absent, then a pair of not and absent must
   13650 	    * be the value.
   13651 	    */
   13652 	    if (completeWild->nsSet != NULL) {
   13653 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13654 		completeWild->nsSet = NULL;
   13655 	    }
   13656 	    if (completeWild->negNsSet == NULL) {
   13657 		completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   13658 		if (completeWild->negNsSet == NULL)
   13659 		    return (-1);
   13660 	    }
   13661 	    completeWild->negNsSet->value = NULL;
   13662 	} else if ((!nsFound) && absentFound) {
   13663 	    /*
   13664 	    * 5.3 If the set S includes absent but not the negated
   13665 	    * namespace name, then the union is not expressible.
   13666 	    */
   13667 	    xmlSchemaPErr(ctxt, completeWild->node,
   13668 		XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
   13669 		"The union of the wilcard is not expressible.\n",
   13670 		NULL, NULL);
   13671 	    return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
   13672 	} else if ((!nsFound) && (!absentFound)) {
   13673 	    /*
   13674 	    * 5.4 If the set S does not include either the negated namespace
   13675 	    * name or absent, then whichever of O1 or O2 is a pair of not
   13676 	    * and a namespace name must be the value.
   13677 	    */
   13678 	    if (completeWild->negNsSet == NULL) {
   13679 		if (completeWild->nsSet != NULL) {
   13680 		    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13681 		    completeWild->nsSet = NULL;
   13682 		}
   13683 		completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   13684 		if (completeWild->negNsSet == NULL)
   13685 		    return (-1);
   13686 		completeWild->negNsSet->value = curWild->negNsSet->value;
   13687 	    }
   13688 	}
   13689 	return (0);
   13690     }
   13691     /*
   13692      * 6.
   13693      */
   13694     if (((completeWild->negNsSet != NULL) &&
   13695 	(completeWild->negNsSet->value == NULL) &&
   13696 	(curWild->nsSet != NULL)) ||
   13697 	((curWild->negNsSet != NULL) &&
   13698 	(curWild->negNsSet->value == NULL) &&
   13699 	(completeWild->nsSet != NULL))) {
   13700 
   13701 	if (completeWild->nsSet != NULL) {
   13702 	    cur = completeWild->nsSet;
   13703 	} else {
   13704 	    cur = curWild->nsSet;
   13705 	}
   13706 	while (cur != NULL) {
   13707 	    if (cur->value == NULL) {
   13708 		/*
   13709 		* 6.1 If the set S includes absent, then any must be the
   13710 		* value.
   13711 		*/
   13712 		completeWild->any = 1;
   13713 		if (completeWild->nsSet != NULL) {
   13714 		    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13715 		    completeWild->nsSet = NULL;
   13716 		}
   13717 		if (completeWild->negNsSet != NULL) {
   13718 		    xmlFree(completeWild->negNsSet);
   13719 		    completeWild->negNsSet = NULL;
   13720 		}
   13721 		return (0);
   13722 	    }
   13723 	    cur = cur->next;
   13724 	}
   13725 	if (completeWild->negNsSet == NULL) {
   13726 	    /*
   13727 	    * 6.2 If the set S does not include absent, then a pair of not
   13728 	    * and absent must be the value.
   13729 	    */
   13730 	    if (completeWild->nsSet != NULL) {
   13731 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13732 		completeWild->nsSet = NULL;
   13733 	    }
   13734 	    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   13735 	    if (completeWild->negNsSet == NULL)
   13736 		return (-1);
   13737 	    completeWild->negNsSet->value = NULL;
   13738 	}
   13739 	return (0);
   13740     }
   13741     return (0);
   13742 
   13743 }
   13744 
   13745 /**
   13746  * xmlSchemaIntersectWildcards:
   13747  * @ctxt:  the schema parser context
   13748  * @completeWild:  the first wildcard
   13749  * @curWild: the second wildcard
   13750  *
   13751  * Intersects the namespace constraints of the given wildcards.
   13752  * @completeWild will hold the resulting intersection.
   13753  * Returns a positive error code on failure, -1 in case of an
   13754  * internal error, 0 otherwise.
   13755  */
   13756 static int
   13757 xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
   13758 			    xmlSchemaWildcardPtr completeWild,
   13759 			    xmlSchemaWildcardPtr curWild)
   13760 {
   13761     xmlSchemaWildcardNsPtr cur, curB, prev,  tmp;
   13762 
   13763     /*
   13764     * 1 If O1 and O2 are the same value, then that value must be the
   13765     * value.
   13766     */
   13767     if ((completeWild->any == curWild->any) &&
   13768 	((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
   13769 	((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
   13770 
   13771 	if ((completeWild->negNsSet == NULL) ||
   13772 	    (completeWild->negNsSet->value == curWild->negNsSet->value)) {
   13773 
   13774 	    if (completeWild->nsSet != NULL) {
   13775 		int found = 0;
   13776 
   13777 		/*
   13778 		* Check equality of sets.
   13779 		*/
   13780 		cur = completeWild->nsSet;
   13781 		while (cur != NULL) {
   13782 		    found = 0;
   13783 		    curB = curWild->nsSet;
   13784 		    while (curB != NULL) {
   13785 			if (cur->value == curB->value) {
   13786 			    found = 1;
   13787 			    break;
   13788 			}
   13789 			curB = curB->next;
   13790 		    }
   13791 		    if (!found)
   13792 			break;
   13793 		    cur = cur->next;
   13794 		}
   13795 		if (found)
   13796 		    return(0);
   13797 	    } else
   13798 		return(0);
   13799 	}
   13800     }
   13801     /*
   13802     * 2 If either O1 or O2 is any, then the other must be the value.
   13803     */
   13804     if ((completeWild->any != curWild->any) && (completeWild->any)) {
   13805 	if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
   13806 	    return(-1);
   13807 	return(0);
   13808     }
   13809     /*
   13810     * 3 If either O1 or O2 is a pair of not and a value (a namespace
   13811     * name or absent) and the other is a set of (namespace names or
   13812     * absent), then that set, minus the negated value if it was in
   13813     * the set, minus absent if it was in the set, must be the value.
   13814     */
   13815     if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
   13816 	((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
   13817 	const xmlChar *neg;
   13818 
   13819 	if (completeWild->nsSet == NULL) {
   13820 	    neg = completeWild->negNsSet->value;
   13821 	    if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
   13822 		return(-1);
   13823 	} else
   13824 	    neg = curWild->negNsSet->value;
   13825 	/*
   13826 	* Remove absent and negated.
   13827 	*/
   13828 	prev = NULL;
   13829 	cur = completeWild->nsSet;
   13830 	while (cur != NULL) {
   13831 	    if (cur->value == NULL) {
   13832 		if (prev == NULL)
   13833 		    completeWild->nsSet = cur->next;
   13834 		else
   13835 		    prev->next = cur->next;
   13836 		xmlFree(cur);
   13837 		break;
   13838 	    }
   13839 	    prev = cur;
   13840 	    cur = cur->next;
   13841 	}
   13842 	if (neg != NULL) {
   13843 	    prev = NULL;
   13844 	    cur = completeWild->nsSet;
   13845 	    while (cur != NULL) {
   13846 		if (cur->value == neg) {
   13847 		    if (prev == NULL)
   13848 			completeWild->nsSet = cur->next;
   13849 		    else
   13850 			prev->next = cur->next;
   13851 		    xmlFree(cur);
   13852 		    break;
   13853 		}
   13854 		prev = cur;
   13855 		cur = cur->next;
   13856 	    }
   13857 	}
   13858 
   13859 	return(0);
   13860     }
   13861     /*
   13862     * 4 If both O1 and O2 are sets of (namespace names or absent),
   13863     * then the intersection of those sets must be the value.
   13864     */
   13865     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
   13866 	int found;
   13867 
   13868 	cur = completeWild->nsSet;
   13869 	prev = NULL;
   13870 	while (cur != NULL) {
   13871 	    found = 0;
   13872 	    curB = curWild->nsSet;
   13873 	    while (curB != NULL) {
   13874 		if (cur->value == curB->value) {
   13875 		    found = 1;
   13876 		    break;
   13877 		}
   13878 		curB = curB->next;
   13879 	    }
   13880 	    if (!found) {
   13881 		if (prev == NULL)
   13882 		    completeWild->nsSet = cur->next;
   13883 		else
   13884 		    prev->next = cur->next;
   13885 		tmp = cur->next;
   13886 		xmlFree(cur);
   13887 		cur = tmp;
   13888 		continue;
   13889 	    }
   13890 	    prev = cur;
   13891 	    cur = cur->next;
   13892 	}
   13893 
   13894 	return(0);
   13895     }
   13896     /* 5 If the two are negations of different namespace names,
   13897     * then the intersection is not expressible
   13898     */
   13899     if ((completeWild->negNsSet != NULL) &&
   13900 	(curWild->negNsSet != NULL) &&
   13901 	(completeWild->negNsSet->value != curWild->negNsSet->value) &&
   13902 	(completeWild->negNsSet->value != NULL) &&
   13903 	(curWild->negNsSet->value != NULL)) {
   13904 
   13905 	xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
   13906 	    "The intersection of the wilcard is not expressible.\n",
   13907 	    NULL, NULL);
   13908 	return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
   13909     }
   13910     /*
   13911     * 6 If the one is a negation of a namespace name and the other
   13912     * is a negation of absent, then the one which is the negation
   13913     * of a namespace name must be the value.
   13914     */
   13915     if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
   13916 	(completeWild->negNsSet->value != curWild->negNsSet->value) &&
   13917 	(completeWild->negNsSet->value == NULL)) {
   13918 	completeWild->negNsSet->value =  curWild->negNsSet->value;
   13919     }
   13920     return(0);
   13921 }
   13922 
   13923 /**
   13924  * xmlSchemaIsWildcardNsConstraintSubset:
   13925  * @ctxt:  the schema parser context
   13926  * @sub:  the first wildcard
   13927  * @super: the second wildcard
   13928  *
   13929  * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
   13930  *
   13931  * Returns 0 if the namespace constraint of @sub is an intensional
   13932  * subset of @super, 1 otherwise.
   13933  */
   13934 static int
   13935 xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
   13936 			  xmlSchemaWildcardPtr super)
   13937 {
   13938     /*
   13939     * 1 super must be any.
   13940     */
   13941     if (super->any)
   13942 	return (0);
   13943     /*
   13944     * 2.1 sub must be a pair of not and a namespace name or absent.
   13945     * 2.2 super must be a pair of not and the same value.
   13946     */
   13947     if ((sub->negNsSet != NULL) &&
   13948 	(super->negNsSet != NULL) &&
   13949 	(sub->negNsSet->value == sub->negNsSet->value))
   13950 	return (0);
   13951     /*
   13952     * 3.1 sub must be a set whose members are either namespace names or absent.
   13953     */
   13954     if (sub->nsSet != NULL) {
   13955 	/*
   13956 	* 3.2.1 super must be the same set or a superset thereof.
   13957 	*/
   13958 	if (super->nsSet != NULL) {
   13959 	    xmlSchemaWildcardNsPtr cur, curB;
   13960 	    int found = 0;
   13961 
   13962 	    cur = sub->nsSet;
   13963 	    while (cur != NULL) {
   13964 		found = 0;
   13965 		curB = super->nsSet;
   13966 		while (curB != NULL) {
   13967 		    if (cur->value == curB->value) {
   13968 			found = 1;
   13969 			break;
   13970 		    }
   13971 		    curB = curB->next;
   13972 		}
   13973 		if (!found)
   13974 		    return (1);
   13975 		cur = cur->next;
   13976 	    }
   13977 	    if (found)
   13978 		return (0);
   13979 	} else if (super->negNsSet != NULL) {
   13980 	    xmlSchemaWildcardNsPtr cur;
   13981 	    /*
   13982 	    * 3.2.2 super must be a pair of not and a namespace name or
   13983 	    * absent and that value must not be in sub's set.
   13984 	    */
   13985 	    cur = sub->nsSet;
   13986 	    while (cur != NULL) {
   13987 		if (cur->value == super->negNsSet->value)
   13988 		    return (1);
   13989 		cur = cur->next;
   13990 	    }
   13991 	    return (0);
   13992 	}
   13993     }
   13994     return (1);
   13995 }
   13996 
   13997 static int
   13998 xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
   13999 				     int *fixed,
   14000 				     const xmlChar **value,
   14001 				     xmlSchemaValPtr *val)
   14002 {
   14003     *fixed = 0;
   14004     *value = NULL;
   14005     if (val != 0)
   14006 	*val = NULL;
   14007 
   14008     if (attruse->defValue != NULL) {
   14009 	*value = attruse->defValue;
   14010 	if (val != NULL)
   14011 	    *val = attruse->defVal;
   14012 	if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
   14013 	    *fixed = 1;
   14014 	return(1);
   14015     } else if ((attruse->attrDecl != NULL) &&
   14016 	(attruse->attrDecl->defValue != NULL)) {
   14017 	*value = attruse->attrDecl->defValue;
   14018 	if (val != NULL)
   14019 	    *val = attruse->attrDecl->defVal;
   14020 	if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
   14021 	    *fixed = 1;
   14022 	return(1);
   14023     }
   14024     return(0);
   14025 }
   14026 /**
   14027  * xmlSchemaCheckCVCWildcardNamespace:
   14028  * @wild:  the wildcard
   14029  * @ns:  the namespace
   14030  *
   14031  * Validation Rule: Wildcard allows Namespace Name
   14032  * (cvc-wildcard-namespace)
   14033  *
   14034  * Returns 0 if the given namespace matches the wildcard,
   14035  * 1 otherwise and -1 on API errors.
   14036  */
   14037 static int
   14038 xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
   14039 				   const xmlChar* ns)
   14040 {
   14041     if (wild == NULL)
   14042 	return(-1);
   14043 
   14044     if (wild->any)
   14045 	return(0);
   14046     else if (wild->nsSet != NULL) {
   14047 	xmlSchemaWildcardNsPtr cur;
   14048 
   14049 	cur = wild->nsSet;
   14050 	while (cur != NULL) {
   14051 	    if (xmlStrEqual(cur->value, ns))
   14052 		return(0);
   14053 	    cur = cur->next;
   14054 	}
   14055     } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
   14056 	(!xmlStrEqual(wild->negNsSet->value, ns)))
   14057 	return(0);
   14058 
   14059     return(1);
   14060 }
   14061 
   14062 #define XML_SCHEMA_ACTION_DERIVE 0
   14063 #define XML_SCHEMA_ACTION_REDEFINE 1
   14064 
   14065 #define WXS_ACTION_STR(a) \
   14066 ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
   14067 
   14068 /*
   14069 * Schema Component Constraint:
   14070 *   Derivation Valid (Restriction, Complex)
   14071 *   derivation-ok-restriction (2) - (4)
   14072 *
   14073 * ATTENTION:
   14074 * In XML Schema 1.1 this will be:
   14075 * Validation Rule:
   14076 *     Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
   14077 *
   14078 */
   14079 static int
   14080 xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
   14081 				       int action,
   14082 				       xmlSchemaBasicItemPtr item,
   14083 				       xmlSchemaBasicItemPtr baseItem,
   14084 				       xmlSchemaItemListPtr uses,
   14085 				       xmlSchemaItemListPtr baseUses,
   14086 				       xmlSchemaWildcardPtr wild,
   14087 				       xmlSchemaWildcardPtr baseWild)
   14088 {
   14089     xmlSchemaAttributeUsePtr cur = NULL, bcur;
   14090     int i, j, found; /* err = 0; */
   14091     const xmlChar *bEffValue;
   14092     int effFixed;
   14093 
   14094     if (uses != NULL) {
   14095 	for (i = 0; i < uses->nbItems; i++) {
   14096 	    cur = uses->items[i];
   14097 	    found = 0;
   14098 	    if (baseUses == NULL)
   14099 		goto not_found;
   14100 	    for (j = 0; j < baseUses->nbItems; j++) {
   14101 		bcur = baseUses->items[j];
   14102 		if ((WXS_ATTRUSE_DECL_NAME(cur) ==
   14103 			WXS_ATTRUSE_DECL_NAME(bcur)) &&
   14104 		    (WXS_ATTRUSE_DECL_TNS(cur) ==
   14105 			WXS_ATTRUSE_DECL_TNS(bcur)))
   14106 		{
   14107 		    /*
   14108 		    * (2.1) "If there is an attribute use in the {attribute
   14109 		    * uses} of the {base type definition} (call this B) whose
   14110 		    * {attribute declaration} has the same {name} and {target
   14111 		    * namespace}, then  all of the following must be true:"
   14112 		    */
   14113 		    found = 1;
   14114 
   14115 		    if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
   14116 			(bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
   14117 		    {
   14118 			xmlChar *str = NULL;
   14119 			/*
   14120 			* (2.1.1) "one of the following must be true:"
   14121 			* (2.1.1.1) "B's {required} is false."
   14122 			* (2.1.1.2) "R's {required} is true."
   14123 			*/
   14124 			xmlSchemaPAttrUseErr4(pctxt,
   14125 			    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
   14126 			    WXS_ITEM_NODE(item), item, cur,
   14127 			    "The 'optional' attribute use is inconsistent "
   14128 			    "with the corresponding 'required' attribute use of "
   14129 			    "the %s %s",
   14130 			    WXS_ACTION_STR(action),
   14131 			    xmlSchemaGetComponentDesignation(&str, baseItem),
   14132 			    NULL, NULL);
   14133 			FREE_AND_NULL(str);
   14134 			/* err = pctxt->err; */
   14135 		    } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
   14136 			WXS_ATTRUSE_TYPEDEF(cur),
   14137 			WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
   14138 		    {
   14139 			xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
   14140 
   14141 			/*
   14142 			* SPEC (2.1.2) "R's {attribute declaration}'s
   14143 			* {type definition} must be validly derived from
   14144 			* B's {type definition} given the empty set as
   14145 			* defined in Type Derivation OK (Simple) (3.14.6)."
   14146 			*/
   14147 			xmlSchemaPAttrUseErr4(pctxt,
   14148 			    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
   14149 			    WXS_ITEM_NODE(item), item, cur,
   14150 			    "The attribute declaration's %s "
   14151 			    "is not validly derived from "
   14152 			    "the corresponding %s of the "
   14153 			    "attribute declaration in the %s %s",
   14154 			    xmlSchemaGetComponentDesignation(&strA,
   14155 				WXS_ATTRUSE_TYPEDEF(cur)),
   14156 			    xmlSchemaGetComponentDesignation(&strB,
   14157 				WXS_ATTRUSE_TYPEDEF(bcur)),
   14158 			    WXS_ACTION_STR(action),
   14159 			    xmlSchemaGetComponentDesignation(&strC, baseItem));
   14160 			    /* xmlSchemaGetComponentDesignation(&str, baseItem), */
   14161 			FREE_AND_NULL(strA);
   14162 			FREE_AND_NULL(strB);
   14163 			FREE_AND_NULL(strC);
   14164 			/* err = pctxt->err; */
   14165 		    } else {
   14166 			/*
   14167 			* 2.1.3 [Definition:]  Let the effective value
   14168 			* constraint of an attribute use be its {value
   14169 			* constraint}, if present, otherwise its {attribute
   14170 			* declaration}'s {value constraint} .
   14171 			*/
   14172 			xmlSchemaGetEffectiveValueConstraint(bcur,
   14173 			    &effFixed, &bEffValue, NULL);
   14174 			/*
   14175 			* 2.1.3 ... one of the following must be true
   14176 			*
   14177 			* 2.1.3.1 B's effective value constraint is
   14178 			* absent or default.
   14179 			*/
   14180 			if ((bEffValue != NULL) &&
   14181 			    (effFixed == 1)) {
   14182 			    const xmlChar *rEffValue = NULL;
   14183 
   14184 			    xmlSchemaGetEffectiveValueConstraint(bcur,
   14185 				&effFixed, &rEffValue, NULL);
   14186 			    /*
   14187 			    * 2.1.3.2 R's effective value constraint is
   14188 			    * fixed with the same string as B's.
   14189 			    * MAYBE TODO: Compare the computed values.
   14190 			    *       Hmm, it says "same string" so
   14191 			    *       string-equality might really be sufficient.
   14192 			    */
   14193 			    if ((effFixed == 0) ||
   14194 				(! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
   14195 			    {
   14196 				xmlChar *str = NULL;
   14197 
   14198 				xmlSchemaPAttrUseErr4(pctxt,
   14199 				    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
   14200 				    WXS_ITEM_NODE(item), item, cur,
   14201 				    "The effective value constraint of the "
   14202 				    "attribute use is inconsistent with "
   14203 				    "its correspondent in the %s %s",
   14204 				    WXS_ACTION_STR(action),
   14205 				    xmlSchemaGetComponentDesignation(&str,
   14206 					baseItem),
   14207 				    NULL, NULL);
   14208 				FREE_AND_NULL(str);
   14209 				/* err = pctxt->err; */
   14210 			    }
   14211 			}
   14212 		    }
   14213 		    break;
   14214 		}
   14215 	    }
   14216 not_found:
   14217 	    if (!found) {
   14218 		/*
   14219 		* (2.2) "otherwise the {base type definition} must have an
   14220 		* {attribute wildcard} and the {target namespace} of the
   14221 		* R's {attribute declaration} must be valid with respect
   14222 		* to that wildcard, as defined in Wildcard allows Namespace
   14223 		* Name (3.10.4)."
   14224 		*/
   14225 		if ((baseWild == NULL) ||
   14226 		    (xmlSchemaCheckCVCWildcardNamespace(baseWild,
   14227 		    (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
   14228 		{
   14229 		    xmlChar *str = NULL;
   14230 
   14231 		    xmlSchemaPAttrUseErr4(pctxt,
   14232 			XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
   14233 			WXS_ITEM_NODE(item), item, cur,
   14234 			"Neither a matching attribute use, "
   14235 			"nor a matching wildcard exists in the %s %s",
   14236 			WXS_ACTION_STR(action),
   14237 			xmlSchemaGetComponentDesignation(&str, baseItem),
   14238 			NULL, NULL);
   14239 		    FREE_AND_NULL(str);
   14240 		    /* err = pctxt->err; */
   14241 		}
   14242 	    }
   14243 	}
   14244     }
   14245     /*
   14246     * SPEC derivation-ok-restriction (3):
   14247     * (3) "For each attribute use in the {attribute uses} of the {base type
   14248     * definition} whose {required} is true, there must be an attribute
   14249     * use with an {attribute declaration} with the same {name} and
   14250     * {target namespace} as its {attribute declaration} in the {attribute
   14251     * uses} of the complex type definition itself whose {required} is true.
   14252     */
   14253     if (baseUses != NULL) {
   14254 	for (j = 0; j < baseUses->nbItems; j++) {
   14255 	    bcur = baseUses->items[j];
   14256 	    if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
   14257 		continue;
   14258 	    found = 0;
   14259 	    if (uses != NULL) {
   14260 		for (i = 0; i < uses->nbItems; i++) {
   14261 		    cur = uses->items[i];
   14262 		    if ((WXS_ATTRUSE_DECL_NAME(cur) ==
   14263 			WXS_ATTRUSE_DECL_NAME(bcur)) &&
   14264 			(WXS_ATTRUSE_DECL_TNS(cur) ==
   14265 			WXS_ATTRUSE_DECL_TNS(bcur))) {
   14266 			found = 1;
   14267 			break;
   14268 		    }
   14269 		}
   14270 	    }
   14271 	    if (!found) {
   14272 		xmlChar *strA = NULL, *strB = NULL;
   14273 
   14274 		xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   14275 		    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
   14276 		    NULL, item,
   14277 		    "A matching attribute use for the "
   14278 		    "'required' %s of the %s %s is missing",
   14279 		    xmlSchemaGetComponentDesignation(&strA, bcur),
   14280 		    WXS_ACTION_STR(action),
   14281 		    xmlSchemaGetComponentDesignation(&strB, baseItem),
   14282 		    NULL);
   14283 		FREE_AND_NULL(strA);
   14284 		FREE_AND_NULL(strB);
   14285 	    }
   14286 	}
   14287     }
   14288     /*
   14289     * derivation-ok-restriction (4)
   14290     */
   14291     if (wild != NULL) {
   14292 	/*
   14293 	* (4) "If there is an {attribute wildcard}, all of the
   14294 	* following must be true:"
   14295 	*/
   14296 	if (baseWild == NULL) {
   14297 	    xmlChar *str = NULL;
   14298 
   14299 	    /*
   14300 	    * (4.1) "The {base type definition} must also have one."
   14301 	    */
   14302 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   14303 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
   14304 		NULL, item,
   14305 		"The %s has an attribute wildcard, "
   14306 		"but the %s %s '%s' does not have one",
   14307 		WXS_ITEM_TYPE_NAME(item),
   14308 		WXS_ACTION_STR(action),
   14309 		WXS_ITEM_TYPE_NAME(baseItem),
   14310 		xmlSchemaGetComponentQName(&str, baseItem));
   14311 	    FREE_AND_NULL(str);
   14312 	    return(pctxt->err);
   14313 	} else if ((baseWild->any == 0) &&
   14314 		xmlSchemaCheckCOSNSSubset(wild, baseWild))
   14315 	{
   14316 	    xmlChar *str = NULL;
   14317 	    /*
   14318 	    * (4.2) "The complex type definition's {attribute wildcard}'s
   14319 	    * {namespace constraint} must be a subset of the {base type
   14320 	    * definition}'s {attribute wildcard}'s {namespace constraint},
   14321 	    * as defined by Wildcard Subset (3.10.6)."
   14322 	    */
   14323 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   14324 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
   14325 		NULL, item,
   14326 		"The attribute wildcard is not a valid "
   14327 		"subset of the wildcard in the %s %s '%s'",
   14328 		WXS_ACTION_STR(action),
   14329 		WXS_ITEM_TYPE_NAME(baseItem),
   14330 		xmlSchemaGetComponentQName(&str, baseItem),
   14331 		NULL);
   14332 	    FREE_AND_NULL(str);
   14333 	    return(pctxt->err);
   14334 	}
   14335 	/* 4.3 Unless the {base type definition} is the ur-type
   14336 	* definition, the complex type definition's {attribute
   14337 	* wildcard}'s {process contents} must be identical to or
   14338 	* stronger than the {base type definition}'s {attribute
   14339 	* wildcard}'s {process contents}, where strict is stronger
   14340 	* than lax is stronger than skip.
   14341 	*/
   14342 	if ((! WXS_IS_ANYTYPE(baseItem)) &&
   14343 	    (wild->processContents < baseWild->processContents)) {
   14344 	    xmlChar *str = NULL;
   14345 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   14346 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
   14347 		NULL, baseItem,
   14348 		"The {process contents} of the attribute wildcard is "
   14349 		"weaker than the one in the %s %s '%s'",
   14350 		WXS_ACTION_STR(action),
   14351 		WXS_ITEM_TYPE_NAME(baseItem),
   14352 		xmlSchemaGetComponentQName(&str, baseItem),
   14353 		NULL);
   14354 	    FREE_AND_NULL(str)
   14355 		return(pctxt->err);
   14356 	}
   14357     }
   14358     return(0);
   14359 }
   14360 
   14361 
   14362 static int
   14363 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
   14364 				  xmlSchemaBasicItemPtr item,
   14365 				  xmlSchemaWildcardPtr *completeWild,
   14366 				  xmlSchemaItemListPtr list,
   14367 				  xmlSchemaItemListPtr prohibs);
   14368 /**
   14369  * xmlSchemaFixupTypeAttributeUses:
   14370  * @ctxt:  the schema parser context
   14371  * @type:  the complex type definition
   14372  *
   14373  *
   14374  * Builds the wildcard and the attribute uses on the given complex type.
   14375  * Returns -1 if an internal error occurs, 0 otherwise.
   14376  *
   14377  * ATTENTION TODO: Experimantally this uses pointer comparisons for
   14378  * strings, so recheck this if we start to hardcode some schemata, since
   14379  * they might not be in the same dict.
   14380  * NOTE: It is allowed to "extend" the xs:anyType type.
   14381  */
   14382 static int
   14383 xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
   14384 				  xmlSchemaTypePtr type)
   14385 {
   14386     xmlSchemaTypePtr baseType = NULL;
   14387     xmlSchemaAttributeUsePtr use;
   14388     xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
   14389 
   14390     if (type->baseType == NULL) {
   14391 	PERROR_INT("xmlSchemaFixupTypeAttributeUses",
   14392 	    "no base type");
   14393         return (-1);
   14394     }
   14395     baseType = type->baseType;
   14396     if (WXS_IS_TYPE_NOT_FIXED(baseType))
   14397 	if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
   14398 	    return(-1);
   14399 
   14400     uses = type->attrUses;
   14401     baseUses = baseType->attrUses;
   14402     /*
   14403     * Expand attribute group references. And build the 'complete'
   14404     * wildcard, i.e. intersect multiple wildcards.
   14405     * Move attribute prohibitions into a separate list.
   14406     */
   14407     if (uses != NULL) {
   14408 	if (WXS_IS_RESTRICTION(type)) {
   14409 	    /*
   14410 	    * This one will transfer all attr. prohibitions
   14411 	    * into pctxt->attrProhibs.
   14412 	    */
   14413 	    if (xmlSchemaExpandAttributeGroupRefs(pctxt,
   14414 		WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
   14415 		pctxt->attrProhibs) == -1)
   14416 	    {
   14417 		PERROR_INT("xmlSchemaFixupTypeAttributeUses",
   14418 		"failed to expand attributes");
   14419 	    }
   14420 	    if (pctxt->attrProhibs->nbItems != 0)
   14421 		prohibs = pctxt->attrProhibs;
   14422 	} else {
   14423 	    if (xmlSchemaExpandAttributeGroupRefs(pctxt,
   14424 		WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
   14425 		NULL) == -1)
   14426 	    {
   14427 		PERROR_INT("xmlSchemaFixupTypeAttributeUses",
   14428 		"failed to expand attributes");
   14429 	    }
   14430 	}
   14431     }
   14432     /*
   14433     * Inherit the attribute uses of the base type.
   14434     */
   14435     if (baseUses != NULL) {
   14436 	int i, j;
   14437 	xmlSchemaAttributeUseProhibPtr pro;
   14438 
   14439 	if (WXS_IS_RESTRICTION(type)) {
   14440 	    int usesCount;
   14441 	    xmlSchemaAttributeUsePtr tmp;
   14442 
   14443 	    if (uses != NULL)
   14444 		usesCount = uses->nbItems;
   14445 	    else
   14446 		usesCount = 0;
   14447 
   14448 	    /* Restriction. */
   14449 	    for (i = 0; i < baseUses->nbItems; i++) {
   14450 		use = baseUses->items[i];
   14451 		if (prohibs) {
   14452 		    /*
   14453 		    * Filter out prohibited uses.
   14454 		    */
   14455 		    for (j = 0; j < prohibs->nbItems; j++) {
   14456 			pro = prohibs->items[j];
   14457 			if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
   14458 			    (WXS_ATTRUSE_DECL_TNS(use) ==
   14459 				pro->targetNamespace))
   14460 			{
   14461 			    goto inherit_next;
   14462 			}
   14463 		    }
   14464 		}
   14465 		if (usesCount) {
   14466 		    /*
   14467 		    * Filter out existing uses.
   14468 		    */
   14469 		    for (j = 0; j < usesCount; j++) {
   14470 			tmp = uses->items[j];
   14471 			if ((WXS_ATTRUSE_DECL_NAME(use) ==
   14472 				WXS_ATTRUSE_DECL_NAME(tmp)) &&
   14473 			    (WXS_ATTRUSE_DECL_TNS(use) ==
   14474 				WXS_ATTRUSE_DECL_TNS(tmp)))
   14475 			{
   14476 			    goto inherit_next;
   14477 			}
   14478 		    }
   14479 		}
   14480 		if (uses == NULL) {
   14481 		    type->attrUses = xmlSchemaItemListCreate();
   14482 		    if (type->attrUses == NULL)
   14483 			goto exit_failure;
   14484 		    uses = type->attrUses;
   14485 		}
   14486 		xmlSchemaItemListAddSize(uses, 2, use);
   14487 inherit_next: {}
   14488 	    }
   14489 	} else {
   14490 	    /* Extension. */
   14491 	    for (i = 0; i < baseUses->nbItems; i++) {
   14492 		use = baseUses->items[i];
   14493 		if (uses == NULL) {
   14494 		    type->attrUses = xmlSchemaItemListCreate();
   14495 		    if (type->attrUses == NULL)
   14496 			goto exit_failure;
   14497 		    uses = type->attrUses;
   14498 		}
   14499 		xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
   14500 	    }
   14501 	}
   14502     }
   14503     /*
   14504     * Shrink attr. uses.
   14505     */
   14506     if (uses) {
   14507 	if (uses->nbItems == 0) {
   14508 	    xmlSchemaItemListFree(uses);
   14509 	    type->attrUses = NULL;
   14510 	}
   14511 	/*
   14512 	* TODO: We could shrink the size of the array
   14513 	* to fit the actual number of items.
   14514 	*/
   14515     }
   14516     /*
   14517     * Compute the complete wildcard.
   14518     */
   14519     if (WXS_IS_EXTENSION(type)) {
   14520 	if (baseType->attributeWildcard != NULL) {
   14521 	    /*
   14522 	    * (3.2.2.1) "If the base wildcard is non-absent, then
   14523 	    * the appropriate case among the following:"
   14524 	    */
   14525 	    if (type->attributeWildcard != NULL) {
   14526 		/*
   14527 		* Union the complete wildcard with the base wildcard.
   14528 		* SPEC {attribute wildcard}
   14529 		* (3.2.2.1.2) "otherwise a wildcard whose {process contents}
   14530 		* and {annotation} are those of the complete wildcard,
   14531 		* and whose {namespace constraint} is the intensional union
   14532 		* of the {namespace constraint} of the complete wildcard
   14533 		* and of the base wildcard, as defined in Attribute
   14534 		* Wildcard Union (3.10.6)."
   14535 		*/
   14536 		if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
   14537 		    baseType->attributeWildcard) == -1)
   14538 		    goto exit_failure;
   14539 	    } else {
   14540 		/*
   14541 		* (3.2.2.1.1) "If the complete wildcard is absent,
   14542 		* then the base wildcard."
   14543 		*/
   14544 		type->attributeWildcard = baseType->attributeWildcard;
   14545 	    }
   14546 	} else {
   14547 	    /*
   14548 	    * (3.2.2.2) "otherwise (the base wildcard is absent) the
   14549 	    * complete wildcard"
   14550 	    * NOOP
   14551 	    */
   14552 	}
   14553     } else {
   14554 	/*
   14555 	* SPEC {attribute wildcard}
   14556 	* (3.1) "If the <restriction> alternative is chosen, then the
   14557 	* complete wildcard;"
   14558 	* NOOP
   14559 	*/
   14560     }
   14561 
   14562     return (0);
   14563 
   14564 exit_failure:
   14565     return(-1);
   14566 }
   14567 
   14568 /**
   14569  * xmlSchemaTypeFinalContains:
   14570  * @schema:  the schema
   14571  * @type:  the type definition
   14572  * @final: the final
   14573  *
   14574  * Evaluates if a type definition contains the given "final".
   14575  * This does take "finalDefault" into account as well.
   14576  *
   14577  * Returns 1 if the type does containt the given "final",
   14578  * 0 otherwise.
   14579  */
   14580 static int
   14581 xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
   14582 {
   14583     if (type == NULL)
   14584 	return (0);
   14585     if (type->flags & final)
   14586 	return (1);
   14587     else
   14588 	return (0);
   14589 }
   14590 
   14591 /**
   14592  * xmlSchemaGetUnionSimpleTypeMemberTypes:
   14593  * @type:  the Union Simple Type
   14594  *
   14595  * Returns a list of member types of @type if existing,
   14596  * returns NULL otherwise.
   14597  */
   14598 static xmlSchemaTypeLinkPtr
   14599 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
   14600 {
   14601     while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
   14602 	if (type->memberTypes != NULL)
   14603 	    return (type->memberTypes);
   14604 	else
   14605 	    type = type->baseType;
   14606     }
   14607     return (NULL);
   14608 }
   14609 
   14610 /**
   14611  * xmlSchemaGetParticleTotalRangeMin:
   14612  * @particle: the particle
   14613  *
   14614  * Schema Component Constraint: Effective Total Range
   14615  * (all and sequence) + (choice)
   14616  *
   14617  * Returns the minimun Effective Total Range.
   14618  */
   14619 static int
   14620 xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
   14621 {
   14622     if ((particle->children == NULL) ||
   14623 	(particle->minOccurs == 0))
   14624 	return (0);
   14625     if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
   14626 	int min = -1, cur;
   14627 	xmlSchemaParticlePtr part =
   14628 	    (xmlSchemaParticlePtr) particle->children->children;
   14629 
   14630 	if (part == NULL)
   14631 	    return (0);
   14632 	while (part != NULL) {
   14633 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
   14634 		(part->children->type == XML_SCHEMA_TYPE_ANY))
   14635 		cur = part->minOccurs;
   14636 	    else
   14637 		cur = xmlSchemaGetParticleTotalRangeMin(part);
   14638 	    if (cur == 0)
   14639 		return (0);
   14640 	    if ((min > cur) || (min == -1))
   14641 		min = cur;
   14642 	    part = (xmlSchemaParticlePtr) part->next;
   14643 	}
   14644 	return (particle->minOccurs * min);
   14645     } else {
   14646 	/* <all> and <sequence> */
   14647 	int sum = 0;
   14648 	xmlSchemaParticlePtr part =
   14649 	    (xmlSchemaParticlePtr) particle->children->children;
   14650 
   14651 	if (part == NULL)
   14652 	    return (0);
   14653 	do {
   14654 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
   14655 		(part->children->type == XML_SCHEMA_TYPE_ANY))
   14656 		sum += part->minOccurs;
   14657 	    else
   14658 		sum += xmlSchemaGetParticleTotalRangeMin(part);
   14659 	    part = (xmlSchemaParticlePtr) part->next;
   14660 	} while (part != NULL);
   14661 	return (particle->minOccurs * sum);
   14662     }
   14663 }
   14664 
   14665 #if 0
   14666 /**
   14667  * xmlSchemaGetParticleTotalRangeMax:
   14668  * @particle: the particle
   14669  *
   14670  * Schema Component Constraint: Effective Total Range
   14671  * (all and sequence) + (choice)
   14672  *
   14673  * Returns the maximum Effective Total Range.
   14674  */
   14675 static int
   14676 xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
   14677 {
   14678     if ((particle->children == NULL) ||
   14679 	(particle->children->children == NULL))
   14680 	return (0);
   14681     if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
   14682 	int max = -1, cur;
   14683 	xmlSchemaParticlePtr part =
   14684 	    (xmlSchemaParticlePtr) particle->children->children;
   14685 
   14686 	for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
   14687 	    if (part->children == NULL)
   14688 		continue;
   14689 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
   14690 		(part->children->type == XML_SCHEMA_TYPE_ANY))
   14691 		cur = part->maxOccurs;
   14692 	    else
   14693 		cur = xmlSchemaGetParticleTotalRangeMax(part);
   14694 	    if (cur == UNBOUNDED)
   14695 		return (UNBOUNDED);
   14696 	    if ((max < cur) || (max == -1))
   14697 		max = cur;
   14698 	}
   14699 	/* TODO: Handle overflows? */
   14700 	return (particle->maxOccurs * max);
   14701     } else {
   14702 	/* <all> and <sequence> */
   14703 	int sum = 0, cur;
   14704 	xmlSchemaParticlePtr part =
   14705 	    (xmlSchemaParticlePtr) particle->children->children;
   14706 
   14707 	for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
   14708 	    if (part->children == NULL)
   14709 		continue;
   14710 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
   14711 		(part->children->type == XML_SCHEMA_TYPE_ANY))
   14712 		cur = part->maxOccurs;
   14713 	    else
   14714 		cur = xmlSchemaGetParticleTotalRangeMax(part);
   14715 	    if (cur == UNBOUNDED)
   14716 		return (UNBOUNDED);
   14717 	    if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
   14718 		return (UNBOUNDED);
   14719 	    sum += cur;
   14720 	}
   14721 	/* TODO: Handle overflows? */
   14722 	return (particle->maxOccurs * sum);
   14723     }
   14724 }
   14725 #endif
   14726 
   14727 /**
   14728  * xmlSchemaIsParticleEmptiable:
   14729  * @particle: the particle
   14730  *
   14731  * Schema Component Constraint: Particle Emptiable
   14732  * Checks whether the given particle is emptiable.
   14733  *
   14734  * Returns 1 if emptiable, 0 otherwise.
   14735  */
   14736 static int
   14737 xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
   14738 {
   14739     /*
   14740     * SPEC (1) "Its {min occurs} is 0."
   14741     */
   14742     if ((particle == NULL) || (particle->minOccurs == 0) ||
   14743 	(particle->children == NULL))
   14744 	return (1);
   14745     /*
   14746     * SPEC (2) "Its {term} is a group and the minimum part of the
   14747     * effective total range of that group, [...] is 0."
   14748     */
   14749     if (WXS_IS_MODEL_GROUP(particle->children)) {
   14750 	if (xmlSchemaGetParticleTotalRangeMin(particle) == 0)
   14751 	    return (1);
   14752     }
   14753     return (0);
   14754 }
   14755 
   14756 /**
   14757  * xmlSchemaCheckCOSSTDerivedOK:
   14758  * @actxt: a context
   14759  * @type:  the derived simple type definition
   14760  * @baseType:  the base type definition
   14761  * @subset: the subset of ('restriction', ect.)
   14762  *
   14763  * Schema Component Constraint:
   14764  * Type Derivation OK (Simple) (cos-st-derived-OK)
   14765  *
   14766  * Checks wheter @type can be validly
   14767  * derived from @baseType.
   14768  *
   14769  * Returns 0 on success, an positive error code otherwise.
   14770  */
   14771 static int
   14772 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
   14773 			     xmlSchemaTypePtr type,
   14774 			     xmlSchemaTypePtr baseType,
   14775 			     int subset)
   14776 {
   14777     /*
   14778     * 1 They are the same type definition.
   14779     * TODO: The identy check might have to be more complex than this.
   14780     */
   14781     if (type == baseType)
   14782 	return (0);
   14783     /*
   14784     * 2.1 restriction is not in the subset, or in the {final}
   14785     * of its own {base type definition};
   14786     *
   14787     * NOTE that this will be used also via "xsi:type".
   14788     *
   14789     * TODO: Revise this, it looks strange. How can the "type"
   14790     * not be fixed or *in* fixing?
   14791     */
   14792     if (WXS_IS_TYPE_NOT_FIXED(type))
   14793 	if (xmlSchemaTypeFixup(type, actxt) == -1)
   14794 	    return(-1);
   14795     if (WXS_IS_TYPE_NOT_FIXED(baseType))
   14796 	if (xmlSchemaTypeFixup(baseType, actxt) == -1)
   14797 	    return(-1);
   14798     if ((subset & SUBSET_RESTRICTION) ||
   14799 	(xmlSchemaTypeFinalContains(type->baseType,
   14800 	    XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
   14801 	return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
   14802     }
   14803     /* 2.2 */
   14804     if (type->baseType == baseType) {
   14805 	/*
   14806 	* 2.2.1 D's base type definition is B.
   14807 	*/
   14808 	return (0);
   14809     }
   14810     /*
   14811     * 2.2.2 D's base type definition is not the ur-type definition
   14812     * and is validly derived from B given the subset, as defined by this
   14813     * constraint.
   14814     */
   14815     if ((! WXS_IS_ANYTYPE(type->baseType)) &&
   14816 	(xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
   14817 	    baseType, subset) == 0)) {
   14818 	return (0);
   14819     }
   14820     /*
   14821     * 2.2.3 D's {variety} is list or union and B is the simple ur-type
   14822     * definition.
   14823     */
   14824     if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
   14825 	(WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
   14826 	return (0);
   14827     }
   14828     /*
   14829     * 2.2.4 B's {variety} is union and D is validly derived from a type
   14830     * definition in B's {member type definitions} given the subset, as
   14831     * defined by this constraint.
   14832     *
   14833     * NOTE: This seems not to involve built-in types, since there is no
   14834     * built-in Union Simple Type.
   14835     */
   14836     if (WXS_IS_UNION(baseType)) {
   14837 	xmlSchemaTypeLinkPtr cur;
   14838 
   14839 	cur = baseType->memberTypes;
   14840 	while (cur != NULL) {
   14841 	    if (WXS_IS_TYPE_NOT_FIXED(cur->type))
   14842 		if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
   14843 		    return(-1);
   14844 	    if (xmlSchemaCheckCOSSTDerivedOK(actxt,
   14845 		    type, cur->type, subset) == 0)
   14846 	    {
   14847 		/*
   14848 		* It just has to be validly derived from at least one
   14849 		* member-type.
   14850 		*/
   14851 		return (0);
   14852 	    }
   14853 	    cur = cur->next;
   14854 	}
   14855     }
   14856     return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
   14857 }
   14858 
   14859 /**
   14860  * xmlSchemaCheckTypeDefCircularInternal:
   14861  * @pctxt:  the schema parser context
   14862  * @ctxtType:  the type definition
   14863  * @ancestor: an ancestor of @ctxtType
   14864  *
   14865  * Checks st-props-correct (2) + ct-props-correct (3).
   14866  * Circular type definitions are not allowed.
   14867  *
   14868  * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
   14869  * circular, 0 otherwise.
   14870  */
   14871 static int
   14872 xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
   14873 			   xmlSchemaTypePtr ctxtType,
   14874 			   xmlSchemaTypePtr ancestor)
   14875 {
   14876     int ret;
   14877 
   14878     if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
   14879 	return (0);
   14880 
   14881     if (ctxtType == ancestor) {
   14882 	xmlSchemaPCustomErr(pctxt,
   14883 	    XML_SCHEMAP_ST_PROPS_CORRECT_2,
   14884 	    WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
   14885 	    "The definition is circular", NULL);
   14886 	return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
   14887     }
   14888     if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
   14889 	/*
   14890 	* Avoid inifinite recursion on circular types not yet checked.
   14891 	*/
   14892 	return (0);
   14893     }
   14894     ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
   14895     ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
   14896 	ancestor->baseType);
   14897     ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
   14898     return (ret);
   14899 }
   14900 
   14901 /**
   14902  * xmlSchemaCheckTypeDefCircular:
   14903  * @item:  the complex/simple type definition
   14904  * @ctxt:  the parser context
   14905  * @name:  the name
   14906  *
   14907  * Checks for circular type definitions.
   14908  */
   14909 static void
   14910 xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
   14911 			      xmlSchemaParserCtxtPtr ctxt)
   14912 {
   14913     if ((item == NULL) ||
   14914 	(item->type == XML_SCHEMA_TYPE_BASIC) ||
   14915 	(item->baseType == NULL))
   14916 	return;
   14917     xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
   14918 	item->baseType);
   14919 }
   14920 
   14921 /*
   14922 * Simple Type Definition Representation OK (src-simple-type) 4
   14923 *
   14924 * "4 Circular union type definition is disallowed. That is, if the
   14925 * <union> alternative is chosen, there must not be any entries in the
   14926 * memberTypes [attribute] at any depth which resolve to the component
   14927 * corresponding to the <simpleType>."
   14928 *
   14929 * Note that this should work on the *representation* of a component,
   14930 * thus assumes any union types in the member types not being yet
   14931 * substituted. At this stage we need the variety of the types
   14932 * to be already computed.
   14933 */
   14934 static int
   14935 xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
   14936 					xmlSchemaTypePtr ctxType,
   14937 					xmlSchemaTypeLinkPtr members)
   14938 {
   14939     xmlSchemaTypeLinkPtr member;
   14940     xmlSchemaTypePtr memberType;
   14941 
   14942     member = members;
   14943     while (member != NULL) {
   14944 	memberType = member->type;
   14945 	while ((memberType != NULL) &&
   14946 	    (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
   14947 	    if (memberType == ctxType) {
   14948 		xmlSchemaPCustomErr(pctxt,
   14949 		    XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
   14950 		    WXS_BASIC_CAST ctxType, NULL,
   14951 		    "The union type definition is circular", NULL);
   14952 		return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
   14953 	    }
   14954 	    if ((WXS_IS_UNION(memberType)) &&
   14955 		((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
   14956 	    {
   14957 		int res;
   14958 		memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
   14959 		res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
   14960 		    ctxType,
   14961 		    xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
   14962 		memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
   14963 		if (res != 0)
   14964 		    return(res);
   14965 	    }
   14966 	    memberType = memberType->baseType;
   14967 	}
   14968 	member = member->next;
   14969     }
   14970     return(0);
   14971 }
   14972 
   14973 static int
   14974 xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
   14975 				   xmlSchemaTypePtr type)
   14976 {
   14977     if (! WXS_IS_UNION(type))
   14978 	return(0);
   14979     return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
   14980 	type->memberTypes));
   14981 }
   14982 
   14983 /**
   14984  * xmlSchemaResolveTypeReferences:
   14985  * @item:  the complex/simple type definition
   14986  * @ctxt:  the parser context
   14987  * @name:  the name
   14988  *
   14989  * Resolvese type definition references
   14990  */
   14991 static void
   14992 xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
   14993 			 xmlSchemaParserCtxtPtr ctxt)
   14994 {
   14995     if (typeDef == NULL)
   14996 	return;
   14997 
   14998     /*
   14999     * Resolve the base type.
   15000     */
   15001     if (typeDef->baseType == NULL) {
   15002 	typeDef->baseType = xmlSchemaGetType(ctxt->schema,
   15003 	    typeDef->base, typeDef->baseNs);
   15004 	if (typeDef->baseType == NULL) {
   15005 	    xmlSchemaPResCompAttrErr(ctxt,
   15006 		XML_SCHEMAP_SRC_RESOLVE,
   15007 		WXS_BASIC_CAST typeDef, typeDef->node,
   15008 		"base", typeDef->base, typeDef->baseNs,
   15009 		XML_SCHEMA_TYPE_SIMPLE, NULL);
   15010 	    return;
   15011 	}
   15012     }
   15013     if (WXS_IS_SIMPLE(typeDef)) {
   15014 	if (WXS_IS_UNION(typeDef)) {
   15015 	    /*
   15016 	    * Resolve the memberTypes.
   15017 	    */
   15018 	    xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
   15019 	    return;
   15020 	} else if (WXS_IS_LIST(typeDef)) {
   15021 	    /*
   15022 	    * Resolve the itemType.
   15023 	    */
   15024 	    if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
   15025 
   15026 		typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
   15027 		    typeDef->base, typeDef->baseNs);
   15028 
   15029 		if ((typeDef->subtypes == NULL) ||
   15030 		    (! WXS_IS_SIMPLE(typeDef->subtypes)))
   15031 		{
   15032 		    typeDef->subtypes = NULL;
   15033 		    xmlSchemaPResCompAttrErr(ctxt,
   15034 			XML_SCHEMAP_SRC_RESOLVE,
   15035 			WXS_BASIC_CAST typeDef, typeDef->node,
   15036 			"itemType", typeDef->base, typeDef->baseNs,
   15037 			XML_SCHEMA_TYPE_SIMPLE, NULL);
   15038 		}
   15039 	    }
   15040 	    return;
   15041 	}
   15042     }
   15043     /*
   15044     * The ball of letters below means, that if we have a particle
   15045     * which has a QName-helper component as its {term}, we want
   15046     * to resolve it...
   15047     */
   15048     else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
   15049 	((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
   15050 	    XML_SCHEMA_TYPE_PARTICLE) &&
   15051 	(WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
   15052 	((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
   15053 	    XML_SCHEMA_EXTRA_QNAMEREF))
   15054     {
   15055 	xmlSchemaQNameRefPtr ref =
   15056 	    WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
   15057 	xmlSchemaModelGroupDefPtr groupDef;
   15058 
   15059 	/*
   15060 	* URGENT TODO: Test this.
   15061 	*/
   15062 	WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
   15063 	/*
   15064 	* Resolve the MG definition reference.
   15065 	*/
   15066 	groupDef =
   15067 	    WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
   15068 		ref->itemType, ref->name, ref->targetNamespace);
   15069 	if (groupDef == NULL) {
   15070 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
   15071 		NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
   15072 		"ref", ref->name, ref->targetNamespace, ref->itemType,
   15073 		NULL);
   15074 	    /* Remove the particle. */
   15075 	    WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
   15076 	} else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
   15077 	    /* Remove the particle. */
   15078 	    WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
   15079 	else {
   15080 	    /*
   15081 	    * Assign the MG definition's {model group} to the
   15082 	    * particle's {term}.
   15083 	    */
   15084 	    WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
   15085 
   15086 	    if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
   15087 		/*
   15088 		* SPEC cos-all-limited (1.2)
   15089 		* "1.2 the {term} property of a particle with
   15090 		* {max occurs}=1 which is part of a pair which constitutes
   15091 		* the {content type} of a complex type definition."
   15092 		*/
   15093 		if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
   15094 		    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   15095 			/* TODO: error code */
   15096 			XML_SCHEMAP_COS_ALL_LIMITED,
   15097 			WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
   15098 			"The particle's {max occurs} must be 1, since the "
   15099 			"reference resolves to an 'all' model group",
   15100 			NULL, NULL);
   15101 		}
   15102 	    }
   15103 	}
   15104     }
   15105 }
   15106 
   15107 
   15108 
   15109 /**
   15110  * xmlSchemaCheckSTPropsCorrect:
   15111  * @ctxt:  the schema parser context
   15112  * @type:  the simple type definition
   15113  *
   15114  * Checks st-props-correct.
   15115  *
   15116  * Returns 0 if the properties are correct,
   15117  * if not, a positive error code and -1 on internal
   15118  * errors.
   15119  */
   15120 static int
   15121 xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
   15122 			     xmlSchemaTypePtr type)
   15123 {
   15124     xmlSchemaTypePtr baseType = type->baseType;
   15125     xmlChar *str = NULL;
   15126 
   15127     /* STATE: error funcs converted. */
   15128     /*
   15129     * Schema Component Constraint: Simple Type Definition Properties Correct
   15130     *
   15131     * NOTE: This is somehow redundant, since we actually built a simple type
   15132     * to have all the needed information; this acts as an self test.
   15133     */
   15134     /* Base type: If the datatype has been derived by restriction
   15135     * then the Simple Type Definition component from which it is derived,
   15136     * otherwise the Simple Type Definition for anySimpleType (4.1.6).
   15137     */
   15138     if (baseType == NULL) {
   15139 	/*
   15140 	* TODO: Think about: "modulo the impact of Missing
   15141 	* Sub-components (5.3)."
   15142 	*/
   15143 	xmlSchemaPCustomErr(ctxt,
   15144 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
   15145 	    WXS_BASIC_CAST type, NULL,
   15146 	    "No base type existent", NULL);
   15147 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
   15148 
   15149     }
   15150     if (! WXS_IS_SIMPLE(baseType)) {
   15151 	xmlSchemaPCustomErr(ctxt,
   15152 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
   15153 	    WXS_BASIC_CAST type, NULL,
   15154 	    "The base type '%s' is not a simple type",
   15155 	    xmlSchemaGetComponentQName(&str, baseType));
   15156 	FREE_AND_NULL(str)
   15157 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
   15158     }
   15159     if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
   15160 	(WXS_IS_RESTRICTION(type) == 0) &&
   15161 	((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
   15162          (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
   15163 	xmlSchemaPCustomErr(ctxt,
   15164 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
   15165 	    WXS_BASIC_CAST type, NULL,
   15166 	    "A type, derived by list or union, must have "
   15167 	    "the simple ur-type definition as base type, not '%s'",
   15168 	    xmlSchemaGetComponentQName(&str, baseType));
   15169 	FREE_AND_NULL(str)
   15170 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
   15171     }
   15172     /*
   15173     * Variety: One of {atomic, list, union}.
   15174     */
   15175     if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
   15176 	(! WXS_IS_LIST(type))) {
   15177 	xmlSchemaPCustomErr(ctxt,
   15178 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
   15179 	    WXS_BASIC_CAST type, NULL,
   15180 	    "The variety is absent", NULL);
   15181 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
   15182     }
   15183     /* TODO: Finish this. Hmm, is this finished? */
   15184 
   15185     /*
   15186     * 3 The {final} of the {base type definition} must not contain restriction.
   15187     */
   15188     if (xmlSchemaTypeFinalContains(baseType,
   15189 	XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
   15190 	xmlSchemaPCustomErr(ctxt,
   15191 	    XML_SCHEMAP_ST_PROPS_CORRECT_3,
   15192 	    WXS_BASIC_CAST type, NULL,
   15193 	    "The 'final' of its base type '%s' must not contain "
   15194 	    "'restriction'",
   15195 	    xmlSchemaGetComponentQName(&str, baseType));
   15196 	FREE_AND_NULL(str)
   15197 	return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
   15198     }
   15199 
   15200     /*
   15201     * 2 All simple type definitions must be derived ultimately from the simple
   15202     * ur-type definition (so circular definitions are disallowed). That is, it
   15203     * must be possible to reach a built-in primitive datatype or the simple
   15204     * ur-type definition by repeatedly following the {base type definition}.
   15205     *
   15206     * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
   15207     */
   15208     return (0);
   15209 }
   15210 
   15211 /**
   15212  * xmlSchemaCheckCOSSTRestricts:
   15213  * @ctxt:  the schema parser context
   15214  * @type:  the simple type definition
   15215  *
   15216  * Schema Component Constraint:
   15217  * Derivation Valid (Restriction, Simple) (cos-st-restricts)
   15218 
   15219  * Checks if the given @type (simpleType) is derived validly by restriction.
   15220  * STATUS:
   15221  *
   15222  * Returns -1 on internal errors, 0 if the type is validly derived,
   15223  * a positive error code otherwise.
   15224  */
   15225 static int
   15226 xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
   15227 			     xmlSchemaTypePtr type)
   15228 {
   15229     xmlChar *str = NULL;
   15230 
   15231     if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
   15232 	PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15233 	    "given type is not a user-derived simpleType");
   15234 	return (-1);
   15235     }
   15236 
   15237     if (WXS_IS_ATOMIC(type)) {
   15238 	xmlSchemaTypePtr primitive;
   15239 	/*
   15240 	* 1.1 The {base type definition} must be an atomic simple
   15241 	* type definition or a built-in primitive datatype.
   15242 	*/
   15243 	if (! WXS_IS_ATOMIC(type->baseType)) {
   15244 	    xmlSchemaPCustomErr(pctxt,
   15245 		XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
   15246 		WXS_BASIC_CAST type, NULL,
   15247 		"The base type '%s' is not an atomic simple type",
   15248 		xmlSchemaGetComponentQName(&str, type->baseType));
   15249 	    FREE_AND_NULL(str)
   15250 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
   15251 	}
   15252 	/* 1.2 The {final} of the {base type definition} must not contain
   15253 	* restriction.
   15254 	*/
   15255 	/* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
   15256 	if (xmlSchemaTypeFinalContains(type->baseType,
   15257 	    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
   15258 	    xmlSchemaPCustomErr(pctxt,
   15259 		XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
   15260 		WXS_BASIC_CAST type, NULL,
   15261 		"The final of its base type '%s' must not contain 'restriction'",
   15262 		xmlSchemaGetComponentQName(&str, type->baseType));
   15263 	    FREE_AND_NULL(str)
   15264 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
   15265 	}
   15266 
   15267 	/*
   15268 	* 1.3.1 DF must be an allowed constraining facet for the {primitive
   15269 	* type definition}, as specified in the appropriate subsection of 3.2
   15270 	* Primitive datatypes.
   15271 	*/
   15272 	if (type->facets != NULL) {
   15273 	    xmlSchemaFacetPtr facet;
   15274 	    int ok = 1;
   15275 
   15276 	    primitive = xmlSchemaGetPrimitiveType(type);
   15277 	    if (primitive == NULL) {
   15278 		PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15279 		    "failed to get primitive type");
   15280 		return (-1);
   15281 	    }
   15282 	    facet = type->facets;
   15283 	    do {
   15284 		if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
   15285 		    ok = 0;
   15286 		    xmlSchemaPIllegalFacetAtomicErr(pctxt,
   15287 			XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
   15288 			type, primitive, facet);
   15289 		}
   15290 		facet = facet->next;
   15291 	    } while (facet != NULL);
   15292 	    if (ok == 0)
   15293 		return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
   15294 	}
   15295 	/*
   15296 	* SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
   15297 	* of the {base type definition} (call this BF),then the DF's {value}
   15298 	* must be a valid restriction of BF's {value} as defined in
   15299 	* [XML Schemas: Datatypes]."
   15300 	*
   15301 	* NOTE (1.3.2) Facet derivation constraints are currently handled in
   15302 	* xmlSchemaDeriveAndValidateFacets()
   15303 	*/
   15304     } else if (WXS_IS_LIST(type)) {
   15305 	xmlSchemaTypePtr itemType = NULL;
   15306 
   15307 	itemType = type->subtypes;
   15308 	if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
   15309 	    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15310 		"failed to evaluate the item type");
   15311 	    return (-1);
   15312 	}
   15313 	if (WXS_IS_TYPE_NOT_FIXED(itemType))
   15314 	    xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
   15315 	/*
   15316 	* 2.1 The {item type definition} must have a {variety} of atomic or
   15317 	* union (in which case all the {member type definitions}
   15318 	* must be atomic).
   15319 	*/
   15320 	if ((! WXS_IS_ATOMIC(itemType)) &&
   15321 	    (! WXS_IS_UNION(itemType))) {
   15322 	    xmlSchemaPCustomErr(pctxt,
   15323 		XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
   15324 		WXS_BASIC_CAST type, NULL,
   15325 		"The item type '%s' does not have a variety of atomic or union",
   15326 		xmlSchemaGetComponentQName(&str, itemType));
   15327 	    FREE_AND_NULL(str)
   15328 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
   15329 	} else if (WXS_IS_UNION(itemType)) {
   15330 	    xmlSchemaTypeLinkPtr member;
   15331 
   15332 	    member = itemType->memberTypes;
   15333 	    while (member != NULL) {
   15334 		if (! WXS_IS_ATOMIC(member->type)) {
   15335 		    xmlSchemaPCustomErr(pctxt,
   15336 			XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
   15337 			WXS_BASIC_CAST type, NULL,
   15338 			"The item type is a union type, but the "
   15339 			"member type '%s' of this item type is not atomic",
   15340 			xmlSchemaGetComponentQName(&str, member->type));
   15341 		    FREE_AND_NULL(str)
   15342 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
   15343 		}
   15344 		member = member->next;
   15345 	    }
   15346 	}
   15347 
   15348 	if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
   15349 	    xmlSchemaFacetPtr facet;
   15350 	    /*
   15351 	    * This is the case if we have: <simpleType><list ..
   15352 	    */
   15353 	    /*
   15354 	    * 2.3.1
   15355 	    * 2.3.1.1 The {final} of the {item type definition} must not
   15356 	    * contain list.
   15357 	    */
   15358 	    if (xmlSchemaTypeFinalContains(itemType,
   15359 		XML_SCHEMAS_TYPE_FINAL_LIST)) {
   15360 		xmlSchemaPCustomErr(pctxt,
   15361 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
   15362 		    WXS_BASIC_CAST type, NULL,
   15363 		    "The final of its item type '%s' must not contain 'list'",
   15364 		    xmlSchemaGetComponentQName(&str, itemType));
   15365 		FREE_AND_NULL(str)
   15366 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
   15367 	    }
   15368 	    /*
   15369 	    * 2.3.1.2 The {facets} must only contain the whiteSpace
   15370 	    * facet component.
   15371 	    * OPTIMIZE TODO: the S4S already disallows any facet
   15372 	    * to be specified.
   15373 	    */
   15374 	    if (type->facets != NULL) {
   15375 		facet = type->facets;
   15376 		do {
   15377 		    if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
   15378 			xmlSchemaPIllegalFacetListUnionErr(pctxt,
   15379 			    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
   15380 			    type, facet);
   15381 			return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
   15382 		    }
   15383 		    facet = facet->next;
   15384 		} while (facet != NULL);
   15385 	    }
   15386 	    /*
   15387 	    * MAYBE TODO: (Hmm, not really) Datatypes states:
   15388 	    * A list datatype can be derived from an atomic datatype
   15389 	    * whose lexical space allows space (such as string or anyURI)or
   15390 	    * a union datatype any of whose {member type definitions}'s
   15391 	    * lexical space allows space.
   15392 	    */
   15393 	} else {
   15394 	    /*
   15395 	    * This is the case if we have: <simpleType><restriction ...
   15396 	    * I.e. the variety of "list" is inherited.
   15397 	    */
   15398 	    /*
   15399 	    * 2.3.2
   15400 	    * 2.3.2.1 The {base type definition} must have a {variety} of list.
   15401 	    */
   15402 	    if (! WXS_IS_LIST(type->baseType)) {
   15403 		xmlSchemaPCustomErr(pctxt,
   15404 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
   15405 		    WXS_BASIC_CAST type, NULL,
   15406 		    "The base type '%s' must be a list type",
   15407 		    xmlSchemaGetComponentQName(&str, type->baseType));
   15408 		FREE_AND_NULL(str)
   15409 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
   15410 	    }
   15411 	    /*
   15412 	    * 2.3.2.2 The {final} of the {base type definition} must not
   15413 	    * contain restriction.
   15414 	    */
   15415 	    if (xmlSchemaTypeFinalContains(type->baseType,
   15416 		XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
   15417 		xmlSchemaPCustomErr(pctxt,
   15418 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
   15419 		    WXS_BASIC_CAST type, NULL,
   15420 		    "The 'final' of the base type '%s' must not contain 'restriction'",
   15421 		    xmlSchemaGetComponentQName(&str, type->baseType));
   15422 		FREE_AND_NULL(str)
   15423 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
   15424 	    }
   15425 	    /*
   15426 	    * 2.3.2.3 The {item type definition} must be validly derived
   15427 	    * from the {base type definition}'s {item type definition} given
   15428 	    * the empty set, as defined in Type Derivation OK (Simple) (3.14.6).
   15429 	    */
   15430 	    {
   15431 		xmlSchemaTypePtr baseItemType;
   15432 
   15433 		baseItemType = type->baseType->subtypes;
   15434 		if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
   15435 		    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15436 			"failed to eval the item type of a base type");
   15437 		    return (-1);
   15438 		}
   15439 		if ((itemType != baseItemType) &&
   15440 		    (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
   15441 			baseItemType, 0) != 0)) {
   15442 		    xmlChar *strBIT = NULL, *strBT = NULL;
   15443 		    xmlSchemaPCustomErrExt(pctxt,
   15444 			XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
   15445 			WXS_BASIC_CAST type, NULL,
   15446 			"The item type '%s' is not validly derived from "
   15447 			"the item type '%s' of the base type '%s'",
   15448 			xmlSchemaGetComponentQName(&str, itemType),
   15449 			xmlSchemaGetComponentQName(&strBIT, baseItemType),
   15450 			xmlSchemaGetComponentQName(&strBT, type->baseType));
   15451 
   15452 		    FREE_AND_NULL(str)
   15453 		    FREE_AND_NULL(strBIT)
   15454 		    FREE_AND_NULL(strBT)
   15455 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
   15456 		}
   15457 	    }
   15458 
   15459 	    if (type->facets != NULL) {
   15460 		xmlSchemaFacetPtr facet;
   15461 		int ok = 1;
   15462 		/*
   15463 		* 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
   15464 		* and enumeration facet components are allowed among the {facets}.
   15465 		*/
   15466 		facet = type->facets;
   15467 		do {
   15468 		    switch (facet->type) {
   15469 			case XML_SCHEMA_FACET_LENGTH:
   15470 			case XML_SCHEMA_FACET_MINLENGTH:
   15471 			case XML_SCHEMA_FACET_MAXLENGTH:
   15472 			case XML_SCHEMA_FACET_WHITESPACE:
   15473 			    /*
   15474 			    * TODO: 2.5.1.2 List datatypes
   15475 			    * The value of whiteSpace is fixed to the value collapse.
   15476 			    */
   15477 			case XML_SCHEMA_FACET_PATTERN:
   15478 			case XML_SCHEMA_FACET_ENUMERATION:
   15479 			    break;
   15480 			default: {
   15481 			    xmlSchemaPIllegalFacetListUnionErr(pctxt,
   15482 				XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
   15483 				type, facet);
   15484 			    /*
   15485 			    * We could return, but it's nicer to report all
   15486 			    * invalid facets.
   15487 			    */
   15488 			    ok = 0;
   15489 			}
   15490 		    }
   15491 		    facet = facet->next;
   15492 		} while (facet != NULL);
   15493 		if (ok == 0)
   15494 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
   15495 		/*
   15496 		* SPEC (2.3.2.5) (same as 1.3.2)
   15497 		*
   15498 		* NOTE (2.3.2.5) This is currently done in
   15499 		* xmlSchemaDeriveAndValidateFacets()
   15500 		*/
   15501 	    }
   15502 	}
   15503     } else if (WXS_IS_UNION(type)) {
   15504 	/*
   15505 	* 3.1 The {member type definitions} must all have {variety} of
   15506 	* atomic or list.
   15507 	*/
   15508 	xmlSchemaTypeLinkPtr member;
   15509 
   15510 	member = type->memberTypes;
   15511 	while (member != NULL) {
   15512 	    if (WXS_IS_TYPE_NOT_FIXED(member->type))
   15513 		xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
   15514 
   15515 	    if ((! WXS_IS_ATOMIC(member->type)) &&
   15516 		(! WXS_IS_LIST(member->type))) {
   15517 		xmlSchemaPCustomErr(pctxt,
   15518 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
   15519 		    WXS_BASIC_CAST type, NULL,
   15520 		    "The member type '%s' is neither an atomic, nor a list type",
   15521 		    xmlSchemaGetComponentQName(&str, member->type));
   15522 		FREE_AND_NULL(str)
   15523 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
   15524 	    }
   15525 	    member = member->next;
   15526 	}
   15527 	/*
   15528 	* 3.3.1 If the {base type definition} is the simple ur-type
   15529 	* definition
   15530 	*/
   15531 	if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
   15532 	    /*
   15533 	    * 3.3.1.1 All of the {member type definitions} must have a
   15534 	    * {final} which does not contain union.
   15535 	    */
   15536 	    member = type->memberTypes;
   15537 	    while (member != NULL) {
   15538 		if (xmlSchemaTypeFinalContains(member->type,
   15539 		    XML_SCHEMAS_TYPE_FINAL_UNION)) {
   15540 		    xmlSchemaPCustomErr(pctxt,
   15541 			XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
   15542 			WXS_BASIC_CAST type, NULL,
   15543 			"The 'final' of member type '%s' contains 'union'",
   15544 			xmlSchemaGetComponentQName(&str, member->type));
   15545 		    FREE_AND_NULL(str)
   15546 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
   15547 		}
   15548 		member = member->next;
   15549 	    }
   15550 	    /*
   15551 	    * 3.3.1.2 The {facets} must be empty.
   15552 	    */
   15553 	    if (type->facetSet != NULL) {
   15554 		xmlSchemaPCustomErr(pctxt,
   15555 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
   15556 		    WXS_BASIC_CAST type, NULL,
   15557 		    "No facets allowed", NULL);
   15558 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
   15559 	    }
   15560 	} else {
   15561 	    /*
   15562 	    * 3.3.2.1 The {base type definition} must have a {variety} of union.
   15563 	    * I.e. the variety of "list" is inherited.
   15564 	    */
   15565 	    if (! WXS_IS_UNION(type->baseType)) {
   15566 		xmlSchemaPCustomErr(pctxt,
   15567 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
   15568 		    WXS_BASIC_CAST type, NULL,
   15569 		    "The base type '%s' is not a union type",
   15570 		    xmlSchemaGetComponentQName(&str, type->baseType));
   15571 		FREE_AND_NULL(str)
   15572 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
   15573 	    }
   15574 	    /*
   15575 	    * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
   15576 	    */
   15577 	    if (xmlSchemaTypeFinalContains(type->baseType,
   15578 		XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
   15579 		xmlSchemaPCustomErr(pctxt,
   15580 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
   15581 		    WXS_BASIC_CAST type, NULL,
   15582 		    "The 'final' of its base type '%s' must not contain 'restriction'",
   15583 		    xmlSchemaGetComponentQName(&str, type->baseType));
   15584 		FREE_AND_NULL(str)
   15585 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
   15586 	    }
   15587 	    /*
   15588 	    * 3.3.2.3 The {member type definitions}, in order, must be validly
   15589 	    * derived from the corresponding type definitions in the {base
   15590 	    * type definition}'s {member type definitions} given the empty set,
   15591 	    * as defined in Type Derivation OK (Simple) (3.14.6).
   15592 	    */
   15593 	    {
   15594 		xmlSchemaTypeLinkPtr baseMember;
   15595 
   15596 		/*
   15597 		* OPTIMIZE: if the type is restricting, it has no local defined
   15598 		* member types and inherits the member types of the base type;
   15599 		* thus a check for equality can be skipped.
   15600 		*/
   15601 		/*
   15602 		* Even worse: I cannot see a scenario where a restricting
   15603 		* union simple type can have other member types as the member
   15604 		* types of it's base type. This check seems not necessary with
   15605 		* respect to the derivation process in libxml2.
   15606 		* But necessary if constructing types with an API.
   15607 		*/
   15608 		if (type->memberTypes != NULL) {
   15609 		    member = type->memberTypes;
   15610 		    baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
   15611 		    if ((member == NULL) && (baseMember != NULL)) {
   15612 			PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15613 			    "different number of member types in base");
   15614 		    }
   15615 		    while (member != NULL) {
   15616 			if (baseMember == NULL) {
   15617 			    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15618 			    "different number of member types in base");
   15619 			} else if ((member->type != baseMember->type) &&
   15620 			    (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
   15621 				member->type, baseMember->type, 0) != 0)) {
   15622 			    xmlChar *strBMT = NULL, *strBT = NULL;
   15623 
   15624 			    xmlSchemaPCustomErrExt(pctxt,
   15625 				XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
   15626 				WXS_BASIC_CAST type, NULL,
   15627 				"The member type %s is not validly "
   15628 				"derived from its corresponding member "
   15629 				"type %s of the base type %s",
   15630 				xmlSchemaGetComponentQName(&str, member->type),
   15631 				xmlSchemaGetComponentQName(&strBMT, baseMember->type),
   15632 				xmlSchemaGetComponentQName(&strBT, type->baseType));
   15633 			    FREE_AND_NULL(str)
   15634 			    FREE_AND_NULL(strBMT)
   15635 			    FREE_AND_NULL(strBT)
   15636 			    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
   15637 			}
   15638 			member = member->next;
   15639                         if (baseMember != NULL)
   15640                             baseMember = baseMember->next;
   15641 		    }
   15642 		}
   15643 	    }
   15644 	    /*
   15645 	    * 3.3.2.4 Only pattern and enumeration facet components are
   15646 	    * allowed among the {facets}.
   15647 	    */
   15648 	    if (type->facets != NULL) {
   15649 		xmlSchemaFacetPtr facet;
   15650 		int ok = 1;
   15651 
   15652 		facet = type->facets;
   15653 		do {
   15654 		    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
   15655 			(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
   15656 			xmlSchemaPIllegalFacetListUnionErr(pctxt,
   15657 				XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
   15658 				type, facet);
   15659 			ok = 0;
   15660 		    }
   15661 		    facet = facet->next;
   15662 		} while (facet != NULL);
   15663 		if (ok == 0)
   15664 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
   15665 
   15666 	    }
   15667 	    /*
   15668 	    * SPEC (3.3.2.5) (same as 1.3.2)
   15669 	    *
   15670 	    * NOTE (3.3.2.5) This is currently done in
   15671 	    * xmlSchemaDeriveAndValidateFacets()
   15672 	    */
   15673 	}
   15674     }
   15675 
   15676     return (0);
   15677 }
   15678 
   15679 /**
   15680  * xmlSchemaCheckSRCSimpleType:
   15681  * @ctxt:  the schema parser context
   15682  * @type:  the simple type definition
   15683  *
   15684  * Checks crc-simple-type constraints.
   15685  *
   15686  * Returns 0 if the constraints are satisfied,
   15687  * if not a positive error code and -1 on internal
   15688  * errors.
   15689  */
   15690 #if 0
   15691 static int
   15692 xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
   15693 			    xmlSchemaTypePtr type)
   15694 {
   15695     /*
   15696     * src-simple-type.1 The corresponding simple type definition, if any,
   15697     * must satisfy the conditions set out in Constraints on Simple Type
   15698     * Definition Schema Components (3.14.6).
   15699     */
   15700     if (WXS_IS_RESTRICTION(type)) {
   15701 	/*
   15702 	* src-simple-type.2 "If the <restriction> alternative is chosen,
   15703 	* either it must have a base [attribute] or a <simpleType> among its
   15704 	* [children], but not both."
   15705 	* NOTE: This is checked in the parse function of <restriction>.
   15706 	*/
   15707 	/*
   15708 	*
   15709 	*/
   15710     } else if (WXS_IS_LIST(type)) {
   15711 	/* src-simple-type.3 "If the <list> alternative is chosen, either it must have
   15712 	* an itemType [attribute] or a <simpleType> among its [children],
   15713 	* but not both."
   15714 	*
   15715 	* NOTE: This is checked in the parse function of <list>.
   15716 	*/
   15717     } else if (WXS_IS_UNION(type)) {
   15718 	/*
   15719 	* src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
   15720 	*/
   15721     }
   15722     return (0);
   15723 }
   15724 #endif
   15725 
   15726 static int
   15727 xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
   15728 {
   15729    if (ctxt->vctxt == NULL) {
   15730 	ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
   15731 	if (ctxt->vctxt == NULL) {
   15732 	    xmlSchemaPErr(ctxt, NULL,
   15733 		XML_SCHEMAP_INTERNAL,
   15734 		"Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
   15735 		"failed to create a temp. validation context.\n",
   15736 		NULL, NULL);
   15737 	    return (-1);
   15738 	}
   15739 	/* TODO: Pass user data. */
   15740 	xmlSchemaSetValidErrors(ctxt->vctxt,
   15741 	    ctxt->error, ctxt->warning, ctxt->errCtxt);
   15742 	xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
   15743 	    ctxt->serror, ctxt->errCtxt);
   15744     }
   15745     return (0);
   15746 }
   15747 
   15748 static int
   15749 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
   15750 			     xmlNodePtr node,
   15751 			     xmlSchemaTypePtr type,
   15752 			     const xmlChar *value,
   15753 			     xmlSchemaValPtr *retVal,
   15754 			     int fireErrors,
   15755 			     int normalize,
   15756 			     int isNormalized);
   15757 
   15758 /**
   15759  * xmlSchemaParseCheckCOSValidDefault:
   15760  * @pctxt:  the schema parser context
   15761  * @type:  the simple type definition
   15762  * @value: the default value
   15763  * @node: an optional node (the holder of the value)
   15764  *
   15765  * Schema Component Constraint: Element Default Valid (Immediate)
   15766  * (cos-valid-default)
   15767  * This will be used by the parser only. For the validator there's
   15768  * an other version.
   15769  *
   15770  * Returns 0 if the constraints are satisfied,
   15771  * if not, a positive error code and -1 on internal
   15772  * errors.
   15773  */
   15774 static int
   15775 xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
   15776 				   xmlNodePtr node,
   15777 				   xmlSchemaTypePtr type,
   15778 				   const xmlChar *value,
   15779 				   xmlSchemaValPtr *val)
   15780 {
   15781     int ret = 0;
   15782 
   15783     /*
   15784     * cos-valid-default:
   15785     * Schema Component Constraint: Element Default Valid (Immediate)
   15786     * For a string to be a valid default with respect to a type
   15787     * definition the appropriate case among the following must be true:
   15788     */
   15789     if WXS_IS_COMPLEX(type) {
   15790 	/*
   15791 	* Complex type.
   15792 	*
   15793 	* SPEC (2.1) "its {content type} must be a simple type definition
   15794 	* or mixed."
   15795 	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
   15796 	* type}'s particle must be emptiable as defined by
   15797 	* Particle Emptiable (3.9.6)."
   15798 	*/
   15799 	if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
   15800 	    ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
   15801 	    /* NOTE that this covers (2.2.2) as well. */
   15802 	    xmlSchemaPCustomErr(pctxt,
   15803 		XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
   15804 		WXS_BASIC_CAST type, type->node,
   15805 		"For a string to be a valid default, the type definition "
   15806 		"must be a simple type or a complex type with mixed content "
   15807 		"and a particle emptiable", NULL);
   15808 	    return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
   15809 	}
   15810     }
   15811     /*
   15812     * 1 If the type definition is a simple type definition, then the string
   15813     * must be valid with respect to that definition as defined by String
   15814     * Valid (3.14.4).
   15815     *
   15816     * AND
   15817     *
   15818     * 2.2.1 If the {content type} is a simple type definition, then the
   15819     * string must be valid with respect to that simple type definition
   15820     * as defined by String Valid (3.14.4).
   15821     */
   15822     if (WXS_IS_SIMPLE(type))
   15823 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
   15824 	    type, value, val, 1, 1, 0);
   15825     else if (WXS_HAS_SIMPLE_CONTENT(type))
   15826 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
   15827 	    type->contentTypeDef, value, val, 1, 1, 0);
   15828     else
   15829 	return (ret);
   15830 
   15831     if (ret < 0) {
   15832 	PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
   15833 	    "calling xmlSchemaVCheckCVCSimpleType()");
   15834     }
   15835 
   15836     return (ret);
   15837 }
   15838 
   15839 /**
   15840  * xmlSchemaCheckCTPropsCorrect:
   15841  * @ctxt:  the schema parser context
   15842  * @type:  the complex type definition
   15843  *
   15844  *.(4.6) Constraints on Complex Type Definition Schema Components
   15845  * Schema Component Constraint:
   15846  * Complex Type Definition Properties Correct (ct-props-correct)
   15847  * STATUS: (seems) complete
   15848  *
   15849  * Returns 0 if the constraints are satisfied, a positive
   15850  * error code if not and -1 if an internal error occured.
   15851  */
   15852 static int
   15853 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
   15854 			     xmlSchemaTypePtr type)
   15855 {
   15856     /*
   15857     * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
   15858     *
   15859     * SPEC (1) "The values of the properties of a complex type definition must
   15860     * be as described in the property tableau in The Complex Type Definition
   15861     * Schema Component (3.4.1), modulo the impact of Missing
   15862     * Sub-components (5.3)."
   15863     */
   15864     if ((type->baseType != NULL) &&
   15865 	(WXS_IS_SIMPLE(type->baseType)) &&
   15866 	(WXS_IS_EXTENSION(type) == 0)) {
   15867 	/*
   15868 	* SPEC (2) "If the {base type definition} is a simple type definition,
   15869 	* the {derivation method} must be extension."
   15870 	*/
   15871 	xmlSchemaCustomErr(ACTXT_CAST pctxt,
   15872 	    XML_SCHEMAP_SRC_CT_1,
   15873 	    NULL, WXS_BASIC_CAST type,
   15874 	    "If the base type is a simple type, the derivation method must be "
   15875 	    "'extension'", NULL, NULL);
   15876 	return (XML_SCHEMAP_SRC_CT_1);
   15877     }
   15878     /*
   15879     * SPEC (3) "Circular definitions are disallowed, except for the ur-type
   15880     * definition. That is, it must be possible to reach the ur-type
   15881     * definition by repeatedly following the {base type definition}."
   15882     *
   15883     * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
   15884     */
   15885     /*
   15886     * NOTE that (4) and (5) need the following:
   15887     *   - attribute uses need to be already inherited (apply attr. prohibitions)
   15888     *   - attribute group references need to be expanded already
   15889     *   - simple types need to be typefixed already
   15890     */
   15891     if (type->attrUses &&
   15892 	(((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
   15893     {
   15894 	xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
   15895 	xmlSchemaAttributeUsePtr use, tmp;
   15896 	int i, j, hasId = 0;
   15897 
   15898 	for (i = uses->nbItems -1; i >= 0; i--) {
   15899 	    use = uses->items[i];
   15900 
   15901 	    /*
   15902 	    * SPEC ct-props-correct
   15903 	    * (4) "Two distinct attribute declarations in the
   15904 	    * {attribute uses} must not have identical {name}s and
   15905 	    * {target namespace}s."
   15906 	    */
   15907 	    if (i > 0) {
   15908 		for (j = i -1; j >= 0; j--) {
   15909 		    tmp = uses->items[j];
   15910 		    if ((WXS_ATTRUSE_DECL_NAME(use) ==
   15911 			WXS_ATTRUSE_DECL_NAME(tmp)) &&
   15912 			(WXS_ATTRUSE_DECL_TNS(use) ==
   15913 			WXS_ATTRUSE_DECL_TNS(tmp)))
   15914 		    {
   15915 			xmlChar *str = NULL;
   15916 
   15917 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   15918 			    XML_SCHEMAP_AG_PROPS_CORRECT,
   15919 			    NULL, WXS_BASIC_CAST type,
   15920 			    "Duplicate %s",
   15921 			    xmlSchemaGetComponentDesignation(&str, use),
   15922 			    NULL);
   15923 			FREE_AND_NULL(str);
   15924 			/*
   15925 			* Remove the duplicate.
   15926 			*/
   15927 			if (xmlSchemaItemListRemove(uses, i) == -1)
   15928 			    goto exit_failure;
   15929 			goto next_use;
   15930 		    }
   15931 		}
   15932 	    }
   15933 	    /*
   15934 	    * SPEC ct-props-correct
   15935 	    * (5) "Two distinct attribute declarations in the
   15936 	    * {attribute uses} must not have {type definition}s which
   15937 	    * are or are derived from ID."
   15938 	    */
   15939 	    if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
   15940 		if (xmlSchemaIsDerivedFromBuiltInType(
   15941 		    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
   15942 		{
   15943 		    if (hasId) {
   15944 			xmlChar *str = NULL;
   15945 
   15946 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   15947 			    XML_SCHEMAP_AG_PROPS_CORRECT,
   15948 			    NULL, WXS_BASIC_CAST type,
   15949 			    "There must not exist more than one attribute "
   15950 			    "declaration of type 'xs:ID' "
   15951 			    "(or derived from 'xs:ID'). The %s violates this "
   15952 			    "constraint",
   15953 			    xmlSchemaGetComponentDesignation(&str, use),
   15954 			    NULL);
   15955 			FREE_AND_NULL(str);
   15956 			if (xmlSchemaItemListRemove(uses, i) == -1)
   15957 			    goto exit_failure;
   15958 		    }
   15959 
   15960 		    hasId = 1;
   15961 		}
   15962 	    }
   15963 next_use: {}
   15964 	}
   15965     }
   15966     return (0);
   15967 exit_failure:
   15968     return(-1);
   15969 }
   15970 
   15971 static int
   15972 xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
   15973 		       xmlSchemaTypePtr typeB)
   15974 {
   15975     /*
   15976     * TODO: This should implement component-identity
   15977     * in the future.
   15978     */
   15979     if ((typeA == NULL) || (typeB == NULL))
   15980 	return (0);
   15981     return (typeA == typeB);
   15982 }
   15983 
   15984 /**
   15985  * xmlSchemaCheckCOSCTDerivedOK:
   15986  * @ctxt:  the schema parser context
   15987  * @type:  the to-be derived complex type definition
   15988  * @baseType:  the base complex type definition
   15989  * @set: the given set
   15990  *
   15991  * Schema Component Constraint:
   15992  * Type Derivation OK (Complex) (cos-ct-derived-ok)
   15993  *
   15994  * STATUS: completed
   15995  *
   15996  * Returns 0 if the constraints are satisfied, or 1
   15997  * if not.
   15998  */
   15999 static int
   16000 xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
   16001 			     xmlSchemaTypePtr type,
   16002 			     xmlSchemaTypePtr baseType,
   16003 			     int set)
   16004 {
   16005     int equal = xmlSchemaAreEqualTypes(type, baseType);
   16006     /* TODO: Error codes. */
   16007     /*
   16008     * SPEC "For a complex type definition (call it D, for derived)
   16009     * to be validly derived from a type definition (call this
   16010     * B, for base) given a subset of {extension, restriction}
   16011     * all of the following must be true:"
   16012     */
   16013     if (! equal) {
   16014 	/*
   16015 	* SPEC (1) "If B and D are not the same type definition, then the
   16016 	* {derivation method} of D must not be in the subset."
   16017 	*/
   16018 	if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
   16019 	    ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
   16020 	    return (1);
   16021     } else {
   16022 	/*
   16023 	* SPEC (2.1) "B and D must be the same type definition."
   16024 	*/
   16025 	return (0);
   16026     }
   16027     /*
   16028     * SPEC (2.2) "B must be D's {base type definition}."
   16029     */
   16030     if (type->baseType == baseType)
   16031 	return (0);
   16032     /*
   16033     * SPEC (2.3.1) "D's {base type definition} must not be the ur-type
   16034     * definition."
   16035     */
   16036     if (WXS_IS_ANYTYPE(type->baseType))
   16037 	return (1);
   16038 
   16039     if (WXS_IS_COMPLEX(type->baseType)) {
   16040 	/*
   16041 	* SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
   16042 	* must be validly derived from B given the subset as defined by this
   16043 	* constraint."
   16044 	*/
   16045 	return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
   16046 	    baseType, set));
   16047     } else {
   16048 	/*
   16049 	* SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
   16050 	* must be validly derived from B given the subset as defined in Type
   16051 	* Derivation OK (Simple) (3.14.6).
   16052 	*/
   16053 	return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
   16054 	    baseType, set));
   16055     }
   16056 }
   16057 
   16058 /**
   16059  * xmlSchemaCheckCOSDerivedOK:
   16060  * @type:  the derived simple type definition
   16061  * @baseType:  the base type definition
   16062  *
   16063  * Calls:
   16064  * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
   16065  *
   16066  * Checks wheter @type can be validly derived from @baseType.
   16067  *
   16068  * Returns 0 on success, an positive error code otherwise.
   16069  */
   16070 static int
   16071 xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
   16072 			   xmlSchemaTypePtr type,
   16073 			   xmlSchemaTypePtr baseType,
   16074 			   int set)
   16075 {
   16076     if (WXS_IS_SIMPLE(type))
   16077 	return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
   16078     else
   16079 	return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
   16080 }
   16081 
   16082 /**
   16083  * xmlSchemaCheckCOSCTExtends:
   16084  * @ctxt:  the schema parser context
   16085  * @type:  the complex type definition
   16086  *
   16087  * (3.4.6) Constraints on Complex Type Definition Schema Components
   16088  * Schema Component Constraint:
   16089  * Derivation Valid (Extension) (cos-ct-extends)
   16090  *
   16091  * STATUS:
   16092  *   missing:
   16093  *     (1.5)
   16094  *     (1.4.3.2.2.2) "Particle Valid (Extension)"
   16095  *
   16096  * Returns 0 if the constraints are satisfied, a positive
   16097  * error code if not and -1 if an internal error occured.
   16098  */
   16099 static int
   16100 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
   16101 			   xmlSchemaTypePtr type)
   16102 {
   16103     xmlSchemaTypePtr base = type->baseType;
   16104     /*
   16105     * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
   16106     * temporarily only.
   16107     */
   16108     /*
   16109     * SPEC (1) "If the {base type definition} is a complex type definition,
   16110     * then all of the following must be true:"
   16111     */
   16112     if (WXS_IS_COMPLEX(base)) {
   16113 	/*
   16114 	* SPEC (1.1) "The {final} of the {base type definition} must not
   16115 	* contain extension."
   16116 	*/
   16117 	if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
   16118 	    xmlSchemaPCustomErr(ctxt,
   16119 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16120 		WXS_BASIC_CAST type, NULL,
   16121 		"The 'final' of the base type definition "
   16122 		"contains 'extension'", NULL);
   16123 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16124 	}
   16125 
   16126 	/*
   16127 	* ATTENTION: The constrains (1.2) and (1.3) are not applied,
   16128 	* since they are automatically satisfied through the
   16129 	* inheriting mechanism.
   16130 	* Note that even if redefining components, the inheriting mechanism
   16131 	* is used.
   16132 	*/
   16133 #if 0
   16134 	/*
   16135 	* SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
   16136 	* uses}
   16137 	* of the complex type definition itself, that is, for every attribute
   16138 	* use in the {attribute uses} of the {base type definition}, there
   16139 	* must be an attribute use in the {attribute uses} of the complex
   16140 	* type definition itself whose {attribute declaration} has the same
   16141 	* {name}, {target namespace} and {type definition} as its attribute
   16142 	* declaration"
   16143 	*/
   16144 	if (base->attrUses != NULL) {
   16145 	    int i, j, found;
   16146 	    xmlSchemaAttributeUsePtr use, buse;
   16147 
   16148 	    for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
   16149 		buse = (WXS_LIST_CAST base->attrUses)->items[i];
   16150 		found = 0;
   16151 		if (type->attrUses != NULL) {
   16152 		    use = (WXS_LIST_CAST type->attrUses)->items[j];
   16153 		    for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
   16154 		    {
   16155 			if ((WXS_ATTRUSE_DECL_NAME(use) ==
   16156 				WXS_ATTRUSE_DECL_NAME(buse)) &&
   16157 			    (WXS_ATTRUSE_DECL_TNS(use) ==
   16158 				WXS_ATTRUSE_DECL_TNS(buse)) &&
   16159 			    (WXS_ATTRUSE_TYPEDEF(use) ==
   16160 				WXS_ATTRUSE_TYPEDEF(buse))
   16161 			{
   16162 			    found = 1;
   16163 			    break;
   16164 			}
   16165 		    }
   16166 		}
   16167 		if (! found) {
   16168 		    xmlChar *str = NULL;
   16169 
   16170 		    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   16171 			XML_SCHEMAP_COS_CT_EXTENDS_1_2,
   16172 			NULL, WXS_BASIC_CAST type,
   16173 			/*
   16174 			* TODO: The report does not indicate that also the
   16175 			* type needs to be the same.
   16176 			*/
   16177 			"This type is missing a matching correspondent "
   16178 			"for its {base type}'s %s in its {attribute uses}",
   16179 			xmlSchemaGetComponentDesignation(&str,
   16180 			    buse->children),
   16181 			NULL);
   16182 		    FREE_AND_NULL(str)
   16183 		}
   16184 	    }
   16185 	}
   16186 	/*
   16187 	* SPEC (1.3) "If it has an {attribute wildcard}, the complex type
   16188 	* definition must also have one, and the base type definition's
   16189 	* {attribute  wildcard}'s {namespace constraint} must be a subset
   16190 	* of the complex  type definition's {attribute wildcard}'s {namespace
   16191 	* constraint}, as defined by Wildcard Subset (3.10.6)."
   16192 	*/
   16193 
   16194 	/*
   16195 	* MAYBE TODO: Enable if ever needed. But this will be needed only
   16196 	* if created the type via a schema construction API.
   16197 	*/
   16198 	if (base->attributeWildcard != NULL) {
   16199 	    if (type->attributeWilcard == NULL) {
   16200 		xmlChar *str = NULL;
   16201 
   16202 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   16203 		    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
   16204 		    NULL, type,
   16205 		    "The base %s has an attribute wildcard, "
   16206 		    "but this type is missing an attribute wildcard",
   16207 		    xmlSchemaGetComponentDesignation(&str, base));
   16208 		FREE_AND_NULL(str)
   16209 
   16210 	    } else if (xmlSchemaCheckCOSNSSubset(
   16211 		base->attributeWildcard, type->attributeWildcard))
   16212 	    {
   16213 		xmlChar *str = NULL;
   16214 
   16215 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   16216 		    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
   16217 		    NULL, type,
   16218 		    "The attribute wildcard is not a valid "
   16219 		    "superset of the one in the base %s",
   16220 		    xmlSchemaGetComponentDesignation(&str, base));
   16221 		FREE_AND_NULL(str)
   16222 	    }
   16223 	}
   16224 #endif
   16225 	/*
   16226 	* SPEC (1.4) "One of the following must be true:"
   16227 	*/
   16228 	if ((type->contentTypeDef != NULL) &&
   16229 	    (type->contentTypeDef == base->contentTypeDef)) {
   16230 	    /*
   16231 	    * SPEC (1.4.1) "The {content type} of the {base type definition}
   16232 	    * and the {content type} of the complex type definition itself
   16233 	    * must be the same simple type definition"
   16234 	    * PASS
   16235 	    */
   16236 	} else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
   16237 	    (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
   16238 	    /*
   16239 	    * SPEC (1.4.2) "The {content type} of both the {base type
   16240 	    * definition} and the complex type definition itself must
   16241 	    * be empty."
   16242 	    * PASS
   16243 	    */
   16244 	} else {
   16245 	    /*
   16246 	    * SPEC (1.4.3) "All of the following must be true:"
   16247 	    */
   16248 	    if (type->subtypes == NULL) {
   16249 		/*
   16250 		* SPEC 1.4.3.1 The {content type} of the complex type
   16251 		* definition itself must specify a particle.
   16252 		*/
   16253 		xmlSchemaPCustomErr(ctxt,
   16254 		    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16255 		    WXS_BASIC_CAST type, NULL,
   16256 		    "The content type must specify a particle", NULL);
   16257 		return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16258 	    }
   16259 	    /*
   16260 	    * SPEC (1.4.3.2) "One of the following must be true:"
   16261 	    */
   16262 	    if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   16263 		/*
   16264 		* SPEC (1.4.3.2.1) "The {content type} of the {base type
   16265 		* definition} must be empty.
   16266 		* PASS
   16267 		*/
   16268 	    } else {
   16269 		/*
   16270 		* SPEC (1.4.3.2.2) "All of the following must be true:"
   16271 		*/
   16272 		if ((type->contentType != base->contentType) ||
   16273 		    ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
   16274 		    (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
   16275 		    /*
   16276 		    * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
   16277 		    * or both must be element-only."
   16278 		    */
   16279 		    xmlSchemaPCustomErr(ctxt,
   16280 			XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16281 			WXS_BASIC_CAST type, NULL,
   16282 			"The content type of both, the type and its base "
   16283 			"type, must either 'mixed' or 'element-only'", NULL);
   16284 		    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16285 		}
   16286 		/*
   16287 		* URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
   16288 		* complex type definition must be a valid extension
   16289 		* of the {base type definition}'s particle, as defined
   16290 		* in Particle Valid (Extension) (3.9.6)."
   16291 		*
   16292 		* NOTE that we won't check "Particle Valid (Extension)",
   16293 		* since it is ensured by the derivation process in
   16294 		* xmlSchemaTypeFixup(). We need to implement this when heading
   16295 		* for a construction API
   16296 		* TODO: !! This is needed to be checked if redefining a type !!
   16297 		*/
   16298 	    }
   16299 	    /*
   16300 	    * URGENT TODO (1.5)
   16301 	    */
   16302 	}
   16303     } else {
   16304 	/*
   16305 	* SPEC (2) "If the {base type definition} is a simple type definition,
   16306 	* then all of the following must be true:"
   16307 	*/
   16308 	if (type->contentTypeDef != base) {
   16309 	    /*
   16310 	    * SPEC (2.1) "The {content type} must be the same simple type
   16311 	    * definition."
   16312 	    */
   16313 	    xmlSchemaPCustomErr(ctxt,
   16314 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16315 		WXS_BASIC_CAST type, NULL,
   16316 		"The content type must be the simple base type", NULL);
   16317 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16318 	}
   16319 	if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
   16320 	    /*
   16321 	    * SPEC (2.2) "The {final} of the {base type definition} must not
   16322 	    * contain extension"
   16323 	    * NOTE that this is the same as (1.1).
   16324 	    */
   16325 	    xmlSchemaPCustomErr(ctxt,
   16326 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16327 		WXS_BASIC_CAST type, NULL,
   16328 		"The 'final' of the base type definition "
   16329 		"contains 'extension'", NULL);
   16330 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16331 	}
   16332     }
   16333     return (0);
   16334 }
   16335 
   16336 /**
   16337  * xmlSchemaCheckDerivationOKRestriction:
   16338  * @ctxt:  the schema parser context
   16339  * @type:  the complex type definition
   16340  *
   16341  * (3.4.6) Constraints on Complex Type Definition Schema Components
   16342  * Schema Component Constraint:
   16343  * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
   16344  *
   16345  * STATUS:
   16346  *   missing:
   16347  *     (5.4.2) ???
   16348  *
   16349  * ATTENTION:
   16350  * In XML Schema 1.1 this will be:
   16351  * Validation Rule: Checking complex type subsumption
   16352  *
   16353  * Returns 0 if the constraints are satisfied, a positive
   16354  * error code if not and -1 if an internal error occured.
   16355  */
   16356 static int
   16357 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
   16358 				      xmlSchemaTypePtr type)
   16359 {
   16360     xmlSchemaTypePtr base;
   16361 
   16362     /*
   16363     * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
   16364     * temporarily only.
   16365     */
   16366     base = type->baseType;
   16367     if (! WXS_IS_COMPLEX(base)) {
   16368 	xmlSchemaCustomErr(ACTXT_CAST ctxt,
   16369 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16370 	    type->node, WXS_BASIC_CAST type,
   16371 	    "The base type must be a complex type", NULL, NULL);
   16372 	return(ctxt->err);
   16373     }
   16374     if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
   16375 	/*
   16376 	* SPEC (1) "The {base type definition} must be a complex type
   16377 	* definition whose {final} does not contain restriction."
   16378 	*/
   16379 	xmlSchemaCustomErr(ACTXT_CAST ctxt,
   16380 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16381 	    type->node, WXS_BASIC_CAST type,
   16382 	    "The 'final' of the base type definition "
   16383 	    "contains 'restriction'", NULL, NULL);
   16384 	return (ctxt->err);
   16385     }
   16386     /*
   16387     * SPEC (2), (3) and (4)
   16388     * Those are handled in a separate function, since the
   16389     * same constraints are needed for redefinition of
   16390     * attribute groups as well.
   16391     */
   16392     if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
   16393 	XML_SCHEMA_ACTION_DERIVE,
   16394 	WXS_BASIC_CAST type, WXS_BASIC_CAST base,
   16395 	type->attrUses, base->attrUses,
   16396 	type->attributeWildcard,
   16397 	base->attributeWildcard) == -1)
   16398     {
   16399 	return(-1);
   16400     }
   16401     /*
   16402     * SPEC (5) "One of the following must be true:"
   16403     */
   16404     if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
   16405 	/*
   16406 	* SPEC (5.1) "The {base type definition} must be the
   16407 	* ur-type definition."
   16408 	* PASS
   16409 	*/
   16410     } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
   16411 	    (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
   16412 	/*
   16413 	* SPEC (5.2.1) "The {content type} of the complex type definition
   16414 	* must be a simple type definition"
   16415 	*
   16416 	* SPEC (5.2.2) "One of the following must be true:"
   16417 	*/
   16418 	if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
   16419 	    (base->contentType == XML_SCHEMA_CONTENT_BASIC))
   16420 	{
   16421 	    int err;
   16422 	    /*
   16423 	    * SPEC (5.2.2.1) "The {content type} of the {base type
   16424 	    * definition} must be a simple type definition from which
   16425 	    * the {content type} is validly derived given the empty
   16426 	    * set as defined in Type Derivation OK (Simple) (3.14.6)."
   16427 	    *
   16428 	    * ATTENTION TODO: This seems not needed if the type implicitely
   16429 	    * derived from the base type.
   16430 	    *
   16431 	    */
   16432 	    err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
   16433 		type->contentTypeDef, base->contentTypeDef, 0);
   16434 	    if (err != 0) {
   16435 		xmlChar *strA = NULL, *strB = NULL;
   16436 
   16437 		if (err == -1)
   16438 		    return(-1);
   16439 		xmlSchemaCustomErr(ACTXT_CAST ctxt,
   16440 		    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16441 		    NULL, WXS_BASIC_CAST type,
   16442 		    "The {content type} %s is not validly derived from the "
   16443 		    "base type's {content type} %s",
   16444 		    xmlSchemaGetComponentDesignation(&strA,
   16445 			type->contentTypeDef),
   16446 		    xmlSchemaGetComponentDesignation(&strB,
   16447 			base->contentTypeDef));
   16448 		FREE_AND_NULL(strA);
   16449 		FREE_AND_NULL(strB);
   16450 		return(ctxt->err);
   16451 	    }
   16452 	} else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
   16453 	    (xmlSchemaIsParticleEmptiable(
   16454 		(xmlSchemaParticlePtr) base->subtypes))) {
   16455 	    /*
   16456 	    * SPEC (5.2.2.2) "The {base type definition} must be mixed
   16457 	    * and have a particle which is emptiable as defined in
   16458 	    * Particle Emptiable (3.9.6)."
   16459 	    * PASS
   16460 	    */
   16461 	} else {
   16462 	    xmlSchemaPCustomErr(ctxt,
   16463 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16464 		WXS_BASIC_CAST type, NULL,
   16465 		"The content type of the base type must be either "
   16466 		"a simple type or 'mixed' and an emptiable particle", NULL);
   16467 	    return (ctxt->err);
   16468 	}
   16469     } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   16470 	/*
   16471 	* SPEC (5.3.1) "The {content type} of the complex type itself must
   16472 	* be empty"
   16473 	*/
   16474 	if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   16475 	    /*
   16476 	    * SPEC (5.3.2.1) "The {content type} of the {base type
   16477 	    * definition} must also be empty."
   16478 	    * PASS
   16479 	    */
   16480 	} else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
   16481 	    (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
   16482 	    xmlSchemaIsParticleEmptiable(
   16483 		(xmlSchemaParticlePtr) base->subtypes)) {
   16484 	    /*
   16485 	    * SPEC (5.3.2.2) "The {content type} of the {base type
   16486 	    * definition} must be elementOnly or mixed and have a particle
   16487 	    * which is emptiable as defined in Particle Emptiable (3.9.6)."
   16488 	    * PASS
   16489 	    */
   16490 	} else {
   16491 	    xmlSchemaPCustomErr(ctxt,
   16492 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16493 		WXS_BASIC_CAST type, NULL,
   16494 		"The content type of the base type must be either "
   16495 		"empty or 'mixed' (or 'elements-only') and an emptiable "
   16496 		"particle", NULL);
   16497 	    return (ctxt->err);
   16498 	}
   16499     } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
   16500 	WXS_HAS_MIXED_CONTENT(type)) {
   16501 	/*
   16502 	* SPEC (5.4.1.1) "The {content type} of the complex type definition
   16503 	* itself must be element-only"
   16504 	*/
   16505 	if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
   16506 	    /*
   16507 	    * SPEC (5.4.1.2) "The {content type} of the complex type
   16508 	    * definition itself and of the {base type definition} must be
   16509 	    * mixed"
   16510 	    */
   16511 	    xmlSchemaPCustomErr(ctxt,
   16512 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16513 		WXS_BASIC_CAST type, NULL,
   16514 		"If the content type is 'mixed', then the content type of the "
   16515 		"base type must also be 'mixed'", NULL);
   16516 	    return (ctxt->err);
   16517 	}
   16518 	/*
   16519 	* SPEC (5.4.2) "The particle of the complex type definition itself
   16520 	* must be a valid restriction of the particle of the {content
   16521 	* type} of the {base type definition} as defined in Particle Valid
   16522 	* (Restriction) (3.9.6).
   16523 	*
   16524 	* URGENT TODO: (5.4.2)
   16525 	*/
   16526     } else {
   16527 	xmlSchemaPCustomErr(ctxt,
   16528 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16529 	    WXS_BASIC_CAST type, NULL,
   16530 	    "The type is not a valid restriction of its base type", NULL);
   16531 	return (ctxt->err);
   16532     }
   16533     return (0);
   16534 }
   16535 
   16536 /**
   16537  * xmlSchemaCheckCTComponent:
   16538  * @ctxt:  the schema parser context
   16539  * @type:  the complex type definition
   16540  *
   16541  * (3.4.6) Constraints on Complex Type Definition Schema Components
   16542  *
   16543  * Returns 0 if the constraints are satisfied, a positive
   16544  * error code if not and -1 if an internal error occured.
   16545  */
   16546 static int
   16547 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
   16548 			  xmlSchemaTypePtr type)
   16549 {
   16550     int ret;
   16551     /*
   16552     * Complex Type Definition Properties Correct
   16553     */
   16554     ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
   16555     if (ret != 0)
   16556 	return (ret);
   16557     if (WXS_IS_EXTENSION(type))
   16558 	ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
   16559     else
   16560 	ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
   16561     return (ret);
   16562 }
   16563 
   16564 /**
   16565  * xmlSchemaCheckSRCCT:
   16566  * @ctxt:  the schema parser context
   16567  * @type:  the complex type definition
   16568  *
   16569  * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
   16570  * Schema Representation Constraint:
   16571  * Complex Type Definition Representation OK (src-ct)
   16572  *
   16573  * Returns 0 if the constraints are satisfied, a positive
   16574  * error code if not and -1 if an internal error occured.
   16575  */
   16576 static int
   16577 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
   16578 		    xmlSchemaTypePtr type)
   16579 {
   16580     xmlSchemaTypePtr base;
   16581     int ret = 0;
   16582 
   16583     /*
   16584     * TODO: Adjust the error codes here, as I used
   16585     * XML_SCHEMAP_SRC_CT_1 only yet.
   16586     */
   16587     base = type->baseType;
   16588     if (! WXS_HAS_SIMPLE_CONTENT(type)) {
   16589 	/*
   16590 	* 1 If the <complexContent> alternative is chosen, the type definition
   16591 	* resolved to by the actual value of the base [attribute]
   16592 	* must be a complex type definition;
   16593 	*/
   16594 	if (! WXS_IS_COMPLEX(base)) {
   16595 	    xmlChar *str = NULL;
   16596 	    xmlSchemaPCustomErr(ctxt,
   16597 		XML_SCHEMAP_SRC_CT_1,
   16598 		WXS_BASIC_CAST type, type->node,
   16599 		"If using <complexContent>, the base type is expected to be "
   16600 		"a complex type. The base type '%s' is a simple type",
   16601 		xmlSchemaFormatQName(&str, base->targetNamespace,
   16602 		base->name));
   16603 	    FREE_AND_NULL(str)
   16604 	    return (XML_SCHEMAP_SRC_CT_1);
   16605 	}
   16606     } else {
   16607 	/*
   16608 	* SPEC
   16609 	* 2 If the <simpleContent> alternative is chosen, all of the
   16610 	* following must be true:
   16611 	* 2.1 The type definition resolved to by the actual value of the
   16612 	* base [attribute] must be one of the following:
   16613 	*/
   16614 	if (WXS_IS_SIMPLE(base)) {
   16615 	    if (WXS_IS_EXTENSION(type) == 0) {
   16616 		xmlChar *str = NULL;
   16617 		/*
   16618 		* 2.1.3 only if the <extension> alternative is also
   16619 		* chosen, a simple type definition.
   16620 		*/
   16621 		/* TODO: Change error code to ..._SRC_CT_2_1_3. */
   16622 		xmlSchemaPCustomErr(ctxt,
   16623 		    XML_SCHEMAP_SRC_CT_1,
   16624 		    WXS_BASIC_CAST type, NULL,
   16625 		    "If using <simpleContent> and <restriction>, the base "
   16626 		    "type must be a complex type. The base type '%s' is "
   16627 		    "a simple type",
   16628 		    xmlSchemaFormatQName(&str, base->targetNamespace,
   16629 			base->name));
   16630 		FREE_AND_NULL(str)
   16631 		return (XML_SCHEMAP_SRC_CT_1);
   16632 	    }
   16633 	} else {
   16634 	    /* Base type is a complex type. */
   16635 	    if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
   16636 		(base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
   16637 		/*
   16638 		* 2.1.1 a complex type definition whose {content type} is a
   16639 		* simple type definition;
   16640 		* PASS
   16641 		*/
   16642 		if (base->contentTypeDef == NULL) {
   16643 		    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
   16644 			WXS_BASIC_CAST type, NULL,
   16645 			"Internal error: xmlSchemaCheckSRCCT, "
   16646 			"'%s', base type has no content type",
   16647 			type->name);
   16648 		    return (-1);
   16649 		}
   16650 	    } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
   16651 		(WXS_IS_RESTRICTION(type))) {
   16652 
   16653 		/*
   16654 		* 2.1.2 only if the <restriction> alternative is also
   16655 		* chosen, a complex type definition whose {content type}
   16656 		* is mixed and a particle emptiable.
   16657 		*/
   16658 		if (! xmlSchemaIsParticleEmptiable(
   16659 		    (xmlSchemaParticlePtr) base->subtypes)) {
   16660 		    ret = XML_SCHEMAP_SRC_CT_1;
   16661 		} else
   16662 		    /*
   16663 		    * Attention: at this point the <simpleType> child is in
   16664 		    * ->contentTypeDef (put there during parsing).
   16665 		    */
   16666 		    if (type->contentTypeDef == NULL) {
   16667 		    xmlChar *str = NULL;
   16668 		    /*
   16669 		    * 2.2 If clause 2.1.2 above is satisfied, then there
   16670 		    * must be a <simpleType> among the [children] of
   16671 		    * <restriction>.
   16672 		    */
   16673 		    /* TODO: Change error code to ..._SRC_CT_2_2. */
   16674 		    xmlSchemaPCustomErr(ctxt,
   16675 			XML_SCHEMAP_SRC_CT_1,
   16676 			WXS_BASIC_CAST type, NULL,
   16677 			"A <simpleType> is expected among the children "
   16678 			"of <restriction>, if <simpleContent> is used and "
   16679 			"the base type '%s' is a complex type",
   16680 			xmlSchemaFormatQName(&str, base->targetNamespace,
   16681 			base->name));
   16682 		    FREE_AND_NULL(str)
   16683 		    return (XML_SCHEMAP_SRC_CT_1);
   16684 		}
   16685 	    } else {
   16686 		ret = XML_SCHEMAP_SRC_CT_1;
   16687 	    }
   16688 	}
   16689 	if (ret > 0) {
   16690 	    xmlChar *str = NULL;
   16691 	    if (WXS_IS_RESTRICTION(type)) {
   16692 		xmlSchemaPCustomErr(ctxt,
   16693 		    XML_SCHEMAP_SRC_CT_1,
   16694 		    WXS_BASIC_CAST type, NULL,
   16695 		    "If <simpleContent> and <restriction> is used, the "
   16696 		    "base type must be a simple type or a complex type with "
   16697 		    "mixed content and particle emptiable. The base type "
   16698 		    "'%s' is none of those",
   16699 		    xmlSchemaFormatQName(&str, base->targetNamespace,
   16700 		    base->name));
   16701 	    } else {
   16702 		xmlSchemaPCustomErr(ctxt,
   16703 		    XML_SCHEMAP_SRC_CT_1,
   16704 		    WXS_BASIC_CAST type, NULL,
   16705 		    "If <simpleContent> and <extension> is used, the "
   16706 		    "base type must be a simple type. The base type '%s' "
   16707 		    "is a complex type",
   16708 		    xmlSchemaFormatQName(&str, base->targetNamespace,
   16709 		    base->name));
   16710 	    }
   16711 	    FREE_AND_NULL(str)
   16712 	}
   16713     }
   16714     /*
   16715     * SPEC (3) "The corresponding complex type definition component must
   16716     * satisfy the conditions set out in Constraints on Complex Type
   16717     * Definition Schema Components (3.4.6);"
   16718     * NOTE (3) will be done in xmlSchemaTypeFixup().
   16719     */
   16720     /*
   16721     * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
   16722     * above for {attribute wildcard} is satisfied, the intensional
   16723     * intersection must be expressible, as defined in Attribute Wildcard
   16724     * Intersection (3.10.6).
   16725     * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
   16726     */
   16727     return (ret);
   16728 }
   16729 
   16730 #ifdef ENABLE_PARTICLE_RESTRICTION
   16731 /**
   16732  * xmlSchemaCheckParticleRangeOK:
   16733  * @ctxt:  the schema parser context
   16734  * @type:  the complex type definition
   16735  *
   16736  * (3.9.6) Constraints on Particle Schema Components
   16737  * Schema Component Constraint:
   16738  * Occurrence Range OK (range-ok)
   16739  *
   16740  * STATUS: complete
   16741  *
   16742  * Returns 0 if the constraints are satisfied, a positive
   16743  * error code if not and -1 if an internal error occured.
   16744  */
   16745 static int
   16746 xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
   16747 			      int bmin, int bmax)
   16748 {
   16749     if (rmin < bmin)
   16750 	return (1);
   16751     if ((bmax != UNBOUNDED) &&
   16752 	(rmax > bmax))
   16753 	return (1);
   16754     return (0);
   16755 }
   16756 
   16757 /**
   16758  * xmlSchemaCheckRCaseNameAndTypeOK:
   16759  * @ctxt:  the schema parser context
   16760  * @r: the restricting element declaration particle
   16761  * @b: the base element declaration particle
   16762  *
   16763  * (3.9.6) Constraints on Particle Schema Components
   16764  * Schema Component Constraint:
   16765  * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
   16766  * (rcase-NameAndTypeOK)
   16767  *
   16768  * STATUS:
   16769  *   MISSING (3.2.3)
   16770  *   CLARIFY: (3.2.2)
   16771  *
   16772  * Returns 0 if the constraints are satisfied, a positive
   16773  * error code if not and -1 if an internal error occured.
   16774  */
   16775 static int
   16776 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
   16777 				 xmlSchemaParticlePtr r,
   16778 				 xmlSchemaParticlePtr b)
   16779 {
   16780     xmlSchemaElementPtr elemR, elemB;
   16781 
   16782     /* TODO: Error codes (rcase-NameAndTypeOK). */
   16783     elemR = (xmlSchemaElementPtr) r->children;
   16784     elemB = (xmlSchemaElementPtr) b->children;
   16785     /*
   16786     * SPEC (1) "The declarations' {name}s and {target namespace}s are
   16787     * the same."
   16788     */
   16789     if ((elemR != elemB) &&
   16790 	((! xmlStrEqual(elemR->name, elemB->name)) ||
   16791 	(! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
   16792 	return (1);
   16793     /*
   16794     * SPEC (2) "R's occurrence range is a valid restriction of B's
   16795     * occurrence range as defined by Occurrence Range OK (3.9.6)."
   16796     */
   16797     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
   16798 	    b->minOccurs, b->maxOccurs) != 0)
   16799 	return (1);
   16800     /*
   16801     * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
   16802     * {scope} are global."
   16803     */
   16804     if (elemR == elemB)
   16805 	return (0);
   16806     /*
   16807     * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
   16808     */
   16809     if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
   16810 	(elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
   16811 	 return (1);
   16812     /*
   16813     * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
   16814     * or is not fixed, or R's declaration's {value constraint} is fixed
   16815     * with the same value."
   16816     */
   16817     if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
   16818 	((elemR->value == NULL) ||
   16819 	 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
   16820 	 /* TODO: Equality of the initial value or normalized or canonical? */
   16821 	 (! xmlStrEqual(elemR->value, elemB->value))))
   16822 	 return (1);
   16823     /*
   16824     * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
   16825     * definitions} is a subset of B's declaration's {identity-constraint
   16826     * definitions}, if any."
   16827     */
   16828     if (elemB->idcs != NULL) {
   16829 	/* TODO */
   16830     }
   16831     /*
   16832     * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
   16833     * superset of B's declaration's {disallowed substitutions}."
   16834     */
   16835     if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
   16836 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
   16837 	((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
   16838 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
   16839 	((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
   16840 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
   16841 	 return (1);
   16842     /*
   16843     * SPEC (3.2.5) "R's {type definition} is validly derived given
   16844     * {extension, list, union} from B's {type definition}"
   16845     *
   16846     * BADSPEC TODO: What's the point of adding "list" and "union" to the
   16847     * set, if the corresponding constraints handle "restriction" and
   16848     * "extension" only?
   16849     *
   16850     */
   16851     {
   16852 	int set = 0;
   16853 
   16854 	set |= SUBSET_EXTENSION;
   16855 	set |= SUBSET_LIST;
   16856 	set |= SUBSET_UNION;
   16857 	if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
   16858 	    elemB->subtypes, set) != 0)
   16859 	    return (1);
   16860     }
   16861     return (0);
   16862 }
   16863 
   16864 /**
   16865  * xmlSchemaCheckRCaseNSCompat:
   16866  * @ctxt:  the schema parser context
   16867  * @r: the restricting element declaration particle
   16868  * @b: the base wildcard particle
   16869  *
   16870  * (3.9.6) Constraints on Particle Schema Components
   16871  * Schema Component Constraint:
   16872  * Particle Derivation OK (Elt:Any -- NSCompat)
   16873  * (rcase-NSCompat)
   16874  *
   16875  * STATUS: complete
   16876  *
   16877  * Returns 0 if the constraints are satisfied, a positive
   16878  * error code if not and -1 if an internal error occured.
   16879  */
   16880 static int
   16881 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
   16882 			    xmlSchemaParticlePtr r,
   16883 			    xmlSchemaParticlePtr b)
   16884 {
   16885     /* TODO:Error codes (rcase-NSCompat). */
   16886     /*
   16887     * SPEC "For an element declaration particle to be a valid restriction
   16888     * of a wildcard particle all of the following must be true:"
   16889     *
   16890     * SPEC (1) "The element declaration's {target namespace} is valid
   16891     * with respect to the wildcard's {namespace constraint} as defined by
   16892     * Wildcard allows Namespace Name (3.10.4)."
   16893     */
   16894     if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
   16895 	((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
   16896 	return (1);
   16897     /*
   16898     * SPEC (2) "R's occurrence range is a valid restriction of B's
   16899     * occurrence range as defined by Occurrence Range OK (3.9.6)."
   16900     */
   16901     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
   16902 	    b->minOccurs, b->maxOccurs) != 0)
   16903 	return (1);
   16904 
   16905     return (0);
   16906 }
   16907 
   16908 /**
   16909  * xmlSchemaCheckRCaseRecurseAsIfGroup:
   16910  * @ctxt:  the schema parser context
   16911  * @r: the restricting element declaration particle
   16912  * @b: the base model group particle
   16913  *
   16914  * (3.9.6) Constraints on Particle Schema Components
   16915  * Schema Component Constraint:
   16916  * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
   16917  * (rcase-RecurseAsIfGroup)
   16918  *
   16919  * STATUS: TODO
   16920  *
   16921  * Returns 0 if the constraints are satisfied, a positive
   16922  * error code if not and -1 if an internal error occured.
   16923  */
   16924 static int
   16925 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
   16926 				    xmlSchemaParticlePtr r,
   16927 				    xmlSchemaParticlePtr b)
   16928 {
   16929     /* TODO: Error codes (rcase-RecurseAsIfGroup). */
   16930     TODO
   16931     return (0);
   16932 }
   16933 
   16934 /**
   16935  * xmlSchemaCheckRCaseNSSubset:
   16936  * @ctxt:  the schema parser context
   16937  * @r: the restricting wildcard particle
   16938  * @b: the base wildcard particle
   16939  *
   16940  * (3.9.6) Constraints on Particle Schema Components
   16941  * Schema Component Constraint:
   16942  * Particle Derivation OK (Any:Any -- NSSubset)
   16943  * (rcase-NSSubset)
   16944  *
   16945  * STATUS: complete
   16946  *
   16947  * Returns 0 if the constraints are satisfied, a positive
   16948  * error code if not and -1 if an internal error occured.
   16949  */
   16950 static int
   16951 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
   16952 				    xmlSchemaParticlePtr r,
   16953 				    xmlSchemaParticlePtr b,
   16954 				    int isAnyTypeBase)
   16955 {
   16956     /* TODO: Error codes (rcase-NSSubset). */
   16957     /*
   16958     * SPEC (1) "R's occurrence range is a valid restriction of B's
   16959     * occurrence range as defined by Occurrence Range OK (3.9.6)."
   16960     */
   16961     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
   16962 	    b->minOccurs, b->maxOccurs))
   16963 	return (1);
   16964     /*
   16965     * SPEC (2) "R's {namespace constraint} must be an intensional subset
   16966     * of B's {namespace constraint} as defined by Wildcard Subset (3.10.6)."
   16967     */
   16968     if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
   16969 	(xmlSchemaWildcardPtr) b->children))
   16970 	return (1);
   16971     /*
   16972     * SPEC (3) "Unless B is the content model wildcard of the ur-type
   16973     * definition, R's {process contents} must be identical to or stronger
   16974     * than B's {process contents}, where strict is stronger than lax is
   16975     * stronger than skip."
   16976     */
   16977     if (! isAnyTypeBase) {
   16978 	if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
   16979 	    ((xmlSchemaWildcardPtr) b->children)->processContents)
   16980 	    return (1);
   16981     }
   16982 
   16983     return (0);
   16984 }
   16985 
   16986 /**
   16987  * xmlSchemaCheckCOSParticleRestrict:
   16988  * @ctxt:  the schema parser context
   16989  * @type:  the complex type definition
   16990  *
   16991  * (3.9.6) Constraints on Particle Schema Components
   16992  * Schema Component Constraint:
   16993  * Particle Valid (Restriction) (cos-particle-restrict)
   16994  *
   16995  * STATUS: TODO
   16996  *
   16997  * Returns 0 if the constraints are satisfied, a positive
   16998  * error code if not and -1 if an internal error occured.
   16999  */
   17000 static int
   17001 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
   17002 				  xmlSchemaParticlePtr r,
   17003 				  xmlSchemaParticlePtr b)
   17004 {
   17005     int ret = 0;
   17006 
   17007     /*part = WXS_TYPE_PARTICLE(type);
   17008     basePart = WXS_TYPE_PARTICLE(base);
   17009     */
   17010 
   17011     TODO
   17012 
   17013     /*
   17014     * SPEC (1) "They are the same particle."
   17015     */
   17016     if (r == b)
   17017 	return (0);
   17018 
   17019 
   17020     return (0);
   17021 }
   17022 
   17023 #if 0
   17024 /**
   17025  * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
   17026  * @ctxt:  the schema parser context
   17027  * @r: the model group particle
   17028  * @b: the base wildcard particle
   17029  *
   17030  * (3.9.6) Constraints on Particle Schema Components
   17031  * Schema Component Constraint:
   17032  * Particle Derivation OK (All/Choice/Sequence:Any --
   17033  *                         NSRecurseCheckCardinality)
   17034  * (rcase-NSRecurseCheckCardinality)
   17035  *
   17036  * STATUS: TODO: subst-groups
   17037  *
   17038  * Returns 0 if the constraints are satisfied, a positive
   17039  * error code if not and -1 if an internal error occured.
   17040  */
   17041 static int
   17042 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
   17043 					     xmlSchemaParticlePtr r,
   17044 					     xmlSchemaParticlePtr b)
   17045 {
   17046     xmlSchemaParticlePtr part;
   17047     /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
   17048     if ((r->children == NULL) || (r->children->children == NULL))
   17049 	return (-1);
   17050     /*
   17051     * SPEC "For a group particle to be a valid restriction of a
   17052     * wildcard particle..."
   17053     *
   17054     * SPEC (1) "Every member of the {particles} of the group is a valid
   17055     * restriction of the wildcard as defined by
   17056     * Particle Valid (Restriction) (3.9.6)."
   17057     */
   17058     part = (xmlSchemaParticlePtr) r->children->children;
   17059     do {
   17060 	if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
   17061 	    return (1);
   17062 	part = (xmlSchemaParticlePtr) part->next;
   17063     } while (part != NULL);
   17064     /*
   17065     * SPEC (2) "The effective total range of the group [...] is a
   17066     * valid restriction of B's occurrence range as defined by
   17067     * Occurrence Range OK (3.9.6)."
   17068     */
   17069     if (xmlSchemaCheckParticleRangeOK(
   17070 	    xmlSchemaGetParticleTotalRangeMin(r),
   17071 	    xmlSchemaGetParticleTotalRangeMax(r),
   17072 	    b->minOccurs, b->maxOccurs) != 0)
   17073 	return (1);
   17074     return (0);
   17075 }
   17076 #endif
   17077 
   17078 /**
   17079  * xmlSchemaCheckRCaseRecurse:
   17080  * @ctxt:  the schema parser context
   17081  * @r: the <all> or <sequence> model group particle
   17082  * @b: the base <all> or <sequence> model group particle
   17083  *
   17084  * (3.9.6) Constraints on Particle Schema Components
   17085  * Schema Component Constraint:
   17086  * Particle Derivation OK (All:All,Sequence:Sequence --
   17087                            Recurse)
   17088  * (rcase-Recurse)
   17089  *
   17090  * STATUS:  ?
   17091  * TODO: subst-groups
   17092  *
   17093  * Returns 0 if the constraints are satisfied, a positive
   17094  * error code if not and -1 if an internal error occured.
   17095  */
   17096 static int
   17097 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
   17098 			   xmlSchemaParticlePtr r,
   17099 			   xmlSchemaParticlePtr b)
   17100 {
   17101     /* xmlSchemaParticlePtr part; */
   17102     /* TODO: Error codes (rcase-Recurse). */
   17103     if ((r->children == NULL) || (b->children == NULL) ||
   17104 	(r->children->type != b->children->type))
   17105 	return (-1);
   17106     /*
   17107     * SPEC "For an all or sequence group particle to be a valid
   17108     * restriction of another group particle with the same {compositor}..."
   17109     *
   17110     * SPEC (1) "R's occurrence range is a valid restriction of B's
   17111     * occurrence range as defined by Occurrence Range OK (3.9.6)."
   17112     */
   17113     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
   17114 	    b->minOccurs, b->maxOccurs))
   17115 	return (1);
   17116 
   17117 
   17118     return (0);
   17119 }
   17120 
   17121 #endif
   17122 
   17123 #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
   17124     xmlSchemaPCustomErrExt(pctxt,      \
   17125 	XML_SCHEMAP_INVALID_FACET_VALUE, \
   17126 	WXS_BASIC_CAST fac1, fac1->node, \
   17127 	"It is an error for both '%s' and '%s' to be specified on the "\
   17128 	"same type definition", \
   17129 	BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
   17130 	BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
   17131 
   17132 #define FACET_RESTR_ERR(fac1, msg) \
   17133     xmlSchemaPCustomErr(pctxt,      \
   17134 	XML_SCHEMAP_INVALID_FACET_VALUE, \
   17135 	WXS_BASIC_CAST fac1, fac1->node, \
   17136 	msg, NULL);
   17137 
   17138 #define FACET_RESTR_FIXED_ERR(fac) \
   17139     xmlSchemaPCustomErr(pctxt, \
   17140 	XML_SCHEMAP_INVALID_FACET_VALUE, \
   17141 	WXS_BASIC_CAST fac, fac->node, \
   17142 	"The base type's facet is 'fixed', thus the value must not " \
   17143 	"differ", NULL);
   17144 
   17145 static void
   17146 xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
   17147 			xmlSchemaFacetPtr facet1,
   17148 			xmlSchemaFacetPtr facet2,
   17149 			int lessGreater,
   17150 			int orEqual,
   17151 			int ofBase)
   17152 {
   17153     xmlChar *msg = NULL;
   17154 
   17155     msg = xmlStrdup(BAD_CAST "'");
   17156     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
   17157     msg = xmlStrcat(msg, BAD_CAST "' has to be");
   17158     if (lessGreater == 0)
   17159 	msg = xmlStrcat(msg, BAD_CAST " equal to");
   17160     if (lessGreater == 1)
   17161 	msg = xmlStrcat(msg, BAD_CAST " greater than");
   17162     else
   17163 	msg = xmlStrcat(msg, BAD_CAST " less than");
   17164 
   17165     if (orEqual)
   17166 	msg = xmlStrcat(msg, BAD_CAST " or equal to");
   17167     msg = xmlStrcat(msg, BAD_CAST " '");
   17168     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
   17169     if (ofBase)
   17170 	msg = xmlStrcat(msg, BAD_CAST "' of the base type");
   17171     else
   17172 	msg = xmlStrcat(msg, BAD_CAST "'");
   17173 
   17174     xmlSchemaPCustomErr(pctxt,
   17175 	XML_SCHEMAP_INVALID_FACET_VALUE,
   17176 	WXS_BASIC_CAST facet1, NULL,
   17177 	(const char *) msg, NULL);
   17178 
   17179     if (msg != NULL)
   17180 	xmlFree(msg);
   17181 }
   17182 
   17183 /*
   17184 * xmlSchemaDeriveAndValidateFacets:
   17185 *
   17186 * Schema Component Constraint: Simple Type Restriction (Facets)
   17187 * (st-restrict-facets)
   17188 */
   17189 static int
   17190 xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
   17191 				 xmlSchemaTypePtr type)
   17192 {
   17193     xmlSchemaTypePtr base = type->baseType;
   17194     xmlSchemaFacetLinkPtr link, cur, last = NULL;
   17195     xmlSchemaFacetPtr facet, bfacet,
   17196 	flength = NULL, ftotdig = NULL, ffracdig = NULL,
   17197 	fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
   17198 	fmininc = NULL, fmaxinc = NULL,
   17199 	fminexc = NULL, fmaxexc = NULL,
   17200 	bflength = NULL, bftotdig = NULL, bffracdig = NULL,
   17201 	bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
   17202 	bfmininc = NULL, bfmaxinc = NULL,
   17203 	bfminexc = NULL, bfmaxexc = NULL;
   17204     int res; /* err = 0, fixedErr; */
   17205 
   17206     /*
   17207     * SPEC st-restrict-facets 1:
   17208     * "The {variety} of R is the same as that of B."
   17209     */
   17210     /*
   17211     * SPEC st-restrict-facets 2:
   17212     * "If {variety} is atomic, the {primitive type definition}
   17213     * of R is the same as that of B."
   17214     *
   17215     * NOTE: we leave 1 & 2 out for now, since this will be
   17216     * satisfied by the derivation process.
   17217     * CONSTRUCTION TODO: Maybe needed if using a construction API.
   17218     */
   17219     /*
   17220     * SPEC st-restrict-facets 3:
   17221     * "The {facets} of R are the union of S and the {facets}
   17222     * of B, eliminating duplicates. To eliminate duplicates,
   17223     * when a facet of the same kind occurs in both S and the
   17224     * {facets} of B, the one in the {facets} of B is not
   17225     * included, with the exception of enumeration and pattern
   17226     * facets, for which multiple occurrences with distinct values
   17227     * are allowed."
   17228     */
   17229 
   17230     if ((type->facetSet == NULL) && (base->facetSet == NULL))
   17231 	return (0);
   17232 
   17233     last = type->facetSet;
   17234     if (last != NULL)
   17235 	while (last->next != NULL)
   17236 	    last = last->next;
   17237 
   17238     for (cur = type->facetSet; cur != NULL; cur = cur->next) {
   17239 	facet = cur->facet;
   17240 	switch (facet->type) {
   17241 	    case XML_SCHEMA_FACET_LENGTH:
   17242 		flength = facet; break;
   17243 	    case XML_SCHEMA_FACET_MINLENGTH:
   17244 		fminlen = facet; break;
   17245 	    case XML_SCHEMA_FACET_MININCLUSIVE:
   17246 		fmininc = facet; break;
   17247 	    case XML_SCHEMA_FACET_MINEXCLUSIVE:
   17248 		fminexc = facet; break;
   17249 	    case XML_SCHEMA_FACET_MAXLENGTH:
   17250 		fmaxlen = facet; break;
   17251 	    case XML_SCHEMA_FACET_MAXINCLUSIVE:
   17252 		fmaxinc = facet; break;
   17253 	    case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   17254 		fmaxexc = facet; break;
   17255 	    case XML_SCHEMA_FACET_TOTALDIGITS:
   17256 		ftotdig = facet; break;
   17257 	    case XML_SCHEMA_FACET_FRACTIONDIGITS:
   17258 		ffracdig = facet; break;
   17259 	    default:
   17260 		break;
   17261 	}
   17262     }
   17263     for (cur = base->facetSet; cur != NULL; cur = cur->next) {
   17264 	facet = cur->facet;
   17265 	switch (facet->type) {
   17266 	    case XML_SCHEMA_FACET_LENGTH:
   17267 		bflength = facet; break;
   17268 	    case XML_SCHEMA_FACET_MINLENGTH:
   17269 		bfminlen = facet; break;
   17270 	    case XML_SCHEMA_FACET_MININCLUSIVE:
   17271 		bfmininc = facet; break;
   17272 	    case XML_SCHEMA_FACET_MINEXCLUSIVE:
   17273 		bfminexc = facet; break;
   17274 	    case XML_SCHEMA_FACET_MAXLENGTH:
   17275 		bfmaxlen = facet; break;
   17276 	    case XML_SCHEMA_FACET_MAXINCLUSIVE:
   17277 		bfmaxinc = facet; break;
   17278 	    case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   17279 		bfmaxexc = facet; break;
   17280 	    case XML_SCHEMA_FACET_TOTALDIGITS:
   17281 		bftotdig = facet; break;
   17282 	    case XML_SCHEMA_FACET_FRACTIONDIGITS:
   17283 		bffracdig = facet; break;
   17284 	    default:
   17285 		break;
   17286 	}
   17287     }
   17288     /*
   17289     * length and minLength or maxLength (2.2) + (3.2)
   17290     */
   17291     if (flength && (fminlen || fmaxlen)) {
   17292 	FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
   17293 	    "either of 'minLength' or 'maxLength' to be specified on "
   17294 	    "the same type definition")
   17295     }
   17296     /*
   17297     * Mutual exclusions in the same derivation step.
   17298     */
   17299     if ((fmaxinc) && (fmaxexc)) {
   17300 	/*
   17301 	* SCC "maxInclusive and maxExclusive"
   17302 	*/
   17303 	FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
   17304     }
   17305     if ((fmininc) && (fminexc)) {
   17306 	/*
   17307 	* SCC "minInclusive and minExclusive"
   17308 	*/
   17309 	FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
   17310     }
   17311 
   17312     if (flength && bflength) {
   17313 	/*
   17314 	* SCC "length valid restriction"
   17315 	* The values have to be equal.
   17316 	*/
   17317 	res = xmlSchemaCompareValues(flength->val, bflength->val);
   17318 	if (res == -2)
   17319 	    goto internal_error;
   17320 	if (res != 0)
   17321 	    xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
   17322 	if ((res != 0) && (bflength->fixed)) {
   17323 	    FACET_RESTR_FIXED_ERR(flength)
   17324 	}
   17325 
   17326     }
   17327     if (fminlen && bfminlen) {
   17328 	/*
   17329 	* SCC "minLength valid restriction"
   17330 	* minLength >= BASE minLength
   17331 	*/
   17332 	res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
   17333 	if (res == -2)
   17334 	    goto internal_error;
   17335 	if (res == -1)
   17336 	    xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
   17337 	if ((res != 0) && (bfminlen->fixed)) {
   17338 	    FACET_RESTR_FIXED_ERR(fminlen)
   17339 	}
   17340     }
   17341     if (fmaxlen && bfmaxlen) {
   17342 	/*
   17343 	* SCC "maxLength valid restriction"
   17344 	* maxLength <= BASE minLength
   17345 	*/
   17346 	res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
   17347 	if (res == -2)
   17348 	    goto internal_error;
   17349 	if (res == 1)
   17350 	    xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
   17351 	if ((res != 0) && (bfmaxlen->fixed)) {
   17352 	    FACET_RESTR_FIXED_ERR(fmaxlen)
   17353 	}
   17354     }
   17355     /*
   17356     * SCC "length and minLength or maxLength"
   17357     */
   17358     if (! flength)
   17359 	flength = bflength;
   17360     if (flength) {
   17361 	if (! fminlen)
   17362 	    fminlen = bfminlen;
   17363 	if (fminlen) {
   17364 	    /* (1.1) length >= minLength */
   17365 	    res = xmlSchemaCompareValues(flength->val, fminlen->val);
   17366 	    if (res == -2)
   17367 		goto internal_error;
   17368 	    if (res == -1)
   17369 		xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
   17370 	}
   17371 	if (! fmaxlen)
   17372 	    fmaxlen = bfmaxlen;
   17373 	if (fmaxlen) {
   17374 	    /* (2.1) length <= maxLength */
   17375 	    res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
   17376 	    if (res == -2)
   17377 		goto internal_error;
   17378 	    if (res == 1)
   17379 		xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
   17380 	}
   17381     }
   17382     if (fmaxinc) {
   17383 	/*
   17384 	* "maxInclusive"
   17385 	*/
   17386 	if (fmininc) {
   17387 	    /* SCC "maxInclusive >= minInclusive" */
   17388 	    res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
   17389 	    if (res == -2)
   17390 		goto internal_error;
   17391 	    if (res == -1) {
   17392 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
   17393 	    }
   17394 	}
   17395 	/*
   17396 	* SCC "maxInclusive valid restriction"
   17397 	*/
   17398 	if (bfmaxinc) {
   17399 	    /* maxInclusive <= BASE maxInclusive */
   17400 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
   17401 	    if (res == -2)
   17402 		goto internal_error;
   17403 	    if (res == 1)
   17404 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
   17405 	    if ((res != 0) && (bfmaxinc->fixed)) {
   17406 		FACET_RESTR_FIXED_ERR(fmaxinc)
   17407 	    }
   17408 	}
   17409 	if (bfmaxexc) {
   17410 	    /* maxInclusive < BASE maxExclusive */
   17411 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
   17412 	    if (res == -2)
   17413 		goto internal_error;
   17414 	    if (res != -1) {
   17415 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
   17416 	    }
   17417 	}
   17418 	if (bfmininc) {
   17419 	    /* maxInclusive >= BASE minInclusive */
   17420 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
   17421 	    if (res == -2)
   17422 		goto internal_error;
   17423 	    if (res == -1) {
   17424 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
   17425 	    }
   17426 	}
   17427 	if (bfminexc) {
   17428 	    /* maxInclusive > BASE minExclusive */
   17429 	    res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
   17430 	    if (res == -2)
   17431 		goto internal_error;
   17432 	    if (res != 1) {
   17433 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
   17434 	    }
   17435 	}
   17436     }
   17437     if (fmaxexc) {
   17438 	/*
   17439 	* "maxExclusive >= minExclusive"
   17440 	*/
   17441 	if (fminexc) {
   17442 	    res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
   17443 	    if (res == -2)
   17444 		goto internal_error;
   17445 	    if (res == -1) {
   17446 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
   17447 	    }
   17448 	}
   17449 	/*
   17450 	* "maxExclusive valid restriction"
   17451 	*/
   17452 	if (bfmaxexc) {
   17453 	    /* maxExclusive <= BASE maxExclusive */
   17454 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
   17455 	    if (res == -2)
   17456 		goto internal_error;
   17457 	    if (res == 1) {
   17458 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
   17459 	    }
   17460 	    if ((res != 0) && (bfmaxexc->fixed)) {
   17461 		FACET_RESTR_FIXED_ERR(fmaxexc)
   17462 	    }
   17463 	}
   17464 	if (bfmaxinc) {
   17465 	    /* maxExclusive <= BASE maxInclusive */
   17466 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
   17467 	    if (res == -2)
   17468 		goto internal_error;
   17469 	    if (res == 1) {
   17470 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
   17471 	    }
   17472 	}
   17473 	if (bfmininc) {
   17474 	    /* maxExclusive > BASE minInclusive */
   17475 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
   17476 	    if (res == -2)
   17477 		goto internal_error;
   17478 	    if (res != 1) {
   17479 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
   17480 	    }
   17481 	}
   17482 	if (bfminexc) {
   17483 	    /* maxExclusive > BASE minExclusive */
   17484 	    res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
   17485 	    if (res == -2)
   17486 		goto internal_error;
   17487 	    if (res != 1) {
   17488 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
   17489 	    }
   17490 	}
   17491     }
   17492     if (fminexc) {
   17493 	/*
   17494 	* "minExclusive < maxInclusive"
   17495 	*/
   17496 	if (fmaxinc) {
   17497 	    res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
   17498 	    if (res == -2)
   17499 		goto internal_error;
   17500 	    if (res != -1) {
   17501 		xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
   17502 	    }
   17503 	}
   17504 	/*
   17505 	* "minExclusive valid restriction"
   17506 	*/
   17507 	if (bfminexc) {
   17508 	    /* minExclusive >= BASE minExclusive */
   17509 	    res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
   17510 	    if (res == -2)
   17511 		goto internal_error;
   17512 	    if (res == -1) {
   17513 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
   17514 	    }
   17515 	    if ((res != 0) && (bfminexc->fixed)) {
   17516 		FACET_RESTR_FIXED_ERR(fminexc)
   17517 	    }
   17518 	}
   17519 	if (bfmaxinc) {
   17520 	    /* minExclusive <= BASE maxInclusive */
   17521 	    res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
   17522 	    if (res == -2)
   17523 		goto internal_error;
   17524 	    if (res == 1) {
   17525 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
   17526 	    }
   17527 	}
   17528 	if (bfmininc) {
   17529 	    /* minExclusive >= BASE minInclusive */
   17530 	    res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
   17531 	    if (res == -2)
   17532 		goto internal_error;
   17533 	    if (res == -1) {
   17534 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
   17535 	    }
   17536 	}
   17537 	if (bfmaxexc) {
   17538 	    /* minExclusive < BASE maxExclusive */
   17539 	    res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
   17540 	    if (res == -2)
   17541 		goto internal_error;
   17542 	    if (res != -1) {
   17543 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
   17544 	    }
   17545 	}
   17546     }
   17547     if (fmininc) {
   17548 	/*
   17549 	* "minInclusive < maxExclusive"
   17550 	*/
   17551 	if (fmaxexc) {
   17552 	    res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
   17553 	    if (res == -2)
   17554 		goto internal_error;
   17555 	    if (res != -1) {
   17556 		xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
   17557 	    }
   17558 	}
   17559 	/*
   17560 	* "minExclusive valid restriction"
   17561 	*/
   17562 	if (bfmininc) {
   17563 	    /* minInclusive >= BASE minInclusive */
   17564 	    res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
   17565 	    if (res == -2)
   17566 		goto internal_error;
   17567 	    if (res == -1) {
   17568 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
   17569 	    }
   17570 	    if ((res != 0) && (bfmininc->fixed)) {
   17571 		FACET_RESTR_FIXED_ERR(fmininc)
   17572 	    }
   17573 	}
   17574 	if (bfmaxinc) {
   17575 	    /* minInclusive <= BASE maxInclusive */
   17576 	    res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
   17577 	    if (res == -2)
   17578 		goto internal_error;
   17579 	    if (res == 1) {
   17580 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
   17581 	    }
   17582 	}
   17583 	if (bfminexc) {
   17584 	    /* minInclusive > BASE minExclusive */
   17585 	    res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
   17586 	    if (res == -2)
   17587 		goto internal_error;
   17588 	    if (res != 1)
   17589 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
   17590 	}
   17591 	if (bfmaxexc) {
   17592 	    /* minInclusive < BASE maxExclusive */
   17593 	    res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
   17594 	    if (res == -2)
   17595 		goto internal_error;
   17596 	    if (res != -1)
   17597 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
   17598 	}
   17599     }
   17600     if (ftotdig && bftotdig) {
   17601 	/*
   17602 	* SCC " totalDigits valid restriction"
   17603 	* totalDigits <= BASE totalDigits
   17604 	*/
   17605 	res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
   17606 	if (res == -2)
   17607 	    goto internal_error;
   17608 	if (res == 1)
   17609 	    xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
   17610 	    -1, 1, 1);
   17611 	if ((res != 0) && (bftotdig->fixed)) {
   17612 	    FACET_RESTR_FIXED_ERR(ftotdig)
   17613 	}
   17614     }
   17615     if (ffracdig && bffracdig) {
   17616 	/*
   17617 	* SCC  "fractionDigits valid restriction"
   17618 	* fractionDigits <= BASE fractionDigits
   17619 	*/
   17620 	res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
   17621 	if (res == -2)
   17622 	    goto internal_error;
   17623 	if (res == 1)
   17624 	    xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
   17625 	    -1, 1, 1);
   17626 	if ((res != 0) && (bffracdig->fixed)) {
   17627 	    FACET_RESTR_FIXED_ERR(ffracdig)
   17628 	}
   17629     }
   17630     /*
   17631     * SCC "fractionDigits less than or equal to totalDigits"
   17632     */
   17633     if (! ftotdig)
   17634 	ftotdig = bftotdig;
   17635     if (! ffracdig)
   17636 	ffracdig = bffracdig;
   17637     if (ftotdig && ffracdig) {
   17638 	res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
   17639 	if (res == -2)
   17640 	    goto internal_error;
   17641 	if (res == 1)
   17642 	    xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
   17643 		-1, 1, 0);
   17644     }
   17645     /*
   17646     * *Enumerations* won' be added here, since only the first set
   17647     * of enumerations in the ancestor-or-self axis is used
   17648     * for validation, plus we need to use the base type of those
   17649     * enumerations for whitespace.
   17650     *
   17651     * *Patterns*: won't be add here, since they are ORed at
   17652     * type level and ANDed at ancestor level. This will
   17653     * happed during validation by walking the base axis
   17654     * of the type.
   17655     */
   17656     for (cur = base->facetSet; cur != NULL; cur = cur->next) {
   17657 	bfacet = cur->facet;
   17658 	/*
   17659 	* Special handling of enumerations and patterns.
   17660 	* TODO: hmm, they should not appear in the set, so remove this.
   17661 	*/
   17662 	if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
   17663 	    (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
   17664 	    continue;
   17665 	/*
   17666 	* Search for a duplicate facet in the current type.
   17667 	*/
   17668 	link = type->facetSet;
   17669 	/* err = 0; */
   17670 	/* fixedErr = 0; */
   17671 	while (link != NULL) {
   17672 	    facet = link->facet;
   17673 	    if (facet->type == bfacet->type) {
   17674 		switch (facet->type) {
   17675 		    case XML_SCHEMA_FACET_WHITESPACE:
   17676 			/*
   17677 			* The whitespace must be stronger.
   17678 			*/
   17679 			if (facet->whitespace < bfacet->whitespace) {
   17680 			    FACET_RESTR_ERR(facet,
   17681 				"The 'whitespace' value has to be equal to "
   17682 				"or stronger than the 'whitespace' value of "
   17683 				"the base type")
   17684 			}
   17685 			if ((bfacet->fixed) &&
   17686 			    (facet->whitespace != bfacet->whitespace)) {
   17687 			    FACET_RESTR_FIXED_ERR(facet)
   17688 			}
   17689 			break;
   17690 		    default:
   17691 			break;
   17692 		}
   17693 		/* Duplicate found. */
   17694 		break;
   17695 	    }
   17696 	    link = link->next;
   17697 	}
   17698 	/*
   17699 	* If no duplicate was found: add the base types's facet
   17700 	* to the set.
   17701 	*/
   17702 	if (link == NULL) {
   17703 	    link = (xmlSchemaFacetLinkPtr)
   17704 		xmlMalloc(sizeof(xmlSchemaFacetLink));
   17705 	    if (link == NULL) {
   17706 		xmlSchemaPErrMemory(pctxt,
   17707 		    "deriving facets, creating a facet link", NULL);
   17708 		return (-1);
   17709 	    }
   17710 	    link->facet = cur->facet;
   17711 	    link->next = NULL;
   17712 	    if (last == NULL)
   17713 		type->facetSet = link;
   17714 	    else
   17715 		last->next = link;
   17716 	    last = link;
   17717 	}
   17718 
   17719     }
   17720 
   17721     return (0);
   17722 internal_error:
   17723     PERROR_INT("xmlSchemaDeriveAndValidateFacets",
   17724 	"an error occured");
   17725     return (-1);
   17726 }
   17727 
   17728 static int
   17729 xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
   17730 					     xmlSchemaTypePtr type)
   17731 {
   17732     xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
   17733     /*
   17734     * The actual value is then formed by replacing any union type
   17735     * definition in the explicit members with the members of their
   17736     * {member type definitions}, in order.
   17737     *
   17738     * TODO: There's a bug entry at
   17739     * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
   17740     * which indicates that we'll keep the union types the future.
   17741     */
   17742     link = type->memberTypes;
   17743     while (link != NULL) {
   17744 
   17745 	if (WXS_IS_TYPE_NOT_FIXED(link->type))
   17746 	    xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
   17747 
   17748 	if (WXS_IS_UNION(link->type)) {
   17749 	    subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
   17750 	    if (subLink != NULL) {
   17751 		link->type = subLink->type;
   17752 		if (subLink->next != NULL) {
   17753 		    lastLink = link->next;
   17754 		    subLink = subLink->next;
   17755 		    prevLink = link;
   17756 		    while (subLink != NULL) {
   17757 			newLink = (xmlSchemaTypeLinkPtr)
   17758 			    xmlMalloc(sizeof(xmlSchemaTypeLink));
   17759 			if (newLink == NULL) {
   17760 			    xmlSchemaPErrMemory(pctxt, "allocating a type link",
   17761 				NULL);
   17762 			    return (-1);
   17763 			}
   17764 			newLink->type = subLink->type;
   17765 			prevLink->next = newLink;
   17766 			prevLink = newLink;
   17767 			newLink->next = lastLink;
   17768 
   17769 			subLink = subLink->next;
   17770 		    }
   17771 		}
   17772 	    }
   17773 	}
   17774 	link = link->next;
   17775     }
   17776     return (0);
   17777 }
   17778 
   17779 static void
   17780 xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
   17781 {
   17782     int has = 0, needVal = 0, normVal = 0;
   17783 
   17784     has	= (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
   17785     if (has) {
   17786 	needVal = (type->baseType->flags &
   17787 	    XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
   17788 	normVal = (type->baseType->flags &
   17789 	    XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
   17790     }
   17791     if (type->facets != NULL) {
   17792 	xmlSchemaFacetPtr fac;
   17793 
   17794 	for (fac = type->facets; fac != NULL; fac = fac->next) {
   17795 	    switch (fac->type) {
   17796 		case XML_SCHEMA_FACET_WHITESPACE:
   17797 		    break;
   17798 		case XML_SCHEMA_FACET_PATTERN:
   17799 		    normVal = 1;
   17800 		    has = 1;
   17801 		    break;
   17802 		case XML_SCHEMA_FACET_ENUMERATION:
   17803 		    needVal = 1;
   17804 		    normVal = 1;
   17805 		    has = 1;
   17806 		    break;
   17807 		default:
   17808 		    has = 1;
   17809 		    break;
   17810 	    }
   17811 	}
   17812     }
   17813     if (normVal)
   17814 	type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
   17815     if (needVal)
   17816 	type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
   17817     if (has)
   17818 	type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
   17819 
   17820     if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
   17821 	xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
   17822 	/*
   17823 	* OPTIMIZE VAL TODO: Some facets need a computed value.
   17824 	*/
   17825 	if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
   17826 	    (prim->builtInType != XML_SCHEMAS_STRING)) {
   17827 	    type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
   17828 	}
   17829     }
   17830 }
   17831 
   17832 static int
   17833 xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
   17834 {
   17835 
   17836 
   17837     /*
   17838     * Evaluate the whitespace-facet value.
   17839     */
   17840     if (WXS_IS_LIST(type)) {
   17841 	type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
   17842 	return (0);
   17843     } else if (WXS_IS_UNION(type))
   17844 	return (0);
   17845 
   17846     if (type->facetSet != NULL) {
   17847 	xmlSchemaFacetLinkPtr lin;
   17848 
   17849 	for (lin = type->facetSet; lin != NULL; lin = lin->next) {
   17850 	    if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
   17851 		switch (lin->facet->whitespace) {
   17852 		case XML_SCHEMAS_FACET_PRESERVE:
   17853 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
   17854 		    break;
   17855 		case XML_SCHEMAS_FACET_REPLACE:
   17856 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
   17857 		    break;
   17858 		case XML_SCHEMAS_FACET_COLLAPSE:
   17859 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
   17860 		    break;
   17861 		default:
   17862 		    return (-1);
   17863 		}
   17864 		return (0);
   17865 	    }
   17866 	}
   17867     }
   17868     /*
   17869     * For all atomic datatypes other than string (and types derived
   17870     * by restriction from it) the value of whiteSpace is fixed to
   17871     * collapse
   17872     */
   17873     {
   17874 	xmlSchemaTypePtr anc;
   17875 
   17876 	for (anc = type->baseType; anc != NULL &&
   17877 		anc->builtInType != XML_SCHEMAS_ANYTYPE;
   17878 		anc = anc->baseType) {
   17879 
   17880 	    if (anc->type == XML_SCHEMA_TYPE_BASIC) {
   17881 		if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
   17882 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
   17883 
   17884 		} else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
   17885 		    (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
   17886 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
   17887 
   17888 		} else
   17889 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
   17890 		break;
   17891 	    }
   17892 	}
   17893     }
   17894     return (0);
   17895 }
   17896 
   17897 static int
   17898 xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
   17899 			  xmlSchemaTypePtr type)
   17900 {
   17901     if (type->type != XML_SCHEMA_TYPE_SIMPLE)
   17902 	return(0);
   17903     if (! WXS_IS_TYPE_NOT_FIXED_1(type))
   17904 	return(0);
   17905     type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
   17906 
   17907     if (WXS_IS_LIST(type)) {
   17908 	/*
   17909 	* Corresponds to <simpleType><list>...
   17910 	*/
   17911 	if (type->subtypes == NULL) {
   17912 	    /*
   17913 	    * This one is really needed, so get out.
   17914 	    */
   17915 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
   17916 		"list type has no item-type assigned");
   17917 	    return(-1);
   17918 	}
   17919     } else if (WXS_IS_UNION(type)) {
   17920 	/*
   17921 	* Corresponds to <simpleType><union>...
   17922 	*/
   17923 	if (type->memberTypes == NULL) {
   17924 	    /*
   17925 	    * This one is really needed, so get out.
   17926 	    */
   17927 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
   17928 		"union type has no member-types assigned");
   17929 	    return(-1);
   17930 	}
   17931     } else {
   17932 	/*
   17933 	* Corresponds to <simpleType><restriction>...
   17934 	*/
   17935 	if (type->baseType == NULL) {
   17936 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
   17937 		"type has no base-type assigned");
   17938 	    return(-1);
   17939 	}
   17940 	if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
   17941 	    if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
   17942 		return(-1);
   17943 	/*
   17944 	* Variety
   17945 	* If the <restriction> alternative is chosen, then the
   17946 	* {variety} of the {base type definition}.
   17947 	*/
   17948 	if (WXS_IS_ATOMIC(type->baseType))
   17949 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
   17950 	else if (WXS_IS_LIST(type->baseType)) {
   17951 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
   17952 	    /*
   17953 	    * Inherit the itemType.
   17954 	    */
   17955 	    type->subtypes = type->baseType->subtypes;
   17956 	} else if (WXS_IS_UNION(type->baseType)) {
   17957 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
   17958 	    /*
   17959 	    * NOTE that we won't assign the memberTypes of the base,
   17960 	    * since this will make trouble when freeing them; we will
   17961 	    * use a lookup function to access them instead.
   17962 	    */
   17963 	}
   17964     }
   17965     return(0);
   17966 }
   17967 
   17968 #ifdef DEBUG_TYPE
   17969 static void
   17970 xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
   17971 		       xmlSchemaTypePtr type)
   17972 {
   17973     if (type->node != NULL) {
   17974         xmlGenericError(xmlGenericErrorContext,
   17975                         "Type of %s : %s:%d :", name,
   17976                         type->node->doc->URL,
   17977                         xmlGetLineNo(type->node));
   17978     } else {
   17979         xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
   17980     }
   17981     if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
   17982 	switch (type->contentType) {
   17983 	    case XML_SCHEMA_CONTENT_SIMPLE:
   17984 		xmlGenericError(xmlGenericErrorContext, "simple\n");
   17985 		break;
   17986 	    case XML_SCHEMA_CONTENT_ELEMENTS:
   17987 		xmlGenericError(xmlGenericErrorContext, "elements\n");
   17988 		break;
   17989 	    case XML_SCHEMA_CONTENT_UNKNOWN:
   17990 		xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
   17991 		break;
   17992 	    case XML_SCHEMA_CONTENT_EMPTY:
   17993 		xmlGenericError(xmlGenericErrorContext, "empty\n");
   17994 		break;
   17995 	    case XML_SCHEMA_CONTENT_MIXED:
   17996 		if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
   17997 		    type->subtypes))
   17998 		    xmlGenericError(xmlGenericErrorContext,
   17999 			"mixed as emptiable particle\n");
   18000 		else
   18001 		    xmlGenericError(xmlGenericErrorContext, "mixed\n");
   18002 		break;
   18003 		/* Removed, since not used. */
   18004 		/*
   18005 		case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
   18006 		xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
   18007 		break;
   18008 		*/
   18009 	    case XML_SCHEMA_CONTENT_BASIC:
   18010 		xmlGenericError(xmlGenericErrorContext, "basic\n");
   18011 		break;
   18012 	    default:
   18013 		xmlGenericError(xmlGenericErrorContext,
   18014 		    "not registered !!!\n");
   18015 		break;
   18016 	}
   18017     }
   18018 }
   18019 #endif
   18020 
   18021 /*
   18022 * 3.14.6 Constraints on Simple Type Definition Schema Components
   18023 */
   18024 static int
   18025 xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
   18026 				 xmlSchemaTypePtr type)
   18027 {
   18028     int res, olderrs = pctxt->nberrors;
   18029 
   18030     if (type->type != XML_SCHEMA_TYPE_SIMPLE)
   18031 	return(-1);
   18032 
   18033     if (! WXS_IS_TYPE_NOT_FIXED(type))
   18034 	return(0);
   18035 
   18036     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
   18037     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   18038 
   18039     if (type->baseType == NULL) {
   18040 	PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
   18041 	    "missing baseType");
   18042 	goto exit_failure;
   18043     }
   18044     if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
   18045 	xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
   18046     /*
   18047     * If a member type of a union is a union itself, we need to substitute
   18048     * that member type for its member types.
   18049     * NOTE that this might change in WXS 1.1; i.e. we will keep the union
   18050     * types in WXS 1.1.
   18051     */
   18052     if ((type->memberTypes != NULL) &&
   18053 	(xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
   18054 	return(-1);
   18055     /*
   18056     * SPEC src-simple-type 1
   18057     * "The corresponding simple type definition, if any, must satisfy
   18058     * the conditions set out in Constraints on Simple Type Definition
   18059     * Schema Components (3.14.6)."
   18060     */
   18061     /*
   18062     * Schema Component Constraint: Simple Type Definition Properties Correct
   18063     * (st-props-correct)
   18064     */
   18065     res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
   18066     HFAILURE HERROR
   18067     /*
   18068     * Schema Component Constraint: Derivation Valid (Restriction, Simple)
   18069     * (cos-st-restricts)
   18070     */
   18071     res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
   18072     HFAILURE HERROR
   18073     /*
   18074     * TODO: Removed the error report, since it got annoying to get an
   18075     * extra error report, if anything failed until now.
   18076     * Enable this if needed.
   18077     *
   18078     * xmlSchemaPErr(ctxt, type->node,
   18079     *    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   18080     *    "Simple type '%s' does not satisfy the constraints "
   18081     *    "on simple type definitions.\n",
   18082     *    type->name, NULL);
   18083     */
   18084     /*
   18085     * Schema Component Constraint: Simple Type Restriction (Facets)
   18086     * (st-restrict-facets)
   18087     */
   18088     res = xmlSchemaCheckFacetValues(type, pctxt);
   18089     HFAILURE HERROR
   18090     if ((type->facetSet != NULL) ||
   18091 	(type->baseType->facetSet != NULL)) {
   18092 	res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
   18093 	HFAILURE HERROR
   18094     }
   18095     /*
   18096     * Whitespace value.
   18097     */
   18098     res = xmlSchemaTypeFixupWhitespace(type);
   18099     HFAILURE HERROR
   18100     xmlSchemaTypeFixupOptimFacets(type);
   18101 
   18102 exit_error:
   18103 #ifdef DEBUG_TYPE
   18104     xmlSchemaDebugFixedType(pctxt, type);
   18105 #endif
   18106     if (olderrs != pctxt->nberrors)
   18107 	return(pctxt->err);
   18108     return(0);
   18109 
   18110 exit_failure:
   18111 #ifdef DEBUG_TYPE
   18112     xmlSchemaDebugFixedType(pctxt, type);
   18113 #endif
   18114     return(-1);
   18115 }
   18116 
   18117 static int
   18118 xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
   18119 			  xmlSchemaTypePtr type)
   18120 {
   18121     int res = 0, olderrs = pctxt->nberrors;
   18122     xmlSchemaTypePtr baseType = type->baseType;
   18123 
   18124     if (! WXS_IS_TYPE_NOT_FIXED(type))
   18125 	return(0);
   18126     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
   18127     if (baseType == NULL) {
   18128 	PERROR_INT("xmlSchemaFixupComplexType",
   18129 	    "missing baseType");
   18130 	goto exit_failure;
   18131     }
   18132     /*
   18133     * Fixup the base type.
   18134     */
   18135     if (WXS_IS_TYPE_NOT_FIXED(baseType))
   18136 	xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
   18137     if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
   18138 	/*
   18139 	* Skip fixup if the base type is invalid.
   18140 	* TODO: Generate a warning!
   18141 	*/
   18142 	return(0);
   18143     }
   18144     /*
   18145     * This basically checks if the base type can be derived.
   18146     */
   18147     res = xmlSchemaCheckSRCCT(pctxt, type);
   18148     HFAILURE HERROR
   18149     /*
   18150     * Fixup the content type.
   18151     */
   18152     if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
   18153 	/*
   18154 	* Corresponds to <complexType><simpleContent>...
   18155 	*/
   18156 	if ((WXS_IS_COMPLEX(baseType)) &&
   18157 	    (baseType->contentTypeDef != NULL) &&
   18158 	    (WXS_IS_RESTRICTION(type))) {
   18159 	    xmlSchemaTypePtr contentBase, content;
   18160 #ifdef ENABLE_NAMED_LOCALS
   18161 	    char buf[30];
   18162 	    const xmlChar *tmpname;
   18163 #endif
   18164 	    /*
   18165 	    * SPEC (1) If <restriction> + base type is <complexType>,
   18166 	    * "whose own {content type} is a simple type..."
   18167 	    */
   18168 	    if (type->contentTypeDef != NULL) {
   18169 		/*
   18170 		* SPEC (1.1) "the simple type definition corresponding to the
   18171 		* <simpleType> among the [children] of <restriction> if there
   18172 		* is one;"
   18173 		* Note that this "<simpleType> among the [children]" was put
   18174 		* into ->contentTypeDef during parsing.
   18175 		*/
   18176 		contentBase = type->contentTypeDef;
   18177 		type->contentTypeDef = NULL;
   18178 	    } else {
   18179 		/*
   18180 		* (1.2) "...otherwise (<restriction> has no <simpleType>
   18181 		* among its [children]), the simple type definition which
   18182 		* is the {content type} of the ... base type."
   18183 		*/
   18184 		contentBase = baseType->contentTypeDef;
   18185 	    }
   18186 	    /*
   18187 	    * SPEC
   18188 	    * "... a simple type definition which restricts the simple
   18189 	    * type definition identified in clause 1.1 or clause 1.2
   18190 	    * with a set of facet components"
   18191 	    *
   18192 	    * Create the anonymous simple type, which will be the content
   18193 	    * type of the complex type.
   18194 	    */
   18195 #ifdef ENABLE_NAMED_LOCALS
   18196 	    snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
   18197 	    tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
   18198 	    content = xmlSchemaAddType(pctxt, pctxt->schema,
   18199 		XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
   18200 		type->node, 0);
   18201 #else
   18202 	    content = xmlSchemaAddType(pctxt, pctxt->schema,
   18203 		XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
   18204 		type->node, 0);
   18205 #endif
   18206 	    if (content == NULL)
   18207 		goto exit_failure;
   18208 	    /*
   18209 	    * We will use the same node as for the <complexType>
   18210 	    * to have it somehow anchored in the schema doc.
   18211 	    */
   18212 	    content->type = XML_SCHEMA_TYPE_SIMPLE;
   18213 	    content->baseType = contentBase;
   18214 	    /*
   18215 	    * Move the facets, previously anchored on the
   18216 	    * complexType during parsing.
   18217 	    */
   18218 	    content->facets = type->facets;
   18219 	    type->facets = NULL;
   18220 	    content->facetSet = type->facetSet;
   18221 	    type->facetSet = NULL;
   18222 
   18223 	    type->contentTypeDef = content;
   18224 	    if (WXS_IS_TYPE_NOT_FIXED(contentBase))
   18225 		xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
   18226 	    /*
   18227 	    * Fixup the newly created type. We don't need to check
   18228 	    * for circularity here.
   18229 	    */
   18230 	    res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
   18231 	    HFAILURE HERROR
   18232 	    res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
   18233 	    HFAILURE HERROR
   18234 
   18235 	} else if ((WXS_IS_COMPLEX(baseType)) &&
   18236 	    (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
   18237 	    (WXS_IS_RESTRICTION(type))) {
   18238 	    /*
   18239 	    * SPEC (2) If <restriction> + base is a mixed <complexType> with
   18240 	    * an emptiable particle, then a simple type definition which
   18241 	    * restricts the <restriction>'s <simpleType> child.
   18242 	    */
   18243 	    if ((type->contentTypeDef == NULL) ||
   18244 		(type->contentTypeDef->baseType == NULL)) {
   18245 		/*
   18246 		* TODO: Check if this ever happens.
   18247 		*/
   18248 		xmlSchemaPCustomErr(pctxt,
   18249 		    XML_SCHEMAP_INTERNAL,
   18250 		    WXS_BASIC_CAST type, NULL,
   18251 		    "Internal error: xmlSchemaTypeFixup, "
   18252 		    "complex type '%s': the <simpleContent><restriction> "
   18253 		    "is missing a <simpleType> child, but was not catched "
   18254 		    "by xmlSchemaCheckSRCCT()", type->name);
   18255 		goto exit_failure;
   18256 	    }
   18257 	} else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
   18258 	    /*
   18259 	    * SPEC (3) If <extension> + base is <complexType> with
   18260 	    * <simpleType> content, "...then the {content type} of that
   18261 	    * complex type definition"
   18262 	    */
   18263 	    if (baseType->contentTypeDef == NULL) {
   18264 		/*
   18265 		* TODO: Check if this ever happens. xmlSchemaCheckSRCCT
   18266 		* should have catched this already.
   18267 		*/
   18268 		xmlSchemaPCustomErr(pctxt,
   18269 		    XML_SCHEMAP_INTERNAL,
   18270 		    WXS_BASIC_CAST type, NULL,
   18271 		    "Internal error: xmlSchemaTypeFixup, "
   18272 		    "complex type '%s': the <extension>ed base type is "
   18273 		    "a complex type with no simple content type",
   18274 		    type->name);
   18275 		goto exit_failure;
   18276 	    }
   18277 	    type->contentTypeDef = baseType->contentTypeDef;
   18278 	} else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
   18279 	    /*
   18280 	    * SPEC (4) <extension> + base is <simpleType>
   18281 	    * "... then that simple type definition"
   18282 	    */
   18283 	    type->contentTypeDef = baseType;
   18284 	} else {
   18285 	    /*
   18286 	    * TODO: Check if this ever happens.
   18287 	    */
   18288 	    xmlSchemaPCustomErr(pctxt,
   18289 		XML_SCHEMAP_INTERNAL,
   18290 		WXS_BASIC_CAST type, NULL,
   18291 		"Internal error: xmlSchemaTypeFixup, "
   18292 		"complex type '%s' with <simpleContent>: unhandled "
   18293 		"derivation case", type->name);
   18294 	    goto exit_failure;
   18295 	}
   18296     } else {
   18297 	int dummySequence = 0;
   18298 	xmlSchemaParticlePtr particle =
   18299 	    (xmlSchemaParticlePtr) type->subtypes;
   18300 	/*
   18301 	* Corresponds to <complexType><complexContent>...
   18302 	*
   18303 	* NOTE that the effective mixed was already set during parsing of
   18304 	* <complexType> and <complexContent>; its flag value is
   18305 	* XML_SCHEMAS_TYPE_MIXED.
   18306 	*
   18307 	* Compute the "effective content":
   18308 	* (2.1.1) + (2.1.2) + (2.1.3)
   18309 	*/
   18310 	if ((particle == NULL) ||
   18311 	    ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
   18312 	    ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
   18313 	    (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
   18314 	    ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
   18315 	    (particle->minOccurs == 0))) &&
   18316 	    ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
   18317 	    if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
   18318 		/*
   18319 		* SPEC (2.1.4) "If the effective mixed is true, then
   18320 		* a particle whose properties are as follows:..."
   18321 		*
   18322 		* Empty sequence model group with
   18323 		* minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
   18324 		* NOTE that we sill assign it the <complexType> node to
   18325 		* somehow anchor it in the doc.
   18326 		*/
   18327 		if ((particle == NULL) ||
   18328 		    (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
   18329 		    /*
   18330 		    * Create the particle.
   18331 		    */
   18332 		    particle = xmlSchemaAddParticle(pctxt,
   18333 			type->node, 1, 1);
   18334 		    if (particle == NULL)
   18335 			goto exit_failure;
   18336 		    /*
   18337 		    * Create the model group.
   18338 		    */ /* URGENT TODO: avoid adding to pending items. */
   18339 		    particle->children = (xmlSchemaTreeItemPtr)
   18340 			xmlSchemaAddModelGroup(pctxt, pctxt->schema,
   18341 			XML_SCHEMA_TYPE_SEQUENCE, type->node);
   18342 		    if (particle->children == NULL)
   18343 			goto exit_failure;
   18344 
   18345 		    type->subtypes = (xmlSchemaTypePtr) particle;
   18346 		}
   18347 		dummySequence = 1;
   18348 		type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
   18349 	    } else {
   18350 		/*
   18351 		* SPEC (2.1.5) "otherwise empty"
   18352 		*/
   18353 		type->contentType = XML_SCHEMA_CONTENT_EMPTY;
   18354 	    }
   18355 	} else {
   18356 	    /*
   18357 	    * SPEC (2.2) "otherwise the particle corresponding to the
   18358 	    * <all>, <choice>, <group> or <sequence> among the
   18359 	    * [children]."
   18360 	    */
   18361 	    type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
   18362 	}
   18363 	/*
   18364 	* Compute the "content type".
   18365 	*/
   18366 	if (WXS_IS_RESTRICTION(type)) {
   18367 	    /*
   18368 	    * SPEC (3.1) "If <restriction>..."
   18369 	    * (3.1.1) + (3.1.2) */
   18370 	    if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
   18371 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
   18372 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
   18373 	    }
   18374 	} else {
   18375 	    /*
   18376 	    * SPEC (3.2) "If <extension>..."
   18377 	    */
   18378 	    if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   18379 		/*
   18380 		* SPEC (3.2.1)
   18381 		* "If the effective content is empty, then the
   18382 		*  {content type} of the [...] base ..."
   18383 		*/
   18384 		type->contentType = baseType->contentType;
   18385 		type->subtypes = baseType->subtypes;
   18386 		/*
   18387 		* Fixes bug #347316:
   18388 		* This is the case when the base type has a simple
   18389 		* type definition as content.
   18390 		*/
   18391 		type->contentTypeDef = baseType->contentTypeDef;
   18392 		/*
   18393 		* NOTE that the effective mixed is ignored here.
   18394 		*/
   18395 	    } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   18396 		/*
   18397 		* SPEC (3.2.2)
   18398 		*/
   18399 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
   18400 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
   18401 	    } else {
   18402 		/*
   18403 		* SPEC (3.2.3)
   18404 		*/
   18405 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
   18406 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
   18407 		    /*
   18408 		    * "A model group whose {compositor} is sequence and whose
   18409 		    * {particles} are..."
   18410 		    */
   18411 		if ((WXS_TYPE_PARTICLE(type) != NULL) &&
   18412 		    (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
   18413 		    ((WXS_TYPE_PARTICLE_TERM(type))->type ==
   18414 			XML_SCHEMA_TYPE_ALL))
   18415 		{
   18416 		    /*
   18417 		    * SPEC cos-all-limited (1)
   18418 		    */
   18419 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18420 			/* TODO: error code */
   18421 			XML_SCHEMAP_COS_ALL_LIMITED,
   18422 			WXS_ITEM_NODE(type), NULL,
   18423 			"The type has an 'all' model group in its "
   18424 			"{content type} and thus cannot be derived from "
   18425 			"a non-empty type, since this would produce a "
   18426 			"'sequence' model group containing the 'all' "
   18427 			"model group; 'all' model groups are not "
   18428 			"allowed to appear inside other model groups",
   18429 			NULL, NULL);
   18430 
   18431 		} else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
   18432 		    (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
   18433 		    ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
   18434 			XML_SCHEMA_TYPE_ALL))
   18435 		{
   18436 		    /*
   18437 		    * SPEC cos-all-limited (1)
   18438 		    */
   18439 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18440 			/* TODO: error code */
   18441 			XML_SCHEMAP_COS_ALL_LIMITED,
   18442 			WXS_ITEM_NODE(type), NULL,
   18443 			"A type cannot be derived by extension from a type "
   18444 			"which has an 'all' model group in its "
   18445 			"{content type}, since this would produce a "
   18446 			"'sequence' model group containing the 'all' "
   18447 			"model group; 'all' model groups are not "
   18448 			"allowed to appear inside other model groups",
   18449 			NULL, NULL);
   18450 
   18451 		} else if (! dummySequence) {
   18452 		    xmlSchemaTreeItemPtr effectiveContent =
   18453 			(xmlSchemaTreeItemPtr) type->subtypes;
   18454 		    /*
   18455 		    * Create the particle.
   18456 		    */
   18457 		    particle = xmlSchemaAddParticle(pctxt,
   18458 			type->node, 1, 1);
   18459 		    if (particle == NULL)
   18460 			goto exit_failure;
   18461 		    /*
   18462 		    * Create the "sequence" model group.
   18463 		    */
   18464 		    particle->children = (xmlSchemaTreeItemPtr)
   18465 			xmlSchemaAddModelGroup(pctxt, pctxt->schema,
   18466 			XML_SCHEMA_TYPE_SEQUENCE, type->node);
   18467 		    if (particle->children == NULL)
   18468 			goto exit_failure;
   18469 		    WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
   18470 		    /*
   18471 		    * SPEC "the particle of the {content type} of
   18472 		    * the ... base ..."
   18473 		    * Create a duplicate of the base type's particle
   18474 		    * and assign its "term" to it.
   18475 		    */
   18476 		    particle->children->children =
   18477 			(xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
   18478 			type->node,
   18479 			((xmlSchemaParticlePtr) type->subtypes)->minOccurs,
   18480 			((xmlSchemaParticlePtr) type->subtypes)->maxOccurs);
   18481 		    if (particle->children->children == NULL)
   18482 			goto exit_failure;
   18483 		    particle = (xmlSchemaParticlePtr)
   18484 			particle->children->children;
   18485 		    particle->children =
   18486 			((xmlSchemaParticlePtr) baseType->subtypes)->children;
   18487 		    /*
   18488 		    * SPEC "followed by the effective content."
   18489 		    */
   18490 		    particle->next = effectiveContent;
   18491 		    /*
   18492 		    * This all will result in:
   18493 		    * new-particle
   18494 		    *   --> new-sequence(
   18495 		    *         new-particle
   18496 		    *           --> base-model,
   18497 		    *         this-particle
   18498 		    *	        --> this-model
   18499 		    *	    )
   18500 		    */
   18501 		} else {
   18502 		    /*
   18503 		    * This is the case when there is already an empty
   18504 		    * <sequence> with minOccurs==maxOccurs==1.
   18505 		    * Just add the base types's content type.
   18506 		    * NOTE that, although we miss to add an intermediate
   18507 		    * <sequence>, this should produce no difference to
   18508 		    * neither the regex compilation of the content model,
   18509 		    * nor to the complex type contraints.
   18510 		    */
   18511 		    particle->children->children =
   18512 			(xmlSchemaTreeItemPtr) baseType->subtypes;
   18513 		}
   18514 	    }
   18515 	}
   18516     }
   18517     /*
   18518     * Now fixup attribute uses:
   18519     *   - expand attr. group references
   18520     *     - intersect attribute wildcards
   18521     *   - inherit attribute uses of the base type
   18522     *   - inherit or union attr. wildcards if extending
   18523     *   - apply attr. use prohibitions if restricting
   18524     */
   18525     res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
   18526     HFAILURE HERROR
   18527     /*
   18528     * Apply the complex type component constraints; this will not
   18529     * check attributes, since this is done in
   18530     * xmlSchemaFixupTypeAttributeUses().
   18531     */
   18532     res = xmlSchemaCheckCTComponent(pctxt, type);
   18533     HFAILURE HERROR
   18534 
   18535 #ifdef DEBUG_TYPE
   18536     xmlSchemaDebugFixedType(pctxt, type);
   18537 #endif
   18538     if (olderrs != pctxt->nberrors)
   18539 	return(pctxt->err);
   18540     else
   18541 	return(0);
   18542 
   18543 exit_error:
   18544     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
   18545 #ifdef DEBUG_TYPE
   18546     xmlSchemaDebugFixedType(pctxt, type);
   18547 #endif
   18548     return(pctxt->err);
   18549 
   18550 exit_failure:
   18551     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
   18552 #ifdef DEBUG_TYPE
   18553     xmlSchemaDebugFixedType(pctxt, type);
   18554 #endif
   18555     return(-1);
   18556 }
   18557 
   18558 
   18559 /**
   18560  * xmlSchemaTypeFixup:
   18561  * @typeDecl:  the schema type definition
   18562  * @ctxt:  the schema parser context
   18563  *
   18564  * Fixes the content model of the type.
   18565  * URGENT TODO: We need an int result!
   18566  */
   18567 static int
   18568 xmlSchemaTypeFixup(xmlSchemaTypePtr type,
   18569                    xmlSchemaAbstractCtxtPtr actxt)
   18570 {
   18571     if (type == NULL)
   18572         return(0);
   18573     if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
   18574 	AERROR_INT("xmlSchemaTypeFixup",
   18575 	    "this function needs a parser context");
   18576 	return(-1);
   18577     }
   18578     if (! WXS_IS_TYPE_NOT_FIXED(type))
   18579 	return(0);
   18580     if (type->type == XML_SCHEMA_TYPE_COMPLEX)
   18581 	return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
   18582     else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
   18583 	return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
   18584     return(0);
   18585 }
   18586 
   18587 /**
   18588  * xmlSchemaCheckFacet:
   18589  * @facet:  the facet
   18590  * @typeDecl:  the schema type definition
   18591  * @pctxt:  the schema parser context or NULL
   18592  * @name: the optional name of the type
   18593  *
   18594  * Checks and computes the values of facets.
   18595  *
   18596  * Returns 0 if valid, a positive error code if not valid and
   18597  *         -1 in case of an internal or API error.
   18598  */
   18599 int
   18600 xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
   18601                     xmlSchemaTypePtr typeDecl,
   18602                     xmlSchemaParserCtxtPtr pctxt,
   18603 		    const xmlChar * name ATTRIBUTE_UNUSED)
   18604 {
   18605     int ret = 0, ctxtGiven;
   18606 
   18607     if ((facet == NULL) || (typeDecl == NULL))
   18608         return(-1);
   18609     /*
   18610     * TODO: will the parser context be given if used from
   18611     * the relaxNG module?
   18612     */
   18613     if (pctxt == NULL)
   18614 	ctxtGiven = 0;
   18615     else
   18616 	ctxtGiven = 1;
   18617 
   18618     switch (facet->type) {
   18619         case XML_SCHEMA_FACET_MININCLUSIVE:
   18620         case XML_SCHEMA_FACET_MINEXCLUSIVE:
   18621         case XML_SCHEMA_FACET_MAXINCLUSIVE:
   18622         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   18623 	case XML_SCHEMA_FACET_ENUMERATION: {
   18624                 /*
   18625                  * Okay we need to validate the value
   18626                  * at that point.
   18627                  */
   18628 		xmlSchemaTypePtr base;
   18629 
   18630 		/* 4.3.5.5 Constraints on enumeration Schema Components
   18631 		* Schema Component Constraint: enumeration valid restriction
   18632 		* It is an error if any member of {value} is not in the
   18633 		* value space of {base type definition}.
   18634 		*
   18635 		* minInclusive, maxInclusive, minExclusive, maxExclusive:
   18636 		* The value must be in the
   18637 		* value space of the base type.
   18638 		*/
   18639 		/*
   18640 		* This function is intended to deliver a compiled value
   18641 		* on the facet. In this implementation of XML Schemata the
   18642 		* type holding a facet, won't be a built-in type.
   18643 		* Thus to ensure that other API
   18644 		* calls (relaxng) do work, if the given type is a built-in
   18645 		* type, we will assume that the given built-in type *is
   18646 		* already* the base type.
   18647 		*/
   18648 		if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
   18649 		    base = typeDecl->baseType;
   18650 		    if (base == NULL) {
   18651 			PERROR_INT("xmlSchemaCheckFacet",
   18652 			    "a type user derived type has no base type");
   18653 			return (-1);
   18654 		    }
   18655 		} else
   18656 		    base = typeDecl;
   18657 
   18658 		if (! ctxtGiven) {
   18659 		    /*
   18660 		    * A context is needed if called from RelaxNG.
   18661 		    */
   18662 		    pctxt = xmlSchemaNewParserCtxt("*");
   18663 		    if (pctxt == NULL)
   18664 			return (-1);
   18665 		}
   18666 		/*
   18667 		* NOTE: This call does not check the content nodes,
   18668 		* since they are not available:
   18669 		* facet->node is just the node holding the facet
   18670 		* definition, *not* the attribute holding the *value*
   18671 		* of the facet.
   18672 		*/
   18673 		ret = xmlSchemaVCheckCVCSimpleType(
   18674 		    ACTXT_CAST pctxt, facet->node, base,
   18675 		    facet->value, &(facet->val), 1, 1, 0);
   18676                 if (ret != 0) {
   18677 		    if (ret < 0) {
   18678 			/* No error message for RelaxNG. */
   18679 			if (ctxtGiven) {
   18680 			    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18681 				XML_SCHEMAP_INTERNAL, facet->node, NULL,
   18682 				"Internal error: xmlSchemaCheckFacet, "
   18683 				"failed to validate the value '%s' of the "
   18684 				"facet '%s' against the base type",
   18685 				facet->value, xmlSchemaFacetTypeToString(facet->type));
   18686 			}
   18687 			goto internal_error;
   18688 		    }
   18689 		    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
   18690 		    /* No error message for RelaxNG. */
   18691 		    if (ctxtGiven) {
   18692 			xmlChar *str = NULL;
   18693 
   18694 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18695 			    ret, facet->node, WXS_BASIC_CAST facet,
   18696 			    "The value '%s' of the facet does not validate "
   18697 			    "against the base type '%s'",
   18698 			    facet->value,
   18699 			    xmlSchemaFormatQName(&str,
   18700 				base->targetNamespace, base->name));
   18701 			FREE_AND_NULL(str);
   18702 		    }
   18703 		    goto exit;
   18704                 } else if (facet->val == NULL) {
   18705 		    if (ctxtGiven) {
   18706 			PERROR_INT("xmlSchemaCheckFacet",
   18707 			    "value was not computed");
   18708 		    }
   18709 		    TODO
   18710 		}
   18711                 break;
   18712             }
   18713         case XML_SCHEMA_FACET_PATTERN:
   18714             facet->regexp = xmlRegexpCompile(facet->value);
   18715             if (facet->regexp == NULL) {
   18716 		ret = XML_SCHEMAP_REGEXP_INVALID;
   18717 		/* No error message for RelaxNG. */
   18718 		if (ctxtGiven) {
   18719 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18720 			ret, facet->node, WXS_BASIC_CAST typeDecl,
   18721 			"The value '%s' of the facet 'pattern' is not a "
   18722 			"valid regular expression",
   18723 			facet->value, NULL);
   18724 		}
   18725             }
   18726             break;
   18727         case XML_SCHEMA_FACET_TOTALDIGITS:
   18728         case XML_SCHEMA_FACET_FRACTIONDIGITS:
   18729         case XML_SCHEMA_FACET_LENGTH:
   18730         case XML_SCHEMA_FACET_MAXLENGTH:
   18731         case XML_SCHEMA_FACET_MINLENGTH:
   18732 
   18733 	    if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
   18734 		ret = xmlSchemaValidatePredefinedType(
   18735 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
   18736 		    facet->value, &(facet->val));
   18737 	    } else {
   18738 		ret = xmlSchemaValidatePredefinedType(
   18739 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
   18740 		    facet->value, &(facet->val));
   18741 	    }
   18742 	    if (ret != 0) {
   18743 		if (ret < 0) {
   18744 		    /* No error message for RelaxNG. */
   18745 		    if (ctxtGiven) {
   18746 			PERROR_INT("xmlSchemaCheckFacet",
   18747 			    "validating facet value");
   18748 		    }
   18749 		    goto internal_error;
   18750 		}
   18751 		ret = XML_SCHEMAP_INVALID_FACET_VALUE;
   18752 		/* No error message for RelaxNG. */
   18753 		if (ctxtGiven) {
   18754 		    /* error code */
   18755 		    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   18756 			ret, facet->node, WXS_BASIC_CAST typeDecl,
   18757 			"The value '%s' of the facet '%s' is not a valid '%s'",
   18758 			facet->value,
   18759 			xmlSchemaFacetTypeToString(facet->type),
   18760 			(facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
   18761 			    BAD_CAST "nonNegativeInteger" :
   18762 			    BAD_CAST "positiveInteger",
   18763 			NULL);
   18764 		}
   18765 	    }
   18766 	    break;
   18767 
   18768         case XML_SCHEMA_FACET_WHITESPACE:{
   18769                 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
   18770                     facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
   18771                 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
   18772                     facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
   18773                 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
   18774                     facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
   18775                 } else {
   18776 		    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
   18777                     /* No error message for RelaxNG. */
   18778 		    if (ctxtGiven) {
   18779 			/* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
   18780 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18781 			    ret, facet->node, WXS_BASIC_CAST typeDecl,
   18782 			    "The value '%s' of the facet 'whitespace' is not "
   18783 			    "valid", facet->value, NULL);
   18784                     }
   18785                 }
   18786             }
   18787         default:
   18788             break;
   18789     }
   18790 exit:
   18791     if ((! ctxtGiven) && (pctxt != NULL))
   18792 	xmlSchemaFreeParserCtxt(pctxt);
   18793     return (ret);
   18794 internal_error:
   18795     if ((! ctxtGiven) && (pctxt != NULL))
   18796 	xmlSchemaFreeParserCtxt(pctxt);
   18797     return (-1);
   18798 }
   18799 
   18800 /**
   18801  * xmlSchemaCheckFacetValues:
   18802  * @typeDecl:  the schema type definition
   18803  * @ctxt:  the schema parser context
   18804  *
   18805  * Checks the default values types, especially for facets
   18806  */
   18807 static int
   18808 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
   18809 			  xmlSchemaParserCtxtPtr pctxt)
   18810 {
   18811     int res, olderrs = pctxt->nberrors;
   18812     const xmlChar *name = typeDecl->name;
   18813     /*
   18814     * NOTE: It is intended to use the facets list, instead
   18815     * of facetSet.
   18816     */
   18817     if (typeDecl->facets != NULL) {
   18818 	xmlSchemaFacetPtr facet = typeDecl->facets;
   18819 
   18820 	/*
   18821 	* Temporarily assign the "schema" to the validation context
   18822 	* of the parser context. This is needed for NOTATION validation.
   18823 	*/
   18824 	if (pctxt->vctxt == NULL) {
   18825 	    if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
   18826 		return(-1);
   18827 	}
   18828 	pctxt->vctxt->schema = pctxt->schema;
   18829 	while (facet != NULL) {
   18830 	    res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
   18831 	    HFAILURE
   18832 	    facet = facet->next;
   18833 	}
   18834 	pctxt->vctxt->schema = NULL;
   18835     }
   18836     if (olderrs != pctxt->nberrors)
   18837 	return(pctxt->err);
   18838     return(0);
   18839 exit_failure:
   18840     return(-1);
   18841 }
   18842 
   18843 /**
   18844  * xmlSchemaGetCircModelGrDefRef:
   18845  * @ctxtMGroup: the searched model group
   18846  * @selfMGroup: the second searched model group
   18847  * @particle: the first particle
   18848  *
   18849  * This one is intended to be used by
   18850  * xmlSchemaCheckGroupDefCircular only.
   18851  *
   18852  * Returns the particle with the circular model group definition reference,
   18853  * otherwise NULL.
   18854  */
   18855 static xmlSchemaTreeItemPtr
   18856 xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
   18857 			      xmlSchemaTreeItemPtr particle)
   18858 {
   18859     xmlSchemaTreeItemPtr circ = NULL;
   18860     xmlSchemaTreeItemPtr term;
   18861     xmlSchemaModelGroupDefPtr gdef;
   18862 
   18863     for (; particle != NULL; particle = particle->next) {
   18864 	term = particle->children;
   18865 	if (term == NULL)
   18866 	    continue;
   18867 	switch (term->type) {
   18868 	    case XML_SCHEMA_TYPE_GROUP:
   18869 		gdef = (xmlSchemaModelGroupDefPtr) term;
   18870 		if (gdef == groupDef)
   18871 		    return (particle);
   18872 		/*
   18873 		* Mark this model group definition to avoid infinite
   18874 		* recursion on circular references not yet examined.
   18875 		*/
   18876 		if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
   18877 		    continue;
   18878 		if (gdef->children != NULL) {
   18879 		    gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
   18880 		    circ = xmlSchemaGetCircModelGrDefRef(groupDef,
   18881 			gdef->children->children);
   18882 		    gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
   18883 		    if (circ != NULL)
   18884 			return (circ);
   18885 		}
   18886 		break;
   18887 	    case XML_SCHEMA_TYPE_SEQUENCE:
   18888 	    case XML_SCHEMA_TYPE_CHOICE:
   18889 	    case XML_SCHEMA_TYPE_ALL:
   18890 		circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
   18891 		if (circ != NULL)
   18892 		    return (circ);
   18893 		break;
   18894 	    default:
   18895 		break;
   18896 	}
   18897     }
   18898     return (NULL);
   18899 }
   18900 
   18901 /**
   18902  * xmlSchemaCheckGroupDefCircular:
   18903  * @item:  the model group definition
   18904  * @ctxt:  the parser context
   18905  * @name:  the name
   18906  *
   18907  * Checks for circular references to model group definitions.
   18908  */
   18909 static void
   18910 xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
   18911 			       xmlSchemaParserCtxtPtr ctxt)
   18912 {
   18913     /*
   18914     * Schema Component Constraint: Model Group Correct
   18915     * 2 Circular groups are disallowed. That is, within the {particles}
   18916     * of a group there must not be at any depth a particle whose {term}
   18917     * is the group itself.
   18918     */
   18919     if ((item == NULL) ||
   18920 	(item->type != XML_SCHEMA_TYPE_GROUP) ||
   18921 	(item->children == NULL))
   18922 	return;
   18923     {
   18924 	xmlSchemaTreeItemPtr circ;
   18925 
   18926 	circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
   18927 	if (circ != NULL) {
   18928 	    xmlChar *str = NULL;
   18929 	    /*
   18930 	    * TODO: The error report is not adequate: this constraint
   18931 	    * is defined for model groups but not definitions, but since
   18932 	    * there cannot be any circular model groups without a model group
   18933 	    * definition (if not using a construction API), we check those
   18934 	    * defintions only.
   18935 	    */
   18936 	    xmlSchemaPCustomErr(ctxt,
   18937 		XML_SCHEMAP_MG_PROPS_CORRECT_2,
   18938 		NULL, WXS_ITEM_NODE(circ),
   18939 		"Circular reference to the model group definition '%s' "
   18940 		"defined", xmlSchemaFormatQName(&str,
   18941 		    item->targetNamespace, item->name));
   18942 	    FREE_AND_NULL(str)
   18943 	    /*
   18944 	    * NOTE: We will cut the reference to avoid further
   18945 	    * confusion of the processor. This is a fatal error.
   18946 	    */
   18947 	    circ->children = NULL;
   18948 	}
   18949     }
   18950 }
   18951 
   18952 /**
   18953  * xmlSchemaModelGroupToModelGroupDefFixup:
   18954  * @ctxt:  the parser context
   18955  * @mg:  the model group
   18956  *
   18957  * Assigns the model group of model group definitions to the "term"
   18958  * of the referencing particle.
   18959  * In xmlSchemaResolveModelGroupParticleReferences the model group
   18960  * definitions were assigned to the "term", since needed for the
   18961  * circularity check.
   18962  *
   18963  * Schema Component Constraint:
   18964  *     All Group Limited (cos-all-limited) (1.2)
   18965  */
   18966 static void
   18967 xmlSchemaModelGroupToModelGroupDefFixup(
   18968     xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
   18969     xmlSchemaModelGroupPtr mg)
   18970 {
   18971     xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
   18972 
   18973     while (particle != NULL) {
   18974 	if ((WXS_PARTICLE_TERM(particle) == NULL) ||
   18975 	    ((WXS_PARTICLE_TERM(particle))->type !=
   18976 		XML_SCHEMA_TYPE_GROUP))
   18977 	{
   18978 	    particle = WXS_PTC_CAST particle->next;
   18979 	    continue;
   18980 	}
   18981 	if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
   18982 	    /*
   18983 	    * TODO: Remove the particle.
   18984 	    */
   18985 	    WXS_PARTICLE_TERM(particle) = NULL;
   18986 	    particle = WXS_PTC_CAST particle->next;
   18987 	    continue;
   18988 	}
   18989 	/*
   18990 	* Assign the model group to the {term} of the particle.
   18991 	*/
   18992 	WXS_PARTICLE_TERM(particle) =
   18993 	    WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
   18994 
   18995 	particle = WXS_PTC_CAST particle->next;
   18996     }
   18997 }
   18998 
   18999 /**
   19000  * xmlSchemaCheckAttrGroupCircularRecur:
   19001  * @ctxtGr: the searched attribute group
   19002  * @attr: the current attribute list to be processed
   19003  *
   19004  * This one is intended to be used by
   19005  * xmlSchemaCheckAttrGroupCircular only.
   19006  *
   19007  * Returns the circular attribute grou reference, otherwise NULL.
   19008  */
   19009 static xmlSchemaQNameRefPtr
   19010 xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
   19011 				     xmlSchemaItemListPtr list)
   19012 {
   19013     xmlSchemaAttributeGroupPtr gr;
   19014     xmlSchemaQNameRefPtr ref, circ;
   19015     int i;
   19016     /*
   19017     * We will search for an attribute group reference which
   19018     * references the context attribute group.
   19019     */
   19020     for (i = 0; i < list->nbItems; i++) {
   19021 	ref = list->items[i];
   19022 	if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
   19023 	    (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
   19024 	    (ref->item != NULL))
   19025 	{
   19026 	    gr = WXS_ATTR_GROUP_CAST ref->item;
   19027 	    if (gr == ctxtGr)
   19028 		return(ref);
   19029 	    if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
   19030 		continue;
   19031 	    /*
   19032 	    * Mark as visited to avoid infinite recursion on
   19033 	    * circular references not yet examined.
   19034 	    */
   19035 	    if ((gr->attrUses) &&
   19036 		(gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
   19037 	    {
   19038 		gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
   19039 		circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
   19040 		    (xmlSchemaItemListPtr) gr->attrUses);
   19041 		gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
   19042 		if (circ != NULL)
   19043 		    return (circ);
   19044 	    }
   19045 
   19046 	}
   19047     }
   19048     return (NULL);
   19049 }
   19050 
   19051 /**
   19052  * xmlSchemaCheckAttrGroupCircular:
   19053  * attrGr:  the attribute group definition
   19054  * @ctxt:  the parser context
   19055  * @name:  the name
   19056  *
   19057  * Checks for circular references of attribute groups.
   19058  */
   19059 static int
   19060 xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
   19061 				xmlSchemaParserCtxtPtr ctxt)
   19062 {
   19063     /*
   19064     * Schema Representation Constraint:
   19065     * Attribute Group Definition Representation OK
   19066     * 3 Circular group reference is disallowed outside <redefine>.
   19067     * That is, unless this element information item's parent is
   19068     * <redefine>, then among the [children], if any, there must
   19069     * not be an <attributeGroup> with ref [attribute] which resolves
   19070     * to the component corresponding to this <attributeGroup>. Indirect
   19071     * circularity is also ruled out. That is, when QName resolution
   19072     * (Schema Document) (3.15.3) is applied to a QName arising from
   19073     * any <attributeGroup>s with a ref [attribute] among the [children],
   19074     * it must not be the case that a QName is encountered at any depth
   19075     * which resolves to the component corresponding to this <attributeGroup>.
   19076     */
   19077     if (attrGr->attrUses == NULL)
   19078 	return(0);
   19079     else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
   19080 	return(0);
   19081     else {
   19082 	xmlSchemaQNameRefPtr circ;
   19083 
   19084 	circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
   19085 	    (xmlSchemaItemListPtr) attrGr->attrUses);
   19086 	if (circ != NULL) {
   19087 	    xmlChar *str = NULL;
   19088 	    /*
   19089 	    * TODO: Report the referenced attr group as QName.
   19090 	    */
   19091 	    xmlSchemaPCustomErr(ctxt,
   19092 		XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
   19093 		NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
   19094 		"Circular reference to the attribute group '%s' "
   19095 		"defined", xmlSchemaGetComponentQName(&str, attrGr));
   19096 	    FREE_AND_NULL(str);
   19097 	    /*
   19098 	    * NOTE: We will cut the reference to avoid further
   19099 	    * confusion of the processor.
   19100 	    * BADSPEC TODO: The spec should define how to process in this case.
   19101 	    */
   19102 	    circ->item = NULL;
   19103 	    return(ctxt->err);
   19104 	}
   19105     }
   19106     return(0);
   19107 }
   19108 
   19109 static int
   19110 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
   19111 				  xmlSchemaAttributeGroupPtr attrGr);
   19112 
   19113 /**
   19114  * xmlSchemaExpandAttributeGroupRefs:
   19115  * @pctxt: the parser context
   19116  * @node: the node of the component holding the attribute uses
   19117  * @completeWild: the intersected wildcard to be returned
   19118  * @list: the attribute uses
   19119  *
   19120  * Substitutes contained attribute group references
   19121  * for their attribute uses. Wilcards are intersected.
   19122  * Attribute use prohibitions are removed from the list
   19123  * and returned via the @prohibs list.
   19124  * Pointlessness of attr. prohibs, if a matching attr. decl
   19125  * is existent a well, are checked.
   19126  */
   19127 static int
   19128 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
   19129 				  xmlSchemaBasicItemPtr item,
   19130 				  xmlSchemaWildcardPtr *completeWild,
   19131 				  xmlSchemaItemListPtr list,
   19132 				  xmlSchemaItemListPtr prohibs)
   19133 {
   19134     xmlSchemaAttributeGroupPtr gr;
   19135     xmlSchemaAttributeUsePtr use;
   19136     xmlSchemaItemListPtr sublist;
   19137     int i, j;
   19138     int created = (*completeWild == NULL) ? 0 : 1;
   19139 
   19140     if (prohibs)
   19141 	prohibs->nbItems = 0;
   19142 
   19143     for (i = 0; i < list->nbItems; i++) {
   19144 	use = list->items[i];
   19145 
   19146 	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
   19147 	    if (prohibs == NULL) {
   19148 		PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
   19149 		    "unexpected attr prohibition found");
   19150 		return(-1);
   19151 	    }
   19152 	    /*
   19153 	    * Remove from attribute uses.
   19154 	    */
   19155 	    if (xmlSchemaItemListRemove(list, i) == -1)
   19156 		return(-1);
   19157 	    i--;
   19158 	    /*
   19159 	    * Note that duplicate prohibitions were already
   19160 	    * handled at parsing time.
   19161 	    */
   19162 	    /*
   19163 	    * Add to list of prohibitions.
   19164 	    */
   19165 	    xmlSchemaItemListAddSize(prohibs, 2, use);
   19166 	    continue;
   19167 	}
   19168 	if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
   19169 	    ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
   19170 	{
   19171 	    if ((WXS_QNAME_CAST use)->item == NULL)
   19172 		return(-1);
   19173 	    gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
   19174 	    /*
   19175 	    * Expand the referenced attr. group.
   19176 	    * TODO: remove this, this is done in a previous step, so
   19177 	    * already done here.
   19178 	    */
   19179 	    if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
   19180 		if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
   19181 		    return(-1);
   19182 	    }
   19183 	    /*
   19184 	    * Build the 'complete' wildcard; i.e. intersect multiple
   19185 	    * wildcards.
   19186 	    */
   19187 	    if (gr->attributeWildcard != NULL) {
   19188 		if (*completeWild == NULL) {
   19189 		    *completeWild = gr->attributeWildcard;
   19190 		} else {
   19191 		    if (! created) {
   19192 			xmlSchemaWildcardPtr tmpWild;
   19193 
   19194 			 /*
   19195 			* Copy the first encountered wildcard as context,
   19196 			* except for the annotation.
   19197 			*
   19198 			* Although the complete wildcard might not correspond
   19199 			* to any node in the schema, we will anchor it on
   19200 			* the node of the owner component.
   19201 			*/
   19202 			tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
   19203 			    XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
   19204 			    WXS_ITEM_NODE(item));
   19205 			if (tmpWild == NULL)
   19206 			    return(-1);
   19207 			if (xmlSchemaCloneWildcardNsConstraints(pctxt,
   19208 			    tmpWild, *completeWild) == -1)
   19209 			    return (-1);
   19210 			tmpWild->processContents = (*completeWild)->processContents;
   19211 			*completeWild = tmpWild;
   19212 			created = 1;
   19213 		    }
   19214 
   19215 		    if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
   19216 			gr->attributeWildcard) == -1)
   19217 			return(-1);
   19218 		}
   19219 	    }
   19220 	    /*
   19221 	    * Just remove the reference if the referenced group does not
   19222 	    * contain any attribute uses.
   19223 	    */
   19224 	    sublist = ((xmlSchemaItemListPtr) gr->attrUses);
   19225 	    if ((sublist == NULL) || sublist->nbItems == 0) {
   19226 		if (xmlSchemaItemListRemove(list, i) == -1)
   19227 		    return(-1);
   19228 		i--;
   19229 		continue;
   19230 	    }
   19231 	    /*
   19232 	    * Add the attribute uses.
   19233 	    */
   19234 	    list->items[i] = sublist->items[0];
   19235 	    if (sublist->nbItems != 1) {
   19236 		for (j = 1; j < sublist->nbItems; j++) {
   19237 		    i++;
   19238 		    if (xmlSchemaItemListInsert(list,
   19239 			    sublist->items[j], i) == -1)
   19240 			return(-1);
   19241 		}
   19242 	    }
   19243 	}
   19244 
   19245     }
   19246     /*
   19247     * Handle pointless prohibitions of declared attributes.
   19248     */
   19249     if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
   19250 	xmlSchemaAttributeUseProhibPtr prohib;
   19251 
   19252 	for (i = prohibs->nbItems -1; i >= 0; i--) {
   19253 	    prohib = prohibs->items[i];
   19254 	    for (j = 0; j < list->nbItems; j++) {
   19255 		use = list->items[j];
   19256 
   19257 		if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
   19258 		    (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
   19259 		{
   19260 		    xmlChar *str = NULL;
   19261 
   19262 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   19263 			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   19264 			prohib->node, NULL,
   19265 			"Skipping pointless attribute use prohibition "
   19266 			"'%s', since a corresponding attribute use "
   19267 			"exists already in the type definition",
   19268 			xmlSchemaFormatQName(&str,
   19269 			    prohib->targetNamespace, prohib->name),
   19270 			NULL, NULL);
   19271 		    FREE_AND_NULL(str);
   19272 		    /*
   19273 		    * Remove the prohibition.
   19274 		    */
   19275 		    if (xmlSchemaItemListRemove(prohibs, i) == -1)
   19276 			return(-1);
   19277 		    break;
   19278 		}
   19279 	    }
   19280 	}
   19281     }
   19282     return(0);
   19283 }
   19284 
   19285 /**
   19286  * xmlSchemaAttributeGroupExpandRefs:
   19287  * @pctxt:  the parser context
   19288  * @attrGr:  the attribute group definition
   19289  *
   19290  * Computation of:
   19291  * {attribute uses} property
   19292  * {attribute wildcard} property
   19293  *
   19294  * Substitutes contained attribute group references
   19295  * for their attribute uses. Wilcards are intersected.
   19296  */
   19297 static int
   19298 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
   19299 				  xmlSchemaAttributeGroupPtr attrGr)
   19300 {
   19301     if ((attrGr->attrUses == NULL) ||
   19302 	(attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
   19303 	return(0);
   19304 
   19305     attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
   19306     if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
   19307 	&(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
   19308 	return(-1);
   19309     return(0);
   19310 }
   19311 
   19312 /**
   19313  * xmlSchemaAttributeGroupExpandRefs:
   19314  * @pctxt:  the parser context
   19315  * @attrGr:  the attribute group definition
   19316  *
   19317  * Substitutes contained attribute group references
   19318  * for their attribute uses. Wilcards are intersected.
   19319  *
   19320  * Schema Component Constraint:
   19321  *    Attribute Group Definition Properties Correct (ag-props-correct)
   19322  */
   19323 static int
   19324 xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
   19325 				  xmlSchemaAttributeGroupPtr attrGr)
   19326 {
   19327     /*
   19328     * SPEC ag-props-correct
   19329     * (1) "The values of the properties of an attribute group definition
   19330     * must be as described in the property tableau in The Attribute
   19331     * Group Definition Schema Component (3.6.1), modulo the impact of
   19332     * Missing Sub-components (5.3);"
   19333     */
   19334 
   19335     if ((attrGr->attrUses != NULL) &&
   19336 	(WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
   19337     {
   19338 	xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
   19339 	xmlSchemaAttributeUsePtr use, tmp;
   19340 	int i, j, hasId = 0;
   19341 
   19342 	for (i = uses->nbItems -1; i >= 0; i--) {
   19343 	    use = uses->items[i];
   19344 	    /*
   19345 	    * SPEC ag-props-correct
   19346 	    * (2) "Two distinct members of the {attribute uses} must not have
   19347 	    * {attribute declaration}s both of whose {name}s match and whose
   19348 	    * {target namespace}s are identical."
   19349 	    */
   19350 	    if (i > 0) {
   19351 		for (j = i -1; j >= 0; j--) {
   19352 		    tmp = uses->items[j];
   19353 		    if ((WXS_ATTRUSE_DECL_NAME(use) ==
   19354 			WXS_ATTRUSE_DECL_NAME(tmp)) &&
   19355 			(WXS_ATTRUSE_DECL_TNS(use) ==
   19356 			WXS_ATTRUSE_DECL_TNS(tmp)))
   19357 		    {
   19358 			xmlChar *str = NULL;
   19359 
   19360 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19361 			    XML_SCHEMAP_AG_PROPS_CORRECT,
   19362 			    attrGr->node, WXS_BASIC_CAST attrGr,
   19363 			    "Duplicate %s",
   19364 			    xmlSchemaGetComponentDesignation(&str, use),
   19365 			    NULL);
   19366 			FREE_AND_NULL(str);
   19367 			/*
   19368 			* Remove the duplicate.
   19369 			*/
   19370 			if (xmlSchemaItemListRemove(uses, i) == -1)
   19371 			    return(-1);
   19372 			goto next_use;
   19373 		    }
   19374 		}
   19375 	    }
   19376 	    /*
   19377 	    * SPEC ag-props-correct
   19378 	    * (3) "Two distinct members of the {attribute uses} must not have
   19379 	    * {attribute declaration}s both of whose {type definition}s are or
   19380 	    * are derived from ID."
   19381 	    * TODO: Does 'derived' include member-types of unions?
   19382 	    */
   19383 	    if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
   19384 		if (xmlSchemaIsDerivedFromBuiltInType(
   19385 		    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
   19386 		{
   19387 		    if (hasId) {
   19388 			xmlChar *str = NULL;
   19389 
   19390 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19391 			    XML_SCHEMAP_AG_PROPS_CORRECT,
   19392 			    attrGr->node, WXS_BASIC_CAST attrGr,
   19393 			    "There must not exist more than one attribute "
   19394 			    "declaration of type 'xs:ID' "
   19395 			    "(or derived from 'xs:ID'). The %s violates this "
   19396 			    "constraint",
   19397 			    xmlSchemaGetComponentDesignation(&str, use),
   19398 			    NULL);
   19399 			FREE_AND_NULL(str);
   19400 			if (xmlSchemaItemListRemove(uses, i) == -1)
   19401 			    return(-1);
   19402 		    }
   19403 		    hasId = 1;
   19404 		}
   19405 	    }
   19406 next_use: {}
   19407 	}
   19408     }
   19409     return(0);
   19410 }
   19411 
   19412 /**
   19413  * xmlSchemaResolveAttrGroupReferences:
   19414  * @attrgrpDecl:  the schema attribute definition
   19415  * @ctxt:  the schema parser context
   19416  * @name:  the attribute name
   19417  *
   19418  * Resolves references to attribute group definitions.
   19419  */
   19420 static int
   19421 xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
   19422 				    xmlSchemaParserCtxtPtr ctxt)
   19423 {
   19424     xmlSchemaAttributeGroupPtr group;
   19425 
   19426     if (ref->item != NULL)
   19427         return(0);
   19428     group = xmlSchemaGetAttributeGroup(ctxt->schema,
   19429 	ref->name,
   19430 	ref->targetNamespace);
   19431     if (group == NULL) {
   19432 	xmlSchemaPResCompAttrErr(ctxt,
   19433 	    XML_SCHEMAP_SRC_RESOLVE,
   19434 	    NULL, ref->node,
   19435 	    "ref", ref->name, ref->targetNamespace,
   19436 	    ref->itemType, NULL);
   19437 	return(ctxt->err);
   19438     }
   19439     ref->item = WXS_BASIC_CAST group;
   19440     return(0);
   19441 }
   19442 
   19443 /**
   19444  * xmlSchemaCheckAttrPropsCorrect:
   19445  * @item:  an schema attribute declaration/use
   19446  * @ctxt:  a schema parser context
   19447  * @name:  the name of the attribute
   19448  *
   19449  *
   19450  * Schema Component Constraint:
   19451  *    Attribute Declaration Properties Correct (a-props-correct)
   19452  *
   19453  * Validates the value constraints of an attribute declaration/use.
   19454  * NOTE that this needs the simle type definitions to be already
   19455  *   builded and checked.
   19456  */
   19457 static int
   19458 xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
   19459 			       xmlSchemaAttributePtr attr)
   19460 {
   19461 
   19462     /*
   19463     * SPEC a-props-correct (1)
   19464     * "The values of the properties of an attribute declaration must
   19465     * be as described in the property tableau in The Attribute
   19466     * Declaration Schema Component (3.2.1), modulo the impact of
   19467     * Missing Sub-components (5.3)."
   19468     */
   19469 
   19470     if (WXS_ATTR_TYPEDEF(attr) == NULL)
   19471 	return(0);
   19472 
   19473     if (attr->defValue != NULL) {
   19474 	int ret;
   19475 
   19476 	/*
   19477 	* SPEC a-props-correct (3)
   19478 	* "If the {type definition} is or is derived from ID then there
   19479 	* must not be a {value constraint}."
   19480 	*/
   19481 	if (xmlSchemaIsDerivedFromBuiltInType(
   19482 	    WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
   19483 	{
   19484 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19485 		XML_SCHEMAP_A_PROPS_CORRECT_3,
   19486 		NULL, WXS_BASIC_CAST attr,
   19487 		"Value constraints are not allowed if the type definition "
   19488 		"is or is derived from xs:ID",
   19489 		NULL, NULL);
   19490 	    return(pctxt->err);
   19491 	}
   19492 	/*
   19493 	* SPEC a-props-correct (2)
   19494 	* "if there is a {value constraint}, the canonical lexical
   19495 	* representation of its value must be valid with respect
   19496 	* to the {type definition} as defined in String Valid (3.14.4)."
   19497 	* TODO: Don't care about the *cononical* stuff here, this requirement
   19498 	* will be removed in WXS 1.1 anyway.
   19499 	*/
   19500 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
   19501 	    attr->node, WXS_ATTR_TYPEDEF(attr),
   19502 	    attr->defValue, &(attr->defVal),
   19503 	    1, 1, 0);
   19504 	if (ret != 0) {
   19505 	    if (ret < 0) {
   19506 		PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
   19507 		    "calling xmlSchemaVCheckCVCSimpleType()");
   19508 		return(-1);
   19509 	    }
   19510 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19511 		XML_SCHEMAP_A_PROPS_CORRECT_2,
   19512 		NULL, WXS_BASIC_CAST attr,
   19513 		"The value of the value constraint is not valid",
   19514 		NULL, NULL);
   19515 	    return(pctxt->err);
   19516 	}
   19517     }
   19518 
   19519     return(0);
   19520 }
   19521 
   19522 static xmlSchemaElementPtr
   19523 xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
   19524 				 xmlSchemaElementPtr ancestor)
   19525 {
   19526     xmlSchemaElementPtr ret;
   19527 
   19528     if (WXS_SUBST_HEAD(ancestor) == NULL)
   19529 	return (NULL);
   19530     if (WXS_SUBST_HEAD(ancestor) == elemDecl)
   19531 	return (ancestor);
   19532 
   19533     if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
   19534 	return (NULL);
   19535     WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
   19536     ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
   19537 	WXS_SUBST_HEAD(ancestor));
   19538     WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
   19539 
   19540     return (ret);
   19541 }
   19542 
   19543 /**
   19544  * xmlSchemaCheckElemPropsCorrect:
   19545  * @ctxt:  a schema parser context
   19546  * @decl: the element declaration
   19547  * @name:  the name of the attribute
   19548  *
   19549  * Schema Component Constraint:
   19550  * Element Declaration Properties Correct (e-props-correct)
   19551  *
   19552  * STATUS:
   19553  *   missing: (6)
   19554  */
   19555 static int
   19556 xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
   19557 			       xmlSchemaElementPtr elemDecl)
   19558 {
   19559     int ret = 0;
   19560     xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
   19561     /*
   19562     * SPEC (1) "The values of the properties of an element declaration
   19563     * must be as described in the property tableau in The Element
   19564     * Declaration Schema Component (3.3.1), modulo the impact of Missing
   19565     * Sub-components (5.3)."
   19566     */
   19567     if (WXS_SUBST_HEAD(elemDecl) != NULL) {
   19568 	xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
   19569 
   19570 	xmlSchemaCheckElementDeclComponent(head, pctxt);
   19571 	/*
   19572 	* SPEC (3) "If there is a non-absent {substitution group
   19573 	* affiliation}, then {scope} must be global."
   19574 	*/
   19575 	if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
   19576 	    xmlSchemaPCustomErr(pctxt,
   19577 		XML_SCHEMAP_E_PROPS_CORRECT_3,
   19578 		WXS_BASIC_CAST elemDecl, NULL,
   19579 		"Only global element declarations can have a "
   19580 		"substitution group affiliation", NULL);
   19581 	    ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
   19582 	}
   19583 	/*
   19584 	* TODO: SPEC (6) "Circular substitution groups are disallowed.
   19585 	* That is, it must not be possible to return to an element declaration
   19586 	* by repeatedly following the {substitution group affiliation}
   19587 	* property."
   19588 	*/
   19589 	if (head == elemDecl)
   19590 	    circ = head;
   19591 	else if (WXS_SUBST_HEAD(head) != NULL)
   19592 	    circ = xmlSchemaCheckSubstGroupCircular(head, head);
   19593 	else
   19594 	    circ = NULL;
   19595 	if (circ != NULL) {
   19596 	    xmlChar *strA = NULL, *strB = NULL;
   19597 
   19598 	    xmlSchemaPCustomErrExt(pctxt,
   19599 		XML_SCHEMAP_E_PROPS_CORRECT_6,
   19600 		WXS_BASIC_CAST circ, NULL,
   19601 		"The element declaration '%s' defines a circular "
   19602 		"substitution group to element declaration '%s'",
   19603 		xmlSchemaGetComponentQName(&strA, circ),
   19604 		xmlSchemaGetComponentQName(&strB, head),
   19605 		NULL);
   19606 	    FREE_AND_NULL(strA)
   19607 	    FREE_AND_NULL(strB)
   19608 	    ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
   19609 	}
   19610 	/*
   19611 	* SPEC (4) "If there is a {substitution group affiliation},
   19612 	* the {type definition}
   19613 	* of the element declaration must be validly derived from the {type
   19614 	* definition} of the {substitution group affiliation}, given the value
   19615 	* of the {substitution group exclusions} of the {substitution group
   19616 	* affiliation}, as defined in Type Derivation OK (Complex) (3.4.6)
   19617 	* (if the {type definition} is complex) or as defined in
   19618 	* Type Derivation OK (Simple) (3.14.6) (if the {type definition} is
   19619 	* simple)."
   19620 	*
   19621 	* NOTE: {substitution group exclusions} means the values of the
   19622 	* attribute "final".
   19623 	*/
   19624 
   19625 	if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
   19626 	    int set = 0;
   19627 
   19628 	    if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
   19629 		set |= SUBSET_EXTENSION;
   19630 	    if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
   19631 		set |= SUBSET_RESTRICTION;
   19632 
   19633 	    if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
   19634 		WXS_ELEM_TYPEDEF(head), set) != 0) {
   19635 		xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
   19636 
   19637 		ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
   19638 		xmlSchemaPCustomErrExt(pctxt,
   19639 		    XML_SCHEMAP_E_PROPS_CORRECT_4,
   19640 		    WXS_BASIC_CAST elemDecl, NULL,
   19641 		    "The type definition '%s' was "
   19642 		    "either rejected by the substitution group "
   19643 		    "affiliation '%s', or not validly derived from its type "
   19644 		    "definition '%s'",
   19645 		    xmlSchemaGetComponentQName(&strA, typeDef),
   19646 		    xmlSchemaGetComponentQName(&strB, head),
   19647 		    xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
   19648 		FREE_AND_NULL(strA)
   19649 		FREE_AND_NULL(strB)
   19650 		FREE_AND_NULL(strC)
   19651 	    }
   19652 	}
   19653     }
   19654     /*
   19655     * SPEC (5) "If the {type definition} or {type definition}'s
   19656     * {content type}
   19657     * is or is derived from ID then there must not be a {value constraint}.
   19658     * Note: The use of ID as a type definition for elements goes beyond
   19659     * XML 1.0, and should be avoided if backwards compatibility is desired"
   19660     */
   19661     if ((elemDecl->value != NULL) &&
   19662 	((WXS_IS_SIMPLE(typeDef) &&
   19663 	  xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
   19664 	 (WXS_IS_COMPLEX(typeDef) &&
   19665 	  WXS_HAS_SIMPLE_CONTENT(typeDef) &&
   19666 	  xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
   19667 	    XML_SCHEMAS_ID)))) {
   19668 
   19669 	ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
   19670 	xmlSchemaPCustomErr(pctxt,
   19671 	    XML_SCHEMAP_E_PROPS_CORRECT_5,
   19672 	    WXS_BASIC_CAST elemDecl, NULL,
   19673 	    "The type definition (or type definition's content type) is or "
   19674 	    "is derived from ID; value constraints are not allowed in "
   19675 	    "conjunction with such a type definition", NULL);
   19676     } else if (elemDecl->value != NULL) {
   19677 	int vcret;
   19678 	xmlNodePtr node = NULL;
   19679 
   19680 	/*
   19681 	* SPEC (2) "If there is a {value constraint}, the canonical lexical
   19682 	* representation of its value must be valid with respect to the
   19683 	* {type definition} as defined in Element Default Valid (Immediate)
   19684 	* (3.3.6)."
   19685 	*/
   19686 	if (typeDef == NULL) {
   19687 	    xmlSchemaPErr(pctxt, elemDecl->node,
   19688 		XML_SCHEMAP_INTERNAL,
   19689 		"Internal error: xmlSchemaCheckElemPropsCorrect, "
   19690 		"type is missing... skipping validation of "
   19691 		"the value constraint", NULL, NULL);
   19692 	    return (-1);
   19693 	}
   19694 	if (elemDecl->node != NULL) {
   19695 	    if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
   19696 		node = (xmlNodePtr) xmlHasProp(elemDecl->node,
   19697 		    BAD_CAST "fixed");
   19698 	    else
   19699 		node = (xmlNodePtr) xmlHasProp(elemDecl->node,
   19700 		    BAD_CAST "default");
   19701 	}
   19702 	vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
   19703 	    typeDef, elemDecl->value, &(elemDecl->defVal));
   19704 	if (vcret != 0) {
   19705 	    if (vcret < 0) {
   19706 		PERROR_INT("xmlSchemaElemCheckValConstr",
   19707 		    "failed to validate the value constraint of an "
   19708 		    "element declaration");
   19709 		return (-1);
   19710 	    }
   19711 	    return (vcret);
   19712 	}
   19713     }
   19714 
   19715     return (ret);
   19716 }
   19717 
   19718 /**
   19719  * xmlSchemaCheckElemSubstGroup:
   19720  * @ctxt:  a schema parser context
   19721  * @decl: the element declaration
   19722  * @name:  the name of the attribute
   19723  *
   19724  * Schema Component Constraint:
   19725  * Substitution Group (cos-equiv-class)
   19726  *
   19727  * In Libxml2 the subst. groups will be precomputed, in terms of that
   19728  * a list will be built for each subst. group head, holding all direct
   19729  * referents to this head.
   19730  * NOTE that this function needs:
   19731  *   1. circular subst. groups to be checked beforehand
   19732  *   2. the declaration's type to be derived from the head's type
   19733  *
   19734  * STATUS:
   19735  *
   19736  */
   19737 static void
   19738 xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
   19739 			     xmlSchemaElementPtr elemDecl)
   19740 {
   19741     if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
   19742 	/* SPEC (1) "Its {abstract} is false." */
   19743 	(elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
   19744 	return;
   19745     {
   19746 	xmlSchemaElementPtr head;
   19747 	xmlSchemaTypePtr headType, type;
   19748 	int set, methSet;
   19749 	/*
   19750 	* SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
   19751 	* {disallowed substitutions} as the blocking constraint, as defined in
   19752 	* Substitution Group OK (Transitive) (3.3.6)."
   19753 	*/
   19754 	for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
   19755 	    head = WXS_SUBST_HEAD(head)) {
   19756 	    set = 0;
   19757 	    methSet = 0;
   19758 	    /*
   19759 	    * The blocking constraints.
   19760 	    */
   19761 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
   19762 		continue;
   19763 	    headType = head->subtypes;
   19764 	    type = elemDecl->subtypes;
   19765 	    if (headType == type)
   19766 		goto add_member;
   19767 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
   19768 		set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
   19769 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
   19770 		set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
   19771 	    /*
   19772 	    * SPEC: Substitution Group OK (Transitive) (2.3)
   19773 	    * "The set of all {derivation method}s involved in the
   19774 	    * derivation of D's {type definition} from C's {type definition}
   19775 	    * does not intersect with the union of the blocking constraint,
   19776 	    * C's {prohibited substitutions} (if C is complex, otherwise the
   19777 	    * empty set) and the {prohibited substitutions} (respectively the
   19778 	    * empty set) of any intermediate {type definition}s in the
   19779 	    * derivation of D's {type definition} from C's {type definition}."
   19780 	    */
   19781 	    /*
   19782 	    * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
   19783 	    * subst.head axis, the methSet does not need to be computed for
   19784 	    * the full depth over and over.
   19785 	    */
   19786 	    /*
   19787 	    * The set of all {derivation method}s involved in the derivation
   19788 	    */
   19789 	    while ((type != NULL) && (type != headType)) {
   19790 		if ((WXS_IS_EXTENSION(type)) &&
   19791 		    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
   19792 		    methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
   19793 
   19794 		if (WXS_IS_RESTRICTION(type) &&
   19795 		    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
   19796 		    methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
   19797 
   19798 		type = type->baseType;
   19799 	    }
   19800 	    /*
   19801 	    * The {prohibited substitutions} of all intermediate types +
   19802 	    * the head's type.
   19803 	    */
   19804 	    type = elemDecl->subtypes->baseType;
   19805 	    while (type != NULL) {
   19806 		if (WXS_IS_COMPLEX(type)) {
   19807 		    if ((type->flags &
   19808 			    XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
   19809 			((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
   19810 		    set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
   19811 		    if ((type->flags &
   19812 			    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
   19813 			((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
   19814 		    set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
   19815 		} else
   19816 		    break;
   19817 		if (type == headType)
   19818 		    break;
   19819 		type = type->baseType;
   19820 	    }
   19821 	    if ((set != 0) &&
   19822 		(((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
   19823 		(methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
   19824 		((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
   19825 		(methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
   19826 		continue;
   19827 	    }
   19828 add_member:
   19829 	    xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
   19830 	    if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
   19831 		head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
   19832 	}
   19833     }
   19834 }
   19835 
   19836 #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
   19837 /**
   19838  * xmlSchemaCheckElementDeclComponent
   19839  * @pctxt: the schema parser context
   19840  * @ctxtComponent: the context component (an element declaration)
   19841  * @ctxtParticle: the first particle of the context component
   19842  * @searchParticle: the element declaration particle to be analysed
   19843  *
   19844  * Schema Component Constraint: Element Declarations Consistent
   19845  */
   19846 static int
   19847 xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
   19848 				    xmlSchemaBasicItemPtr ctxtComponent,
   19849 				    xmlSchemaParticlePtr ctxtParticle,
   19850 				    xmlSchemaParticlePtr searchParticle,
   19851 				    xmlSchemaParticlePtr curParticle,
   19852 				    int search)
   19853 {
   19854     return(0);
   19855 
   19856     int ret = 0;
   19857     xmlSchemaParticlePtr cur = curParticle;
   19858     if (curParticle == NULL) {
   19859 	return(0);
   19860     }
   19861     if (WXS_PARTICLE_TERM(curParticle) == NULL) {
   19862 	/*
   19863 	* Just return in this case. A missing "term" of the particle
   19864 	* might arise due to an invalid "term" component.
   19865 	*/
   19866 	return(0);
   19867     }
   19868     while (cur != NULL) {
   19869 	switch (WXS_PARTICLE_TERM(cur)->type) {
   19870 	    case XML_SCHEMA_TYPE_ANY:
   19871 		break;
   19872 	    case XML_SCHEMA_TYPE_ELEMENT:
   19873 		if (search == 0) {
   19874 		    ret = xmlSchemaCheckElementDeclConsistent(pctxt,
   19875 			ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
   19876 		    if (ret != 0)
   19877 			return(ret);
   19878 		} else {
   19879 		    xmlSchemaElementPtr elem =
   19880 			WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
   19881 		    /*
   19882 		    * SPEC Element Declarations Consistent:
   19883 		    * "If the {particles} contains, either directly,
   19884 		    * indirectly (that is, within the {particles} of a
   19885 		    * contained model group, recursively) or implicitly
   19886 		    * two or more element declaration particles with
   19887 		    * the same {name} and {target namespace}, then
   19888 		    * all their type definitions must be the same
   19889 		    * top-level definition [...]"
   19890 		    */
   19891 		    if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
   19892 			    WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
   19893 			xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
   19894 			    WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
   19895 		    {
   19896 			xmlChar *strA = NULL, *strB = NULL;
   19897 
   19898 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19899 			    /* TODO: error code */
   19900 			    XML_SCHEMAP_COS_NONAMBIG,
   19901 			    WXS_ITEM_NODE(cur), NULL,
   19902 			    "In the content model of %s, there are multiple "
   19903 			    "element declarations for '%s' with different "
   19904 			    "type definitions",
   19905 			    xmlSchemaGetComponentDesignation(&strA,
   19906 				ctxtComponent),
   19907 			    xmlSchemaFormatQName(&strB,
   19908 				WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
   19909 				WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
   19910 			FREE_AND_NULL(strA);
   19911 			FREE_AND_NULL(strB);
   19912 			return(XML_SCHEMAP_COS_NONAMBIG);
   19913 		    }
   19914 		}
   19915 		break;
   19916 	    case XML_SCHEMA_TYPE_SEQUENCE: {
   19917 		break;
   19918 		}
   19919 	    case XML_SCHEMA_TYPE_CHOICE:{
   19920 		/*
   19921 		xmlSchemaTreeItemPtr sub;
   19922 
   19923 		sub = WXS_PARTICLE_TERM(particle)->children;  (xmlSchemaParticlePtr)
   19924 		while (sub != NULL) {
   19925 		    ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
   19926 			ctxtParticle, ctxtElem);
   19927 		    if (ret != 0)
   19928 			return(ret);
   19929 		    sub = sub->next;
   19930 		}
   19931 		*/
   19932 		break;
   19933 		}
   19934 	    case XML_SCHEMA_TYPE_ALL:
   19935 		break;
   19936 	    case XML_SCHEMA_TYPE_GROUP:
   19937 		break;
   19938 	    default:
   19939 		xmlSchemaInternalErr2(ACTXT_CAST pctxt,
   19940 		    "xmlSchemaCheckElementDeclConsistent",
   19941 		    "found unexpected term of type '%s' in content model",
   19942 		    WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
   19943 		return(-1);
   19944 	}
   19945 	cur = (xmlSchemaParticlePtr) cur->next;
   19946     }
   19947 
   19948 exit:
   19949     return(ret);
   19950 }
   19951 #endif
   19952 
   19953 /**
   19954  * xmlSchemaCheckElementDeclComponent
   19955  * @item:  an schema element declaration/particle
   19956  * @ctxt:  a schema parser context
   19957  * @name:  the name of the attribute
   19958  *
   19959  * Validates the value constraints of an element declaration.
   19960  * Adds substitution group members.
   19961  */
   19962 static void
   19963 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
   19964 				   xmlSchemaParserCtxtPtr ctxt)
   19965 {
   19966     if (elemDecl == NULL)
   19967 	return;
   19968     if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
   19969 	return;
   19970     elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
   19971     if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
   19972 	/*
   19973 	* Adds substitution group members.
   19974 	*/
   19975 	xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
   19976     }
   19977 }
   19978 
   19979 /**
   19980  * xmlSchemaResolveModelGroupParticleReferences:
   19981  * @particle:  a particle component
   19982  * @ctxt:  a parser context
   19983  *
   19984  * Resolves references of a model group's {particles} to
   19985  * model group definitions and to element declarations.
   19986  */
   19987 static void
   19988 xmlSchemaResolveModelGroupParticleReferences(
   19989     xmlSchemaParserCtxtPtr ctxt,
   19990     xmlSchemaModelGroupPtr mg)
   19991 {
   19992     xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
   19993     xmlSchemaQNameRefPtr ref;
   19994     xmlSchemaBasicItemPtr refItem;
   19995 
   19996     /*
   19997     * URGENT TODO: Test this.
   19998     */
   19999     while (particle != NULL) {
   20000 	if ((WXS_PARTICLE_TERM(particle) == NULL) ||
   20001 	    ((WXS_PARTICLE_TERM(particle))->type !=
   20002 		XML_SCHEMA_EXTRA_QNAMEREF))
   20003 	{
   20004 	    goto next_particle;
   20005 	}
   20006 	ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
   20007 	/*
   20008 	* Resolve the reference.
   20009 	* NULL the {term} by default.
   20010 	*/
   20011 	particle->children = NULL;
   20012 
   20013 	refItem = xmlSchemaGetNamedComponent(ctxt->schema,
   20014 	    ref->itemType, ref->name, ref->targetNamespace);
   20015 	if (refItem == NULL) {
   20016 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
   20017 		NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
   20018 		ref->targetNamespace, ref->itemType, NULL);
   20019 	    /* TODO: remove the particle. */
   20020 	    goto next_particle;
   20021 	}
   20022 	if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
   20023 	    if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
   20024 		/* TODO: remove the particle. */
   20025 		goto next_particle;
   20026 	    /*
   20027 	    * NOTE that we will assign the model group definition
   20028 	    * itself to the "term" of the particle. This will ease
   20029 	    * the check for circular model group definitions. After
   20030 	    * that the "term" will be assigned the model group of the
   20031 	    * model group definition.
   20032 	    */
   20033 	    if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
   20034 		    XML_SCHEMA_TYPE_ALL) {
   20035 		/*
   20036 		* SPEC cos-all-limited (1)
   20037 		* SPEC cos-all-limited (1.2)
   20038 		* "It appears only as the value of one or both of the
   20039 		* following properties:"
   20040 		* (1.1) "the {model group} property of a model group
   20041 		*        definition."
   20042 		* (1.2) "the {term} property of a particle [... of] the "
   20043 		* {content type} of a complex type definition."
   20044 		*/
   20045 		xmlSchemaCustomErr(ACTXT_CAST ctxt,
   20046 		    /* TODO: error code */
   20047 		    XML_SCHEMAP_COS_ALL_LIMITED,
   20048 		    WXS_ITEM_NODE(particle), NULL,
   20049 		    "A model group definition is referenced, but "
   20050 		    "it contains an 'all' model group, which "
   20051 		    "cannot be contained by model groups",
   20052 		    NULL, NULL);
   20053 		/* TODO: remove the particle. */
   20054 		goto next_particle;
   20055 	    }
   20056 	    particle->children = (xmlSchemaTreeItemPtr) refItem;
   20057 	} else {
   20058 	    /*
   20059 	    * TODO: Are referenced element declarations the only
   20060 	    * other components we expect here?
   20061 	    */
   20062 	    particle->children = (xmlSchemaTreeItemPtr) refItem;
   20063 	}
   20064 next_particle:
   20065 	particle = WXS_PTC_CAST particle->next;
   20066     }
   20067 }
   20068 
   20069 static int
   20070 xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
   20071 		       xmlSchemaValPtr y)
   20072 {
   20073     xmlSchemaTypePtr tx, ty, ptx, pty;
   20074     int ret;
   20075 
   20076     while (x != NULL) {
   20077 	/* Same types. */
   20078 	tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
   20079 	ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
   20080 	ptx = xmlSchemaGetPrimitiveType(tx);
   20081 	pty = xmlSchemaGetPrimitiveType(ty);
   20082 	/*
   20083 	* (1) if a datatype T' is derived by restriction from an
   20084 	* atomic datatype T then the value space of T' is a subset of
   20085 	* the value space of T. */
   20086 	/*
   20087 	* (2) if datatypes T' and T'' are derived by restriction
   20088 	* from a common atomic ancestor T then the value spaces of T'
   20089 	* and T'' may overlap.
   20090 	*/
   20091 	if (ptx != pty)
   20092 	    return(0);
   20093 	/*
   20094 	* We assume computed values to be normalized, so do a fast
   20095 	* string comparison for string based types.
   20096 	*/
   20097 	if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
   20098 	    WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
   20099 	    if (! xmlStrEqual(
   20100 		xmlSchemaValueGetAsString(x),
   20101 		xmlSchemaValueGetAsString(y)))
   20102 		return (0);
   20103 	} else {
   20104 	    ret = xmlSchemaCompareValuesWhtsp(
   20105 		x, XML_SCHEMA_WHITESPACE_PRESERVE,
   20106 		y, XML_SCHEMA_WHITESPACE_PRESERVE);
   20107 	    if (ret == -2)
   20108 		return(-1);
   20109 	    if (ret != 0)
   20110 		return(0);
   20111 	}
   20112 	/*
   20113 	* Lists.
   20114 	*/
   20115 	x = xmlSchemaValueGetNext(x);
   20116 	if (x != NULL) {
   20117 	    y = xmlSchemaValueGetNext(y);
   20118 	    if (y == NULL)
   20119 		return (0);
   20120 	} else if (xmlSchemaValueGetNext(y) != NULL)
   20121 	    return (0);
   20122 	else
   20123 	    return (1);
   20124     }
   20125     return (0);
   20126 }
   20127 
   20128 /**
   20129  * xmlSchemaResolveAttrUseReferences:
   20130  * @item:  an attribute use
   20131  * @ctxt:  a parser context
   20132  *
   20133  * Resolves the referenced attribute declaration.
   20134  */
   20135 static int
   20136 xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
   20137 				  xmlSchemaParserCtxtPtr ctxt)
   20138 {
   20139     if ((ctxt == NULL) || (ause == NULL))
   20140 	return(-1);
   20141     if ((ause->attrDecl == NULL) ||
   20142 	(ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
   20143 	return(0);
   20144 
   20145     {
   20146 	xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
   20147 
   20148 	/*
   20149 	* TODO: Evaluate, what errors could occur if the declaration is not
   20150 	* found.
   20151 	*/
   20152 	ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
   20153 	    ref->name, ref->targetNamespace);
   20154         if (ause->attrDecl == NULL) {
   20155 	    xmlSchemaPResCompAttrErr(ctxt,
   20156 	    	XML_SCHEMAP_SRC_RESOLVE,
   20157 		WXS_BASIC_CAST ause, ause->node,
   20158 		"ref", ref->name, ref->targetNamespace,
   20159 		XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
   20160             return(ctxt->err);;
   20161         }
   20162     }
   20163     return(0);
   20164 }
   20165 
   20166 /**
   20167  * xmlSchemaCheckAttrUsePropsCorrect:
   20168  * @ctxt:  a parser context
   20169  * @use:  an attribute use
   20170  *
   20171  * Schema Component Constraint:
   20172  * Attribute Use Correct (au-props-correct)
   20173  *
   20174  */
   20175 static int
   20176 xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
   20177 			     xmlSchemaAttributeUsePtr use)
   20178 {
   20179     if ((ctxt == NULL) || (use == NULL))
   20180 	return(-1);
   20181     if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
   20182 	((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
   20183 	return(0);
   20184 
   20185     /*
   20186     * SPEC au-props-correct (1)
   20187     * "The values of the properties of an attribute use must be as
   20188     * described in the property tableau in The Attribute Use Schema
   20189     * Component (3.5.1), modulo the impact of Missing
   20190     * Sub-components (5.3)."
   20191     */
   20192 
   20193     if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
   20194 	((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
   20195         ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
   20196     {
   20197 	xmlSchemaPCustomErr(ctxt,
   20198 	    XML_SCHEMAP_AU_PROPS_CORRECT_2,
   20199 	    WXS_BASIC_CAST use, NULL,
   20200 	    "The attribute declaration has a 'fixed' value constraint "
   20201 	    ", thus the attribute use must also have a 'fixed' value "
   20202 	    "constraint",
   20203 	    NULL);
   20204 	return(ctxt->err);
   20205     }
   20206     /*
   20207     * Compute and check the value constraint's value.
   20208     */
   20209     if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
   20210 	int ret;
   20211 	/*
   20212 	* TODO: The spec seems to be missing a check of the
   20213 	* value constraint of the attribute use. We will do it here.
   20214 	*/
   20215 	/*
   20216 	* SPEC a-props-correct (3)
   20217 	*/
   20218 	if (xmlSchemaIsDerivedFromBuiltInType(
   20219 	    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
   20220 	{
   20221 	    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   20222 		XML_SCHEMAP_AU_PROPS_CORRECT,
   20223 		NULL, WXS_BASIC_CAST use,
   20224 		"Value constraints are not allowed if the type definition "
   20225 		"is or is derived from xs:ID",
   20226 		NULL, NULL);
   20227 	    return(ctxt->err);
   20228 	}
   20229 
   20230 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
   20231 	    use->node, WXS_ATTRUSE_TYPEDEF(use),
   20232 	    use->defValue, &(use->defVal),
   20233 	    1, 1, 0);
   20234 	if (ret != 0) {
   20235 	    if (ret < 0) {
   20236 		PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
   20237 		    "calling xmlSchemaVCheckCVCSimpleType()");
   20238 		return(-1);
   20239 	    }
   20240 	    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   20241 		XML_SCHEMAP_AU_PROPS_CORRECT,
   20242 		NULL, WXS_BASIC_CAST use,
   20243 		"The value of the value constraint is not valid",
   20244 		NULL, NULL);
   20245 	    return(ctxt->err);
   20246 	}
   20247     }
   20248     /*
   20249     * SPEC au-props-correct (2)
   20250     * "If the {attribute declaration} has a fixed
   20251     * {value constraint}, then if the attribute use itself has a
   20252     * {value constraint}, it must also be fixed and its value must match
   20253     * that of the {attribute declaration}'s {value constraint}."
   20254     */
   20255     if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
   20256 	(((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
   20257     {
   20258 	if (! xmlSchemaAreValuesEqual(use->defVal,
   20259 		(WXS_ATTRUSE_DECL(use))->defVal))
   20260 	{
   20261 	    xmlSchemaPCustomErr(ctxt,
   20262 		XML_SCHEMAP_AU_PROPS_CORRECT_2,
   20263 		WXS_BASIC_CAST use, NULL,
   20264 		"The 'fixed' value constraint of the attribute use "
   20265 		"must match the attribute declaration's value "
   20266 		"constraint '%s'",
   20267 		(WXS_ATTRUSE_DECL(use))->defValue);
   20268 	}
   20269 	return(ctxt->err);
   20270     }
   20271     return(0);
   20272 }
   20273 
   20274 
   20275 
   20276 
   20277 /**
   20278  * xmlSchemaResolveAttrTypeReferences:
   20279  * @item:  an attribute declaration
   20280  * @ctxt:  a parser context
   20281  *
   20282  * Resolves the referenced type definition component.
   20283  */
   20284 static int
   20285 xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
   20286 				   xmlSchemaParserCtxtPtr ctxt)
   20287 {
   20288     /*
   20289     * The simple type definition corresponding to the <simpleType> element
   20290     * information item in the [children], if present, otherwise the simple
   20291     * type definition resolved to by the actual value of the type
   20292     * [attribute], if present, otherwise the simple ur-type definition.
   20293     */
   20294     if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
   20295 	return(0);
   20296     item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
   20297     if (item->subtypes != NULL)
   20298         return(0);
   20299     if (item->typeName != NULL) {
   20300         xmlSchemaTypePtr type;
   20301 
   20302 	type = xmlSchemaGetType(ctxt->schema, item->typeName,
   20303 	    item->typeNs);
   20304 	if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
   20305 	    xmlSchemaPResCompAttrErr(ctxt,
   20306 		XML_SCHEMAP_SRC_RESOLVE,
   20307 		WXS_BASIC_CAST item, item->node,
   20308 		"type", item->typeName, item->typeNs,
   20309 		XML_SCHEMA_TYPE_SIMPLE, NULL);
   20310 	    return(ctxt->err);
   20311 	} else
   20312 	    item->subtypes = type;
   20313 
   20314     } else {
   20315 	/*
   20316 	* The type defaults to the xs:anySimpleType.
   20317 	*/
   20318 	item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
   20319     }
   20320     return(0);
   20321 }
   20322 
   20323 /**
   20324  * xmlSchemaResolveIDCKeyReferences:
   20325  * @idc:  the identity-constraint definition
   20326  * @ctxt:  the schema parser context
   20327  * @name:  the attribute name
   20328  *
   20329  * Resolve keyRef references to key/unique IDCs.
   20330  * Schema Component Constraint:
   20331  *   Identity-constraint Definition Properties Correct (c-props-correct)
   20332  */
   20333 static int
   20334 xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
   20335 			  xmlSchemaParserCtxtPtr pctxt)
   20336 {
   20337     if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
   20338         return(0);
   20339     if (idc->ref->name != NULL) {
   20340 	idc->ref->item = (xmlSchemaBasicItemPtr)
   20341 	    xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
   20342 		idc->ref->targetNamespace);
   20343         if (idc->ref->item == NULL) {
   20344 	    /*
   20345 	    * TODO: It is actually not an error to fail to resolve
   20346 	    * at this stage. BUT we need to be that strict!
   20347 	    */
   20348 	    xmlSchemaPResCompAttrErr(pctxt,
   20349 		XML_SCHEMAP_SRC_RESOLVE,
   20350 		WXS_BASIC_CAST idc, idc->node,
   20351 		"refer", idc->ref->name,
   20352 		idc->ref->targetNamespace,
   20353 		XML_SCHEMA_TYPE_IDC_KEY, NULL);
   20354             return(pctxt->err);
   20355 	} else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
   20356 	    /*
   20357 	    * SPEC c-props-correct (1)
   20358 	    */
   20359 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20360 		XML_SCHEMAP_C_PROPS_CORRECT,
   20361 		NULL, WXS_BASIC_CAST idc,
   20362 		"The keyref references a keyref",
   20363 		NULL, NULL);
   20364 	    idc->ref->item = NULL;
   20365 	    return(pctxt->err);
   20366 	} else {
   20367 	    if (idc->nbFields !=
   20368 		((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
   20369 		xmlChar *str = NULL;
   20370 		xmlSchemaIDCPtr refer;
   20371 
   20372 		refer = (xmlSchemaIDCPtr) idc->ref->item;
   20373 		/*
   20374 		* SPEC c-props-correct(2)
   20375 		* "If the {identity-constraint category} is keyref,
   20376 		* the cardinality of the {fields} must equal that of
   20377 		* the {fields} of the {referenced key}.
   20378 		*/
   20379 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20380 		    XML_SCHEMAP_C_PROPS_CORRECT,
   20381 		    NULL, WXS_BASIC_CAST idc,
   20382 		    "The cardinality of the keyref differs from the "
   20383 		    "cardinality of the referenced key/unique '%s'",
   20384 		    xmlSchemaFormatQName(&str, refer->targetNamespace,
   20385 			refer->name),
   20386 		    NULL);
   20387 		FREE_AND_NULL(str)
   20388 		return(pctxt->err);
   20389 	    }
   20390 	}
   20391     }
   20392     return(0);
   20393 }
   20394 
   20395 static int
   20396 xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
   20397 				       xmlSchemaParserCtxtPtr pctxt)
   20398 {
   20399     if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
   20400 	prohib->targetNamespace) == NULL) {
   20401 
   20402 	xmlSchemaPResCompAttrErr(pctxt,
   20403 	    XML_SCHEMAP_SRC_RESOLVE,
   20404 	    NULL, prohib->node,
   20405 	    "ref", prohib->name, prohib->targetNamespace,
   20406 	    XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
   20407 	return(XML_SCHEMAP_SRC_RESOLVE);
   20408     }
   20409     return(0);
   20410 }
   20411 
   20412 #define WXS_REDEFINED_TYPE(c) \
   20413 (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
   20414 
   20415 #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
   20416 (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
   20417 
   20418 #define WXS_REDEFINED_ATTR_GROUP(c) \
   20419 (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
   20420 
   20421 static int
   20422 xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
   20423 {
   20424     int err = 0;
   20425     xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
   20426     xmlSchemaBasicItemPtr prev, item;
   20427     int wasRedefined;
   20428 
   20429     if (redef == NULL)
   20430 	return(0);
   20431 
   20432     do {
   20433 	item = redef->item;
   20434 	/*
   20435 	* First try to locate the redefined component in the
   20436 	* schema graph starting with the redefined schema.
   20437 	* NOTE: According to this schema bug entry:
   20438 	*   http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
   20439 	*   it's not clear if the referenced component needs to originate
   20440 	*   from the <redefine>d schema _document_ or the schema; the latter
   20441 	*   would include all imported and included sub-schemas of the
   20442 	*   <redefine>d schema. Currenlty we latter approach is used.
   20443 	*   SUPPLEMENT: It seems that the WG moves towards the latter
   20444 	*   approach, so we are doing it right.
   20445 	*
   20446 	*/
   20447 	prev = xmlSchemaFindRedefCompInGraph(
   20448 	    redef->targetBucket, item->type,
   20449 	    redef->refName, redef->refTargetNs);
   20450 	if (prev == NULL) {
   20451 	    xmlChar *str = NULL;
   20452 	    xmlNodePtr node;
   20453 
   20454 	    /*
   20455 	    * SPEC src-redefine:
   20456 	    * (6.2.1) "The actual value of its own name attribute plus
   20457 	    * target namespace must successfully resolve to a model
   20458 	    * group definition in I."
   20459 	    * (7.2.1) "The actual value of its own name attribute plus
   20460 	    * target namespace must successfully resolve to an attribute
   20461 	    * group definition in I."
   20462 
   20463 	    *
   20464 	    * Note that, if we are redefining with the use of references
   20465 	    * to components, the spec assumes the src-resolve to be used;
   20466 	    * but this won't assure that we search only *inside* the
   20467 	    * redefined schema.
   20468 	    */
   20469 	    if (redef->reference)
   20470 		node = WXS_ITEM_NODE(redef->reference);
   20471 	    else
   20472 		node = WXS_ITEM_NODE(item);
   20473 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20474 		/*
   20475 		* TODO: error code.
   20476 		* Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
   20477 		* reference kind.
   20478 		*/
   20479 		XML_SCHEMAP_SRC_REDEFINE, node, NULL,
   20480 		"The %s '%s' to be redefined could not be found in "
   20481 		"the redefined schema",
   20482 		WXS_ITEM_TYPE_NAME(item),
   20483 		xmlSchemaFormatQName(&str, redef->refTargetNs,
   20484 		    redef->refName));
   20485 	    FREE_AND_NULL(str);
   20486 	    err = pctxt->err;
   20487 	    redef = redef->next;
   20488 	    continue;
   20489 	}
   20490 	/*
   20491 	* TODO: Obtaining and setting the redefinition state is really
   20492 	* clumsy.
   20493 	*/
   20494 	wasRedefined = 0;
   20495 	switch (item->type) {
   20496 	    case XML_SCHEMA_TYPE_COMPLEX:
   20497 	    case XML_SCHEMA_TYPE_SIMPLE:
   20498 		if ((WXS_TYPE_CAST prev)->flags &
   20499 		    XML_SCHEMAS_TYPE_REDEFINED)
   20500 		{
   20501 		    wasRedefined = 1;
   20502 		    break;
   20503 		}
   20504 		/* Mark it as redefined. */
   20505 		(WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
   20506 		/*
   20507 		* Assign the redefined type to the
   20508 		* base type of the redefining type.
   20509 		* TODO: How
   20510 		*/
   20511 		((xmlSchemaTypePtr) item)->baseType =
   20512 		    (xmlSchemaTypePtr) prev;
   20513 		break;
   20514 	    case XML_SCHEMA_TYPE_GROUP:
   20515 		if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
   20516 		    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
   20517 		{
   20518 		    wasRedefined = 1;
   20519 		    break;
   20520 		}
   20521 		/* Mark it as redefined. */
   20522 		(WXS_MODEL_GROUPDEF_CAST prev)->flags |=
   20523 		    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
   20524 		if (redef->reference != NULL) {
   20525 		    /*
   20526 		    * Overwrite the QName-reference with the
   20527 		    * referenced model group def.
   20528 		    */
   20529 		    (WXS_PTC_CAST redef->reference)->children =
   20530 			WXS_TREE_CAST prev;
   20531 		}
   20532 		redef->target = prev;
   20533 		break;
   20534 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   20535 		if ((WXS_ATTR_GROUP_CAST prev)->flags &
   20536 		    XML_SCHEMAS_ATTRGROUP_REDEFINED)
   20537 		{
   20538 		    wasRedefined = 1;
   20539 		    break;
   20540 		}
   20541 		(WXS_ATTR_GROUP_CAST prev)->flags |=
   20542 		    XML_SCHEMAS_ATTRGROUP_REDEFINED;
   20543 		if (redef->reference != NULL) {
   20544 		    /*
   20545 		    * Assign the redefined attribute group to the
   20546 		    * QName-reference component.
   20547 		    * This is the easy case, since we will just
   20548 		    * expand the redefined group.
   20549 		    */
   20550 		    (WXS_QNAME_CAST redef->reference)->item = prev;
   20551 		    redef->target = NULL;
   20552 		} else {
   20553 		    /*
   20554 		    * This is the complicated case: we need
   20555 		    * to apply src-redefine (7.2.2) at a later
   20556 		    * stage, i.e. when attribute group references
   20557 		    * have beed expanded and simple types have
   20558 		    * beed fixed.
   20559 		    */
   20560 		    redef->target = prev;
   20561 		}
   20562 		break;
   20563 	    default:
   20564 		PERROR_INT("xmlSchemaResolveRedefReferences",
   20565 		    "Unexpected redefined component type");
   20566 		return(-1);
   20567 	}
   20568 	if (wasRedefined) {
   20569 	    xmlChar *str = NULL;
   20570 	    xmlNodePtr node;
   20571 
   20572 	    if (redef->reference)
   20573 		node = WXS_ITEM_NODE(redef->reference);
   20574 	    else
   20575 		node = WXS_ITEM_NODE(redef->item);
   20576 
   20577 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20578 		/* TODO: error code. */
   20579 		XML_SCHEMAP_SRC_REDEFINE,
   20580 		node, NULL,
   20581 		"The referenced %s was already redefined. Multiple "
   20582 		"redefinition of the same component is not supported",
   20583 		xmlSchemaGetComponentDesignation(&str, prev),
   20584 		NULL);
   20585 	    FREE_AND_NULL(str)
   20586 	    err = pctxt->err;
   20587 	    redef = redef->next;
   20588 	    continue;
   20589 	}
   20590 	redef = redef->next;
   20591     } while (redef != NULL);
   20592 
   20593     return(err);
   20594 }
   20595 
   20596 static int
   20597 xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
   20598 {
   20599     int err = 0;
   20600     xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
   20601     xmlSchemaBasicItemPtr item;
   20602 
   20603     if (redef == NULL)
   20604 	return(0);
   20605 
   20606     do {
   20607 	if (redef->target == NULL) {
   20608 	    redef = redef->next;
   20609 	    continue;
   20610 	}
   20611 	item = redef->item;
   20612 
   20613 	switch (item->type) {
   20614 	    case XML_SCHEMA_TYPE_SIMPLE:
   20615 	    case XML_SCHEMA_TYPE_COMPLEX:
   20616 		/*
   20617 		* Since the spec wants the {name} of the redefined
   20618 		* type to be 'absent', we'll NULL it.
   20619 		*/
   20620 		(WXS_TYPE_CAST redef->target)->name = NULL;
   20621 
   20622 		/*
   20623 		* TODO: Seems like there's nothing more to do. The normal
   20624 		* inheritance mechanism is used. But not 100% sure.
   20625 		*/
   20626 		break;
   20627 	    case XML_SCHEMA_TYPE_GROUP:
   20628 		/*
   20629 		* URGENT TODO:
   20630 		* SPEC src-redefine:
   20631 		* (6.2.2) "The {model group} of the model group definition
   20632 		* which corresponds to it per XML Representation of Model
   20633 		* Group Definition Schema Components (3.7.2) must be a
   20634 		* valid restriction of the {model group} of that model
   20635 		* group definition in I, as defined in Particle Valid
   20636 		* (Restriction) (3.9.6)."
   20637 		*/
   20638 		break;
   20639 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   20640 		/*
   20641 		* SPEC src-redefine:
   20642 		* (7.2.2) "The {attribute uses} and {attribute wildcard} of
   20643 		* the attribute group definition which corresponds to it
   20644 		* per XML Representation of Attribute Group Definition Schema
   20645 		* Components (3.6.2) must be valid restrictions of the
   20646 		* {attribute uses} and {attribute wildcard} of that attribute
   20647 		* group definition in I, as defined in clause 2, clause 3 and
   20648 		* clause 4 of Derivation Valid (Restriction, Complex)
   20649 		* (3.4.6) (where references to the base type definition are
   20650 		* understood as references to the attribute group definition
   20651 		* in I)."
   20652 		*/
   20653 		err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
   20654 		    XML_SCHEMA_ACTION_REDEFINE,
   20655 		    item, redef->target,
   20656 		    (WXS_ATTR_GROUP_CAST item)->attrUses,
   20657 		    (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
   20658 		    (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
   20659 		    (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
   20660 		if (err == -1)
   20661 		    return(-1);
   20662 		break;
   20663 	    default:
   20664 		break;
   20665 	}
   20666 	redef = redef->next;
   20667     } while (redef != NULL);
   20668     return(0);
   20669 }
   20670 
   20671 
   20672 static int
   20673 xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
   20674 		       xmlSchemaBucketPtr bucket)
   20675 {
   20676     xmlSchemaBasicItemPtr item;
   20677     int err;
   20678     xmlHashTablePtr *table;
   20679     const xmlChar *name;
   20680     int i;
   20681 
   20682 #define WXS_GET_GLOBAL_HASH(c, slot) { \
   20683     if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
   20684 	table = &(WXS_IMPBUCKET((c))->schema->slot); \
   20685     else \
   20686 	table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
   20687 
   20688     /*
   20689     * Add global components to the schema's hash tables.
   20690     * This is the place where duplicate components will be
   20691     * detected.
   20692     * TODO: I think normally we should support imports of the
   20693     *   same namespace from multiple locations. We don't do currently,
   20694     *   but if we do then according to:
   20695     *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
   20696     *   we would need, if imported directly, to import redefined
   20697     *   components as well to be able to catch clashing components.
   20698     *   (I hope I'll still know what this means after some months :-()
   20699     */
   20700     if (bucket == NULL)
   20701 	return(-1);
   20702     if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
   20703 	return(0);
   20704     bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
   20705 
   20706     for (i = 0; i < bucket->globals->nbItems; i++) {
   20707 	item = bucket->globals->items[i];
   20708 	table = NULL;
   20709 	switch (item->type) {
   20710 	    case XML_SCHEMA_TYPE_COMPLEX:
   20711 	    case XML_SCHEMA_TYPE_SIMPLE:
   20712 		if (WXS_REDEFINED_TYPE(item))
   20713 		    continue;
   20714 		name = (WXS_TYPE_CAST item)->name;
   20715 		WXS_GET_GLOBAL_HASH(bucket, typeDecl)
   20716 		break;
   20717 	    case XML_SCHEMA_TYPE_ELEMENT:
   20718 		name = (WXS_ELEM_CAST item)->name;
   20719 		WXS_GET_GLOBAL_HASH(bucket, elemDecl)
   20720 		break;
   20721 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
   20722 		name = (WXS_ATTR_CAST item)->name;
   20723 		WXS_GET_GLOBAL_HASH(bucket, attrDecl)
   20724 		break;
   20725 	    case XML_SCHEMA_TYPE_GROUP:
   20726 		if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
   20727 		    continue;
   20728 		name = (WXS_MODEL_GROUPDEF_CAST item)->name;
   20729 		WXS_GET_GLOBAL_HASH(bucket, groupDecl)
   20730 		break;
   20731 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   20732 		if (WXS_REDEFINED_ATTR_GROUP(item))
   20733 		    continue;
   20734 		name = (WXS_ATTR_GROUP_CAST item)->name;
   20735 		WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
   20736 		break;
   20737 	    case XML_SCHEMA_TYPE_IDC_KEY:
   20738 	    case XML_SCHEMA_TYPE_IDC_UNIQUE:
   20739 	    case XML_SCHEMA_TYPE_IDC_KEYREF:
   20740 		name = (WXS_IDC_CAST item)->name;
   20741 		WXS_GET_GLOBAL_HASH(bucket, idcDef)
   20742 		break;
   20743 	    case XML_SCHEMA_TYPE_NOTATION:
   20744 		name = ((xmlSchemaNotationPtr) item)->name;
   20745 		WXS_GET_GLOBAL_HASH(bucket, notaDecl)
   20746 		break;
   20747 	    default:
   20748 		PERROR_INT("xmlSchemaAddComponents",
   20749 		    "Unexpected global component type");
   20750 		continue;
   20751 	}
   20752 	if (*table == NULL) {
   20753 	    *table = xmlHashCreateDict(10, pctxt->dict);
   20754 	    if (*table == NULL) {
   20755 		PERROR_INT("xmlSchemaAddComponents",
   20756 		    "failed to create a component hash table");
   20757 		return(-1);
   20758 	    }
   20759 	}
   20760 	err = xmlHashAddEntry(*table, name, item);
   20761 	if (err != 0) {
   20762 	    xmlChar *str = NULL;
   20763 
   20764 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20765 		XML_SCHEMAP_REDEFINED_TYPE,
   20766 		WXS_ITEM_NODE(item),
   20767 		WXS_BASIC_CAST item,
   20768 		"A global %s '%s' does already exist",
   20769 		WXS_ITEM_TYPE_NAME(item),
   20770 		xmlSchemaGetComponentQName(&str, item));
   20771 	    FREE_AND_NULL(str);
   20772 	}
   20773     }
   20774     /*
   20775     * Process imported/included schemas.
   20776     */
   20777     if (bucket->relations != NULL) {
   20778 	xmlSchemaSchemaRelationPtr rel = bucket->relations;
   20779 	do {
   20780 	    if ((rel->bucket != NULL) &&
   20781 		((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
   20782 		if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
   20783 		    return(-1);
   20784 	    }
   20785 	    rel = rel->next;
   20786 	} while (rel != NULL);
   20787     }
   20788     return(0);
   20789 }
   20790 
   20791 static int
   20792 xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
   20793 			 xmlSchemaBucketPtr rootBucket)
   20794 {
   20795     xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
   20796     xmlSchemaTreeItemPtr item, *items;
   20797     int nbItems, i, ret = 0;
   20798     xmlSchemaBucketPtr oldbucket = con->bucket;
   20799     xmlSchemaElementPtr elemDecl;
   20800 
   20801 #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
   20802 
   20803     if ((con->pending == NULL) ||
   20804 	(con->pending->nbItems == 0))
   20805 	return(0);
   20806 
   20807     /*
   20808     * Since xmlSchemaFixupComplexType() will create new particles
   20809     * (local components), and those particle components need a bucket
   20810     * on the constructor, we'll assure here that the constructor has
   20811     * a bucket.
   20812     * TODO: Think about storing locals _only_ on the main bucket.
   20813     */
   20814     if (con->bucket == NULL)
   20815 	con->bucket = rootBucket;
   20816 
   20817     /* TODO:
   20818     * SPEC (src-redefine):
   20819     * (6.2) "If it has no such self-reference, then all of the
   20820     * following must be true:"
   20821 
   20822     * (6.2.2) The {model group} of the model group definition which
   20823     * corresponds to it per XML Representation of Model Group
   20824     * Definition Schema Components (3.7.2) must be a valid
   20825     * restriction of the {model group} of that model group definition
   20826     * in I, as defined in Particle Valid (Restriction) (3.9.6)."
   20827     */
   20828     xmlSchemaCheckSRCRedefineFirst(pctxt);
   20829 
   20830     /*
   20831     * Add global components to the schemata's hash tables.
   20832     */
   20833     xmlSchemaAddComponents(pctxt, rootBucket);
   20834 
   20835     pctxt->ctxtType = NULL;
   20836     items = (xmlSchemaTreeItemPtr *) con->pending->items;
   20837     nbItems = con->pending->nbItems;
   20838     /*
   20839     * Now that we have parsed *all* the schema document(s) and converted
   20840     * them to schema components, we can resolve references, apply component
   20841     * constraints, create the FSA from the content model, etc.
   20842     */
   20843     /*
   20844     * Resolve references of..
   20845     *
   20846     * 1. element declarations:
   20847     *   - the type definition
   20848     *   - the substitution group affiliation
   20849     * 2. simple/complex types:
   20850     *   - the base type definition
   20851     *   - the memberTypes of union types
   20852     *   - the itemType of list types
   20853     * 3. attributes declarations and attribute uses:
   20854     *   - the type definition
   20855     *   - if an attribute use, then the attribute declaration
   20856     * 4. attribute group references:
   20857     *   - the attribute group definition
   20858     * 5. particles:
   20859     *   - the term of the particle (e.g. a model group)
   20860     * 6. IDC key-references:
   20861     *   - the referenced IDC 'key' or 'unique' definition
   20862     * 7. Attribute prohibitions which had a "ref" attribute.
   20863     */
   20864     for (i = 0; i < nbItems; i++) {
   20865 	item = items[i];
   20866 	switch (item->type) {
   20867 	    case XML_SCHEMA_TYPE_ELEMENT:
   20868 		xmlSchemaResolveElementReferences(
   20869 		    (xmlSchemaElementPtr) item, pctxt);
   20870 		FIXHFAILURE;
   20871 		break;
   20872 	    case XML_SCHEMA_TYPE_COMPLEX:
   20873 	    case XML_SCHEMA_TYPE_SIMPLE:
   20874 		xmlSchemaResolveTypeReferences(
   20875 		    (xmlSchemaTypePtr) item, pctxt);
   20876 		FIXHFAILURE;
   20877 		break;
   20878 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
   20879 		xmlSchemaResolveAttrTypeReferences(
   20880 		    (xmlSchemaAttributePtr) item, pctxt);
   20881 		FIXHFAILURE;
   20882 		break;
   20883 	    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   20884 		xmlSchemaResolveAttrUseReferences(
   20885 		    (xmlSchemaAttributeUsePtr) item, pctxt);
   20886 		FIXHFAILURE;
   20887 		break;
   20888 	    case XML_SCHEMA_EXTRA_QNAMEREF:
   20889 		if ((WXS_QNAME_CAST item)->itemType ==
   20890 		    XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
   20891 		{
   20892 		    xmlSchemaResolveAttrGroupReferences(
   20893 			WXS_QNAME_CAST item, pctxt);
   20894 		}
   20895 		FIXHFAILURE;
   20896 		break;
   20897 	    case XML_SCHEMA_TYPE_SEQUENCE:
   20898 	    case XML_SCHEMA_TYPE_CHOICE:
   20899 	    case XML_SCHEMA_TYPE_ALL:
   20900 		xmlSchemaResolveModelGroupParticleReferences(pctxt,
   20901 		    WXS_MODEL_GROUP_CAST item);
   20902 		FIXHFAILURE;
   20903 		break;
   20904 	    case XML_SCHEMA_TYPE_IDC_KEY:
   20905 	    case XML_SCHEMA_TYPE_IDC_UNIQUE:
   20906 	    case XML_SCHEMA_TYPE_IDC_KEYREF:
   20907 		xmlSchemaResolveIDCKeyReferences(
   20908 		    (xmlSchemaIDCPtr) item, pctxt);
   20909 		FIXHFAILURE;
   20910 		break;
   20911 	    case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
   20912 		/*
   20913 		* Handle attribue prohibition which had a
   20914 		* "ref" attribute.
   20915 		*/
   20916 		xmlSchemaResolveAttrUseProhibReferences(
   20917 		    WXS_ATTR_PROHIB_CAST item, pctxt);
   20918 		FIXHFAILURE;
   20919 		break;
   20920 	    default:
   20921 		break;
   20922 	}
   20923     }
   20924     if (pctxt->nberrors != 0)
   20925 	goto exit_error;
   20926 
   20927     /*
   20928     * Now that all references are resolved we
   20929     * can check for circularity of...
   20930     * 1. the base axis of type definitions
   20931     * 2. nested model group definitions
   20932     * 3. nested attribute group definitions
   20933     * TODO: check for circual substitution groups.
   20934     */
   20935     for (i = 0; i < nbItems; i++) {
   20936 	item = items[i];
   20937 	/*
   20938 	* Let's better stop on the first error here.
   20939 	*/
   20940 	switch (item->type) {
   20941 	    case XML_SCHEMA_TYPE_COMPLEX:
   20942 	    case XML_SCHEMA_TYPE_SIMPLE:
   20943 		xmlSchemaCheckTypeDefCircular(
   20944 		    (xmlSchemaTypePtr) item, pctxt);
   20945 		FIXHFAILURE;
   20946 		if (pctxt->nberrors != 0)
   20947 		    goto exit_error;
   20948 		break;
   20949 	    case XML_SCHEMA_TYPE_GROUP:
   20950 		xmlSchemaCheckGroupDefCircular(
   20951 		    (xmlSchemaModelGroupDefPtr) item, pctxt);
   20952 		FIXHFAILURE;
   20953 		if (pctxt->nberrors != 0)
   20954 		    goto exit_error;
   20955 		break;
   20956 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   20957 		xmlSchemaCheckAttrGroupCircular(
   20958 		    (xmlSchemaAttributeGroupPtr) item, pctxt);
   20959 		FIXHFAILURE;
   20960 		if (pctxt->nberrors != 0)
   20961 		    goto exit_error;
   20962 		break;
   20963 	    default:
   20964 		break;
   20965 	}
   20966     }
   20967     if (pctxt->nberrors != 0)
   20968 	goto exit_error;
   20969     /*
   20970     * Model group definition references:
   20971     * Such a reference is reflected by a particle at the component
   20972     * level. Until now the 'term' of such particles pointed
   20973     * to the model group definition; this was done, in order to
   20974     * ease circularity checks. Now we need to set the 'term' of
   20975     * such particles to the model group of the model group definition.
   20976     */
   20977     for (i = 0; i < nbItems; i++) {
   20978 	item = items[i];
   20979 	switch (item->type) {
   20980 	    case XML_SCHEMA_TYPE_SEQUENCE:
   20981 	    case XML_SCHEMA_TYPE_CHOICE:
   20982 		xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
   20983 		    WXS_MODEL_GROUP_CAST item);
   20984 		break;
   20985 	    default:
   20986 		break;
   20987 	}
   20988     }
   20989     if (pctxt->nberrors != 0)
   20990 	goto exit_error;
   20991     /*
   20992     * Expand attribute group references of attribute group definitions.
   20993     */
   20994     for (i = 0; i < nbItems; i++) {
   20995 	item = items[i];
   20996 	switch (item->type) {
   20997             case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   20998 		if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
   20999 		    WXS_ATTR_GROUP_HAS_REFS(item))
   21000 		{
   21001 		    xmlSchemaAttributeGroupExpandRefs(pctxt,
   21002 			WXS_ATTR_GROUP_CAST item);
   21003 		    FIXHFAILURE;
   21004 		}
   21005 		break;
   21006 	    default:
   21007 		break;
   21008 	}
   21009     }
   21010     if (pctxt->nberrors != 0)
   21011 	goto exit_error;
   21012     /*
   21013     * First compute the variety of simple types. This is needed as
   21014     * a seperate step, since otherwise we won't be able to detect
   21015     * circular union types in all cases.
   21016     */
   21017     for (i = 0; i < nbItems; i++) {
   21018 	item = items[i];
   21019 	switch (item->type) {
   21020             case XML_SCHEMA_TYPE_SIMPLE:
   21021 		if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
   21022 		    xmlSchemaFixupSimpleTypeStageOne(pctxt,
   21023 			(xmlSchemaTypePtr) item);
   21024 		    FIXHFAILURE;
   21025 		}
   21026 		break;
   21027 	    default:
   21028 		break;
   21029 	}
   21030     }
   21031     if (pctxt->nberrors != 0)
   21032 	goto exit_error;
   21033     /*
   21034     * Detect circular union types. Note that this needs the variety to
   21035     * be already computed.
   21036     */
   21037     for (i = 0; i < nbItems; i++) {
   21038 	item = items[i];
   21039 	switch (item->type) {
   21040             case XML_SCHEMA_TYPE_SIMPLE:
   21041 		if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
   21042 		    xmlSchemaCheckUnionTypeDefCircular(pctxt,
   21043 			(xmlSchemaTypePtr) item);
   21044 		    FIXHFAILURE;
   21045 		}
   21046 		break;
   21047 	    default:
   21048 		break;
   21049 	}
   21050     }
   21051     if (pctxt->nberrors != 0)
   21052 	goto exit_error;
   21053 
   21054     /*
   21055     * Do the complete type fixup for simple types.
   21056     */
   21057     for (i = 0; i < nbItems; i++) {
   21058 	item = items[i];
   21059 	switch (item->type) {
   21060             case XML_SCHEMA_TYPE_SIMPLE:
   21061 		if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
   21062 		    xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
   21063 		    FIXHFAILURE;
   21064 		}
   21065 		break;
   21066 	    default:
   21067 		break;
   21068 	}
   21069     }
   21070     if (pctxt->nberrors != 0)
   21071 	goto exit_error;
   21072     /*
   21073     * At this point we need build and check all simple types.
   21074     */
   21075     /*
   21076     * Apply contraints for attribute declarations.
   21077     */
   21078     for (i = 0; i < nbItems; i++) {
   21079 	item = items[i];
   21080 	switch (item->type) {
   21081 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
   21082 		xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
   21083 		FIXHFAILURE;
   21084 		break;
   21085 	    default:
   21086 		break;
   21087 	}
   21088     }
   21089     if (pctxt->nberrors != 0)
   21090 	goto exit_error;
   21091     /*
   21092     * Apply constraints for attribute uses.
   21093     */
   21094     for (i = 0; i < nbItems; i++) {
   21095 	item = items[i];
   21096 	switch (item->type) {
   21097 	    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   21098 		if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
   21099 		    xmlSchemaCheckAttrUsePropsCorrect(pctxt,
   21100 			WXS_ATTR_USE_CAST item);
   21101 		    FIXHFAILURE;
   21102 		}
   21103 		break;
   21104 	    default:
   21105 		break;
   21106 	}
   21107     }
   21108     if (pctxt->nberrors != 0)
   21109 	goto exit_error;
   21110 
   21111     /*
   21112     * Apply constraints for attribute group definitions.
   21113     */
   21114     for (i = 0; i < nbItems; i++) {
   21115 	item = items[i];
   21116 	switch (item->type) {
   21117 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   21118 	    if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
   21119 		( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
   21120 	    {
   21121 		xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
   21122 		FIXHFAILURE;
   21123 	    }
   21124 	    break;
   21125 	default:
   21126 	    break;
   21127 	}
   21128     }
   21129     if (pctxt->nberrors != 0)
   21130 	goto exit_error;
   21131 
   21132     /*
   21133     * Apply constraints for redefinitions.
   21134     */
   21135     if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
   21136 	xmlSchemaCheckSRCRedefineSecond(pctxt);
   21137     if (pctxt->nberrors != 0)
   21138 	goto exit_error;
   21139 
   21140     /*
   21141     * Complex types are builded and checked.
   21142     */
   21143     for (i = 0; i < nbItems; i++) {
   21144 	item = con->pending->items[i];
   21145 	switch (item->type) {
   21146 	    case XML_SCHEMA_TYPE_COMPLEX:
   21147 		if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
   21148 		    xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
   21149 		    FIXHFAILURE;
   21150 		}
   21151 		break;
   21152 	    default:
   21153 		break;
   21154 	}
   21155     }
   21156     if (pctxt->nberrors != 0)
   21157 	goto exit_error;
   21158 
   21159     /*
   21160     * The list could have changed, since xmlSchemaFixupComplexType()
   21161     * will create particles and model groups in some cases.
   21162     */
   21163     items = (xmlSchemaTreeItemPtr *) con->pending->items;
   21164     nbItems = con->pending->nbItems;
   21165 
   21166     /*
   21167     * Apply some constraints for element declarations.
   21168     */
   21169     for (i = 0; i < nbItems; i++) {
   21170 	item = items[i];
   21171 	switch (item->type) {
   21172 	    case XML_SCHEMA_TYPE_ELEMENT:
   21173 		elemDecl = (xmlSchemaElementPtr) item;
   21174 
   21175 		if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
   21176 		{
   21177 		    xmlSchemaCheckElementDeclComponent(
   21178 			(xmlSchemaElementPtr) elemDecl, pctxt);
   21179 		    FIXHFAILURE;
   21180 		}
   21181 
   21182 #ifdef WXS_ELEM_DECL_CONS_ENABLED
   21183 		/*
   21184 		* Schema Component Constraint: Element Declarations Consistent
   21185 		* Apply this constraint to local types of element declarations.
   21186 		*/
   21187 		if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
   21188 		    (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
   21189 		    (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
   21190 		{
   21191 		    xmlSchemaCheckElementDeclConsistent(pctxt,
   21192 			WXS_BASIC_CAST elemDecl,
   21193 			WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
   21194 			NULL, NULL, 0);
   21195 		}
   21196 #endif
   21197 		break;
   21198 	    default:
   21199 		break;
   21200 	}
   21201     }
   21202     if (pctxt->nberrors != 0)
   21203 	goto exit_error;
   21204 
   21205     /*
   21206     * Finally we can build the automaton from the content model of
   21207     * complex types.
   21208     */
   21209 
   21210     for (i = 0; i < nbItems; i++) {
   21211 	item = items[i];
   21212 	switch (item->type) {
   21213 	    case XML_SCHEMA_TYPE_COMPLEX:
   21214 		xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
   21215 		/* FIXHFAILURE; */
   21216 		break;
   21217 	    default:
   21218 		break;
   21219 	}
   21220     }
   21221     if (pctxt->nberrors != 0)
   21222 	goto exit_error;
   21223     /*
   21224     * URGENT TODO: cos-element-consistent
   21225     */
   21226     goto exit;
   21227 
   21228 exit_error:
   21229     ret = pctxt->err;
   21230     goto exit;
   21231 
   21232 exit_failure:
   21233     ret = -1;
   21234 
   21235 exit:
   21236     /*
   21237     * Reset the constructor. This is needed for XSI acquisition, since
   21238     * those items will be processed over and over again for every XSI
   21239     * if not cleared here.
   21240     */
   21241     con->bucket = oldbucket;
   21242     con->pending->nbItems = 0;
   21243     if (con->substGroups != NULL) {
   21244 	xmlHashFree(con->substGroups,
   21245 	    (xmlHashDeallocator) xmlSchemaSubstGroupFree);
   21246 	con->substGroups = NULL;
   21247     }
   21248     if (con->redefs != NULL) {
   21249 	xmlSchemaRedefListFree(con->redefs);
   21250 	con->redefs = NULL;
   21251     }
   21252     return(ret);
   21253 }
   21254 /**
   21255  * xmlSchemaParse:
   21256  * @ctxt:  a schema validation context
   21257  *
   21258  * parse a schema definition resource and build an internal
   21259  * XML Shema struture which can be used to validate instances.
   21260  *
   21261  * Returns the internal XML Schema structure built from the resource or
   21262  *         NULL in case of error
   21263  */
   21264 xmlSchemaPtr
   21265 xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
   21266 {
   21267     xmlSchemaPtr mainSchema = NULL;
   21268     xmlSchemaBucketPtr bucket = NULL;
   21269     int res;
   21270 
   21271     /*
   21272     * This one is used if the schema to be parsed was specified via
   21273     * the API; i.e. not automatically by the validated instance document.
   21274     */
   21275 
   21276     xmlSchemaInitTypes();
   21277 
   21278     if (ctxt == NULL)
   21279         return (NULL);
   21280 
   21281     /* TODO: Init the context. Is this all we need?*/
   21282     ctxt->nberrors = 0;
   21283     ctxt->err = 0;
   21284     ctxt->counter = 0;
   21285 
   21286     /* Create the *main* schema. */
   21287     mainSchema = xmlSchemaNewSchema(ctxt);
   21288     if (mainSchema == NULL)
   21289 	goto exit_failure;
   21290     /*
   21291     * Create the schema constructor.
   21292     */
   21293     if (ctxt->constructor == NULL) {
   21294 	ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
   21295 	if (ctxt->constructor == NULL)
   21296 	    return(NULL);
   21297 	/* Take ownership of the constructor to be able to free it. */
   21298 	ctxt->ownsConstructor = 1;
   21299     }
   21300     ctxt->constructor->mainSchema = mainSchema;
   21301     /*
   21302     * Locate and add the schema document.
   21303     */
   21304     res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
   21305 	ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
   21306 	NULL, NULL, &bucket);
   21307     if (res == -1)
   21308 	goto exit_failure;
   21309     if (res != 0)
   21310 	goto exit;
   21311 
   21312     if (bucket == NULL) {
   21313 	/* TODO: Error code, actually we failed to *locate* the schema. */
   21314 	if (ctxt->URL)
   21315 	    xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
   21316 		NULL, NULL,
   21317 		"Failed to locate the main schema resource at '%s'",
   21318 		ctxt->URL, NULL);
   21319 	else
   21320 	    xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
   21321 		NULL, NULL,
   21322 		"Failed to locate the main schema resource",
   21323 		    NULL, NULL);
   21324 	goto exit;
   21325     }
   21326     /* Then do the parsing for good. */
   21327     if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
   21328 	goto exit_failure;
   21329     if (ctxt->nberrors != 0)
   21330 	goto exit;
   21331 
   21332     mainSchema->doc = bucket->doc;
   21333     mainSchema->preserve = ctxt->preserve;
   21334 
   21335     ctxt->schema = mainSchema;
   21336 
   21337     if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
   21338 	goto exit_failure;
   21339 
   21340     /*
   21341     * TODO: This is not nice, since we cannot distinguish from the
   21342     * result if there was an internal error or not.
   21343     */
   21344 exit:
   21345     if (ctxt->nberrors != 0) {
   21346 	if (mainSchema) {
   21347 	    xmlSchemaFree(mainSchema);
   21348 	    mainSchema = NULL;
   21349 	}
   21350 	if (ctxt->constructor) {
   21351 	    xmlSchemaConstructionCtxtFree(ctxt->constructor);
   21352 	    ctxt->constructor = NULL;
   21353 	    ctxt->ownsConstructor = 0;
   21354 	}
   21355     }
   21356     ctxt->schema = NULL;
   21357     return(mainSchema);
   21358 exit_failure:
   21359     /*
   21360     * Quite verbose, but should catch internal errors, which were
   21361     * not communitated.
   21362     */
   21363     if (mainSchema) {
   21364         xmlSchemaFree(mainSchema);
   21365 	mainSchema = NULL;
   21366     }
   21367     if (ctxt->constructor) {
   21368 	xmlSchemaConstructionCtxtFree(ctxt->constructor);
   21369 	ctxt->constructor = NULL;
   21370 	ctxt->ownsConstructor = 0;
   21371     }
   21372     PERROR_INT2("xmlSchemaParse",
   21373 	"An internal error occured");
   21374     ctxt->schema = NULL;
   21375     return(NULL);
   21376 }
   21377 
   21378 /**
   21379  * xmlSchemaSetParserErrors:
   21380  * @ctxt:  a schema validation context
   21381  * @err:  the error callback
   21382  * @warn:  the warning callback
   21383  * @ctx:  contextual data for the callbacks
   21384  *
   21385  * Set the callback functions used to handle errors for a validation context
   21386  */
   21387 void
   21388 xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
   21389                          xmlSchemaValidityErrorFunc err,
   21390                          xmlSchemaValidityWarningFunc warn, void *ctx)
   21391 {
   21392     if (ctxt == NULL)
   21393         return;
   21394     ctxt->error = err;
   21395     ctxt->warning = warn;
   21396     ctxt->errCtxt = ctx;
   21397     if (ctxt->vctxt != NULL)
   21398 	xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
   21399 }
   21400 
   21401 /**
   21402  * xmlSchemaSetParserStructuredErrors:
   21403  * @ctxt:  a schema parser context
   21404  * @serror:  the structured error function
   21405  * @ctx: the functions context
   21406  *
   21407  * Set the structured error callback
   21408  */
   21409 void
   21410 xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
   21411 				   xmlStructuredErrorFunc serror,
   21412 				   void *ctx)
   21413 {
   21414     if (ctxt == NULL)
   21415 	return;
   21416     ctxt->serror = serror;
   21417     ctxt->errCtxt = ctx;
   21418     if (ctxt->vctxt != NULL)
   21419 	xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
   21420 }
   21421 
   21422 /**
   21423  * xmlSchemaGetParserErrors:
   21424  * @ctxt:  a XMl-Schema parser context
   21425  * @err: the error callback result
   21426  * @warn: the warning callback result
   21427  * @ctx: contextual data for the callbacks result
   21428  *
   21429  * Get the callback information used to handle errors for a parser context
   21430  *
   21431  * Returns -1 in case of failure, 0 otherwise
   21432  */
   21433 int
   21434 xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
   21435 			 xmlSchemaValidityErrorFunc * err,
   21436 			 xmlSchemaValidityWarningFunc * warn, void **ctx)
   21437 {
   21438 	if (ctxt == NULL)
   21439 		return(-1);
   21440 	if (err != NULL)
   21441 		*err = ctxt->error;
   21442 	if (warn != NULL)
   21443 		*warn = ctxt->warning;
   21444 	if (ctx != NULL)
   21445 		*ctx = ctxt->errCtxt;
   21446 	return(0);
   21447 }
   21448 
   21449 /**
   21450  * xmlSchemaFacetTypeToString:
   21451  * @type:  the facet type
   21452  *
   21453  * Convert the xmlSchemaTypeType to a char string.
   21454  *
   21455  * Returns the char string representation of the facet type if the
   21456  *     type is a facet and an "Internal Error" string otherwise.
   21457  */
   21458 static const xmlChar *
   21459 xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
   21460 {
   21461     switch (type) {
   21462         case XML_SCHEMA_FACET_PATTERN:
   21463             return (BAD_CAST "pattern");
   21464         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   21465             return (BAD_CAST "maxExclusive");
   21466         case XML_SCHEMA_FACET_MAXINCLUSIVE:
   21467             return (BAD_CAST "maxInclusive");
   21468         case XML_SCHEMA_FACET_MINEXCLUSIVE:
   21469             return (BAD_CAST "minExclusive");
   21470         case XML_SCHEMA_FACET_MININCLUSIVE:
   21471             return (BAD_CAST "minInclusive");
   21472         case XML_SCHEMA_FACET_WHITESPACE:
   21473             return (BAD_CAST "whiteSpace");
   21474         case XML_SCHEMA_FACET_ENUMERATION:
   21475             return (BAD_CAST "enumeration");
   21476         case XML_SCHEMA_FACET_LENGTH:
   21477             return (BAD_CAST "length");
   21478         case XML_SCHEMA_FACET_MAXLENGTH:
   21479             return (BAD_CAST "maxLength");
   21480         case XML_SCHEMA_FACET_MINLENGTH:
   21481             return (BAD_CAST "minLength");
   21482         case XML_SCHEMA_FACET_TOTALDIGITS:
   21483             return (BAD_CAST "totalDigits");
   21484         case XML_SCHEMA_FACET_FRACTIONDIGITS:
   21485             return (BAD_CAST "fractionDigits");
   21486         default:
   21487             break;
   21488     }
   21489     return (BAD_CAST "Internal Error");
   21490 }
   21491 
   21492 static xmlSchemaWhitespaceValueType
   21493 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
   21494 {
   21495     /*
   21496     * The normalization type can be changed only for types which are derived
   21497     * from xsd:string.
   21498     */
   21499     if (type->type == XML_SCHEMA_TYPE_BASIC) {
   21500 	/*
   21501 	* Note that we assume a whitespace of preserve for anySimpleType.
   21502 	*/
   21503 	if ((type->builtInType == XML_SCHEMAS_STRING) ||
   21504 	    (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
   21505 	    return(XML_SCHEMA_WHITESPACE_PRESERVE);
   21506 	else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
   21507 	    return(XML_SCHEMA_WHITESPACE_REPLACE);
   21508 	else {
   21509 	    /*
   21510 	    * For all atomic datatypes other than string (and types derived
   21511 	    * by restriction from it) the value of whiteSpace is fixed to
   21512 	    * collapse
   21513 	    * Note that this includes built-in list datatypes.
   21514 	    */
   21515 	    return(XML_SCHEMA_WHITESPACE_COLLAPSE);
   21516 	}
   21517     } else if (WXS_IS_LIST(type)) {
   21518 	/*
   21519 	* For list types the facet "whiteSpace" is fixed to "collapse".
   21520 	*/
   21521 	return (XML_SCHEMA_WHITESPACE_COLLAPSE);
   21522     } else if (WXS_IS_UNION(type)) {
   21523 	return (XML_SCHEMA_WHITESPACE_UNKNOWN);
   21524     } else if (WXS_IS_ATOMIC(type)) {
   21525 	if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
   21526 	    return (XML_SCHEMA_WHITESPACE_PRESERVE);
   21527 	else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
   21528 	    return (XML_SCHEMA_WHITESPACE_REPLACE);
   21529 	else
   21530 	    return (XML_SCHEMA_WHITESPACE_COLLAPSE);
   21531     }
   21532     return (-1);
   21533 }
   21534 
   21535 /************************************************************************
   21536  * 									*
   21537  * 			Simple type validation				*
   21538  * 									*
   21539  ************************************************************************/
   21540 
   21541 
   21542 /************************************************************************
   21543  * 									*
   21544  * 			DOM Validation code				*
   21545  * 									*
   21546  ************************************************************************/
   21547 
   21548 /**
   21549  * xmlSchemaAssembleByLocation:
   21550  * @pctxt:  a schema parser context
   21551  * @vctxt:  a schema validation context
   21552  * @schema: the existing schema
   21553  * @node: the node that fired the assembling
   21554  * @nsName: the namespace name of the new schema
   21555  * @location: the location of the schema
   21556  *
   21557  * Expands an existing schema by an additional schema.
   21558  *
   21559  * Returns 0 if the new schema is correct, a positive error code
   21560  * number otherwise and -1 in case of an internal or API error.
   21561  */
   21562 static int
   21563 xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
   21564 			    xmlSchemaPtr schema,
   21565 			    xmlNodePtr node,
   21566 			    const xmlChar *nsName,
   21567 			    const xmlChar *location)
   21568 {
   21569     int ret = 0;
   21570     xmlSchemaParserCtxtPtr pctxt;
   21571     xmlSchemaBucketPtr bucket = NULL;
   21572 
   21573     if ((vctxt == NULL) || (schema == NULL))
   21574 	return (-1);
   21575 
   21576     if (vctxt->pctxt == NULL) {
   21577 	VERROR_INT("xmlSchemaAssembleByLocation",
   21578 	    "no parser context available");
   21579 	return(-1);
   21580     }
   21581     pctxt = vctxt->pctxt;
   21582     if (pctxt->constructor == NULL) {
   21583 	PERROR_INT("xmlSchemaAssembleByLocation",
   21584 	    "no constructor");
   21585 	return(-1);
   21586     }
   21587     /*
   21588     * Acquire the schema document.
   21589     */
   21590     location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
   21591 	location, node);
   21592     /*
   21593     * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
   21594     * the process will automatically change this to
   21595     * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
   21596     */
   21597     ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
   21598 	location, NULL, NULL, 0, node, NULL, nsName,
   21599 	&bucket);
   21600     if (ret != 0)
   21601 	return(ret);
   21602     if (bucket == NULL) {
   21603 	/*
   21604 	* Generate a warning that the document could not be located.
   21605 	*/
   21606 	xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
   21607 	    node, NULL,
   21608 	    "The document at location '%s' could not be acquired",
   21609 	    location, NULL, NULL);
   21610 	return(ret);
   21611     }
   21612     /*
   21613     * The first located schema will be handled as if all other
   21614     * schemas imported by XSI were imported by this first schema.
   21615     */
   21616     if ((bucket != NULL) &&
   21617 	(WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
   21618 	WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
   21619     /*
   21620     * TODO: Is this handled like an import? I.e. is it not an error
   21621     * if the schema cannot be located?
   21622     */
   21623     if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
   21624 	return(0);
   21625     /*
   21626     * We will reuse the parser context for every schema imported
   21627     * directly via XSI. So reset the context.
   21628     */
   21629     pctxt->nberrors = 0;
   21630     pctxt->err = 0;
   21631     pctxt->doc = bucket->doc;
   21632 
   21633     ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
   21634     if (ret == -1) {
   21635 	pctxt->doc = NULL;
   21636 	goto exit_failure;
   21637     }
   21638     /* Paranoid error channelling. */
   21639     if ((ret == 0) && (pctxt->nberrors != 0))
   21640 	ret = pctxt->err;
   21641     if (pctxt->nberrors == 0) {
   21642 	/*
   21643 	* Only bother to fixup pending components, if there was
   21644 	* no error yet.
   21645 	* For every XSI acquired schema (and its sub-schemata) we will
   21646 	* fixup the components.
   21647 	*/
   21648 	xmlSchemaFixupComponents(pctxt, bucket);
   21649 	ret = pctxt->err;
   21650 	/*
   21651 	* Not nice, but we need somehow to channel the schema parser
   21652 	* error to the validation context.
   21653 	*/
   21654 	if ((ret != 0) && (vctxt->err == 0))
   21655 	    vctxt->err = ret;
   21656 	vctxt->nberrors += pctxt->nberrors;
   21657     } else {
   21658 	/* Add to validation error sum. */
   21659 	vctxt->nberrors += pctxt->nberrors;
   21660     }
   21661     pctxt->doc = NULL;
   21662     return(ret);
   21663 exit_failure:
   21664     pctxt->doc = NULL;
   21665     return (-1);
   21666 }
   21667 
   21668 static xmlSchemaAttrInfoPtr
   21669 xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
   21670 			 int metaType)
   21671 {
   21672     if (vctxt->nbAttrInfos == 0)
   21673 	return (NULL);
   21674     {
   21675 	int i;
   21676 	xmlSchemaAttrInfoPtr iattr;
   21677 
   21678 	for (i = 0; i < vctxt->nbAttrInfos; i++) {
   21679 	    iattr = vctxt->attrInfos[i];
   21680 	    if (iattr->metaType == metaType)
   21681 		return (iattr);
   21682 	}
   21683 
   21684     }
   21685     return (NULL);
   21686 }
   21687 
   21688 /**
   21689  * xmlSchemaAssembleByXSI:
   21690  * @vctxt:  a schema validation context
   21691  *
   21692  * Expands an existing schema by an additional schema using
   21693  * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
   21694  * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
   21695  * must be set to 1.
   21696  *
   21697  * Returns 0 if the new schema is correct, a positive error code
   21698  * number otherwise and -1 in case of an internal or API error.
   21699  */
   21700 static int
   21701 xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
   21702 {
   21703     const xmlChar *cur, *end;
   21704     const xmlChar *nsname = NULL, *location;
   21705     int count = 0;
   21706     int ret = 0;
   21707     xmlSchemaAttrInfoPtr iattr;
   21708 
   21709     /*
   21710     * Parse the value; we will assume an even number of values
   21711     * to be given (this is how Xerces and XSV work).
   21712     *
   21713     * URGENT TODO: !! This needs to work for both
   21714     * @noNamespaceSchemaLocation AND @schemaLocation on the same
   21715     * element !!
   21716     */
   21717     iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   21718 	XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
   21719     if (iattr == NULL)
   21720 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   21721 	XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
   21722     if (iattr == NULL)
   21723 	return (0);
   21724     cur = iattr->value;
   21725     do {
   21726 	/*
   21727 	* TODO: Move the string parsing mechanism away from here.
   21728 	*/
   21729 	if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
   21730 	    /*
   21731 	    * Get the namespace name.
   21732 	    */
   21733 	    while (IS_BLANK_CH(*cur))
   21734 		cur++;
   21735 	    end = cur;
   21736 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   21737 		end++;
   21738 	    if (end == cur)
   21739 		break;
   21740 	    count++; /* TODO: Don't use the schema's dict. */
   21741 	    nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
   21742 	    cur = end;
   21743 	}
   21744 	/*
   21745 	* Get the URI.
   21746 	*/
   21747 	while (IS_BLANK_CH(*cur))
   21748 	    cur++;
   21749 	end = cur;
   21750 	while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   21751 	    end++;
   21752 	if (end == cur) {
   21753 	    if (iattr->metaType ==
   21754 		XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
   21755 	    {
   21756 		/*
   21757 		* If using @schemaLocation then tuples are expected.
   21758 		* I.e. the namespace name *and* the document's URI.
   21759 		*/
   21760 		xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
   21761 		    iattr->node, NULL,
   21762 		    "The value must consist of tuples: the target namespace "
   21763 		    "name and the document's URI", NULL, NULL, NULL);
   21764 	    }
   21765 	    break;
   21766 	}
   21767 	count++; /* TODO: Don't use the schema's dict. */
   21768 	location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
   21769 	cur = end;
   21770 	ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
   21771 	    iattr->node, nsname, location);
   21772 	if (ret == -1) {
   21773 	    VERROR_INT("xmlSchemaAssembleByXSI",
   21774 		"assembling schemata");
   21775 	    return (-1);
   21776 	}
   21777     } while (*cur != 0);
   21778     return (ret);
   21779 }
   21780 
   21781 static const xmlChar *
   21782 xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
   21783 			 const xmlChar *prefix)
   21784 {
   21785     if (vctxt->sax != NULL) {
   21786 	int i, j;
   21787 	xmlSchemaNodeInfoPtr inode;
   21788 
   21789 	for (i = vctxt->depth; i >= 0; i--) {
   21790 	    if (vctxt->elemInfos[i]->nbNsBindings != 0) {
   21791 		inode = vctxt->elemInfos[i];
   21792 		for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
   21793 		    if (((prefix == NULL) &&
   21794 			    (inode->nsBindings[j] == NULL)) ||
   21795 			((prefix != NULL) && xmlStrEqual(prefix,
   21796 			    inode->nsBindings[j]))) {
   21797 
   21798 			/*
   21799 			* Note that the namespace bindings are already
   21800 			* in a string dict.
   21801 			*/
   21802 			return (inode->nsBindings[j+1]);
   21803 		    }
   21804 		}
   21805 	    }
   21806 	}
   21807 	return (NULL);
   21808 #ifdef LIBXML_READER_ENABLED
   21809     } else if (vctxt->reader != NULL) {
   21810 	xmlChar *nsName;
   21811 
   21812 	nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
   21813 	if (nsName != NULL) {
   21814 	    const xmlChar *ret;
   21815 
   21816 	    ret = xmlDictLookup(vctxt->dict, nsName, -1);
   21817 	    xmlFree(nsName);
   21818 	    return (ret);
   21819 	} else
   21820 	    return (NULL);
   21821 #endif
   21822     } else {
   21823 	xmlNsPtr ns;
   21824 
   21825 	if ((vctxt->inode->node == NULL) ||
   21826 	    (vctxt->inode->node->doc == NULL)) {
   21827 	    VERROR_INT("xmlSchemaLookupNamespace",
   21828 		"no node or node's doc avaliable");
   21829 	    return (NULL);
   21830 	}
   21831 	ns = xmlSearchNs(vctxt->inode->node->doc,
   21832 	    vctxt->inode->node, prefix);
   21833 	if (ns != NULL)
   21834 	    return (ns->href);
   21835 	return (NULL);
   21836     }
   21837 }
   21838 
   21839 /*
   21840 * This one works on the schema of the validation context.
   21841 */
   21842 static int
   21843 xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
   21844 			  xmlSchemaPtr schema,
   21845 			  xmlNodePtr node,
   21846 			  const xmlChar *value,
   21847 			  xmlSchemaValPtr *val,
   21848 			  int valNeeded)
   21849 {
   21850     int ret;
   21851 
   21852     if (vctxt && (vctxt->schema == NULL)) {
   21853 	VERROR_INT("xmlSchemaValidateNotation",
   21854 	    "a schema is needed on the validation context");
   21855 	return (-1);
   21856     }
   21857     ret = xmlValidateQName(value, 1);
   21858     if (ret != 0)
   21859 	return (ret);
   21860     {
   21861 	xmlChar *localName = NULL;
   21862 	xmlChar *prefix = NULL;
   21863 
   21864 	localName = xmlSplitQName2(value, &prefix);
   21865 	if (prefix != NULL) {
   21866 	    const xmlChar *nsName = NULL;
   21867 
   21868 	    if (vctxt != NULL)
   21869 		nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
   21870 	    else if (node != NULL) {
   21871 		xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
   21872 		if (ns != NULL)
   21873 		    nsName = ns->href;
   21874 	    } else {
   21875 		xmlFree(prefix);
   21876 		xmlFree(localName);
   21877 		return (1);
   21878 	    }
   21879 	    if (nsName == NULL) {
   21880 		xmlFree(prefix);
   21881 		xmlFree(localName);
   21882 		return (1);
   21883 	    }
   21884 	    if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
   21885 		if ((valNeeded) && (val != NULL)) {
   21886 		    (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
   21887 						       xmlStrdup(nsName));
   21888 		    if (*val == NULL)
   21889 			ret = -1;
   21890 		}
   21891 	    } else
   21892 		ret = 1;
   21893 	    xmlFree(prefix);
   21894 	    xmlFree(localName);
   21895 	} else {
   21896 	    if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
   21897 		if (valNeeded && (val != NULL)) {
   21898 		    (*val) = xmlSchemaNewNOTATIONValue(
   21899 			BAD_CAST xmlStrdup(value), NULL);
   21900 		    if (*val == NULL)
   21901 			ret = -1;
   21902 		}
   21903 	    } else
   21904 		return (1);
   21905 	}
   21906     }
   21907     return (ret);
   21908 }
   21909 
   21910 static int
   21911 xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
   21912 		       const xmlChar* lname,
   21913 		       const xmlChar* nsname)
   21914 {
   21915     int i;
   21916 
   21917     lname = xmlDictLookup(vctxt->dict, lname, -1);
   21918     if (lname == NULL)
   21919 	return(-1);
   21920     if (nsname != NULL) {
   21921 	nsname = xmlDictLookup(vctxt->dict, nsname, -1);
   21922 	if (nsname == NULL)
   21923 	    return(-1);
   21924     }
   21925     for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
   21926 	if ((vctxt->nodeQNames->items [i] == lname) &&
   21927 	    (vctxt->nodeQNames->items[i +1] == nsname))
   21928 	    /* Already there */
   21929 	    return(i);
   21930     }
   21931     /* Add new entry. */
   21932     i = vctxt->nodeQNames->nbItems;
   21933     xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
   21934     xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
   21935     return(i);
   21936 }
   21937 
   21938 /************************************************************************
   21939  * 									*
   21940  *  Validation of identity-constraints (IDC)                            *
   21941  * 									*
   21942  ************************************************************************/
   21943 
   21944 /**
   21945  * xmlSchemaAugmentIDC:
   21946  * @idcDef: the IDC definition
   21947  *
   21948  * Creates an augmented IDC definition item.
   21949  *
   21950  * Returns the item, or NULL on internal errors.
   21951  */
   21952 static void
   21953 xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef,
   21954 		    xmlSchemaValidCtxtPtr vctxt)
   21955 {
   21956     xmlSchemaIDCAugPtr aidc;
   21957 
   21958     aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
   21959     if (aidc == NULL) {
   21960 	xmlSchemaVErrMemory(vctxt,
   21961 	    "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
   21962 	    NULL);
   21963 	return;
   21964     }
   21965     aidc->keyrefDepth = -1;
   21966     aidc->def = idcDef;
   21967     aidc->next = NULL;
   21968     if (vctxt->aidcs == NULL)
   21969 	vctxt->aidcs = aidc;
   21970     else {
   21971 	aidc->next = vctxt->aidcs;
   21972 	vctxt->aidcs = aidc;
   21973     }
   21974     /*
   21975     * Save if we have keyrefs at all.
   21976     */
   21977     if ((vctxt->hasKeyrefs == 0) &&
   21978 	(idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
   21979 	vctxt->hasKeyrefs = 1;
   21980 }
   21981 
   21982 /**
   21983  * xmlSchemaAugmentImportedIDC:
   21984  * @imported: the imported schema
   21985  *
   21986  * Creates an augmented IDC definition for the imported schema.
   21987  */
   21988 static void
   21989 xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) {
   21990     if (imported->schema->idcDef != NULL) {
   21991 	    xmlHashScan(imported->schema->idcDef ,
   21992 	    (xmlHashScanner) xmlSchemaAugmentIDC, vctxt);
   21993     }
   21994 }
   21995 
   21996 /**
   21997  * xmlSchemaIDCNewBinding:
   21998  * @idcDef: the IDC definition of this binding
   21999  *
   22000  * Creates a new IDC binding.
   22001  *
   22002  * Returns the new IDC binding, NULL on internal errors.
   22003  */
   22004 static xmlSchemaPSVIIDCBindingPtr
   22005 xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
   22006 {
   22007     xmlSchemaPSVIIDCBindingPtr ret;
   22008 
   22009     ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
   22010 	    sizeof(xmlSchemaPSVIIDCBinding));
   22011     if (ret == NULL) {
   22012 	xmlSchemaVErrMemory(NULL,
   22013 	    "allocating a PSVI IDC binding item", NULL);
   22014 	return (NULL);
   22015     }
   22016     memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
   22017     ret->definition = idcDef;
   22018     return (ret);
   22019 }
   22020 
   22021 /**
   22022  * xmlSchemaIDCStoreNodeTableItem:
   22023  * @vctxt: the WXS validation context
   22024  * @item: the IDC node table item
   22025  *
   22026  * The validation context is used to store IDC node table items.
   22027  * They are stored to avoid copying them if IDC node-tables are merged
   22028  * with corresponding parent IDC node-tables (bubbling).
   22029  *
   22030  * Returns 0 if succeeded, -1 on internal errors.
   22031  */
   22032 static int
   22033 xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
   22034 			       xmlSchemaPSVIIDCNodePtr item)
   22035 {
   22036     /*
   22037     * Add to gobal list.
   22038     */
   22039     if (vctxt->idcNodes == NULL) {
   22040 	vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
   22041 	    xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
   22042 	if (vctxt->idcNodes == NULL) {
   22043 	    xmlSchemaVErrMemory(vctxt,
   22044 		"allocating the IDC node table item list", NULL);
   22045 	    return (-1);
   22046 	}
   22047 	vctxt->sizeIdcNodes = 20;
   22048     } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
   22049 	vctxt->sizeIdcNodes *= 2;
   22050 	vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
   22051 	    xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
   22052 	    sizeof(xmlSchemaPSVIIDCNodePtr));
   22053 	if (vctxt->idcNodes == NULL) {
   22054 	    xmlSchemaVErrMemory(vctxt,
   22055 		"re-allocating the IDC node table item list", NULL);
   22056 	    return (-1);
   22057 	}
   22058     }
   22059     vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
   22060 
   22061     return (0);
   22062 }
   22063 
   22064 /**
   22065  * xmlSchemaIDCStoreKey:
   22066  * @vctxt: the WXS validation context
   22067  * @item: the IDC key
   22068  *
   22069  * The validation context is used to store an IDC key.
   22070  *
   22071  * Returns 0 if succeeded, -1 on internal errors.
   22072  */
   22073 static int
   22074 xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
   22075 		     xmlSchemaPSVIIDCKeyPtr key)
   22076 {
   22077     /*
   22078     * Add to gobal list.
   22079     */
   22080     if (vctxt->idcKeys == NULL) {
   22081 	vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
   22082 	    xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
   22083 	if (vctxt->idcKeys == NULL) {
   22084 	    xmlSchemaVErrMemory(vctxt,
   22085 		"allocating the IDC key storage list", NULL);
   22086 	    return (-1);
   22087 	}
   22088 	vctxt->sizeIdcKeys = 40;
   22089     } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
   22090 	vctxt->sizeIdcKeys *= 2;
   22091 	vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
   22092 	    xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
   22093 	    sizeof(xmlSchemaPSVIIDCKeyPtr));
   22094 	if (vctxt->idcKeys == NULL) {
   22095 	    xmlSchemaVErrMemory(vctxt,
   22096 		"re-allocating the IDC key storage list", NULL);
   22097 	    return (-1);
   22098 	}
   22099     }
   22100     vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
   22101 
   22102     return (0);
   22103 }
   22104 
   22105 /**
   22106  * xmlSchemaIDCAppendNodeTableItem:
   22107  * @bind: the IDC binding
   22108  * @ntItem: the node-table item
   22109  *
   22110  * Appends the IDC node-table item to the binding.
   22111  *
   22112  * Returns 0 on success and -1 on internal errors.
   22113  */
   22114 static int
   22115 xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
   22116 				xmlSchemaPSVIIDCNodePtr ntItem)
   22117 {
   22118     if (bind->nodeTable == NULL) {
   22119 	bind->sizeNodes = 10;
   22120 	bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   22121 	    xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
   22122 	if (bind->nodeTable == NULL) {
   22123 	    xmlSchemaVErrMemory(NULL,
   22124 		"allocating an array of IDC node-table items", NULL);
   22125 	    return(-1);
   22126 	}
   22127     } else if (bind->sizeNodes <= bind->nbNodes) {
   22128 	bind->sizeNodes *= 2;
   22129 	bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   22130 	    xmlRealloc(bind->nodeTable, bind->sizeNodes *
   22131 		sizeof(xmlSchemaPSVIIDCNodePtr));
   22132 	if (bind->nodeTable == NULL) {
   22133 	    xmlSchemaVErrMemory(NULL,
   22134 		"re-allocating an array of IDC node-table items", NULL);
   22135 	    return(-1);
   22136 	}
   22137     }
   22138     bind->nodeTable[bind->nbNodes++] = ntItem;
   22139     return(0);
   22140 }
   22141 
   22142 /**
   22143  * xmlSchemaIDCAcquireBinding:
   22144  * @vctxt: the WXS validation context
   22145  * @matcher: the IDC matcher
   22146  *
   22147  * Looks up an PSVI IDC binding, for the IDC definition and
   22148  * of the given matcher. If none found, a new one is created
   22149  * and added to the IDC table.
   22150  *
   22151  * Returns an IDC binding or NULL on internal errors.
   22152  */
   22153 static xmlSchemaPSVIIDCBindingPtr
   22154 xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
   22155 			  xmlSchemaIDCMatcherPtr matcher)
   22156 {
   22157     xmlSchemaNodeInfoPtr ielem;
   22158 
   22159     ielem = vctxt->elemInfos[matcher->depth];
   22160 
   22161     if (ielem->idcTable == NULL) {
   22162 	ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
   22163 	if (ielem->idcTable == NULL)
   22164 	    return (NULL);
   22165 	return(ielem->idcTable);
   22166     } else {
   22167 	xmlSchemaPSVIIDCBindingPtr bind = NULL;
   22168 
   22169 	bind = ielem->idcTable;
   22170 	do {
   22171 	    if (bind->definition == matcher->aidc->def)
   22172 		return(bind);
   22173 	    if (bind->next == NULL) {
   22174 		bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
   22175 		if (bind->next == NULL)
   22176 		    return (NULL);
   22177 		return(bind->next);
   22178 	    }
   22179 	    bind = bind->next;
   22180 	} while (bind != NULL);
   22181     }
   22182     return (NULL);
   22183 }
   22184 
   22185 static xmlSchemaItemListPtr
   22186 xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
   22187 			     xmlSchemaIDCMatcherPtr matcher)
   22188 {
   22189     if (matcher->targets == NULL)
   22190 	matcher->targets = xmlSchemaItemListCreate();
   22191     return(matcher->targets);
   22192 }
   22193 
   22194 /**
   22195  * xmlSchemaIDCFreeKey:
   22196  * @key: the IDC key
   22197  *
   22198  * Frees an IDC key together with its compiled value.
   22199  */
   22200 static void
   22201 xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
   22202 {
   22203     if (key->val != NULL)
   22204 	xmlSchemaFreeValue(key->val);
   22205     xmlFree(key);
   22206 }
   22207 
   22208 /**
   22209  * xmlSchemaIDCFreeBinding:
   22210  *
   22211  * Frees an IDC binding. Note that the node table-items
   22212  * are not freed.
   22213  */
   22214 static void
   22215 xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
   22216 {
   22217     if (bind->nodeTable != NULL)
   22218 	xmlFree(bind->nodeTable);
   22219     if (bind->dupls != NULL)
   22220 	xmlSchemaItemListFree(bind->dupls);
   22221     xmlFree(bind);
   22222 }
   22223 
   22224 /**
   22225  * xmlSchemaIDCFreeIDCTable:
   22226  * @bind: the first IDC binding in the list
   22227  *
   22228  * Frees an IDC table, i.e. all the IDC bindings in the list.
   22229  */
   22230 static void
   22231 xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
   22232 {
   22233     xmlSchemaPSVIIDCBindingPtr prev;
   22234 
   22235     while (bind != NULL) {
   22236 	prev = bind;
   22237 	bind = bind->next;
   22238 	xmlSchemaIDCFreeBinding(prev);
   22239     }
   22240 }
   22241 
   22242 /**
   22243  * xmlSchemaIDCFreeMatcherList:
   22244  * @matcher: the first IDC matcher in the list
   22245  *
   22246  * Frees a list of IDC matchers.
   22247  */
   22248 static void
   22249 xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
   22250 {
   22251     xmlSchemaIDCMatcherPtr next;
   22252 
   22253     while (matcher != NULL) {
   22254 	next = matcher->next;
   22255 	if (matcher->keySeqs != NULL) {
   22256 	    int i;
   22257 	    for (i = 0; i < matcher->sizeKeySeqs; i++)
   22258 		if (matcher->keySeqs[i] != NULL)
   22259 		    xmlFree(matcher->keySeqs[i]);
   22260 	    xmlFree(matcher->keySeqs);
   22261 	}
   22262 	if (matcher->targets != NULL) {
   22263 	    if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
   22264 		int i;
   22265 		xmlSchemaPSVIIDCNodePtr idcNode;
   22266 		/*
   22267 		* Node-table items for keyrefs are not stored globally
   22268 		* to the validation context, since they are not bubbled.
   22269 		* We need to free them here.
   22270 		*/
   22271 		for (i = 0; i < matcher->targets->nbItems; i++) {
   22272 		    idcNode =
   22273 			(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
   22274 		    xmlFree(idcNode->keys);
   22275 		    xmlFree(idcNode);
   22276 		}
   22277 	    }
   22278 	    xmlSchemaItemListFree(matcher->targets);
   22279 	}
   22280 	xmlFree(matcher);
   22281 	matcher = next;
   22282     }
   22283 }
   22284 
   22285 /**
   22286  * xmlSchemaIDCReleaseMatcherList:
   22287  * @vctxt: the WXS validation context
   22288  * @matcher: the first IDC matcher in the list
   22289  *
   22290  * Caches a list of IDC matchers for reuse.
   22291  */
   22292 static void
   22293 xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
   22294 			       xmlSchemaIDCMatcherPtr matcher)
   22295 {
   22296     xmlSchemaIDCMatcherPtr next;
   22297 
   22298     while (matcher != NULL) {
   22299 	next = matcher->next;
   22300 	if (matcher->keySeqs != NULL) {
   22301 	    int i;
   22302 	    /*
   22303 	    * Don't free the array, but only the content.
   22304 	    */
   22305 	    for (i = 0; i < matcher->sizeKeySeqs; i++)
   22306 		if (matcher->keySeqs[i] != NULL) {
   22307 		    xmlFree(matcher->keySeqs[i]);
   22308 		    matcher->keySeqs[i] = NULL;
   22309 		}
   22310 	}
   22311 	if (matcher->targets) {
   22312 	    if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
   22313 		int i;
   22314 		xmlSchemaPSVIIDCNodePtr idcNode;
   22315 		/*
   22316 		* Node-table items for keyrefs are not stored globally
   22317 		* to the validation context, since they are not bubbled.
   22318 		* We need to free them here.
   22319 		*/
   22320 		for (i = 0; i < matcher->targets->nbItems; i++) {
   22321 		    idcNode =
   22322 			(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
   22323 		    xmlFree(idcNode->keys);
   22324 		    xmlFree(idcNode);
   22325 		}
   22326 	    }
   22327 	    xmlSchemaItemListFree(matcher->targets);
   22328 	    matcher->targets = NULL;
   22329 	}
   22330 	matcher->next = NULL;
   22331 	/*
   22332 	* Cache the matcher.
   22333 	*/
   22334 	if (vctxt->idcMatcherCache != NULL)
   22335 	    matcher->nextCached = vctxt->idcMatcherCache;
   22336 	vctxt->idcMatcherCache = matcher;
   22337 
   22338 	matcher = next;
   22339     }
   22340 }
   22341 
   22342 /**
   22343  * xmlSchemaIDCAddStateObject:
   22344  * @vctxt: the WXS validation context
   22345  * @matcher: the IDC matcher
   22346  * @sel: the XPath information
   22347  * @parent: the parent "selector" state object if any
   22348  * @type: "selector" or "field"
   22349  *
   22350  * Creates/reuses and activates state objects for the given
   22351  * XPath information; if the XPath expression consists of unions,
   22352  * multiple state objects are created for every unioned expression.
   22353  *
   22354  * Returns 0 on success and -1 on internal errors.
   22355  */
   22356 static int
   22357 xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
   22358 			xmlSchemaIDCMatcherPtr matcher,
   22359 			xmlSchemaIDCSelectPtr sel,
   22360 			int type)
   22361 {
   22362     xmlSchemaIDCStateObjPtr sto;
   22363 
   22364     /*
   22365     * Reuse the state objects from the pool.
   22366     */
   22367     if (vctxt->xpathStatePool != NULL) {
   22368 	sto = vctxt->xpathStatePool;
   22369 	vctxt->xpathStatePool = sto->next;
   22370 	sto->next = NULL;
   22371     } else {
   22372 	/*
   22373 	* Create a new state object.
   22374 	*/
   22375 	sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
   22376 	if (sto == NULL) {
   22377 	    xmlSchemaVErrMemory(NULL,
   22378 		"allocating an IDC state object", NULL);
   22379 	    return (-1);
   22380 	}
   22381 	memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
   22382     }
   22383     /*
   22384     * Add to global list.
   22385     */
   22386     if (vctxt->xpathStates != NULL)
   22387 	sto->next = vctxt->xpathStates;
   22388     vctxt->xpathStates = sto;
   22389 
   22390     /*
   22391     * Free the old xpath validation context.
   22392     */
   22393     if (sto->xpathCtxt != NULL)
   22394 	xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
   22395 
   22396     /*
   22397     * Create a new XPath (pattern) validation context.
   22398     */
   22399     sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
   22400 	(xmlPatternPtr) sel->xpathComp);
   22401     if (sto->xpathCtxt == NULL) {
   22402 	VERROR_INT("xmlSchemaIDCAddStateObject",
   22403 	    "failed to create an XPath validation context");
   22404 	return (-1);
   22405     }
   22406     sto->type = type;
   22407     sto->depth = vctxt->depth;
   22408     sto->matcher = matcher;
   22409     sto->sel = sel;
   22410     sto->nbHistory = 0;
   22411 
   22412 #ifdef DEBUG_IDC
   22413     xmlGenericError(xmlGenericErrorContext, "IDC:   STO push '%s'\n",
   22414 	sto->sel->xpath);
   22415 #endif
   22416     return (0);
   22417 }
   22418 
   22419 /**
   22420  * xmlSchemaXPathEvaluate:
   22421  * @vctxt: the WXS validation context
   22422  * @nodeType: the nodeType of the current node
   22423  *
   22424  * Evaluates all active XPath state objects.
   22425  *
   22426  * Returns the number of IC "field" state objects which resolved to
   22427  * this node, 0 if none resolved and -1 on internal errors.
   22428  */
   22429 static int
   22430 xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
   22431 		       xmlElementType nodeType)
   22432 {
   22433     xmlSchemaIDCStateObjPtr sto, head = NULL, first;
   22434     int res, resolved = 0, depth = vctxt->depth;
   22435 
   22436     if (vctxt->xpathStates == NULL)
   22437 	return (0);
   22438 
   22439     if (nodeType == XML_ATTRIBUTE_NODE)
   22440 	depth++;
   22441 #ifdef DEBUG_IDC
   22442     {
   22443 	xmlChar *str = NULL;
   22444 	xmlGenericError(xmlGenericErrorContext,
   22445 	    "IDC: EVAL on %s, depth %d, type %d\n",
   22446 	    xmlSchemaFormatQName(&str, vctxt->inode->nsName,
   22447 		vctxt->inode->localName), depth, nodeType);
   22448 	FREE_AND_NULL(str)
   22449     }
   22450 #endif
   22451     /*
   22452     * Process all active XPath state objects.
   22453     */
   22454     first = vctxt->xpathStates;
   22455     sto = first;
   22456     while (sto != head) {
   22457 #ifdef DEBUG_IDC
   22458 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
   22459 	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] selector '%s'\n",
   22460 		sto->matcher->aidc->def->name, sto->sel->xpath);
   22461 	else
   22462 	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] field '%s'\n",
   22463 		sto->matcher->aidc->def->name, sto->sel->xpath);
   22464 #endif
   22465 	if (nodeType == XML_ELEMENT_NODE)
   22466 	    res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
   22467 		vctxt->inode->localName, vctxt->inode->nsName);
   22468 	else
   22469 	    res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
   22470 		vctxt->inode->localName, vctxt->inode->nsName);
   22471 
   22472 	if (res == -1) {
   22473 	    VERROR_INT("xmlSchemaXPathEvaluate",
   22474 		"calling xmlStreamPush()");
   22475 	    return (-1);
   22476 	}
   22477 	if (res == 0)
   22478 	    goto next_sto;
   22479 	/*
   22480 	* Full match.
   22481 	*/
   22482 #ifdef DEBUG_IDC
   22483 	xmlGenericError(xmlGenericErrorContext, "IDC:     "
   22484 	    "MATCH\n");
   22485 #endif
   22486 	/*
   22487 	* Register a match in the state object history.
   22488 	*/
   22489 	if (sto->history == NULL) {
   22490 	    sto->history = (int *) xmlMalloc(5 * sizeof(int));
   22491 	    if (sto->history == NULL) {
   22492 		xmlSchemaVErrMemory(NULL,
   22493 		    "allocating the state object history", NULL);
   22494 		return(-1);
   22495 	    }
   22496 	    sto->sizeHistory = 5;
   22497 	} else if (sto->sizeHistory <= sto->nbHistory) {
   22498 	    sto->sizeHistory *= 2;
   22499 	    sto->history = (int *) xmlRealloc(sto->history,
   22500 		sto->sizeHistory * sizeof(int));
   22501 	    if (sto->history == NULL) {
   22502 		xmlSchemaVErrMemory(NULL,
   22503 		    "re-allocating the state object history", NULL);
   22504 		return(-1);
   22505 	    }
   22506 	}
   22507 	sto->history[sto->nbHistory++] = depth;
   22508 
   22509 #ifdef DEBUG_IDC
   22510 	xmlGenericError(xmlGenericErrorContext, "IDC:       push match '%d'\n",
   22511 	    vctxt->depth);
   22512 #endif
   22513 
   22514 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
   22515 	    xmlSchemaIDCSelectPtr sel;
   22516 	    /*
   22517 	    * Activate state objects for the IDC fields of
   22518 	    * the IDC selector.
   22519 	    */
   22520 #ifdef DEBUG_IDC
   22521 	    xmlGenericError(xmlGenericErrorContext, "IDC:     "
   22522 		"activating field states\n");
   22523 #endif
   22524 	    sel = sto->matcher->aidc->def->fields;
   22525 	    while (sel != NULL) {
   22526 		if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
   22527 		    sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
   22528 		    return (-1);
   22529 		sel = sel->next;
   22530 	    }
   22531 	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
   22532 	    /*
   22533 	    * An IDC key node was found by the IDC field.
   22534 	    */
   22535 #ifdef DEBUG_IDC
   22536 	    xmlGenericError(xmlGenericErrorContext,
   22537 		"IDC:     key found\n");
   22538 #endif
   22539 	    /*
   22540 	    * Notify that the character value of this node is
   22541 	    * needed.
   22542 	    */
   22543 	    if (resolved == 0) {
   22544 		if ((vctxt->inode->flags &
   22545 		    XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
   22546 		vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
   22547 	    }
   22548 	    resolved++;
   22549 	}
   22550 next_sto:
   22551 	if (sto->next == NULL) {
   22552 	    /*
   22553 	    * Evaluate field state objects created on this node as well.
   22554 	    */
   22555 	    head = first;
   22556 	    sto = vctxt->xpathStates;
   22557 	} else
   22558 	    sto = sto->next;
   22559     }
   22560     return (resolved);
   22561 }
   22562 
   22563 static const xmlChar *
   22564 xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
   22565 			      xmlChar **buf,
   22566 			      xmlSchemaPSVIIDCKeyPtr *seq,
   22567 			      int count)
   22568 {
   22569     int i, res;
   22570     xmlChar *value = NULL;
   22571 
   22572     *buf = xmlStrdup(BAD_CAST "[");
   22573     for (i = 0; i < count; i++) {
   22574 	*buf = xmlStrcat(*buf, BAD_CAST "'");
   22575 	res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
   22576 	    xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
   22577 	    &value);
   22578 	if (res == 0)
   22579 	    *buf = xmlStrcat(*buf, BAD_CAST value);
   22580 	else {
   22581 	    VERROR_INT("xmlSchemaFormatIDCKeySequence",
   22582 		"failed to compute a canonical value");
   22583 	    *buf = xmlStrcat(*buf, BAD_CAST "???");
   22584 	}
   22585 	if (i < count -1)
   22586 	    *buf = xmlStrcat(*buf, BAD_CAST "', ");
   22587 	else
   22588 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
   22589 	if (value != NULL) {
   22590 	    xmlFree(value);
   22591 	    value = NULL;
   22592 	}
   22593     }
   22594     *buf = xmlStrcat(*buf, BAD_CAST "]");
   22595 
   22596     return (BAD_CAST *buf);
   22597 }
   22598 
   22599 /**
   22600  * xmlSchemaXPathPop:
   22601  * @vctxt: the WXS validation context
   22602  *
   22603  * Pops all XPath states.
   22604  *
   22605  * Returns 0 on success and -1 on internal errors.
   22606  */
   22607 static int
   22608 xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
   22609 {
   22610     xmlSchemaIDCStateObjPtr sto;
   22611     int res;
   22612 
   22613     if (vctxt->xpathStates == NULL)
   22614 	return(0);
   22615     sto = vctxt->xpathStates;
   22616     do {
   22617 	res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
   22618 	if (res == -1)
   22619 	    return (-1);
   22620 	sto = sto->next;
   22621     } while (sto != NULL);
   22622     return(0);
   22623 }
   22624 
   22625 /**
   22626  * xmlSchemaXPathProcessHistory:
   22627  * @vctxt: the WXS validation context
   22628  * @type: the simple/complex type of the current node if any at all
   22629  * @val: the precompiled value
   22630  *
   22631  * Processes and pops the history items of the IDC state objects.
   22632  * IDC key-sequences are validated/created on IDC bindings.
   22633  *
   22634  * Returns 0 on success and -1 on internal errors.
   22635  */
   22636 static int
   22637 xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
   22638 			     int depth)
   22639 {
   22640     xmlSchemaIDCStateObjPtr sto, nextsto;
   22641     int res, matchDepth;
   22642     xmlSchemaPSVIIDCKeyPtr key = NULL;
   22643     xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
   22644 
   22645     if (vctxt->xpathStates == NULL)
   22646 	return (0);
   22647     sto = vctxt->xpathStates;
   22648 
   22649 #ifdef DEBUG_IDC
   22650     {
   22651 	xmlChar *str = NULL;
   22652 	xmlGenericError(xmlGenericErrorContext,
   22653 	    "IDC: BACK on %s, depth %d\n",
   22654 	    xmlSchemaFormatQName(&str, vctxt->inode->nsName,
   22655 		vctxt->inode->localName), vctxt->depth);
   22656 	FREE_AND_NULL(str)
   22657     }
   22658 #endif
   22659     /*
   22660     * Evaluate the state objects.
   22661     */
   22662     while (sto != NULL) {
   22663 	res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
   22664 	if (res == -1) {
   22665 	    VERROR_INT("xmlSchemaXPathProcessHistory",
   22666 		"calling xmlStreamPop()");
   22667 	    return (-1);
   22668 	}
   22669 #ifdef DEBUG_IDC
   22670 	xmlGenericError(xmlGenericErrorContext, "IDC:   stream pop '%s'\n",
   22671 	    sto->sel->xpath);
   22672 #endif
   22673 	if (sto->nbHistory == 0)
   22674 	    goto deregister_check;
   22675 
   22676 	matchDepth = sto->history[sto->nbHistory -1];
   22677 
   22678 	/*
   22679 	* Only matches at the current depth are of interest.
   22680 	*/
   22681 	if (matchDepth != depth) {
   22682 	    sto = sto->next;
   22683 	    continue;
   22684 	}
   22685 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
   22686 	    /*
   22687 	    * NOTE: According to
   22688 	    *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
   22689 	    *   ... the simple-content of complex types is also allowed.
   22690 	    */
   22691 
   22692 	    if (WXS_IS_COMPLEX(type)) {
   22693 		if (WXS_HAS_SIMPLE_CONTENT(type)) {
   22694 		    /*
   22695 		    * Sanity check for complex types with simple content.
   22696 		    */
   22697 		    simpleType = type->contentTypeDef;
   22698 		    if (simpleType == NULL) {
   22699 			VERROR_INT("xmlSchemaXPathProcessHistory",
   22700 			    "field resolves to a CT with simple content "
   22701 			    "but the CT is missing the ST definition");
   22702 			return (-1);
   22703 		    }
   22704 		} else
   22705 		    simpleType = NULL;
   22706 	    } else
   22707 		simpleType = type;
   22708 	    if (simpleType == NULL) {
   22709 		xmlChar *str = NULL;
   22710 
   22711 		/*
   22712 		* Not qualified if the field resolves to a node of non
   22713 		* simple type.
   22714 		*/
   22715 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   22716 		    XML_SCHEMAV_CVC_IDC, NULL,
   22717 		    WXS_BASIC_CAST sto->matcher->aidc->def,
   22718 		    "The XPath '%s' of a field of %s does evaluate to a node of "
   22719 		    "non-simple type",
   22720 		    sto->sel->xpath,
   22721 		    xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
   22722 		FREE_AND_NULL(str);
   22723 		sto->nbHistory--;
   22724 		goto deregister_check;
   22725 	    }
   22726 
   22727 	    if ((key == NULL) && (vctxt->inode->val == NULL)) {
   22728 		/*
   22729 		* Failed to provide the normalized value; maybe
   22730 		* the value was invalid.
   22731 		*/
   22732 		VERROR(XML_SCHEMAV_CVC_IDC,
   22733 		    WXS_BASIC_CAST sto->matcher->aidc->def,
   22734 		    "Warning: No precomputed value available, the value "
   22735 		    "was either invalid or something strange happend");
   22736 		sto->nbHistory--;
   22737 		goto deregister_check;
   22738 	    } else {
   22739 		xmlSchemaIDCMatcherPtr matcher = sto->matcher;
   22740 		xmlSchemaPSVIIDCKeyPtr *keySeq;
   22741 		int pos, idx;
   22742 
   22743 		/*
   22744 		* The key will be anchored on the matcher's list of
   22745 		* key-sequences. The position in this list is determined
   22746 		* by the target node's depth relative to the matcher's
   22747 		* depth of creation (i.e. the depth of the scope element).
   22748 		*
   22749 		* Element        Depth    Pos   List-entries
   22750 		* <scope>          0              NULL
   22751 		*   <bar>          1              NULL
   22752 		*     <target/>    2       2      target
   22753 		*   <bar>
   22754                 * </scope>
   22755 		*
   22756 		* The size of the list is only dependant on the depth of
   22757 		* the tree.
   22758 		* An entry will be NULLed in selector_leave, i.e. when
   22759 		* we hit the target's
   22760 		*/
   22761 		pos = sto->depth - matcher->depth;
   22762 		idx = sto->sel->index;
   22763 
   22764 		/*
   22765 		* Create/grow the array of key-sequences.
   22766 		*/
   22767 		if (matcher->keySeqs == NULL) {
   22768 		    if (pos > 9)
   22769 			matcher->sizeKeySeqs = pos * 2;
   22770 		    else
   22771 			matcher->sizeKeySeqs = 10;
   22772 		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
   22773 			xmlMalloc(matcher->sizeKeySeqs *
   22774 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
   22775 		    if (matcher->keySeqs == NULL) {
   22776 			xmlSchemaVErrMemory(NULL,
   22777 			    "allocating an array of key-sequences",
   22778 			    NULL);
   22779 			return(-1);
   22780 		    }
   22781 		    memset(matcher->keySeqs, 0,
   22782 			matcher->sizeKeySeqs *
   22783 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
   22784 		} else if (pos >= matcher->sizeKeySeqs) {
   22785 		    int i = matcher->sizeKeySeqs;
   22786 
   22787 		    matcher->sizeKeySeqs *= 2;
   22788 		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
   22789 			xmlRealloc(matcher->keySeqs,
   22790 			matcher->sizeKeySeqs *
   22791 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
   22792 		    if (matcher->keySeqs == NULL) {
   22793 			xmlSchemaVErrMemory(NULL,
   22794 			    "reallocating an array of key-sequences",
   22795 			    NULL);
   22796 			return (-1);
   22797 		    }
   22798 		    /*
   22799 		    * The array needs to be NULLed.
   22800 		    * TODO: Use memset?
   22801 		    */
   22802 		    for (; i < matcher->sizeKeySeqs; i++)
   22803 			matcher->keySeqs[i] = NULL;
   22804 		}
   22805 
   22806 		/*
   22807 		* Get/create the key-sequence.
   22808 		*/
   22809 		keySeq = matcher->keySeqs[pos];
   22810 		if (keySeq == NULL) {
   22811 		    goto create_sequence;
   22812 		} else if (keySeq[idx] != NULL) {
   22813 		    xmlChar *str = NULL;
   22814 		    /*
   22815 		    * cvc-identity-constraint:
   22816 		    * 3 For each node in the target node set all
   22817 		    * of the {fields}, with that node as the context
   22818 		    * node, evaluate to either an empty node-set or
   22819 		    * a node-set with exactly one member, which must
   22820 		    * have a simple type.
   22821 		    *
   22822 		    * The key was already set; report an error.
   22823 		    */
   22824 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
   22825 			XML_SCHEMAV_CVC_IDC, NULL,
   22826 			WXS_BASIC_CAST matcher->aidc->def,
   22827 			"The XPath '%s' of a field of %s evaluates to a "
   22828 			"node-set with more than one member",
   22829 			sto->sel->xpath,
   22830 			xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
   22831 		    FREE_AND_NULL(str);
   22832 		    sto->nbHistory--;
   22833 		    goto deregister_check;
   22834 		} else
   22835 		    goto create_key;
   22836 
   22837 create_sequence:
   22838 		/*
   22839 		* Create a key-sequence.
   22840 		*/
   22841 		keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
   22842 		    matcher->aidc->def->nbFields *
   22843 		    sizeof(xmlSchemaPSVIIDCKeyPtr));
   22844 		if (keySeq == NULL) {
   22845 		    xmlSchemaVErrMemory(NULL,
   22846 			"allocating an IDC key-sequence", NULL);
   22847 		    return(-1);
   22848 		}
   22849 		memset(keySeq, 0, matcher->aidc->def->nbFields *
   22850 		    sizeof(xmlSchemaPSVIIDCKeyPtr));
   22851 		matcher->keySeqs[pos] = keySeq;
   22852 create_key:
   22853 		/*
   22854 		* Create a key once per node only.
   22855 		*/
   22856 		if (key == NULL) {
   22857 		    key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
   22858 			sizeof(xmlSchemaPSVIIDCKey));
   22859 		    if (key == NULL) {
   22860 			xmlSchemaVErrMemory(NULL,
   22861 			    "allocating a IDC key", NULL);
   22862 			xmlFree(keySeq);
   22863 			matcher->keySeqs[pos] = NULL;
   22864 			return(-1);
   22865 		    }
   22866 		    /*
   22867 		    * Consume the compiled value.
   22868 		    */
   22869 		    key->type = simpleType;
   22870 		    key->val = vctxt->inode->val;
   22871 		    vctxt->inode->val = NULL;
   22872 		    /*
   22873 		    * Store the key in a global list.
   22874 		    */
   22875 		    if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
   22876 			xmlSchemaIDCFreeKey(key);
   22877 			return (-1);
   22878 		    }
   22879 		}
   22880 		keySeq[idx] = key;
   22881 	    }
   22882 	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
   22883 
   22884 	    xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
   22885 	    /* xmlSchemaPSVIIDCBindingPtr bind; */
   22886 	    xmlSchemaPSVIIDCNodePtr ntItem;
   22887 	    xmlSchemaIDCMatcherPtr matcher;
   22888 	    xmlSchemaIDCPtr idc;
   22889 	    xmlSchemaItemListPtr targets;
   22890 	    int pos, i, j, nbKeys;
   22891 	    /*
   22892 	    * Here we have the following scenario:
   22893 	    * An IDC 'selector' state object resolved to a target node,
   22894 	    * during the time this target node was in the
   22895 	    * ancestor-or-self axis, the 'field' state object(s) looked
   22896 	    * out for matching nodes to create a key-sequence for this
   22897 	    * target node. Now we are back to this target node and need
   22898 	    * to put the key-sequence, together with the target node
   22899 	    * itself, into the node-table of the corresponding IDC
   22900 	    * binding.
   22901 	    */
   22902 	    matcher = sto->matcher;
   22903 	    idc = matcher->aidc->def;
   22904 	    nbKeys = idc->nbFields;
   22905 	    pos = depth - matcher->depth;
   22906 	    /*
   22907 	    * Check if the matcher has any key-sequences at all, plus
   22908 	    * if it has a key-sequence for the current target node.
   22909 	    */
   22910 	    if ((matcher->keySeqs == NULL) ||
   22911 		(matcher->sizeKeySeqs <= pos)) {
   22912 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
   22913 		    goto selector_key_error;
   22914 		else
   22915 		    goto selector_leave;
   22916 	    }
   22917 
   22918 	    keySeq = &(matcher->keySeqs[pos]);
   22919 	    if (*keySeq == NULL) {
   22920 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
   22921 		    goto selector_key_error;
   22922 		else
   22923 		    goto selector_leave;
   22924 	    }
   22925 
   22926 	    for (i = 0; i < nbKeys; i++) {
   22927 		if ((*keySeq)[i] == NULL) {
   22928 		    /*
   22929 		    * Not qualified, if not all fields did resolve.
   22930 		    */
   22931 		    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
   22932 			/*
   22933 			* All fields of a "key" IDC must resolve.
   22934 			*/
   22935 			goto selector_key_error;
   22936 		    }
   22937 		    goto selector_leave;
   22938 		}
   22939 	    }
   22940 	    /*
   22941 	    * All fields did resolve.
   22942 	    */
   22943 
   22944 	    /*
   22945 	    * 4.1 If the {identity-constraint category} is unique(/key),
   22946 	    * then no two members of the qualified node set have
   22947 	    * key-sequences whose members are pairwise equal, as
   22948 	    * defined by Equal in [XML Schemas: Datatypes].
   22949 	    *
   22950 	    * Get the IDC binding from the matcher and check for
   22951 	    * duplicate key-sequences.
   22952 	    */
   22953 #if 0
   22954 	    bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
   22955 #endif
   22956 	    targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
   22957 	    if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
   22958 		(targets->nbItems != 0)) {
   22959 		xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
   22960 
   22961 		i = 0;
   22962 		res = 0;
   22963 		/*
   22964 		* Compare the key-sequences, key by key.
   22965 		*/
   22966 		do {
   22967 		    bkeySeq =
   22968 			((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys;
   22969 		    for (j = 0; j < nbKeys; j++) {
   22970 			ckey = (*keySeq)[j];
   22971 			bkey = bkeySeq[j];
   22972 			res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
   22973 			if (res == -1) {
   22974 			    return (-1);
   22975 			} else if (res == 0) {
   22976 			    /*
   22977 			    * One of the keys differs, so the key-sequence
   22978 			    * won't be equal; get out.
   22979 			    */
   22980 			    break;
   22981 			}
   22982 		    }
   22983 		    if (res == 1) {
   22984 			/*
   22985 			* Duplicate key-sequence found.
   22986 			*/
   22987 			break;
   22988 		    }
   22989 		    i++;
   22990 		} while (i < targets->nbItems);
   22991 		if (i != targets->nbItems) {
   22992 		    xmlChar *str = NULL, *strB = NULL;
   22993 		    /*
   22994 		    * TODO: Try to report the key-sequence.
   22995 		    */
   22996 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
   22997 			XML_SCHEMAV_CVC_IDC, NULL,
   22998 			WXS_BASIC_CAST idc,
   22999 			"Duplicate key-sequence %s in %s",
   23000 			xmlSchemaFormatIDCKeySequence(vctxt, &str,
   23001 			    (*keySeq), nbKeys),
   23002 			xmlSchemaGetIDCDesignation(&strB, idc));
   23003 		    FREE_AND_NULL(str);
   23004 		    FREE_AND_NULL(strB);
   23005 		    goto selector_leave;
   23006 		}
   23007 	    }
   23008 	    /*
   23009 	    * Add a node-table item to the IDC binding.
   23010 	    */
   23011 	    ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
   23012 		sizeof(xmlSchemaPSVIIDCNode));
   23013 	    if (ntItem == NULL) {
   23014 		xmlSchemaVErrMemory(NULL,
   23015 		    "allocating an IDC node-table item", NULL);
   23016 		xmlFree(*keySeq);
   23017 		*keySeq = NULL;
   23018 		return(-1);
   23019 	    }
   23020 	    memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
   23021 
   23022 	    /*
   23023 	    * Store the node-table item in a global list.
   23024 	    */
   23025 	    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
   23026 		if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
   23027 		    xmlFree(ntItem);
   23028 		    xmlFree(*keySeq);
   23029 		    *keySeq = NULL;
   23030 		    return (-1);
   23031 		}
   23032 		ntItem->nodeQNameID = -1;
   23033 	    } else {
   23034 		/*
   23035 		* Save a cached QName for this node on the IDC node, to be
   23036 		* able to report it, even if the node is not saved.
   23037 		*/
   23038 		ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
   23039 		    vctxt->inode->localName, vctxt->inode->nsName);
   23040 		if (ntItem->nodeQNameID == -1) {
   23041 		    xmlFree(ntItem);
   23042 		    xmlFree(*keySeq);
   23043 		    *keySeq = NULL;
   23044 		    return (-1);
   23045 		}
   23046 	    }
   23047 	    /*
   23048 	    * Init the node-table item: Save the node, position and
   23049 	    * consume the key-sequence.
   23050 	    */
   23051 	    ntItem->node = vctxt->node;
   23052 	    ntItem->nodeLine = vctxt->inode->nodeLine;
   23053 	    ntItem->keys = *keySeq;
   23054 	    *keySeq = NULL;
   23055 #if 0
   23056 	    if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
   23057 #endif
   23058 	    if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
   23059 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
   23060 		    /*
   23061 		    * Free the item, since keyref items won't be
   23062 		    * put on a global list.
   23063 		    */
   23064 		    xmlFree(ntItem->keys);
   23065 		    xmlFree(ntItem);
   23066 		}
   23067 		return (-1);
   23068 	    }
   23069 
   23070 	    goto selector_leave;
   23071 selector_key_error:
   23072 	    {
   23073 		xmlChar *str = NULL;
   23074 		/*
   23075 		* 4.2.1 (KEY) The target node set and the
   23076 		* qualified node set are equal, that is, every
   23077 		* member of the target node set is also a member
   23078 		* of the qualified node set and vice versa.
   23079 		*/
   23080 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   23081 		    XML_SCHEMAV_CVC_IDC, NULL,
   23082 		    WXS_BASIC_CAST idc,
   23083 		    "Not all fields of %s evaluate to a node",
   23084 		    xmlSchemaGetIDCDesignation(&str, idc), NULL);
   23085 		FREE_AND_NULL(str);
   23086 	    }
   23087 selector_leave:
   23088 	    /*
   23089 	    * Free the key-sequence if not added to the IDC table.
   23090 	    */
   23091 	    if ((keySeq != NULL) && (*keySeq != NULL)) {
   23092 		xmlFree(*keySeq);
   23093 		*keySeq = NULL;
   23094 	    }
   23095 	} /* if selector */
   23096 
   23097 	sto->nbHistory--;
   23098 
   23099 deregister_check:
   23100 	/*
   23101 	* Deregister state objects if they reach the depth of creation.
   23102 	*/
   23103 	if ((sto->nbHistory == 0) && (sto->depth == depth)) {
   23104 #ifdef DEBUG_IDC
   23105 	    xmlGenericError(xmlGenericErrorContext, "IDC:   STO pop '%s'\n",
   23106 		sto->sel->xpath);
   23107 #endif
   23108 	    if (vctxt->xpathStates != sto) {
   23109 		VERROR_INT("xmlSchemaXPathProcessHistory",
   23110 		    "The state object to be removed is not the first "
   23111 		    "in the list");
   23112 	    }
   23113 	    nextsto = sto->next;
   23114 	    /*
   23115 	    * Unlink from the list of active XPath state objects.
   23116 	    */
   23117 	    vctxt->xpathStates = sto->next;
   23118 	    sto->next = vctxt->xpathStatePool;
   23119 	    /*
   23120 	    * Link it to the pool of reusable state objects.
   23121 	    */
   23122 	    vctxt->xpathStatePool = sto;
   23123 	    sto = nextsto;
   23124 	} else
   23125 	    sto = sto->next;
   23126     } /* while (sto != NULL) */
   23127     return (0);
   23128 }
   23129 
   23130 /**
   23131  * xmlSchemaIDCRegisterMatchers:
   23132  * @vctxt: the WXS validation context
   23133  * @elemDecl: the element declaration
   23134  *
   23135  * Creates helper objects to evaluate IDC selectors/fields
   23136  * successively.
   23137  *
   23138  * Returns 0 if OK and -1 on internal errors.
   23139  */
   23140 static int
   23141 xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
   23142 			     xmlSchemaElementPtr elemDecl)
   23143 {
   23144     xmlSchemaIDCMatcherPtr matcher, last = NULL;
   23145     xmlSchemaIDCPtr idc, refIdc;
   23146     xmlSchemaIDCAugPtr aidc;
   23147 
   23148     idc = (xmlSchemaIDCPtr) elemDecl->idcs;
   23149     if (idc == NULL)
   23150 	return (0);
   23151 
   23152 #ifdef DEBUG_IDC
   23153     {
   23154 	xmlChar *str = NULL;
   23155 	xmlGenericError(xmlGenericErrorContext,
   23156 	    "IDC: REGISTER on %s, depth %d\n",
   23157 	    (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
   23158 		vctxt->inode->localName), vctxt->depth);
   23159 	FREE_AND_NULL(str)
   23160     }
   23161 #endif
   23162     if (vctxt->inode->idcMatchers != NULL) {
   23163 	VERROR_INT("xmlSchemaIDCRegisterMatchers",
   23164 	    "The chain of IDC matchers is expected to be empty");
   23165 	return (-1);
   23166     }
   23167     do {
   23168 	if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
   23169 	    /*
   23170 	    * Since IDCs bubbles are expensive we need to know the
   23171 	    * depth at which the bubbles should stop; this will be
   23172 	    * the depth of the top-most keyref IDC. If no keyref
   23173 	    * references a key/unique IDC, the keyrefDepth will
   23174 	    * be -1, indicating that no bubbles are needed.
   23175 	    */
   23176 	    refIdc = (xmlSchemaIDCPtr) idc->ref->item;
   23177 	    if (refIdc != NULL) {
   23178 		/*
   23179 		* Remember that we have keyrefs on this node.
   23180 		*/
   23181 		vctxt->inode->hasKeyrefs = 1;
   23182 		/*
   23183 		* Lookup the referenced augmented IDC info.
   23184 		*/
   23185 		aidc = vctxt->aidcs;
   23186 		while (aidc != NULL) {
   23187 		    if (aidc->def == refIdc)
   23188 			break;
   23189 		    aidc = aidc->next;
   23190 		}
   23191 		if (aidc == NULL) {
   23192 		    VERROR_INT("xmlSchemaIDCRegisterMatchers",
   23193 			"Could not find an augmented IDC item for an IDC "
   23194 			"definition");
   23195 		    return (-1);
   23196 		}
   23197 		if ((aidc->keyrefDepth == -1) ||
   23198 		    (vctxt->depth < aidc->keyrefDepth))
   23199 		    aidc->keyrefDepth = vctxt->depth;
   23200 	    }
   23201 	}
   23202 	/*
   23203 	* Lookup the augmented IDC item for the IDC definition.
   23204 	*/
   23205 	aidc = vctxt->aidcs;
   23206 	while (aidc != NULL) {
   23207 	    if (aidc->def == idc)
   23208 		break;
   23209 	    aidc = aidc->next;
   23210 	}
   23211 	if (aidc == NULL) {
   23212 	    VERROR_INT("xmlSchemaIDCRegisterMatchers",
   23213 		"Could not find an augmented IDC item for an IDC definition");
   23214 	    return (-1);
   23215 	}
   23216 	/*
   23217 	* Create an IDC matcher for every IDC definition.
   23218 	*/
   23219 	if (vctxt->idcMatcherCache != NULL) {
   23220 	    /*
   23221 	    * Reuse a cached matcher.
   23222 	    */
   23223 	    matcher = vctxt->idcMatcherCache;
   23224 	    vctxt->idcMatcherCache = matcher->nextCached;
   23225 	    matcher->nextCached = NULL;
   23226 	} else {
   23227 	    matcher = (xmlSchemaIDCMatcherPtr)
   23228 		xmlMalloc(sizeof(xmlSchemaIDCMatcher));
   23229 	    if (matcher == NULL) {
   23230 		xmlSchemaVErrMemory(vctxt,
   23231 		    "allocating an IDC matcher", NULL);
   23232 		return (-1);
   23233 	    }
   23234 	    memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
   23235 	}
   23236 	if (last == NULL)
   23237 	    vctxt->inode->idcMatchers = matcher;
   23238 	else
   23239 	    last->next = matcher;
   23240 	last = matcher;
   23241 
   23242 	matcher->type = IDC_MATCHER;
   23243 	matcher->depth = vctxt->depth;
   23244 	matcher->aidc = aidc;
   23245 	matcher->idcType = aidc->def->type;
   23246 #ifdef DEBUG_IDC
   23247 	xmlGenericError(xmlGenericErrorContext, "IDC:   register matcher\n");
   23248 #endif
   23249 	/*
   23250 	* Init the automaton state object.
   23251 	*/
   23252 	if (xmlSchemaIDCAddStateObject(vctxt, matcher,
   23253 	    idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
   23254 	    return (-1);
   23255 
   23256 	idc = idc->next;
   23257     } while (idc != NULL);
   23258     return (0);
   23259 }
   23260 
   23261 static int
   23262 xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
   23263 			   xmlSchemaNodeInfoPtr ielem)
   23264 {
   23265     xmlSchemaPSVIIDCBindingPtr bind;
   23266     int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
   23267     xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
   23268     xmlSchemaPSVIIDCNodePtr *targets, *dupls;
   23269 
   23270     xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
   23271     /* vctxt->createIDCNodeTables */
   23272     while (matcher != NULL) {
   23273 	/*
   23274 	* Skip keyref IDCs and empty IDC target-lists.
   23275 	*/
   23276 	if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
   23277 	    WXS_ILIST_IS_EMPTY(matcher->targets))
   23278 	{
   23279 	    matcher = matcher->next;
   23280 	    continue;
   23281 	}
   23282 	/*
   23283 	* If we _want_ the IDC node-table to be created in any case
   23284 	* then do so. Otherwise create them only if keyrefs need them.
   23285 	*/
   23286 	if ((! vctxt->createIDCNodeTables) &&
   23287 	    ((matcher->aidc->keyrefDepth == -1) ||
   23288 	     (matcher->aidc->keyrefDepth > vctxt->depth)))
   23289 	{
   23290 	    matcher = matcher->next;
   23291 	    continue;
   23292 	}
   23293 	/*
   23294 	* Get/create the IDC binding on this element for the IDC definition.
   23295 	*/
   23296 	bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
   23297 
   23298 	if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
   23299 	    dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
   23300 	    nbDupls = bind->dupls->nbItems;
   23301 	} else {
   23302 	    dupls = NULL;
   23303 	    nbDupls = 0;
   23304 	}
   23305 	if (bind->nodeTable != NULL) {
   23306 	    nbNodeTable = bind->nbNodes;
   23307 	} else {
   23308 	    nbNodeTable = 0;
   23309 	}
   23310 
   23311 	if ((nbNodeTable == 0) && (nbDupls == 0)) {
   23312 	    /*
   23313 	    * Transfer all IDC target-nodes to the IDC node-table.
   23314 	    */
   23315 	    bind->nodeTable =
   23316 		(xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
   23317 	    bind->sizeNodes = matcher->targets->sizeItems;
   23318 	    bind->nbNodes = matcher->targets->nbItems;
   23319 
   23320 	    matcher->targets->items = NULL;
   23321 	    matcher->targets->sizeItems = 0;
   23322 	    matcher->targets->nbItems = 0;
   23323 	} else {
   23324 	    /*
   23325 	    * Compare the key-sequences and add to the IDC node-table.
   23326 	    */
   23327 	    nbTargets = matcher->targets->nbItems;
   23328 	    targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
   23329 	    nbFields = matcher->aidc->def->nbFields;
   23330 	    i = 0;
   23331 	    do {
   23332 		keys = targets[i]->keys;
   23333 		if (nbDupls) {
   23334 		    /*
   23335 		    * Search in already found duplicates first.
   23336 		    */
   23337 		    j = 0;
   23338 		    do {
   23339 			if (nbFields == 1) {
   23340 			    res = xmlSchemaAreValuesEqual(keys[0]->val,
   23341 				dupls[j]->keys[0]->val);
   23342 			    if (res == -1)
   23343 				goto internal_error;
   23344 			    if (res == 1) {
   23345 				/*
   23346 				* Equal key-sequence.
   23347 				*/
   23348 				goto next_target;
   23349 			    }
   23350 			} else {
   23351 			    res = 0;
   23352 			    ntkeys = dupls[j]->keys;
   23353 			    for (k = 0; k < nbFields; k++) {
   23354 				res = xmlSchemaAreValuesEqual(keys[k]->val,
   23355 				    ntkeys[k]->val);
   23356 				if (res == -1)
   23357 				    goto internal_error;
   23358 				if (res == 0) {
   23359 				    /*
   23360 				    * One of the keys differs.
   23361 				    */
   23362 				    break;
   23363 				}
   23364 			    }
   23365 			    if (res == 1) {
   23366 				/*
   23367 				* Equal key-sequence found.
   23368 				*/
   23369 				goto next_target;
   23370 			    }
   23371 			}
   23372 			j++;
   23373 		    } while (j < nbDupls);
   23374 		}
   23375 		if (nbNodeTable) {
   23376 		    j = 0;
   23377 		    do {
   23378 			if (nbFields == 1) {
   23379 			    res = xmlSchemaAreValuesEqual(keys[0]->val,
   23380 				bind->nodeTable[j]->keys[0]->val);
   23381 			    if (res == -1)
   23382 				goto internal_error;
   23383 			    if (res == 0) {
   23384 				/*
   23385 				* The key-sequence differs.
   23386 				*/
   23387 				goto next_node_table_entry;
   23388 			    }
   23389 			} else {
   23390 			    res = 0;
   23391 			    ntkeys = bind->nodeTable[j]->keys;
   23392 			    for (k = 0; k < nbFields; k++) {
   23393 				res = xmlSchemaAreValuesEqual(keys[k]->val,
   23394 				    ntkeys[k]->val);
   23395 				if (res == -1)
   23396 				    goto internal_error;
   23397 				if (res == 0) {
   23398 				    /*
   23399 				    * One of the keys differs.
   23400 				    */
   23401 				    goto next_node_table_entry;
   23402 				}
   23403 			    }
   23404 			}
   23405 			/*
   23406 			* Add the duplicate to the list of duplicates.
   23407 			*/
   23408 			if (bind->dupls == NULL) {
   23409 			    bind->dupls = xmlSchemaItemListCreate();
   23410 			    if (bind->dupls == NULL)
   23411 				goto internal_error;
   23412 			}
   23413 			if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
   23414 			    goto internal_error;
   23415 			/*
   23416 			* Remove the duplicate entry from the IDC node-table.
   23417 			*/
   23418 			bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
   23419 			bind->nbNodes--;
   23420 
   23421 			goto next_target;
   23422 
   23423 next_node_table_entry:
   23424 			j++;
   23425 		    } while (j < nbNodeTable);
   23426 		}
   23427 		/*
   23428 		* If everything is fine, then add the IDC target-node to
   23429 		* the IDC node-table.
   23430 		*/
   23431 		if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
   23432 		    goto internal_error;
   23433 
   23434 next_target:
   23435 		i++;
   23436 	    } while (i < nbTargets);
   23437 	}
   23438 	matcher = matcher->next;
   23439     }
   23440     return(0);
   23441 
   23442 internal_error:
   23443     return(-1);
   23444 }
   23445 
   23446 /**
   23447  * xmlSchemaBubbleIDCNodeTables:
   23448  * @depth: the current tree depth
   23449  *
   23450  * Merges IDC bindings of an element at @depth into the corresponding IDC
   23451  * bindings of its parent element. If a duplicate note-table entry is found,
   23452  * both, the parent node-table entry and child entry are discarded from the
   23453  * node-table of the parent.
   23454  *
   23455  * Returns 0 if OK and -1 on internal errors.
   23456  */
   23457 static int
   23458 xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
   23459 {
   23460     xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
   23461     xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
   23462     xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
   23463     xmlSchemaIDCAugPtr aidc;
   23464     int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
   23465 
   23466     bind = vctxt->inode->idcTable;
   23467     if (bind == NULL) {
   23468 	/* Fine, no table, no bubbles. */
   23469 	return (0);
   23470     }
   23471 
   23472     parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
   23473     /*
   23474     * Walk all bindings; create new or add to existing bindings.
   23475     * Remove duplicate key-sequences.
   23476     */
   23477     while (bind != NULL) {
   23478 
   23479 	if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
   23480 	    goto next_binding;
   23481 	/*
   23482 	* Check if the key/unique IDC table needs to be bubbled.
   23483 	*/
   23484 	if (! vctxt->createIDCNodeTables) {
   23485 	    aidc = vctxt->aidcs;
   23486 	    do {
   23487 		if (aidc->def == bind->definition) {
   23488 		    if ((aidc->keyrefDepth == -1) ||
   23489 			(aidc->keyrefDepth >= vctxt->depth)) {
   23490 			goto next_binding;
   23491 		    }
   23492 		    break;
   23493 		}
   23494 		aidc = aidc->next;
   23495 	    } while (aidc != NULL);
   23496 	}
   23497 
   23498 	if (parTable != NULL)
   23499 	    parBind = *parTable;
   23500 	/*
   23501 	* Search a matching parent binding for the
   23502 	* IDC definition.
   23503 	*/
   23504 	while (parBind != NULL) {
   23505 	    if (parBind->definition == bind->definition)
   23506 		break;
   23507 	    parBind = parBind->next;
   23508 	}
   23509 
   23510 	if (parBind != NULL) {
   23511 	    /*
   23512 	    * Compare every node-table entry of the child node,
   23513 	    * i.e. the key-sequence within, ...
   23514 	    */
   23515 	    oldNum = parBind->nbNodes; /* Skip newly added items. */
   23516 
   23517 	    if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
   23518 		oldDupls = parBind->dupls->nbItems;
   23519 		dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
   23520 	    } else {
   23521 		dupls = NULL;
   23522 		oldDupls = 0;
   23523 	    }
   23524 
   23525 	    parNodes = parBind->nodeTable;
   23526 	    nbFields = bind->definition->nbFields;
   23527 
   23528 	    for (i = 0; i < bind->nbNodes; i++) {
   23529 		node = bind->nodeTable[i];
   23530 		if (node == NULL)
   23531 		    continue;
   23532 		/*
   23533 		* ...with every key-sequence of the parent node, already
   23534 		* evaluated to be a duplicate key-sequence.
   23535 		*/
   23536 		if (oldDupls) {
   23537 		    j = 0;
   23538 		    while (j < oldDupls) {
   23539 			if (nbFields == 1) {
   23540 			    ret = xmlSchemaAreValuesEqual(
   23541 				node->keys[0]->val,
   23542 				dupls[j]->keys[0]->val);
   23543 			    if (ret == -1)
   23544 				goto internal_error;
   23545 			    if (ret == 0) {
   23546 				j++;
   23547 				continue;
   23548 			    }
   23549 			} else {
   23550 			    parNode = dupls[j];
   23551 			    for (k = 0; k < nbFields; k++) {
   23552 				ret = xmlSchemaAreValuesEqual(
   23553 				    node->keys[k]->val,
   23554 				    parNode->keys[k]->val);
   23555 				if (ret == -1)
   23556 				    goto internal_error;
   23557 				if (ret == 0)
   23558 				    break;
   23559 			    }
   23560 			}
   23561 			if (ret == 1)
   23562 			    /* Duplicate found. */
   23563 			    break;
   23564 			j++;
   23565 		    }
   23566 		    if (j != oldDupls) {
   23567 			/* Duplicate found. Skip this entry. */
   23568 			continue;
   23569 		    }
   23570 		}
   23571 		/*
   23572 		* ... and with every key-sequence of the parent node.
   23573 		*/
   23574 		if (oldNum) {
   23575 		    j = 0;
   23576 		    while (j < oldNum) {
   23577 			parNode = parNodes[j];
   23578 			if (nbFields == 1) {
   23579 			    ret = xmlSchemaAreValuesEqual(
   23580 				node->keys[0]->val,
   23581 				parNode->keys[0]->val);
   23582 			    if (ret == -1)
   23583 				goto internal_error;
   23584 			    if (ret == 0) {
   23585 				j++;
   23586 				continue;
   23587 			    }
   23588 			} else {
   23589 			    for (k = 0; k < nbFields; k++) {
   23590 				ret = xmlSchemaAreValuesEqual(
   23591 				    node->keys[k]->val,
   23592 				    parNode->keys[k]->val);
   23593 				if (ret == -1)
   23594 				    goto internal_error;
   23595 				if (ret == 0)
   23596 				    break;
   23597 			    }
   23598 			}
   23599 			if (ret == 1)
   23600 			    /* Duplicate found. */
   23601 			    break;
   23602 			j++;
   23603 		    }
   23604 		    if (j != oldNum) {
   23605 			/*
   23606 			* Handle duplicates. Move the duplicate in
   23607 			* the parent's node-table to the list of
   23608 			* duplicates.
   23609 			*/
   23610 			oldNum--;
   23611 			parBind->nbNodes--;
   23612 			/*
   23613 			* Move last old item to pos of duplicate.
   23614 			*/
   23615 			parNodes[j] = parNodes[oldNum];
   23616 
   23617 			if (parBind->nbNodes != oldNum) {
   23618 			    /*
   23619 			    * If new items exist, move last new item to
   23620 			    * last of old items.
   23621 			    */
   23622 			    parNodes[oldNum] =
   23623 				parNodes[parBind->nbNodes];
   23624 			}
   23625 			if (parBind->dupls == NULL) {
   23626 			    parBind->dupls = xmlSchemaItemListCreate();
   23627 			    if (parBind->dupls == NULL)
   23628 				goto internal_error;
   23629 			}
   23630 			xmlSchemaItemListAdd(parBind->dupls, parNode);
   23631 		    } else {
   23632 			/*
   23633 			* Add the node-table entry (node and key-sequence) of
   23634 			* the child node to the node table of the parent node.
   23635 			*/
   23636 			if (parBind->nodeTable == NULL) {
   23637 			    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   23638 				xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
   23639 			    if (parBind->nodeTable == NULL) {
   23640 				xmlSchemaVErrMemory(NULL,
   23641 				    "allocating IDC list of node-table items", NULL);
   23642 				goto internal_error;
   23643 			    }
   23644 			    parBind->sizeNodes = 1;
   23645 			} else if (parBind->nbNodes >= parBind->sizeNodes) {
   23646 			    parBind->sizeNodes *= 2;
   23647 			    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   23648 				xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
   23649 				sizeof(xmlSchemaPSVIIDCNodePtr));
   23650 			    if (parBind->nodeTable == NULL) {
   23651 				xmlSchemaVErrMemory(NULL,
   23652 				    "re-allocating IDC list of node-table items", NULL);
   23653 				goto internal_error;
   23654 			    }
   23655 			}
   23656 			parNodes = parBind->nodeTable;
   23657 			/*
   23658 			* Append the new node-table entry to the 'new node-table
   23659 			* entries' section.
   23660 			*/
   23661 			parNodes[parBind->nbNodes++] = node;
   23662 		    }
   23663 
   23664 		}
   23665 
   23666 	    }
   23667 	} else {
   23668 	    /*
   23669 	    * No binding for the IDC was found: create a new one and
   23670 	    * copy all node-tables.
   23671 	    */
   23672 	    parBind = xmlSchemaIDCNewBinding(bind->definition);
   23673 	    if (parBind == NULL)
   23674 		goto internal_error;
   23675 
   23676 	    /*
   23677 	    * TODO: Hmm, how to optimize the initial number of
   23678 	    * allocated entries?
   23679 	    */
   23680 	    if (bind->nbNodes != 0) {
   23681 		/*
   23682 		* Add all IDC node-table entries.
   23683 		*/
   23684 		if (! vctxt->psviExposeIDCNodeTables) {
   23685 		    /*
   23686 		    * Just move the entries.
   23687 		    * NOTE: this is quite save here, since
   23688 		    * all the keyref lookups have already been
   23689 		    * performed.
   23690 		    */
   23691 		    parBind->nodeTable = bind->nodeTable;
   23692 		    bind->nodeTable = NULL;
   23693 		    parBind->sizeNodes = bind->sizeNodes;
   23694 		    bind->sizeNodes = 0;
   23695 		    parBind->nbNodes = bind->nbNodes;
   23696 		    bind->nbNodes = 0;
   23697 		} else {
   23698 		    /*
   23699 		    * Copy the entries.
   23700 		    */
   23701 		    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   23702 			xmlMalloc(bind->nbNodes *
   23703 			sizeof(xmlSchemaPSVIIDCNodePtr));
   23704 		    if (parBind->nodeTable == NULL) {
   23705 			xmlSchemaVErrMemory(NULL,
   23706 			    "allocating an array of IDC node-table "
   23707 			    "items", NULL);
   23708 			xmlSchemaIDCFreeBinding(parBind);
   23709 			goto internal_error;
   23710 		    }
   23711 		    parBind->sizeNodes = bind->nbNodes;
   23712 		    parBind->nbNodes = bind->nbNodes;
   23713 		    memcpy(parBind->nodeTable, bind->nodeTable,
   23714 			bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
   23715 		}
   23716 	    }
   23717 	    if (bind->dupls) {
   23718 		/*
   23719 		* Move the duplicates.
   23720 		*/
   23721 		if (parBind->dupls != NULL)
   23722 		    xmlSchemaItemListFree(parBind->dupls);
   23723 		parBind->dupls = bind->dupls;
   23724 		bind->dupls = NULL;
   23725 	    }
   23726             if (parTable != NULL) {
   23727                 if (*parTable == NULL)
   23728                     *parTable = parBind;
   23729                 else {
   23730                     parBind->next = *parTable;
   23731                     *parTable = parBind;
   23732                 }
   23733             }
   23734 	}
   23735 
   23736 next_binding:
   23737 	bind = bind->next;
   23738     }
   23739     return (0);
   23740 
   23741 internal_error:
   23742     return(-1);
   23743 }
   23744 
   23745 /**
   23746  * xmlSchemaCheckCVCIDCKeyRef:
   23747  * @vctxt: the WXS validation context
   23748  * @elemDecl: the element declaration
   23749  *
   23750  * Check the cvc-idc-keyref constraints.
   23751  */
   23752 static int
   23753 xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
   23754 {
   23755     xmlSchemaIDCMatcherPtr matcher;
   23756     xmlSchemaPSVIIDCBindingPtr bind;
   23757 
   23758     matcher = vctxt->inode->idcMatchers;
   23759     /*
   23760     * Find a keyref.
   23761     */
   23762     while (matcher != NULL) {
   23763 	if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
   23764 	    matcher->targets &&
   23765 	    matcher->targets->nbItems)
   23766 	{
   23767 	    int i, j, k, res, nbFields, hasDupls;
   23768 	    xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
   23769 	    xmlSchemaPSVIIDCNodePtr refNode = NULL;
   23770 
   23771 	    nbFields = matcher->aidc->def->nbFields;
   23772 
   23773 	    /*
   23774 	    * Find the IDC node-table for the referenced IDC key/unique.
   23775 	    */
   23776 	    bind = vctxt->inode->idcTable;
   23777 	    while (bind != NULL) {
   23778 		if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
   23779 		    bind->definition)
   23780 		    break;
   23781 		bind = bind->next;
   23782 	    }
   23783 	    hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
   23784 	    /*
   23785 	    * Search for a matching key-sequences.
   23786 	    */
   23787 	    for (i = 0; i < matcher->targets->nbItems; i++) {
   23788 		res = 0;
   23789 		refNode = matcher->targets->items[i];
   23790 		if (bind != NULL) {
   23791 		    refKeys = refNode->keys;
   23792 		    for (j = 0; j < bind->nbNodes; j++) {
   23793 			keys = bind->nodeTable[j]->keys;
   23794 			for (k = 0; k < nbFields; k++) {
   23795 			    res = xmlSchemaAreValuesEqual(keys[k]->val,
   23796 				refKeys[k]->val);
   23797 			    if (res == 0)
   23798 				break;
   23799 			    else if (res == -1) {
   23800 				return (-1);
   23801 			    }
   23802 			}
   23803 			if (res == 1) {
   23804 			    /*
   23805 			    * Match found.
   23806 			    */
   23807 			    break;
   23808 			}
   23809 		    }
   23810 		    if ((res == 0) && hasDupls) {
   23811 			/*
   23812 			* Search in duplicates
   23813 			*/
   23814 			for (j = 0; j < bind->dupls->nbItems; j++) {
   23815 			    keys = ((xmlSchemaPSVIIDCNodePtr)
   23816 				bind->dupls->items[j])->keys;
   23817 			    for (k = 0; k < nbFields; k++) {
   23818 				res = xmlSchemaAreValuesEqual(keys[k]->val,
   23819 				    refKeys[k]->val);
   23820 				if (res == 0)
   23821 				    break;
   23822 				else if (res == -1) {
   23823 				    return (-1);
   23824 				}
   23825 			    }
   23826 			    if (res == 1) {
   23827 				/*
   23828 				* Match in duplicates found.
   23829 				*/
   23830 				xmlChar *str = NULL, *strB = NULL;
   23831 				xmlSchemaKeyrefErr(vctxt,
   23832 				    XML_SCHEMAV_CVC_IDC, refNode,
   23833 				    (xmlSchemaTypePtr) matcher->aidc->def,
   23834 				    "More than one match found for "
   23835 				    "key-sequence %s of keyref '%s'",
   23836 				    xmlSchemaFormatIDCKeySequence(vctxt, &str,
   23837 					refNode->keys, nbFields),
   23838 				    xmlSchemaGetComponentQName(&strB,
   23839 					matcher->aidc->def));
   23840 				FREE_AND_NULL(str);
   23841 				FREE_AND_NULL(strB);
   23842 				break;
   23843 			    }
   23844 			}
   23845 		    }
   23846 		}
   23847 
   23848 		if (res == 0) {
   23849 		    xmlChar *str = NULL, *strB = NULL;
   23850 		    xmlSchemaKeyrefErr(vctxt,
   23851 			XML_SCHEMAV_CVC_IDC, refNode,
   23852 			(xmlSchemaTypePtr) matcher->aidc->def,
   23853 			"No match found for key-sequence %s of keyref '%s'",
   23854 			xmlSchemaFormatIDCKeySequence(vctxt, &str,
   23855 			    refNode->keys, nbFields),
   23856 			xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
   23857 		    FREE_AND_NULL(str);
   23858 		    FREE_AND_NULL(strB);
   23859 		}
   23860 	    }
   23861 	}
   23862 	matcher = matcher->next;
   23863     }
   23864     /* TODO: Return an error if any error encountered. */
   23865     return (0);
   23866 }
   23867 
   23868 /************************************************************************
   23869  * 									*
   23870  * 			XML Reader validation code                      *
   23871  * 									*
   23872  ************************************************************************/
   23873 
   23874 static xmlSchemaAttrInfoPtr
   23875 xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
   23876 {
   23877     xmlSchemaAttrInfoPtr iattr;
   23878     /*
   23879     * Grow/create list of attribute infos.
   23880     */
   23881     if (vctxt->attrInfos == NULL) {
   23882 	vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
   23883 	    xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
   23884 	vctxt->sizeAttrInfos = 1;
   23885 	if (vctxt->attrInfos == NULL) {
   23886 	    xmlSchemaVErrMemory(vctxt,
   23887 		"allocating attribute info list", NULL);
   23888 	    return (NULL);
   23889 	}
   23890     } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
   23891 	vctxt->sizeAttrInfos++;
   23892 	vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
   23893 	    xmlRealloc(vctxt->attrInfos,
   23894 		vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
   23895 	if (vctxt->attrInfos == NULL) {
   23896 	    xmlSchemaVErrMemory(vctxt,
   23897 		"re-allocating attribute info list", NULL);
   23898 	    return (NULL);
   23899 	}
   23900     } else {
   23901 	iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
   23902 	if (iattr->localName != NULL) {
   23903 	    VERROR_INT("xmlSchemaGetFreshAttrInfo",
   23904 		"attr info not cleared");
   23905 	    return (NULL);
   23906 	}
   23907 	iattr->nodeType = XML_ATTRIBUTE_NODE;
   23908 	return (iattr);
   23909     }
   23910     /*
   23911     * Create an attribute info.
   23912     */
   23913     iattr = (xmlSchemaAttrInfoPtr)
   23914 	xmlMalloc(sizeof(xmlSchemaAttrInfo));
   23915     if (iattr == NULL) {
   23916 	xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
   23917 	return (NULL);
   23918     }
   23919     memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
   23920     iattr->nodeType = XML_ATTRIBUTE_NODE;
   23921     vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
   23922 
   23923     return (iattr);
   23924 }
   23925 
   23926 static int
   23927 xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
   23928 			xmlNodePtr attrNode,
   23929 			int nodeLine,
   23930 			const xmlChar *localName,
   23931 			const xmlChar *nsName,
   23932 			int ownedNames,
   23933 			xmlChar *value,
   23934 			int ownedValue)
   23935 {
   23936     xmlSchemaAttrInfoPtr attr;
   23937 
   23938     attr = xmlSchemaGetFreshAttrInfo(vctxt);
   23939     if (attr == NULL) {
   23940 	VERROR_INT("xmlSchemaPushAttribute",
   23941 	    "calling xmlSchemaGetFreshAttrInfo()");
   23942 	return (-1);
   23943     }
   23944     attr->node = attrNode;
   23945     attr->nodeLine = nodeLine;
   23946     attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
   23947     attr->localName = localName;
   23948     attr->nsName = nsName;
   23949     if (ownedNames)
   23950 	attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
   23951     /*
   23952     * Evaluate if it's an XSI attribute.
   23953     */
   23954     if (nsName != NULL) {
   23955 	if (xmlStrEqual(localName, BAD_CAST "nil")) {
   23956 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
   23957 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
   23958 	    }
   23959 	} else if (xmlStrEqual(localName, BAD_CAST "type")) {
   23960 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
   23961 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
   23962 	    }
   23963 	} else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
   23964 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
   23965 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
   23966 	    }
   23967 	} else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
   23968 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
   23969 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
   23970 	    }
   23971 	} else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
   23972 	    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
   23973 	}
   23974     }
   23975     attr->value = value;
   23976     if (ownedValue)
   23977 	attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
   23978     if (attr->metaType != 0)
   23979 	attr->state = XML_SCHEMAS_ATTR_META;
   23980     return (0);
   23981 }
   23982 
   23983 /**
   23984  * xmlSchemaClearElemInfo:
   23985  * @vctxt: the WXS validation context
   23986  * @ielem: the element information item
   23987  */
   23988 static void
   23989 xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
   23990 		       xmlSchemaNodeInfoPtr ielem)
   23991 {
   23992     ielem->hasKeyrefs = 0;
   23993     ielem->appliedXPath = 0;
   23994     if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
   23995 	FREE_AND_NULL(ielem->localName);
   23996 	FREE_AND_NULL(ielem->nsName);
   23997     } else {
   23998 	ielem->localName = NULL;
   23999 	ielem->nsName = NULL;
   24000     }
   24001     if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
   24002 	FREE_AND_NULL(ielem->value);
   24003     } else {
   24004 	ielem->value = NULL;
   24005     }
   24006     if (ielem->val != NULL) {
   24007 	/*
   24008 	* PSVI TODO: Be careful not to free it when the value is
   24009 	* exposed via PSVI.
   24010 	*/
   24011 	xmlSchemaFreeValue(ielem->val);
   24012 	ielem->val = NULL;
   24013     }
   24014     if (ielem->idcMatchers != NULL) {
   24015 	/*
   24016 	* REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
   24017 	*   Does it work?
   24018 	*/
   24019 	xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
   24020 #if 0
   24021 	xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
   24022 #endif
   24023 	ielem->idcMatchers = NULL;
   24024     }
   24025     if (ielem->idcTable != NULL) {
   24026 	/*
   24027 	* OPTIMIZE TODO: Use a pool of IDC tables??.
   24028 	*/
   24029 	xmlSchemaIDCFreeIDCTable(ielem->idcTable);
   24030 	ielem->idcTable = NULL;
   24031     }
   24032     if (ielem->regexCtxt != NULL) {
   24033 	xmlRegFreeExecCtxt(ielem->regexCtxt);
   24034 	ielem->regexCtxt = NULL;
   24035     }
   24036     if (ielem->nsBindings != NULL) {
   24037 	xmlFree((xmlChar **)ielem->nsBindings);
   24038 	ielem->nsBindings = NULL;
   24039 	ielem->nbNsBindings = 0;
   24040 	ielem->sizeNsBindings = 0;
   24041     }
   24042 }
   24043 
   24044 /**
   24045  * xmlSchemaGetFreshElemInfo:
   24046  * @vctxt: the schema validation context
   24047  *
   24048  * Creates/reuses and initializes the element info item for
   24049  * the currect tree depth.
   24050  *
   24051  * Returns the element info item or NULL on API or internal errors.
   24052  */
   24053 static xmlSchemaNodeInfoPtr
   24054 xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
   24055 {
   24056     xmlSchemaNodeInfoPtr info = NULL;
   24057 
   24058     if (vctxt->depth > vctxt->sizeElemInfos) {
   24059 	VERROR_INT("xmlSchemaGetFreshElemInfo",
   24060 	    "inconsistent depth encountered");
   24061 	return (NULL);
   24062     }
   24063     if (vctxt->elemInfos == NULL) {
   24064 	vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
   24065 	    xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
   24066 	if (vctxt->elemInfos == NULL) {
   24067 	    xmlSchemaVErrMemory(vctxt,
   24068 		"allocating the element info array", NULL);
   24069 	    return (NULL);
   24070 	}
   24071 	memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
   24072 	vctxt->sizeElemInfos = 10;
   24073     } else if (vctxt->sizeElemInfos <= vctxt->depth) {
   24074 	int i = vctxt->sizeElemInfos;
   24075 
   24076 	vctxt->sizeElemInfos *= 2;
   24077 	vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
   24078 	    xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
   24079 	    sizeof(xmlSchemaNodeInfoPtr));
   24080 	if (vctxt->elemInfos == NULL) {
   24081 	    xmlSchemaVErrMemory(vctxt,
   24082 		"re-allocating the element info array", NULL);
   24083 	    return (NULL);
   24084 	}
   24085 	/*
   24086 	* We need the new memory to be NULLed.
   24087 	* TODO: Use memset instead?
   24088 	*/
   24089 	for (; i < vctxt->sizeElemInfos; i++)
   24090 	    vctxt->elemInfos[i] = NULL;
   24091     } else
   24092 	info = vctxt->elemInfos[vctxt->depth];
   24093 
   24094     if (info == NULL) {
   24095 	info = (xmlSchemaNodeInfoPtr)
   24096 	    xmlMalloc(sizeof(xmlSchemaNodeInfo));
   24097 	if (info == NULL) {
   24098 	    xmlSchemaVErrMemory(vctxt,
   24099 		"allocating an element info", NULL);
   24100 	    return (NULL);
   24101 	}
   24102 	vctxt->elemInfos[vctxt->depth] = info;
   24103     } else {
   24104 	if (info->localName != NULL) {
   24105 	    VERROR_INT("xmlSchemaGetFreshElemInfo",
   24106 		"elem info has not been cleared");
   24107 	    return (NULL);
   24108 	}
   24109     }
   24110     memset(info, 0, sizeof(xmlSchemaNodeInfo));
   24111     info->nodeType = XML_ELEMENT_NODE;
   24112     info->depth = vctxt->depth;
   24113 
   24114     return (info);
   24115 }
   24116 
   24117 #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
   24118 #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
   24119 #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
   24120 
   24121 static int
   24122 xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
   24123 			xmlNodePtr node,
   24124 			xmlSchemaTypePtr type,
   24125 			xmlSchemaValType valType,
   24126 			const xmlChar * value,
   24127 			xmlSchemaValPtr val,
   24128 			unsigned long length,
   24129 			int fireErrors)
   24130 {
   24131     int ret, error = 0;
   24132 
   24133     xmlSchemaTypePtr tmpType;
   24134     xmlSchemaFacetLinkPtr facetLink;
   24135     xmlSchemaFacetPtr facet;
   24136     unsigned long len = 0;
   24137     xmlSchemaWhitespaceValueType ws;
   24138 
   24139     /*
   24140     * In Libxml2, derived built-in types have currently no explicit facets.
   24141     */
   24142     if (type->type == XML_SCHEMA_TYPE_BASIC)
   24143 	return (0);
   24144 
   24145     /*
   24146     * NOTE: Do not jump away, if the facetSet of the given type is
   24147     * empty: until now, "pattern" and "enumeration" facets of the
   24148     * *base types* need to be checked as well.
   24149     */
   24150     if (type->facetSet == NULL)
   24151 	goto pattern_and_enum;
   24152 
   24153     if (! WXS_IS_ATOMIC(type)) {
   24154 	if (WXS_IS_LIST(type))
   24155 	    goto WXS_IS_LIST;
   24156 	else
   24157 	    goto pattern_and_enum;
   24158     }
   24159     /*
   24160     * Whitespace handling is only of importance for string-based
   24161     * types.
   24162     */
   24163     tmpType = xmlSchemaGetPrimitiveType(type);
   24164     if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
   24165 	WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
   24166 	ws = xmlSchemaGetWhiteSpaceFacetValue(type);
   24167     } else
   24168 	ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
   24169     /*
   24170     * If the value was not computed (for string or
   24171     * anySimpleType based types), then use the provided
   24172     * type.
   24173     */
   24174     if (val == NULL)
   24175 	valType = valType;
   24176     else
   24177 	valType = xmlSchemaGetValType(val);
   24178 
   24179     ret = 0;
   24180     for (facetLink = type->facetSet; facetLink != NULL;
   24181 	facetLink = facetLink->next) {
   24182 	/*
   24183 	* Skip the pattern "whiteSpace": it is used to
   24184 	* format the character content beforehand.
   24185 	*/
   24186 	switch (facetLink->facet->type) {
   24187 	    case XML_SCHEMA_FACET_WHITESPACE:
   24188 	    case XML_SCHEMA_FACET_PATTERN:
   24189 	    case XML_SCHEMA_FACET_ENUMERATION:
   24190 		continue;
   24191 	    case XML_SCHEMA_FACET_LENGTH:
   24192 	    case XML_SCHEMA_FACET_MINLENGTH:
   24193 	    case XML_SCHEMA_FACET_MAXLENGTH:
   24194 		ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
   24195 		    valType, value, val, &len, ws);
   24196 		break;
   24197 	    default:
   24198 		ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
   24199 		    valType, value, val, ws);
   24200 		break;
   24201 	}
   24202 	if (ret < 0) {
   24203 	    AERROR_INT("xmlSchemaValidateFacets",
   24204 		"validating against a atomic type facet");
   24205 	    return (-1);
   24206 	} else if (ret > 0) {
   24207 	    if (fireErrors)
   24208 		xmlSchemaFacetErr(actxt, ret, node,
   24209 		value, len, type, facetLink->facet, NULL, NULL, NULL);
   24210 	    else
   24211 		return (ret);
   24212 	    if (error == 0)
   24213 		error = ret;
   24214 	}
   24215 	ret = 0;
   24216     }
   24217 
   24218 WXS_IS_LIST:
   24219     if (! WXS_IS_LIST(type))
   24220 	goto pattern_and_enum;
   24221     /*
   24222     * "length", "minLength" and "maxLength" of list types.
   24223     */
   24224     ret = 0;
   24225     for (facetLink = type->facetSet; facetLink != NULL;
   24226 	facetLink = facetLink->next) {
   24227 
   24228 	switch (facetLink->facet->type) {
   24229 	    case XML_SCHEMA_FACET_LENGTH:
   24230 	    case XML_SCHEMA_FACET_MINLENGTH:
   24231 	    case XML_SCHEMA_FACET_MAXLENGTH:
   24232 		ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
   24233 		    value, length, NULL);
   24234 		break;
   24235 	    default:
   24236 		continue;
   24237 	}
   24238 	if (ret < 0) {
   24239 	    AERROR_INT("xmlSchemaValidateFacets",
   24240 		"validating against a list type facet");
   24241 	    return (-1);
   24242 	} else if (ret > 0) {
   24243 	    if (fireErrors)
   24244 		xmlSchemaFacetErr(actxt, ret, node,
   24245 		value, length, type, facetLink->facet, NULL, NULL, NULL);
   24246 	    else
   24247 		return (ret);
   24248 	    if (error == 0)
   24249 		error = ret;
   24250 	}
   24251 	ret = 0;
   24252     }
   24253 
   24254 pattern_and_enum:
   24255     if (error >= 0) {
   24256 	int found = 0;
   24257 	/*
   24258 	* Process enumerations. Facet values are in the value space
   24259 	* of the defining type's base type. This seems to be a bug in the
   24260 	* XML Schema 1.0 spec. Use the whitespace type of the base type.
   24261 	* Only the first set of enumerations in the ancestor-or-self axis
   24262 	* is used for validation.
   24263 	*/
   24264 	ret = 0;
   24265 	tmpType = type;
   24266 	do {
   24267 	    for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
   24268 		if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
   24269 		    continue;
   24270 		found = 1;
   24271 		ret = xmlSchemaAreValuesEqual(facet->val, val);
   24272 		if (ret == 1)
   24273 		    break;
   24274 		else if (ret < 0) {
   24275 		    AERROR_INT("xmlSchemaValidateFacets",
   24276 			"validating against an enumeration facet");
   24277 		    return (-1);
   24278 		}
   24279 	    }
   24280 	    if (ret != 0)
   24281 		break;
   24282 	    /*
   24283 	    * Break on the first set of enumerations. Any additional
   24284 	    *  enumerations which might be existent on the ancestors
   24285 	    *  of the current type are restricted by this set; thus
   24286 	    *  *must* *not* be taken into account.
   24287 	    */
   24288 	    if (found)
   24289 		break;
   24290 	    tmpType = tmpType->baseType;
   24291 	} while ((tmpType != NULL) &&
   24292 	    (tmpType->type != XML_SCHEMA_TYPE_BASIC));
   24293 	if (found && (ret == 0)) {
   24294 	    ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
   24295 	    if (fireErrors) {
   24296 		xmlSchemaFacetErr(actxt, ret, node,
   24297 		    value, 0, type, NULL, NULL, NULL, NULL);
   24298 	    } else
   24299 		return (ret);
   24300 	    if (error == 0)
   24301 		error = ret;
   24302 	}
   24303     }
   24304 
   24305     if (error >= 0) {
   24306 	int found;
   24307 	/*
   24308 	* Process patters. Pattern facets are ORed at type level
   24309 	* and ANDed if derived. Walk the base type axis.
   24310 	*/
   24311 	tmpType = type;
   24312 	facet = NULL;
   24313 	do {
   24314 	    found = 0;
   24315 	    for (facetLink = tmpType->facetSet; facetLink != NULL;
   24316 		facetLink = facetLink->next) {
   24317 		if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
   24318 		    continue;
   24319 		found = 1;
   24320 		/*
   24321 		* NOTE that for patterns, @value needs to be the
   24322 		* normalized vaule.
   24323 		*/
   24324 		ret = xmlRegexpExec(facetLink->facet->regexp, value);
   24325 		if (ret == 1)
   24326 		    break;
   24327 		else if (ret < 0) {
   24328 		    AERROR_INT("xmlSchemaValidateFacets",
   24329 			"validating against a pattern facet");
   24330 		    return (-1);
   24331 		} else {
   24332 		    /*
   24333 		    * Save the last non-validating facet.
   24334 		    */
   24335 		    facet = facetLink->facet;
   24336 		}
   24337 	    }
   24338 	    if (found && (ret != 1)) {
   24339 		ret = XML_SCHEMAV_CVC_PATTERN_VALID;
   24340 		if (fireErrors) {
   24341 		    xmlSchemaFacetErr(actxt, ret, node,
   24342 			value, 0, type, facet, NULL, NULL, NULL);
   24343 		} else
   24344 		    return (ret);
   24345 		if (error == 0)
   24346 		    error = ret;
   24347 		break;
   24348 	    }
   24349 	    tmpType = tmpType->baseType;
   24350 	} while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
   24351     }
   24352 
   24353     return (error);
   24354 }
   24355 
   24356 static xmlChar *
   24357 xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
   24358 			const xmlChar *value)
   24359 {
   24360     switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
   24361 	case XML_SCHEMA_WHITESPACE_COLLAPSE:
   24362 	    return (xmlSchemaCollapseString(value));
   24363 	case XML_SCHEMA_WHITESPACE_REPLACE:
   24364 	    return (xmlSchemaWhiteSpaceReplace(value));
   24365 	default:
   24366 	    return (NULL);
   24367     }
   24368 }
   24369 
   24370 static int
   24371 xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
   24372 		       const xmlChar *value,
   24373 		       xmlSchemaValPtr *val,
   24374 		       int valNeeded)
   24375 {
   24376     int ret;
   24377     const xmlChar *nsName;
   24378     xmlChar *local, *prefix = NULL;
   24379 
   24380     ret = xmlValidateQName(value, 1);
   24381     if (ret != 0) {
   24382 	if (ret == -1) {
   24383 	    VERROR_INT("xmlSchemaValidateQName",
   24384 		"calling xmlValidateQName()");
   24385 	    return (-1);
   24386 	}
   24387 	return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
   24388     }
   24389     /*
   24390     * NOTE: xmlSplitQName2 will always return a duplicated
   24391     * strings.
   24392     */
   24393     local = xmlSplitQName2(value, &prefix);
   24394     if (local == NULL)
   24395 	local = xmlStrdup(value);
   24396     /*
   24397     * OPTIMIZE TODO: Use flags for:
   24398     *  - is there any namespace binding?
   24399     *  - is there a default namespace?
   24400     */
   24401     nsName = xmlSchemaLookupNamespace(vctxt, prefix);
   24402 
   24403     if (prefix != NULL) {
   24404 	xmlFree(prefix);
   24405 	/*
   24406 	* A namespace must be found if the prefix is
   24407 	* NOT NULL.
   24408 	*/
   24409 	if (nsName == NULL) {
   24410 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
   24411 	    xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
   24412 		WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
   24413 		"The QName value '%s' has no "
   24414 		"corresponding namespace declaration in "
   24415 		"scope", value, NULL);
   24416 	    if (local != NULL)
   24417 		xmlFree(local);
   24418 	    return (ret);
   24419 	}
   24420     }
   24421     if (valNeeded && val) {
   24422 	if (nsName != NULL)
   24423 	    *val = xmlSchemaNewQNameValue(
   24424 		BAD_CAST xmlStrdup(nsName), BAD_CAST local);
   24425 	else
   24426 	    *val = xmlSchemaNewQNameValue(NULL,
   24427 		BAD_CAST local);
   24428     } else
   24429 	xmlFree(local);
   24430     return (0);
   24431 }
   24432 
   24433 /*
   24434 * cvc-simple-type
   24435 */
   24436 static int
   24437 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
   24438 			     xmlNodePtr node,
   24439 			     xmlSchemaTypePtr type,
   24440 			     const xmlChar *value,
   24441 			     xmlSchemaValPtr *retVal,
   24442 			     int fireErrors,
   24443 			     int normalize,
   24444 			     int isNormalized)
   24445 {
   24446     int ret = 0, valNeeded = (retVal) ? 1 : 0;
   24447     xmlSchemaValPtr val = NULL;
   24448     /* xmlSchemaWhitespaceValueType ws; */
   24449     xmlChar *normValue = NULL;
   24450 
   24451 #define NORMALIZE(atype) \
   24452     if ((! isNormalized) && \
   24453     (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
   24454 	normValue = xmlSchemaNormalizeValue(atype, value); \
   24455 	if (normValue != NULL) \
   24456 	    value = normValue; \
   24457 	isNormalized = 1; \
   24458     }
   24459 
   24460     if ((retVal != NULL) && (*retVal != NULL)) {
   24461 	xmlSchemaFreeValue(*retVal);
   24462 	*retVal = NULL;
   24463     }
   24464     /*
   24465     * 3.14.4 Simple Type Definition Validation Rules
   24466     * Validation Rule: String Valid
   24467     */
   24468     /*
   24469     * 1 It is schema-valid with respect to that definition as defined
   24470     * by Datatype Valid in [XML Schemas: Datatypes].
   24471     */
   24472     /*
   24473     * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
   24474     * the empty set, as defined in Type Derivation OK (Simple) (3.14.6), then
   24475     * the string must be a declared entity name.
   24476     */
   24477     /*
   24478     * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
   24479     * given the empty set, as defined in Type Derivation OK (Simple) (3.14.6),
   24480     * then every whitespace-delimited substring of the string must be a declared
   24481     * entity name.
   24482     */
   24483     /*
   24484     * 2.3 otherwise no further condition applies.
   24485     */
   24486     if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
   24487 	valNeeded = 1;
   24488     if (value == NULL)
   24489 	value = BAD_CAST "";
   24490     if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
   24491 	xmlSchemaTypePtr biType; /* The built-in type. */
   24492 	/*
   24493 	* SPEC (1.2.1) "if {variety} is atomic then the string must match
   24494 	* a literal in the lexical space of {base type definition}"
   24495 	*/
   24496 	/*
   24497 	* Whitespace-normalize.
   24498 	*/
   24499 	NORMALIZE(type);
   24500 	if (type->type != XML_SCHEMA_TYPE_BASIC) {
   24501 	    /*
   24502 	    * Get the built-in type.
   24503 	    */
   24504 	    biType = type->baseType;
   24505 	    while ((biType != NULL) &&
   24506 		(biType->type != XML_SCHEMA_TYPE_BASIC))
   24507 		biType = biType->baseType;
   24508 
   24509 	    if (biType == NULL) {
   24510 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24511 		    "could not get the built-in type");
   24512 		goto internal_error;
   24513 	    }
   24514 	} else
   24515 	    biType = type;
   24516 	/*
   24517 	* NOTATIONs need to be processed here, since they need
   24518 	* to lookup in the hashtable of NOTATION declarations of the schema.
   24519 	*/
   24520 	if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
   24521 	    switch (biType->builtInType) {
   24522 		case XML_SCHEMAS_NOTATION:
   24523 		    ret = xmlSchemaValidateNotation(
   24524 			(xmlSchemaValidCtxtPtr) actxt,
   24525 			((xmlSchemaValidCtxtPtr) actxt)->schema,
   24526 			NULL, value, &val, valNeeded);
   24527 		    break;
   24528 		case XML_SCHEMAS_QNAME:
   24529 		    ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
   24530 			value, &val, valNeeded);
   24531 		    break;
   24532 		default:
   24533 		    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
   24534 		    if (valNeeded)
   24535 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
   24536 			    value, &val, node);
   24537 		    else
   24538 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
   24539 			    value, NULL, node);
   24540 		    break;
   24541 	    }
   24542 	} else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
   24543 	    switch (biType->builtInType) {
   24544 		case XML_SCHEMAS_NOTATION:
   24545 		    ret = xmlSchemaValidateNotation(NULL,
   24546 			((xmlSchemaParserCtxtPtr) actxt)->schema, node,
   24547 			value, &val, valNeeded);
   24548 		    break;
   24549 		default:
   24550 		    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
   24551 		    if (valNeeded)
   24552 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
   24553 			    value, &val, node);
   24554 		    else
   24555 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
   24556 			    value, NULL, node);
   24557 		    break;
   24558 	    }
   24559 	} else {
   24560 	    /*
   24561 	    * Validation via a public API is not implemented yet.
   24562 	    */
   24563 	    TODO
   24564 	    goto internal_error;
   24565 	}
   24566 	if (ret != 0) {
   24567 	    if (ret < 0) {
   24568 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24569 		    "validating against a built-in type");
   24570 		goto internal_error;
   24571 	    }
   24572 	    if (WXS_IS_LIST(type))
   24573 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   24574 	    else
   24575 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
   24576 	}
   24577 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
   24578 	    /*
   24579 	    * Check facets.
   24580 	    */
   24581 	    ret = xmlSchemaValidateFacets(actxt, node, type,
   24582 		(xmlSchemaValType) biType->builtInType, value, val,
   24583 		0, fireErrors);
   24584 	    if (ret != 0) {
   24585 		if (ret < 0) {
   24586 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24587 			"validating facets of atomic simple type");
   24588 		    goto internal_error;
   24589 		}
   24590 		if (WXS_IS_LIST(type))
   24591 		    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   24592 		else
   24593 		    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
   24594 	    }
   24595 	}
   24596 	if (fireErrors && (ret > 0))
   24597 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
   24598     } else if (WXS_IS_LIST(type)) {
   24599 
   24600 	xmlSchemaTypePtr itemType;
   24601 	const xmlChar *cur, *end;
   24602 	xmlChar *tmpValue = NULL;
   24603 	unsigned long len = 0;
   24604 	xmlSchemaValPtr prevVal = NULL, curVal = NULL;
   24605 	/* 1.2.2 if {variety} is list then the string must be a sequence
   24606 	* of white space separated tokens, each of which matches a literal
   24607 	* in the lexical space of {item type definition}
   24608 	*/
   24609 	/*
   24610 	* Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
   24611 	* the list type has an enum or pattern facet.
   24612 	*/
   24613 	NORMALIZE(type);
   24614 	/*
   24615 	* VAL TODO: Optimize validation of empty values.
   24616 	* VAL TODO: We do not have computed values for lists.
   24617 	*/
   24618 	itemType = WXS_LIST_ITEMTYPE(type);
   24619 	cur = value;
   24620 	do {
   24621 	    while (IS_BLANK_CH(*cur))
   24622 		cur++;
   24623 	    end = cur;
   24624 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   24625 		end++;
   24626 	    if (end == cur)
   24627 		break;
   24628 	    tmpValue = xmlStrndup(cur, end - cur);
   24629 	    len++;
   24630 
   24631 	    if (valNeeded)
   24632 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
   24633 		    tmpValue, &curVal, fireErrors, 0, 1);
   24634 	    else
   24635 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
   24636 		    tmpValue, NULL, fireErrors, 0, 1);
   24637 	    FREE_AND_NULL(tmpValue);
   24638 	    if (curVal != NULL) {
   24639 		/*
   24640 		* Add to list of computed values.
   24641 		*/
   24642 		if (val == NULL)
   24643 		    val = curVal;
   24644 		else
   24645 		    xmlSchemaValueAppend(prevVal, curVal);
   24646 		prevVal = curVal;
   24647 		curVal = NULL;
   24648 	    }
   24649 	    if (ret != 0) {
   24650 		if (ret < 0) {
   24651 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24652 			"validating an item of list simple type");
   24653 		    goto internal_error;
   24654 		}
   24655 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   24656 		break;
   24657 	    }
   24658 	    cur = end;
   24659 	} while (*cur != 0);
   24660 	FREE_AND_NULL(tmpValue);
   24661 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
   24662 	    /*
   24663 	    * Apply facets (pattern, enumeration).
   24664 	    */
   24665 	    ret = xmlSchemaValidateFacets(actxt, node, type,
   24666 		XML_SCHEMAS_UNKNOWN, value, val,
   24667 		len, fireErrors);
   24668 	    if (ret != 0) {
   24669 		if (ret < 0) {
   24670 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24671 			"validating facets of list simple type");
   24672 		    goto internal_error;
   24673 		}
   24674 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   24675 	    }
   24676 	}
   24677 	if (fireErrors && (ret > 0)) {
   24678 	    /*
   24679 	    * Report the normalized value.
   24680 	    */
   24681 	    normalize = 1;
   24682 	    NORMALIZE(type);
   24683 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
   24684 	}
   24685     } else if (WXS_IS_UNION(type)) {
   24686 	xmlSchemaTypeLinkPtr memberLink;
   24687 	/*
   24688 	* TODO: For all datatypes derived by union  whiteSpace does
   24689 	* not apply directly; however, the normalization behavior of union
   24690 	* types is controlled by the value of whiteSpace on that one of the
   24691 	* memberTypes against which the union is successfully validated.
   24692 	*
   24693 	* This means that the value is normalized by the first validating
   24694 	* member type, then the facets of the union type are applied. This
   24695 	* needs changing of the value!
   24696 	*/
   24697 
   24698 	/*
   24699 	* 1.2.3 if {variety} is union then the string must match a
   24700 	* literal in the lexical space of at least one member of
   24701 	* {member type definitions}
   24702 	*/
   24703 	memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
   24704 	if (memberLink == NULL) {
   24705 	    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24706 		"union simple type has no member types");
   24707 	    goto internal_error;
   24708 	}
   24709 	/*
   24710 	* Always normalize union type values, since we currently
   24711 	* cannot store the whitespace information with the value
   24712 	* itself; otherwise a later value-comparison would be
   24713 	* not possible.
   24714 	*/
   24715 	while (memberLink != NULL) {
   24716 	    if (valNeeded)
   24717 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
   24718 		    memberLink->type, value, &val, 0, 1, 0);
   24719 	    else
   24720 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
   24721 		    memberLink->type, value, NULL, 0, 1, 0);
   24722 	    if (ret <= 0)
   24723 		break;
   24724 	    memberLink = memberLink->next;
   24725 	}
   24726 	if (ret != 0) {
   24727 	    if (ret < 0) {
   24728 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24729 		    "validating members of union simple type");
   24730 		goto internal_error;
   24731 	    }
   24732 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
   24733 	}
   24734 	/*
   24735 	* Apply facets (pattern, enumeration).
   24736 	*/
   24737 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
   24738 	    /*
   24739 	    * The normalization behavior of union types is controlled by
   24740 	    * the value of whiteSpace on that one of the memberTypes
   24741 	    * against which the union is successfully validated.
   24742 	    */
   24743 	    NORMALIZE(memberLink->type);
   24744 	    ret = xmlSchemaValidateFacets(actxt, node, type,
   24745 		XML_SCHEMAS_UNKNOWN, value, val,
   24746 		0, fireErrors);
   24747 	    if (ret != 0) {
   24748 		if (ret < 0) {
   24749 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24750 			"validating facets of union simple type");
   24751 		    goto internal_error;
   24752 		}
   24753 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
   24754 	    }
   24755 	}
   24756 	if (fireErrors && (ret > 0))
   24757 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
   24758     }
   24759 
   24760     if (normValue != NULL)
   24761 	xmlFree(normValue);
   24762     if (ret == 0) {
   24763 	if (retVal != NULL)
   24764 	    *retVal = val;
   24765 	else if (val != NULL)
   24766 	    xmlSchemaFreeValue(val);
   24767     } else if (val != NULL)
   24768 	xmlSchemaFreeValue(val);
   24769     return (ret);
   24770 internal_error:
   24771     if (normValue != NULL)
   24772 	xmlFree(normValue);
   24773     if (val != NULL)
   24774 	xmlSchemaFreeValue(val);
   24775     return (-1);
   24776 }
   24777 
   24778 static int
   24779 xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
   24780 			   const xmlChar *value,
   24781 			   const xmlChar **nsName,
   24782 			   const xmlChar **localName)
   24783 {
   24784     int ret = 0;
   24785 
   24786     if ((nsName == NULL) || (localName == NULL))
   24787 	return (-1);
   24788     *nsName = NULL;
   24789     *localName = NULL;
   24790 
   24791     ret = xmlValidateQName(value, 1);
   24792     if (ret == -1)
   24793 	return (-1);
   24794     if (ret > 0) {
   24795 	xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
   24796 	    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
   24797 	    value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
   24798 	return (1);
   24799     }
   24800     {
   24801 	xmlChar *local = NULL;
   24802 	xmlChar *prefix;
   24803 
   24804 	/*
   24805 	* NOTE: xmlSplitQName2 will return a duplicated
   24806 	* string.
   24807 	*/
   24808 	local = xmlSplitQName2(value, &prefix);
   24809 	if (local == NULL)
   24810 	    *localName = xmlDictLookup(vctxt->dict, value, -1);
   24811 	else {
   24812 	    *localName = xmlDictLookup(vctxt->dict, local, -1);
   24813 	    xmlFree(local);
   24814 	}
   24815 
   24816 	*nsName = xmlSchemaLookupNamespace(vctxt, prefix);
   24817 
   24818 	if (prefix != NULL) {
   24819 	    xmlFree(prefix);
   24820 	    /*
   24821 	    * A namespace must be found if the prefix is NOT NULL.
   24822 	    */
   24823 	    if (*nsName == NULL) {
   24824 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   24825 		    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
   24826 		    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
   24827 		    "The QName value '%s' has no "
   24828 		    "corresponding namespace declaration in scope",
   24829 		    value, NULL);
   24830 		return (2);
   24831 	    }
   24832 	}
   24833     }
   24834     return (0);
   24835 }
   24836 
   24837 static int
   24838 xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
   24839 			xmlSchemaAttrInfoPtr iattr,
   24840 			xmlSchemaTypePtr *localType,
   24841 			xmlSchemaElementPtr elemDecl)
   24842 {
   24843     int ret = 0;
   24844     /*
   24845     * cvc-elt (3.3.4) : (4)
   24846     * AND
   24847     * Schema-Validity Assessment (Element) (cvc-assess-elt)
   24848     *   (1.2.1.2.1) - (1.2.1.2.4)
   24849     * Handle 'xsi:type'.
   24850     */
   24851     if (localType == NULL)
   24852 	return (-1);
   24853     *localType = NULL;
   24854     if (iattr == NULL)
   24855 	return (0);
   24856     else {
   24857 	const xmlChar *nsName = NULL, *local = NULL;
   24858 	/*
   24859 	* TODO: We should report a *warning* that the type was overriden
   24860 	* by the instance.
   24861 	*/
   24862 	ACTIVATE_ATTRIBUTE(iattr);
   24863 	/*
   24864 	* (cvc-elt) (3.3.4) : (4.1)
   24865 	* (cvc-assess-elt) (1.2.1.2.2)
   24866 	*/
   24867 	ret = xmlSchemaVExpandQName(vctxt, iattr->value,
   24868 	    &nsName, &local);
   24869 	if (ret != 0) {
   24870 	    if (ret < 0) {
   24871 		VERROR_INT("xmlSchemaValidateElementByDeclaration",
   24872 		    "calling xmlSchemaQNameExpand() to validate the "
   24873 		    "attribute 'xsi:type'");
   24874 		goto internal_error;
   24875 	    }
   24876 	    goto exit;
   24877 	}
   24878 	/*
   24879 	* (cvc-elt) (3.3.4) : (4.2)
   24880 	* (cvc-assess-elt) (1.2.1.2.3)
   24881 	*/
   24882 	*localType = xmlSchemaGetType(vctxt->schema, local, nsName);
   24883 	if (*localType == NULL) {
   24884 	    xmlChar *str = NULL;
   24885 
   24886 	    xmlSchemaCustomErr(ACTXT_CAST vctxt,
   24887 		XML_SCHEMAV_CVC_ELT_4_2, NULL,
   24888 		WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
   24889 		"The QName value '%s' of the xsi:type attribute does not "
   24890 		"resolve to a type definition",
   24891 		xmlSchemaFormatQName(&str, nsName, local), NULL);
   24892 	    FREE_AND_NULL(str);
   24893 	    ret = vctxt->err;
   24894 	    goto exit;
   24895 	}
   24896 	if (elemDecl != NULL) {
   24897 	    int set = 0;
   24898 
   24899 	    /*
   24900 	    * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
   24901 	    * "The local type definition must be validly
   24902 	    * derived from the {type definition} given the union of
   24903 	    * the {disallowed substitutions} and the {type definition}'s
   24904 	    * {prohibited substitutions}, as defined in
   24905 	    * Type Derivation OK (Complex) (3.4.6)
   24906 	    * (if it is a complex type definition),
   24907 	    * or given {disallowed substitutions} as defined in Type
   24908 	    * Derivation OK (Simple) (3.14.6) (if it is a simple type
   24909 	    * definition)."
   24910 	    *
   24911 	    * {disallowed substitutions}: the "block" on the element decl.
   24912 	    * {prohibited substitutions}: the "block" on the type def.
   24913 	    */
   24914 	    /*
   24915 	    * OPTIMIZE TODO: We could map types already evaluated
   24916 	    * to be validly derived from other types to avoid checking
   24917 	    * this over and over for the same types.
   24918 	    */
   24919 	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
   24920 		(elemDecl->subtypes->flags &
   24921 		    XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
   24922 		set |= SUBSET_EXTENSION;
   24923 
   24924 	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
   24925 		(elemDecl->subtypes->flags &
   24926 		    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
   24927 		set |= SUBSET_RESTRICTION;
   24928 
   24929 	    /*
   24930 	    * REMOVED and CHANGED since this produced a parser context
   24931 	    * which adds to the string dict of the schema. So this would
   24932 	    * change the schema and we don't want this. We don't need
   24933 	    * the parser context anymore.
   24934 	    *
   24935 	    * if ((vctxt->pctxt == NULL) &&
   24936 	    *	(xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
   24937 	    *	    return (-1);
   24938 	    */
   24939 
   24940 	    if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
   24941 		elemDecl->subtypes, set) != 0) {
   24942 		xmlChar *str = NULL;
   24943 
   24944 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   24945 		    XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
   24946 		    "The type definition '%s', specified by xsi:type, is "
   24947 		    "blocked or not validly derived from the type definition "
   24948 		    "of the element declaration",
   24949 		    xmlSchemaFormatQName(&str,
   24950 			(*localType)->targetNamespace,
   24951 			(*localType)->name),
   24952 		    NULL);
   24953 		FREE_AND_NULL(str);
   24954 		ret = vctxt->err;
   24955 		*localType = NULL;
   24956 	    }
   24957 	}
   24958     }
   24959 exit:
   24960     ACTIVATE_ELEM;
   24961     return (ret);
   24962 internal_error:
   24963     ACTIVATE_ELEM;
   24964     return (-1);
   24965 }
   24966 
   24967 static int
   24968 xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
   24969 {
   24970     xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
   24971     xmlSchemaTypePtr actualType;
   24972 
   24973     /*
   24974     * cvc-elt (3.3.4) : 1
   24975     */
   24976     if (elemDecl == NULL) {
   24977 	VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
   24978 	    "No matching declaration available");
   24979         return (vctxt->err);
   24980     }
   24981     actualType = WXS_ELEM_TYPEDEF(elemDecl);
   24982     /*
   24983     * cvc-elt (3.3.4) : 2
   24984     */
   24985     if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
   24986 	VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
   24987 	    "The element declaration is abstract");
   24988         return (vctxt->err);
   24989     }
   24990     if (actualType == NULL) {
   24991     	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
   24992     	    "The type definition is absent");
   24993     	return (XML_SCHEMAV_CVC_TYPE_1);
   24994     }
   24995     if (vctxt->nbAttrInfos != 0) {
   24996 	int ret;
   24997 	xmlSchemaAttrInfoPtr iattr;
   24998 	/*
   24999 	* cvc-elt (3.3.4) : 3
   25000 	* Handle 'xsi:nil'.
   25001 	*/
   25002 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   25003 	    XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
   25004 	if (iattr) {
   25005 	    ACTIVATE_ATTRIBUTE(iattr);
   25006 	    /*
   25007 	    * Validate the value.
   25008 	    */
   25009 	    ret = xmlSchemaVCheckCVCSimpleType(
   25010 		ACTXT_CAST vctxt, NULL,
   25011 		xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
   25012 		iattr->value, &(iattr->val), 1, 0, 0);
   25013 	    ACTIVATE_ELEM;
   25014 	    if (ret < 0) {
   25015 		VERROR_INT("xmlSchemaValidateElemDecl",
   25016 		    "calling xmlSchemaVCheckCVCSimpleType() to "
   25017 		    "validate the attribute 'xsi:nil'");
   25018 		return (-1);
   25019 	    }
   25020 	    if (ret == 0) {
   25021 		if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
   25022 		    /*
   25023 		    * cvc-elt (3.3.4) : 3.1
   25024 		    */
   25025 		    VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
   25026 			"The element is not 'nillable'");
   25027 		    /* Does not return an error on purpose. */
   25028 		} else {
   25029 		    if (xmlSchemaValueGetAsBoolean(iattr->val)) {
   25030 			/*
   25031 			* cvc-elt (3.3.4) : 3.2.2
   25032 			*/
   25033 			if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
   25034 			    (elemDecl->value != NULL)) {
   25035 			    VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
   25036 				"The element cannot be 'nilled' because "
   25037 				"there is a fixed value constraint defined "
   25038 				"for it");
   25039 			     /* Does not return an error on purpose. */
   25040 			} else
   25041 			    vctxt->inode->flags |=
   25042 				XML_SCHEMA_ELEM_INFO_NILLED;
   25043 		    }
   25044 		}
   25045 	    }
   25046 	}
   25047 	/*
   25048 	* cvc-elt (3.3.4) : 4
   25049 	* Handle 'xsi:type'.
   25050 	*/
   25051 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   25052 	    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
   25053 	if (iattr) {
   25054 	    xmlSchemaTypePtr localType = NULL;
   25055 
   25056 	    ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
   25057 		elemDecl);
   25058 	    if (ret != 0) {
   25059 		if (ret == -1) {
   25060 		    VERROR_INT("xmlSchemaValidateElemDecl",
   25061 			"calling xmlSchemaProcessXSIType() to "
   25062 			"process the attribute 'xsi:type'");
   25063 		    return (-1);
   25064 		}
   25065 		/* Does not return an error on purpose. */
   25066 	    }
   25067 	    if (localType != NULL) {
   25068 		vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
   25069 		actualType = localType;
   25070 	    }
   25071 	}
   25072     }
   25073     /*
   25074     * IDC: Register identity-constraint XPath matchers.
   25075     */
   25076     if ((elemDecl->idcs != NULL) &&
   25077 	(xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
   25078 	    return (-1);
   25079     /*
   25080     * No actual type definition.
   25081     */
   25082     if (actualType == NULL) {
   25083     	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
   25084     	    "The type definition is absent");
   25085     	return (XML_SCHEMAV_CVC_TYPE_1);
   25086     }
   25087     /*
   25088     * Remember the actual type definition.
   25089     */
   25090     vctxt->inode->typeDef = actualType;
   25091 
   25092     return (0);
   25093 }
   25094 
   25095 static int
   25096 xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
   25097 {
   25098     xmlSchemaAttrInfoPtr iattr;
   25099     int ret = 0, i;
   25100 
   25101     /*
   25102     * SPEC cvc-type (3.1.1)
   25103     * "The attributes of must be empty, excepting those whose namespace
   25104     * name is identical to http://www.w3.org/2001/XMLSchema-instance and
   25105     * whose local name is one of type, nil, schemaLocation or
   25106     * noNamespaceSchemaLocation."
   25107     */
   25108     if (vctxt->nbAttrInfos == 0)
   25109 	return (0);
   25110     for (i = 0; i < vctxt->nbAttrInfos; i++) {
   25111 	iattr = vctxt->attrInfos[i];
   25112 	if (! iattr->metaType) {
   25113 	    ACTIVATE_ATTRIBUTE(iattr)
   25114 	    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
   25115 		XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
   25116 	    ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
   25117         }
   25118     }
   25119     ACTIVATE_ELEM
   25120     return (ret);
   25121 }
   25122 
   25123 /*
   25124 * Cleanup currently used attribute infos.
   25125 */
   25126 static void
   25127 xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
   25128 {
   25129     int i;
   25130     xmlSchemaAttrInfoPtr attr;
   25131 
   25132     if (vctxt->nbAttrInfos == 0)
   25133 	return;
   25134     for (i = 0; i < vctxt->nbAttrInfos; i++) {
   25135 	attr = vctxt->attrInfos[i];
   25136 	if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
   25137 	    if (attr->localName != NULL)
   25138 		xmlFree((xmlChar *) attr->localName);
   25139 	    if (attr->nsName != NULL)
   25140 		xmlFree((xmlChar *) attr->nsName);
   25141 	}
   25142 	if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
   25143 	    if (attr->value != NULL)
   25144 		xmlFree((xmlChar *) attr->value);
   25145 	}
   25146 	if (attr->val != NULL) {
   25147 	    xmlSchemaFreeValue(attr->val);
   25148 	    attr->val = NULL;
   25149 	}
   25150 	memset(attr, 0, sizeof(xmlSchemaAttrInfo));
   25151     }
   25152     vctxt->nbAttrInfos = 0;
   25153 }
   25154 
   25155 /*
   25156 * 3.4.4 Complex Type Definition Validation Rules
   25157 *   Element Locally Valid (Complex Type) (cvc-complex-type)
   25158 * 3.2.4 Attribute Declaration Validation Rules
   25159 *   Validation Rule: Attribute Locally Valid (cvc-attribute)
   25160 *   Attribute Locally Valid (Use) (cvc-au)
   25161 *
   25162 * Only "assessed" attribute information items will be visible to
   25163 * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
   25164 */
   25165 static int
   25166 xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
   25167 {
   25168     xmlSchemaTypePtr type = vctxt->inode->typeDef;
   25169     xmlSchemaItemListPtr attrUseList;
   25170     xmlSchemaAttributeUsePtr attrUse = NULL;
   25171     xmlSchemaAttributePtr attrDecl = NULL;
   25172     xmlSchemaAttrInfoPtr iattr, tmpiattr;
   25173     int i, j, found, nbAttrs, nbUses;
   25174     int xpathRes = 0, res, wildIDs = 0, fixed;
   25175     xmlNodePtr defAttrOwnerElem = NULL;
   25176 
   25177     /*
   25178     * SPEC (cvc-attribute)
   25179     * (1) "The declaration must not be absent (see Missing
   25180     * Sub-components (5.3) for how this can fail to be
   25181     * the case)."
   25182     * (2) "Its {type definition} must not be absent."
   25183     *
   25184     * NOTE (1) + (2): This is not handled here, since we currently do not
   25185     * allow validation against schemas which have missing sub-components.
   25186     *
   25187     * SPEC (cvc-complex-type)
   25188     * (3) "For each attribute information item in the element information
   25189     * item's [attributes] excepting those whose [namespace name] is
   25190     * identical to http://www.w3.org/2001/XMLSchema-instance and whose
   25191     * [local name] is one of type, nil, schemaLocation or
   25192     * noNamespaceSchemaLocation, the appropriate case among the following
   25193     * must be true:
   25194     *
   25195     */
   25196     attrUseList = (xmlSchemaItemListPtr) type->attrUses;
   25197     /*
   25198     * @nbAttrs is the number of attributes present in the instance.
   25199     */
   25200     nbAttrs = vctxt->nbAttrInfos;
   25201     if (attrUseList != NULL)
   25202 	nbUses = attrUseList->nbItems;
   25203     else
   25204 	nbUses = 0;
   25205     for (i = 0; i < nbUses; i++) {
   25206         found = 0;
   25207 	attrUse = attrUseList->items[i];
   25208 	attrDecl = WXS_ATTRUSE_DECL(attrUse);
   25209         for (j = 0; j < nbAttrs; j++) {
   25210 	    iattr = vctxt->attrInfos[j];
   25211 	    /*
   25212 	    * SPEC (cvc-complex-type) (3)
   25213 	    * Skip meta attributes.
   25214 	    */
   25215 	    if (iattr->metaType)
   25216 		continue;
   25217 	    if (iattr->localName[0] != attrDecl->name[0])
   25218 		continue;
   25219 	    if (!xmlStrEqual(iattr->localName, attrDecl->name))
   25220 		continue;
   25221 	    if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
   25222 		continue;
   25223 	    found = 1;
   25224 	    /*
   25225 	    * SPEC (cvc-complex-type)
   25226 	    * (3.1) "If there is among the {attribute uses} an attribute
   25227 	    * use with an {attribute declaration} whose {name} matches
   25228 	    * the attribute information item's [local name] and whose
   25229 	    * {target namespace} is identical to the attribute information
   25230 	    * item's [namespace name] (where an absent {target namespace}
   25231 	    * is taken to be identical to a [namespace name] with no value),
   25232 	    * then the attribute information must be valid with respect
   25233 	    * to that attribute use as per Attribute Locally Valid (Use)
   25234 	    * (3.5.4). In this case the {attribute declaration} of that
   25235 	    * attribute use is the context-determined declaration for the
   25236 	    * attribute information item with respect to Schema-Validity
   25237 	    * Assessment (Attribute) (3.2.4) and
   25238 	    * Assessment Outcome (Attribute) (3.2.5).
   25239 	    */
   25240 	    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
   25241 	    iattr->use = attrUse;
   25242 	    /*
   25243 	    * Context-determined declaration.
   25244 	    */
   25245 	    iattr->decl = attrDecl;
   25246 	    iattr->typeDef = attrDecl->subtypes;
   25247 	    break;
   25248 	}
   25249 
   25250 	if (found)
   25251 	    continue;
   25252 
   25253 	if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
   25254 	    /*
   25255 	    * Handle non-existent, required attributes.
   25256 	    *
   25257 	    * SPEC (cvc-complex-type)
   25258 	    * (4) "The {attribute declaration} of each attribute use in
   25259 	    * the {attribute uses} whose {required} is true matches one
   25260 	    * of the attribute information items in the element information
   25261 	    * item's [attributes] as per clause 3.1 above."
   25262 	    */
   25263 	    tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
   25264 	    if (tmpiattr == NULL) {
   25265 		VERROR_INT(
   25266 		    "xmlSchemaVAttributesComplex",
   25267 		    "calling xmlSchemaGetFreshAttrInfo()");
   25268 		return (-1);
   25269 	    }
   25270 	    tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
   25271 	    tmpiattr->use = attrUse;
   25272 	    tmpiattr->decl = attrDecl;
   25273 	} else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
   25274 	    ((attrUse->defValue != NULL) ||
   25275 	     (attrDecl->defValue != NULL))) {
   25276 	    /*
   25277 	    * Handle non-existent, optional, default/fixed attributes.
   25278 	    */
   25279 	    tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
   25280 	    if (tmpiattr == NULL) {
   25281 		VERROR_INT(
   25282 		    "xmlSchemaVAttributesComplex",
   25283 		    "calling xmlSchemaGetFreshAttrInfo()");
   25284 		return (-1);
   25285 	    }
   25286 	    tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
   25287 	    tmpiattr->use = attrUse;
   25288 	    tmpiattr->decl = attrDecl;
   25289 	    tmpiattr->typeDef = attrDecl->subtypes;
   25290 	    tmpiattr->localName = attrDecl->name;
   25291 	    tmpiattr->nsName = attrDecl->targetNamespace;
   25292 	}
   25293     }
   25294 
   25295     if (vctxt->nbAttrInfos == 0)
   25296 	return (0);
   25297     /*
   25298     * Validate against the wildcard.
   25299     */
   25300     if (type->attributeWildcard != NULL) {
   25301 	/*
   25302 	* SPEC (cvc-complex-type)
   25303 	* (3.2.1) "There must be an {attribute wildcard}."
   25304 	*/
   25305 	for (i = 0; i < nbAttrs; i++) {
   25306 	    iattr = vctxt->attrInfos[i];
   25307 	    /*
   25308 	    * SPEC (cvc-complex-type) (3)
   25309 	    * Skip meta attributes.
   25310 	    */
   25311 	    if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
   25312 		continue;
   25313 	    /*
   25314 	    * SPEC (cvc-complex-type)
   25315 	    * (3.2.2) "The attribute information item must be valid with
   25316 	    * respect to it as defined in Item Valid (Wildcard) (3.10.4)."
   25317 	    *
   25318 	    * SPEC Item Valid (Wildcard) (cvc-wildcard)
   25319 	    * "... its [namespace name] must be valid with respect to
   25320 	    * the wildcard constraint, as defined in Wildcard allows
   25321 	    * Namespace Name (3.10.4)."
   25322 	    */
   25323 	    if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
   25324 		    iattr->nsName) == 0) {
   25325 		/*
   25326 		* Handle processContents.
   25327 		*
   25328 		* SPEC (cvc-wildcard):
   25329 		* processContents | context-determined declaration:
   25330 		* "strict"          "mustFind"
   25331 		* "lax"             "none"
   25332 		* "skip"            "skip"
   25333 		*/
   25334 		if (type->attributeWildcard->processContents ==
   25335 		    XML_SCHEMAS_ANY_SKIP) {
   25336 		     /*
   25337 		    * context-determined declaration = "skip"
   25338 		    *
   25339 		    * SPEC PSVI Assessment Outcome (Attribute)
   25340 		    * [validity] = "notKnown"
   25341 		    * [validation attempted] = "none"
   25342 		    */
   25343 		    iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
   25344 		    continue;
   25345 		}
   25346 		/*
   25347 		* Find an attribute declaration.
   25348 		*/
   25349 		iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
   25350 		    iattr->localName, iattr->nsName);
   25351 		if (iattr->decl != NULL) {
   25352 		    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
   25353 		    /*
   25354 		    * SPEC (cvc-complex-type)
   25355 		    * (5) "Let [Definition:]  the wild IDs be the set of
   25356 		    * all attribute information item to which clause 3.2
   25357 		    * applied and whose validation resulted in a
   25358 		    * context-determined declaration of mustFind or no
   25359 		    * context-determined declaration at all, and whose
   25360 		    * [local name] and [namespace name] resolve (as
   25361 		    * defined by QName resolution (Instance) (3.15.4)) to
   25362 		    * an attribute declaration whose {type definition} is
   25363 		    * or is derived from ID. Then all of the following
   25364 		    * must be true:"
   25365 		    */
   25366 		    iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
   25367 		    if (xmlSchemaIsDerivedFromBuiltInType(
   25368 			iattr->typeDef, XML_SCHEMAS_ID)) {
   25369 			/*
   25370 			* SPEC (5.1) "There must be no more than one
   25371 			* item in wild IDs."
   25372 			*/
   25373 			if (wildIDs != 0) {
   25374 			    /* VAL TODO */
   25375 			    iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
   25376 			    TODO
   25377 			    continue;
   25378 			}
   25379 			wildIDs++;
   25380 			/*
   25381 			* SPEC (cvc-complex-type)
   25382 			* (5.2) "If wild IDs is non-empty, there must not
   25383 			* be any attribute uses among the {attribute uses}
   25384 			* whose {attribute declaration}'s {type definition}
   25385 			* is or is derived from ID."
   25386 			*/
   25387                         if (attrUseList != NULL) {
   25388                             for (j = 0; j < attrUseList->nbItems; j++) {
   25389                                 if (xmlSchemaIsDerivedFromBuiltInType(
   25390                                     WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
   25391                                     XML_SCHEMAS_ID)) {
   25392                                     /* URGENT VAL TODO: implement */
   25393                             iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
   25394                                     TODO
   25395                                     break;
   25396                                 }
   25397                             }
   25398                         }
   25399 		    }
   25400 		} else if (type->attributeWildcard->processContents ==
   25401 		    XML_SCHEMAS_ANY_LAX) {
   25402 		    iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
   25403 		    /*
   25404 		    * SPEC PSVI Assessment Outcome (Attribute)
   25405 		    * [validity] = "notKnown"
   25406 		    * [validation attempted] = "none"
   25407 		    */
   25408 		} else {
   25409 		    iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
   25410 		}
   25411 	    }
   25412 	}
   25413     }
   25414 
   25415     if (vctxt->nbAttrInfos == 0)
   25416 	return (0);
   25417 
   25418     /*
   25419     * Get the owner element; needed for creation of default attributes.
   25420     * This fixes bug #341337, reported by David Grohmann.
   25421     */
   25422     if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
   25423 	xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
   25424 	if (ielem && ielem->node && ielem->node->doc)
   25425 	    defAttrOwnerElem = ielem->node;
   25426     }
   25427     /*
   25428     * Validate values, create default attributes, evaluate IDCs.
   25429     */
   25430     for (i = 0; i < vctxt->nbAttrInfos; i++) {
   25431 	iattr = vctxt->attrInfos[i];
   25432 	/*
   25433 	* VAL TODO: Note that we won't try to resolve IDCs to
   25434 	* "lax" and "skip" validated attributes. Check what to
   25435 	* do in this case.
   25436 	*/
   25437 	if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
   25438 	    (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
   25439 	    continue;
   25440 	/*
   25441 	* VAL TODO: What to do if the type definition is missing?
   25442 	*/
   25443 	if (iattr->typeDef == NULL) {
   25444 	    iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
   25445 	    continue;
   25446 	}
   25447 
   25448 	ACTIVATE_ATTRIBUTE(iattr);
   25449 	fixed = 0;
   25450 	xpathRes = 0;
   25451 
   25452 	if (vctxt->xpathStates != NULL) {
   25453 	    /*
   25454 	    * Evaluate IDCs.
   25455 	    */
   25456 	    xpathRes = xmlSchemaXPathEvaluate(vctxt,
   25457 		XML_ATTRIBUTE_NODE);
   25458 	    if (xpathRes == -1) {
   25459 		VERROR_INT("xmlSchemaVAttributesComplex",
   25460 		    "calling xmlSchemaXPathEvaluate()");
   25461 		goto internal_error;
   25462 	    }
   25463 	}
   25464 
   25465 	if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
   25466 	    /*
   25467 	    * Default/fixed attributes.
   25468 	    * We need the value only if we need to resolve IDCs or
   25469 	    * will create default attributes.
   25470 	    */
   25471 	    if ((xpathRes) || (defAttrOwnerElem)) {
   25472 		if (iattr->use->defValue != NULL) {
   25473 		    iattr->value = (xmlChar *) iattr->use->defValue;
   25474 		    iattr->val = iattr->use->defVal;
   25475 		} else {
   25476 		    iattr->value = (xmlChar *) iattr->decl->defValue;
   25477 		    iattr->val = iattr->decl->defVal;
   25478 		}
   25479 		/*
   25480 		* IDCs will consume the precomputed default value,
   25481 		* so we need to clone it.
   25482 		*/
   25483 		if (iattr->val == NULL) {
   25484 		    VERROR_INT("xmlSchemaVAttributesComplex",
   25485 			"default/fixed value on an attribute use was "
   25486 			"not precomputed");
   25487 		    goto internal_error;
   25488 		}
   25489 		iattr->val = xmlSchemaCopyValue(iattr->val);
   25490 		if (iattr->val == NULL) {
   25491 		    VERROR_INT("xmlSchemaVAttributesComplex",
   25492 			"calling xmlSchemaCopyValue()");
   25493 		    goto internal_error;
   25494 		}
   25495 	    }
   25496 	    /*
   25497 	    * PSVI: Add the default attribute to the current element.
   25498 	    * VAL TODO: Should we use the *normalized* value? This currently
   25499 	    *   uses the *initial* value.
   25500 	    */
   25501 
   25502 	    if (defAttrOwnerElem) {
   25503 		xmlChar *normValue;
   25504 		const xmlChar *value;
   25505 
   25506 		value = iattr->value;
   25507 		/*
   25508 		* Normalize the value.
   25509 		*/
   25510 		normValue = xmlSchemaNormalizeValue(iattr->typeDef,
   25511 		    iattr->value);
   25512 		if (normValue != NULL)
   25513 		    value = BAD_CAST normValue;
   25514 
   25515 		if (iattr->nsName == NULL) {
   25516 		    if (xmlNewProp(defAttrOwnerElem,
   25517 			iattr->localName, value) == NULL) {
   25518 			VERROR_INT("xmlSchemaVAttributesComplex",
   25519 			    "callling xmlNewProp()");
   25520 			if (normValue != NULL)
   25521 			    xmlFree(normValue);
   25522 			goto internal_error;
   25523 		    }
   25524 		} else {
   25525 		    xmlNsPtr ns;
   25526 
   25527 		    ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
   25528 			defAttrOwnerElem, iattr->nsName);
   25529 		    if (ns == NULL) {
   25530 			xmlChar prefix[12];
   25531 			int counter = 0;
   25532 
   25533 			/*
   25534 			* Create a namespace declaration on the validation
   25535 			* root node if no namespace declaration is in scope.
   25536 			*/
   25537 			do {
   25538 			    snprintf((char *) prefix, 12, "p%d", counter++);
   25539 			    ns = xmlSearchNs(defAttrOwnerElem->doc,
   25540 				defAttrOwnerElem, BAD_CAST prefix);
   25541 			    if (counter > 1000) {
   25542 				VERROR_INT(
   25543 				    "xmlSchemaVAttributesComplex",
   25544 				    "could not compute a ns prefix for a "
   25545 				    "default/fixed attribute");
   25546 				if (normValue != NULL)
   25547 				    xmlFree(normValue);
   25548 				goto internal_error;
   25549 			    }
   25550 			} while (ns != NULL);
   25551 			ns = xmlNewNs(vctxt->validationRoot,
   25552 			    iattr->nsName, BAD_CAST prefix);
   25553 		    }
   25554 		    /*
   25555 		    * TODO:
   25556 		    * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
   25557 		    * If we have QNames: do we need to ensure there's a
   25558 		    * prefix defined for the QName?
   25559 		    */
   25560 		    xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
   25561 		}
   25562 		if (normValue != NULL)
   25563 		    xmlFree(normValue);
   25564 	    }
   25565 	    /*
   25566 	    * Go directly to IDC evaluation.
   25567 	    */
   25568 	    goto eval_idcs;
   25569 	}
   25570 	/*
   25571 	* Validate the value.
   25572 	*/
   25573 	if (vctxt->value != NULL) {
   25574 	    /*
   25575 	    * Free last computed value; just for safety reasons.
   25576 	    */
   25577 	    xmlSchemaFreeValue(vctxt->value);
   25578 	    vctxt->value = NULL;
   25579 	}
   25580 	/*
   25581 	* Note that the attribute *use* can be unavailable, if
   25582 	* the attribute was a wild attribute.
   25583 	*/
   25584 	if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
   25585 	    ((iattr->use != NULL) &&
   25586 	     (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
   25587 	    fixed = 1;
   25588 	else
   25589 	    fixed = 0;
   25590 	/*
   25591 	* SPEC (cvc-attribute)
   25592 	* (3) "The item's normalized value must be locally valid
   25593 	* with respect to that {type definition} as per
   25594 	* String Valid (3.14.4)."
   25595 	*
   25596 	* VAL TODO: Do we already have the
   25597 	* "normalized attribute value" here?
   25598 	*/
   25599 	if (xpathRes || fixed) {
   25600 	    iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
   25601 	    /*
   25602 	    * Request a computed value.
   25603 	    */
   25604 	    res = xmlSchemaVCheckCVCSimpleType(
   25605 		ACTXT_CAST vctxt,
   25606 		iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
   25607 		1, 1, 0);
   25608 	} else {
   25609 	    res = xmlSchemaVCheckCVCSimpleType(
   25610 		ACTXT_CAST vctxt,
   25611 		iattr->node, iattr->typeDef, iattr->value, NULL,
   25612 		1, 0, 0);
   25613 	}
   25614 
   25615 	if (res != 0) {
   25616 	    if (res == -1) {
   25617 		VERROR_INT("xmlSchemaVAttributesComplex",
   25618 		    "calling xmlSchemaStreamValidateSimpleTypeValue()");
   25619 		goto internal_error;
   25620 	    }
   25621 	    iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
   25622 	    /*
   25623 	    * SPEC PSVI Assessment Outcome (Attribute)
   25624 	    * [validity] = "invalid"
   25625 	    */
   25626 	    goto eval_idcs;
   25627 	}
   25628 
   25629 	if (fixed) {
   25630 	    /*
   25631 	    * SPEC Attribute Locally Valid (Use) (cvc-au)
   25632 	    * "For an attribute information item to bevalid
   25633 	    * with respect to an attribute use its *normalized*
   25634 	    * value must match the *canonical* lexical
   25635 	    * representation of the attribute use's {value
   25636 	    * constraint}value, if it is present and fixed."
   25637 	    *
   25638 	    * VAL TODO: The requirement for the *canonical* value
   25639 	    * will be removed in XML Schema 1.1.
   25640 	    */
   25641 	    /*
   25642 	    * SPEC Attribute Locally Valid (cvc-attribute)
   25643 	    * (4) "The item's *actual* value must match the *value* of
   25644 	    * the {value constraint}, if it is present and fixed."
   25645 	    */
   25646 	    if (iattr->val == NULL) {
   25647 		/* VAL TODO: A value was not precomputed. */
   25648 		TODO
   25649 		goto eval_idcs;
   25650 	    }
   25651 	    if ((iattr->use != NULL) &&
   25652 		(iattr->use->defValue != NULL)) {
   25653 		if (iattr->use->defVal == NULL) {
   25654 		    /* VAL TODO: A default value was not precomputed. */
   25655 		    TODO
   25656 		    goto eval_idcs;
   25657 		}
   25658 		iattr->vcValue = iattr->use->defValue;
   25659 		/*
   25660 		if (xmlSchemaCompareValuesWhtsp(attr->val,
   25661 		    (xmlSchemaWhitespaceValueType) ws,
   25662 		    attr->use->defVal,
   25663 		    (xmlSchemaWhitespaceValueType) ws) != 0) {
   25664 		*/
   25665 		if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
   25666 		    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
   25667 	    } else {
   25668 		if (iattr->decl->defVal == NULL) {
   25669 		    /* VAL TODO: A default value was not precomputed. */
   25670 		    TODO
   25671 		    goto eval_idcs;
   25672 		}
   25673 		iattr->vcValue = iattr->decl->defValue;
   25674 		/*
   25675 		if (xmlSchemaCompareValuesWhtsp(attr->val,
   25676 		    (xmlSchemaWhitespaceValueType) ws,
   25677 		    attrDecl->defVal,
   25678 		    (xmlSchemaWhitespaceValueType) ws) != 0) {
   25679 		*/
   25680 		if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
   25681 		    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
   25682 	    }
   25683 	    /*
   25684 	    * [validity] = "valid"
   25685 	    */
   25686 	}
   25687 eval_idcs:
   25688 	/*
   25689 	* Evaluate IDCs.
   25690 	*/
   25691 	if (xpathRes) {
   25692 	    if (xmlSchemaXPathProcessHistory(vctxt,
   25693 		vctxt->depth +1) == -1) {
   25694 		VERROR_INT("xmlSchemaVAttributesComplex",
   25695 		    "calling xmlSchemaXPathEvaluate()");
   25696 		goto internal_error;
   25697 	    }
   25698 	} else if (vctxt->xpathStates != NULL)
   25699 	    xmlSchemaXPathPop(vctxt);
   25700     }
   25701 
   25702     /*
   25703     * Report errors.
   25704     */
   25705     for (i = 0; i < vctxt->nbAttrInfos; i++) {
   25706 	iattr = vctxt->attrInfos[i];
   25707 	if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
   25708 	    (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
   25709 	    (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
   25710 	    (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
   25711 	    continue;
   25712 	ACTIVATE_ATTRIBUTE(iattr);
   25713 	switch (iattr->state) {
   25714 	    case XML_SCHEMAS_ATTR_ERR_MISSING: {
   25715 		    xmlChar *str = NULL;
   25716 		    ACTIVATE_ELEM;
   25717 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
   25718 			XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
   25719 			"The attribute '%s' is required but missing",
   25720 			xmlSchemaFormatQName(&str,
   25721 			    iattr->decl->targetNamespace,
   25722 			    iattr->decl->name),
   25723 			NULL);
   25724 		    FREE_AND_NULL(str)
   25725 		    break;
   25726 		}
   25727 	    case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
   25728 		VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
   25729 		    "The type definition is absent");
   25730 		break;
   25731 	    case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
   25732 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   25733 		    XML_SCHEMAV_CVC_AU, NULL, NULL,
   25734 		    "The value '%s' does not match the fixed "
   25735 		    "value constraint '%s'",
   25736 		    iattr->value, iattr->vcValue);
   25737 		break;
   25738 	    case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
   25739 		VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
   25740 		    "No matching global attribute declaration available, but "
   25741 		    "demanded by the strict wildcard");
   25742 		break;
   25743 	    case XML_SCHEMAS_ATTR_UNKNOWN:
   25744 		if (iattr->metaType)
   25745 		    break;
   25746 		/*
   25747 		* MAYBE VAL TODO: One might report different error messages
   25748 		* for the following errors.
   25749 		*/
   25750 		if (type->attributeWildcard == NULL) {
   25751 		    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
   25752 			XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
   25753 		} else {
   25754 		    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
   25755 			XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
   25756 		}
   25757 		break;
   25758 	    default:
   25759 		break;
   25760 	}
   25761     }
   25762 
   25763     ACTIVATE_ELEM;
   25764     return (0);
   25765 internal_error:
   25766     ACTIVATE_ELEM;
   25767     return (-1);
   25768 }
   25769 
   25770 static int
   25771 xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
   25772 			      int *skip)
   25773 {
   25774     xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
   25775     /*
   25776     * The namespace of the element was already identified to be
   25777     * matching the wildcard.
   25778     */
   25779     if ((skip == NULL) || (wild == NULL) ||
   25780 	(wild->type != XML_SCHEMA_TYPE_ANY)) {
   25781 	VERROR_INT("xmlSchemaValidateElemWildcard",
   25782 	    "bad arguments");
   25783 	return (-1);
   25784     }
   25785     *skip = 0;
   25786     if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
   25787 	/*
   25788 	* URGENT VAL TODO: Either we need to position the stream to the
   25789 	* next sibling, or walk the whole subtree.
   25790 	*/
   25791 	*skip = 1;
   25792 	return (0);
   25793     }
   25794     {
   25795 	xmlSchemaElementPtr decl = NULL;
   25796 
   25797 	decl = xmlSchemaGetElem(vctxt->schema,
   25798 	    vctxt->inode->localName, vctxt->inode->nsName);
   25799 	if (decl != NULL) {
   25800 	    vctxt->inode->decl = decl;
   25801 	    return (0);
   25802 	}
   25803     }
   25804     if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
   25805 	/* VAL TODO: Change to proper error code. */
   25806 	VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
   25807 	    "No matching global element declaration available, but "
   25808 	    "demanded by the strict wildcard");
   25809 	return (vctxt->err);
   25810     }
   25811     if (vctxt->nbAttrInfos != 0) {
   25812 	xmlSchemaAttrInfoPtr iattr;
   25813 	/*
   25814 	* SPEC Validation Rule: Schema-Validity Assessment (Element)
   25815 	* (1.2.1.2.1) - (1.2.1.2.3 )
   25816 	*
   25817 	* Use the xsi:type attribute for the type definition.
   25818 	*/
   25819 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   25820 	    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
   25821 	if (iattr != NULL) {
   25822 	    if (xmlSchemaProcessXSIType(vctxt, iattr,
   25823 		&(vctxt->inode->typeDef), NULL) == -1) {
   25824 		VERROR_INT("xmlSchemaValidateElemWildcard",
   25825 		    "calling xmlSchemaProcessXSIType() to "
   25826 		    "process the attribute 'xsi:nil'");
   25827 		return (-1);
   25828 	    }
   25829 	    /*
   25830 	    * Don't return an error on purpose.
   25831 	    */
   25832 	    return (0);
   25833 	}
   25834     }
   25835     /*
   25836     * SPEC Validation Rule: Schema-Validity Assessment (Element)
   25837     *
   25838     * Fallback to "anyType".
   25839     */
   25840     vctxt->inode->typeDef =
   25841 	xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
   25842     return (0);
   25843 }
   25844 
   25845 /*
   25846 * xmlSchemaCheckCOSValidDefault:
   25847 *
   25848 * This will be called if: not nilled, no content and a default/fixed
   25849 * value is provided.
   25850 */
   25851 
   25852 static int
   25853 xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
   25854 			      const xmlChar *value,
   25855 			      xmlSchemaValPtr *val)
   25856 {
   25857     int ret = 0;
   25858     xmlSchemaNodeInfoPtr inode = vctxt->inode;
   25859 
   25860     /*
   25861     * cos-valid-default:
   25862     * Schema Component Constraint: Element Default Valid (Immediate)
   25863     * For a string to be a valid default with respect to a type
   25864     * definition the appropriate case among the following must be true:
   25865     */
   25866     if WXS_IS_COMPLEX(inode->typeDef) {
   25867 	/*
   25868 	* Complex type.
   25869 	*
   25870 	* SPEC (2.1) "its {content type} must be a simple type definition
   25871 	* or mixed."
   25872 	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
   25873 	* type}'s particle must be emptiable as defined by
   25874 	* Particle Emptiable (3.9.6)."
   25875 	*/
   25876 	if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
   25877 	    ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
   25878 	     (! WXS_EMPTIABLE(inode->typeDef)))) {
   25879 	    ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
   25880 	    /* NOTE that this covers (2.2.2) as well. */
   25881 	    VERROR(ret, NULL,
   25882 		"For a string to be a valid default, the type definition "
   25883 		"must be a simple type or a complex type with simple content "
   25884 		"or mixed content and a particle emptiable");
   25885 	    return(ret);
   25886 	}
   25887     }
   25888     /*
   25889     * 1 If the type definition is a simple type definition, then the string
   25890     * must be valid with respect to that definition as defined by String
   25891     * Valid (3.14.4).
   25892     *
   25893     * AND
   25894     *
   25895     * 2.2.1 If the {content type} is a simple type definition, then the
   25896     * string must be valid with respect to that simple type definition
   25897     * as defined by String Valid (3.14.4).
   25898     */
   25899     if (WXS_IS_SIMPLE(inode->typeDef)) {
   25900 
   25901 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
   25902 	    NULL, inode->typeDef, value, val, 1, 1, 0);
   25903 
   25904     } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   25905 
   25906 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
   25907 	    NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
   25908     }
   25909     if (ret < 0) {
   25910 	VERROR_INT("xmlSchemaCheckCOSValidDefault",
   25911 	    "calling xmlSchemaVCheckCVCSimpleType()");
   25912     }
   25913     return (ret);
   25914 }
   25915 
   25916 static void
   25917 xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
   25918 			       const xmlChar * name ATTRIBUTE_UNUSED,
   25919 			       xmlSchemaElementPtr item,
   25920 			       xmlSchemaNodeInfoPtr inode)
   25921 {
   25922     inode->decl = item;
   25923 #ifdef DEBUG_CONTENT
   25924     {
   25925 	xmlChar *str = NULL;
   25926 
   25927 	if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
   25928 	    xmlGenericError(xmlGenericErrorContext,
   25929 		"AUTOMATON callback for '%s' [declaration]\n",
   25930 		xmlSchemaFormatQName(&str,
   25931 		inode->localName, inode->nsName));
   25932 	} else {
   25933 	    xmlGenericError(xmlGenericErrorContext,
   25934 		    "AUTOMATON callback for '%s' [wildcard]\n",
   25935 		    xmlSchemaFormatQName(&str,
   25936 		    inode->localName, inode->nsName));
   25937 
   25938 	}
   25939 	FREE_AND_NULL(str)
   25940     }
   25941 #endif
   25942 }
   25943 
   25944 static int
   25945 xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
   25946 {
   25947     vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
   25948     if (vctxt->inode == NULL) {
   25949 	VERROR_INT("xmlSchemaValidatorPushElem",
   25950 	    "calling xmlSchemaGetFreshElemInfo()");
   25951 	return (-1);
   25952     }
   25953     vctxt->nbAttrInfos = 0;
   25954     return (0);
   25955 }
   25956 
   25957 static int
   25958 xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
   25959 			     xmlSchemaNodeInfoPtr inode,
   25960 			     xmlSchemaTypePtr type,
   25961 			     const xmlChar *value)
   25962 {
   25963     if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
   25964 	return (xmlSchemaVCheckCVCSimpleType(
   25965 	    ACTXT_CAST vctxt, NULL,
   25966 	    type, value, &(inode->val), 1, 1, 0));
   25967     else
   25968 	return (xmlSchemaVCheckCVCSimpleType(
   25969 	    ACTXT_CAST vctxt, NULL,
   25970 	    type, value, NULL, 1, 0, 0));
   25971 }
   25972 
   25973 
   25974 
   25975 /*
   25976 * Process END of element.
   25977 */
   25978 static int
   25979 xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
   25980 {
   25981     int ret = 0;
   25982     xmlSchemaNodeInfoPtr inode = vctxt->inode;
   25983 
   25984     if (vctxt->nbAttrInfos != 0)
   25985 	xmlSchemaClearAttrInfos(vctxt);
   25986     if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
   25987 	/*
   25988 	* This element was not expected;
   25989 	* we will not validate child elements of broken parents.
   25990 	* Skip validation of all content of the parent.
   25991 	*/
   25992 	vctxt->skipDepth = vctxt->depth -1;
   25993 	goto end_elem;
   25994     }
   25995     if ((inode->typeDef == NULL) ||
   25996 	(inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
   25997 	/*
   25998 	* 1. the type definition might be missing if the element was
   25999 	*    error prone
   26000 	* 2. it might be abstract.
   26001 	*/
   26002 	goto end_elem;
   26003     }
   26004     /*
   26005     * Check the content model.
   26006     */
   26007     if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
   26008 	(inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
   26009 
   26010 	/*
   26011 	* Workaround for "anyType".
   26012 	*/
   26013 	if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
   26014 	    goto character_content;
   26015 
   26016 	if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
   26017 	    xmlChar *values[10];
   26018 	    int terminal, nbval = 10, nbneg;
   26019 
   26020 	    if (inode->regexCtxt == NULL) {
   26021 		/*
   26022 		* Create the regex context.
   26023 		*/
   26024 		inode->regexCtxt =
   26025 		    xmlRegNewExecCtxt(inode->typeDef->contModel,
   26026 		    (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
   26027 		    vctxt);
   26028 		if (inode->regexCtxt == NULL) {
   26029 		    VERROR_INT("xmlSchemaValidatorPopElem",
   26030 			"failed to create a regex context");
   26031 		    goto internal_error;
   26032 		}
   26033 #ifdef DEBUG_AUTOMATA
   26034 		xmlGenericError(xmlGenericErrorContext,
   26035 		    "AUTOMATON create on '%s'\n", inode->localName);
   26036 #endif
   26037 	    }
   26038 	    /*
   26039 	    * Get hold of the still expected content, since a further
   26040 	    * call to xmlRegExecPushString() will loose this information.
   26041 	    */
   26042 	    xmlRegExecNextValues(inode->regexCtxt,
   26043 		&nbval, &nbneg, &values[0], &terminal);
   26044 	    ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
   26045 	    if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
   26046 		/*
   26047 		* Still missing something.
   26048 		*/
   26049 		ret = 1;
   26050 		inode->flags |=
   26051 		    XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
   26052 		xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
   26053 		    XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
   26054 		    "Missing child element(s)",
   26055 		    nbval, nbneg, values);
   26056 #ifdef DEBUG_AUTOMATA
   26057 		xmlGenericError(xmlGenericErrorContext,
   26058 		    "AUTOMATON missing ERROR on '%s'\n",
   26059 		    inode->localName);
   26060 #endif
   26061 	    } else {
   26062 		/*
   26063 		* Content model is satisfied.
   26064 		*/
   26065 		ret = 0;
   26066 #ifdef DEBUG_AUTOMATA
   26067 		xmlGenericError(xmlGenericErrorContext,
   26068 		    "AUTOMATON succeeded on '%s'\n",
   26069 		    inode->localName);
   26070 #endif
   26071 	    }
   26072 
   26073 	}
   26074     }
   26075     if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
   26076 	goto end_elem;
   26077 
   26078 character_content:
   26079 
   26080     if (vctxt->value != NULL) {
   26081 	xmlSchemaFreeValue(vctxt->value);
   26082 	vctxt->value = NULL;
   26083     }
   26084     /*
   26085     * Check character content.
   26086     */
   26087     if (inode->decl == NULL) {
   26088 	/*
   26089 	* Speedup if no declaration exists.
   26090 	*/
   26091 	if (WXS_IS_SIMPLE(inode->typeDef)) {
   26092 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26093 		inode, inode->typeDef, inode->value);
   26094 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   26095 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26096 		inode, inode->typeDef->contentTypeDef,
   26097 		inode->value);
   26098 	}
   26099 	if (ret < 0) {
   26100 	    VERROR_INT("xmlSchemaValidatorPopElem",
   26101 		"calling xmlSchemaVCheckCVCSimpleType()");
   26102 	    goto internal_error;
   26103 	}
   26104 	goto end_elem;
   26105     }
   26106     /*
   26107     * cvc-elt (3.3.4) : 5
   26108     * The appropriate case among the following must be true:
   26109     */
   26110     /*
   26111     * cvc-elt (3.3.4) : 5.1
   26112     * If the declaration has a {value constraint},
   26113     * the item has neither element nor character [children] and
   26114     * clause 3.2 has not applied, then all of the following must be true:
   26115     */
   26116     if ((inode->decl->value != NULL) &&
   26117 	(inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
   26118 	(! INODE_NILLED(inode))) {
   26119 	/*
   26120 	* cvc-elt (3.3.4) : 5.1.1
   26121 	* If the actual type definition is a local type definition
   26122 	* then the canonical lexical representation of the {value constraint}
   26123 	* value must be a valid default for the actual type definition as
   26124 	* defined in Element Default Valid (Immediate) (3.3.6).
   26125 	*/
   26126 	/*
   26127 	* NOTE: 'local' above means types acquired by xsi:type.
   26128 	* NOTE: Although the *canonical* value is stated, it is not
   26129 	* relevant if canonical or not. Additionally XML Schema 1.1
   26130 	* will removed this requirement as well.
   26131 	*/
   26132 	if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
   26133 
   26134 	    ret = xmlSchemaCheckCOSValidDefault(vctxt,
   26135 		inode->decl->value, &(inode->val));
   26136 	    if (ret != 0) {
   26137 		if (ret < 0) {
   26138 		    VERROR_INT("xmlSchemaValidatorPopElem",
   26139 			"calling xmlSchemaCheckCOSValidDefault()");
   26140 		    goto internal_error;
   26141 		}
   26142 		goto end_elem;
   26143 	    }
   26144 	    /*
   26145 	    * Stop here, to avoid redundant validation of the value
   26146 	    * (see following).
   26147 	    */
   26148 	    goto default_psvi;
   26149 	}
   26150 	/*
   26151 	* cvc-elt (3.3.4) : 5.1.2
   26152 	* The element information item with the canonical lexical
   26153 	* representation of the {value constraint} value used as its
   26154 	* normalized value must be valid with respect to the
   26155 	* actual type definition as defined by Element Locally Valid (Type)
   26156 	* (3.3.4).
   26157 	*/
   26158 	if (WXS_IS_SIMPLE(inode->typeDef)) {
   26159 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26160 		inode, inode->typeDef, inode->decl->value);
   26161 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   26162 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26163 		inode, inode->typeDef->contentTypeDef,
   26164 		inode->decl->value);
   26165 	}
   26166 	if (ret != 0) {
   26167 	    if (ret < 0) {
   26168 		VERROR_INT("xmlSchemaValidatorPopElem",
   26169 		    "calling xmlSchemaVCheckCVCSimpleType()");
   26170 		goto internal_error;
   26171 	    }
   26172 	    goto end_elem;
   26173 	}
   26174 
   26175 default_psvi:
   26176 	/*
   26177 	* PSVI: Create a text node on the instance element.
   26178 	*/
   26179 	if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
   26180 	    (inode->node != NULL)) {
   26181 	    xmlNodePtr textChild;
   26182 	    xmlChar *normValue;
   26183 	    /*
   26184 	    * VAL TODO: Normalize the value.
   26185 	    */
   26186 	    normValue = xmlSchemaNormalizeValue(inode->typeDef,
   26187 		inode->decl->value);
   26188 	    if (normValue != NULL) {
   26189 		textChild = xmlNewText(BAD_CAST normValue);
   26190 		xmlFree(normValue);
   26191 	    } else
   26192 		textChild = xmlNewText(inode->decl->value);
   26193 	    if (textChild == NULL) {
   26194 		VERROR_INT("xmlSchemaValidatorPopElem",
   26195 		    "calling xmlNewText()");
   26196 		goto internal_error;
   26197 	    } else
   26198 		xmlAddChild(inode->node, textChild);
   26199 	}
   26200 
   26201     } else if (! INODE_NILLED(inode)) {
   26202 	/*
   26203 	* 5.2.1 The element information item must be valid with respect
   26204 	* to the actual type definition as defined by Element Locally
   26205 	* Valid (Type) (3.3.4).
   26206 	*/
   26207 	if (WXS_IS_SIMPLE(inode->typeDef)) {
   26208 	     /*
   26209 	    * SPEC (cvc-type) (3.1)
   26210 	    * "If the type definition is a simple type definition, ..."
   26211 	    * (3.1.3) "If clause 3.2 of Element Locally Valid
   26212 	    * (Element) (3.3.4) did not apply, then the normalized value
   26213 	    * must be valid with respect to the type definition as defined
   26214 	    * by String Valid (3.14.4).
   26215 	    */
   26216 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26217 		    inode, inode->typeDef, inode->value);
   26218 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   26219 	    /*
   26220 	    * SPEC (cvc-type) (3.2) "If the type definition is a complex type
   26221 	    * definition, then the element information item must be
   26222 	    * valid with respect to the type definition as per
   26223 	    * Element Locally Valid (Complex Type) (3.4.4);"
   26224 	    *
   26225 	    * SPEC (cvc-complex-type) (2.2)
   26226 	    * "If the {content type} is a simple type definition, ...
   26227 	    * the normalized value of the element information item is
   26228 	    * valid with respect to that simple type definition as
   26229 	    * defined by String Valid (3.14.4)."
   26230 	    */
   26231 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26232 		inode, inode->typeDef->contentTypeDef, inode->value);
   26233 	}
   26234 	if (ret != 0) {
   26235 	    if (ret < 0) {
   26236 		VERROR_INT("xmlSchemaValidatorPopElem",
   26237 		    "calling xmlSchemaVCheckCVCSimpleType()");
   26238 		goto internal_error;
   26239 	    }
   26240 	    goto end_elem;
   26241 	}
   26242 	/*
   26243 	* 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
   26244 	* not applied, all of the following must be true:
   26245 	*/
   26246 	if ((inode->decl->value != NULL) &&
   26247 	    (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
   26248 
   26249 	    /*
   26250 	    * TODO: We will need a computed value, when comparison is
   26251 	    * done on computed values.
   26252 	    */
   26253 	    /*
   26254 	    * 5.2.2.1 The element information item must have no element
   26255 	    * information item [children].
   26256 	    */
   26257 	    if (inode->flags &
   26258 		    XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
   26259 		ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
   26260 		VERROR(ret, NULL,
   26261 		    "The content must not containt element nodes since "
   26262 		    "there is a fixed value constraint");
   26263 		goto end_elem;
   26264 	    } else {
   26265 		/*
   26266 		* 5.2.2.2 The appropriate case among the following must
   26267 		* be true:
   26268 		*/
   26269 		if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
   26270 		    /*
   26271 		    * 5.2.2.2.1 If the {content type} of the actual type
   26272 		    * definition is mixed, then the *initial value* of the
   26273 		    * item must match the canonical lexical representation
   26274 		    * of the {value constraint} value.
   26275 		    *
   26276 		    * ... the *initial value* of an element information
   26277 		    * item is the string composed of, in order, the
   26278 		    * [character code] of each character information item in
   26279 		    * the [children] of that element information item.
   26280 		    */
   26281 		    if (! xmlStrEqual(inode->value, inode->decl->value)){
   26282 			/*
   26283 			* VAL TODO: Report invalid & expected values as well.
   26284 			* VAL TODO: Implement the canonical stuff.
   26285 			*/
   26286 			ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
   26287 			xmlSchemaCustomErr(ACTXT_CAST vctxt,
   26288 			    ret, NULL, NULL,
   26289 			    "The initial value '%s' does not match the fixed "
   26290 			    "value constraint '%s'",
   26291 			    inode->value, inode->decl->value);
   26292 			goto end_elem;
   26293 		    }
   26294 		} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   26295 		    /*
   26296 		    * 5.2.2.2.2 If the {content type} of the actual type
   26297 		    * definition is a simple type definition, then the
   26298 		    * *actual value* of the item must match the canonical
   26299 		    * lexical representation of the {value constraint} value.
   26300 		    */
   26301 		    /*
   26302 		    * VAL TODO: *actual value* is the normalized value, impl.
   26303 		    *           this.
   26304 		    * VAL TODO: Report invalid & expected values as well.
   26305 		    * VAL TODO: Implement a comparison with the computed values.
   26306 		    */
   26307 		    if (! xmlStrEqual(inode->value,
   26308 			    inode->decl->value)) {
   26309 			ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
   26310 			xmlSchemaCustomErr(ACTXT_CAST vctxt,
   26311 			    ret, NULL, NULL,
   26312 			    "The actual value '%s' does not match the fixed "
   26313 			    "value constraint '%s'",
   26314 			    inode->value,
   26315 			    inode->decl->value);
   26316 			goto end_elem;
   26317 		    }
   26318 		}
   26319 	    }
   26320 	}
   26321     }
   26322 
   26323 end_elem:
   26324     if (vctxt->depth < 0) {
   26325 	/* TODO: raise error? */
   26326 	return (0);
   26327     }
   26328     if (vctxt->depth == vctxt->skipDepth)
   26329 	vctxt->skipDepth = -1;
   26330     /*
   26331     * Evaluate the history of XPath state objects.
   26332     */
   26333     if (inode->appliedXPath &&
   26334 	(xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
   26335 	goto internal_error;
   26336     /*
   26337     * MAYBE TODO:
   26338     * SPEC (6) "The element information item must be valid with
   26339     * respect to each of the {identity-constraint definitions} as per
   26340     * Identity-constraint Satisfied (3.11.4)."
   26341     */
   26342     /*
   26343     * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
   26344     *   need to be built in any case.
   26345     *   We will currently build IDC node-tables and bubble them only if
   26346     *   keyrefs do exist.
   26347     */
   26348 
   26349     /*
   26350     * Add the current IDC target-nodes to the IDC node-tables.
   26351     */
   26352     if ((inode->idcMatchers != NULL) &&
   26353 	(vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
   26354     {
   26355 	if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
   26356 	    goto internal_error;
   26357     }
   26358     /*
   26359     * Validate IDC keyrefs.
   26360     */
   26361     if (vctxt->inode->hasKeyrefs)
   26362 	if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
   26363 	    goto internal_error;
   26364     /*
   26365     * Merge/free the IDC table.
   26366     */
   26367     if (inode->idcTable != NULL) {
   26368 #ifdef DEBUG_IDC_NODE_TABLE
   26369 	xmlSchemaDebugDumpIDCTable(stdout,
   26370 	    inode->nsName,
   26371 	    inode->localName,
   26372 	    inode->idcTable);
   26373 #endif
   26374 	if ((vctxt->depth > 0) &&
   26375 	    (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
   26376 	{
   26377 	    /*
   26378 	    * Merge the IDC node table with the table of the parent node.
   26379 	    */
   26380 	    if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
   26381 		goto internal_error;
   26382 	}
   26383     }
   26384     /*
   26385     * Clear the current ielem.
   26386     * VAL TODO: Don't free the PSVI IDC tables if they are
   26387     * requested for the PSVI.
   26388     */
   26389     xmlSchemaClearElemInfo(vctxt, inode);
   26390     /*
   26391     * Skip further processing if we are on the validation root.
   26392     */
   26393     if (vctxt->depth == 0) {
   26394 	vctxt->depth--;
   26395 	vctxt->inode = NULL;
   26396 	return (0);
   26397     }
   26398     /*
   26399     * Reset the keyrefDepth if needed.
   26400     */
   26401     if (vctxt->aidcs != NULL) {
   26402 	xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
   26403 	do {
   26404 	    if (aidc->keyrefDepth == vctxt->depth) {
   26405 		/*
   26406 		* A 'keyrefDepth' of a key/unique IDC matches the current
   26407 		* depth, this means that we are leaving the scope of the
   26408 		* top-most keyref IDC which refers to this IDC.
   26409 		*/
   26410 		aidc->keyrefDepth = -1;
   26411 	    }
   26412 	    aidc = aidc->next;
   26413 	} while (aidc != NULL);
   26414     }
   26415     vctxt->depth--;
   26416     vctxt->inode = vctxt->elemInfos[vctxt->depth];
   26417     /*
   26418     * VAL TODO: 7 If the element information item is the validation root, it must be
   26419     * valid per Validation Root Valid (ID/IDREF) (3.3.4).
   26420     */
   26421     return (ret);
   26422 
   26423 internal_error:
   26424     vctxt->err = -1;
   26425     return (-1);
   26426 }
   26427 
   26428 /*
   26429 * 3.4.4 Complex Type Definition Validation Rules
   26430 * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
   26431 */
   26432 static int
   26433 xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
   26434 {
   26435     xmlSchemaNodeInfoPtr pielem;
   26436     xmlSchemaTypePtr ptype;
   26437     int ret = 0;
   26438 
   26439     if (vctxt->depth <= 0) {
   26440 	VERROR_INT("xmlSchemaValidateChildElem",
   26441 	    "not intended for the validation root");
   26442 	return (-1);
   26443     }
   26444     pielem = vctxt->elemInfos[vctxt->depth -1];
   26445     if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
   26446 	pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
   26447     /*
   26448     * Handle 'nilled' elements.
   26449     */
   26450     if (INODE_NILLED(pielem)) {
   26451 	/*
   26452 	* SPEC (cvc-elt) (3.3.4) : (3.2.1)
   26453 	*/
   26454 	ACTIVATE_PARENT_ELEM;
   26455 	ret = XML_SCHEMAV_CVC_ELT_3_2_1;
   26456 	VERROR(ret, NULL,
   26457 	    "Neither character nor element content is allowed, "
   26458 	    "because the element was 'nilled'");
   26459 	ACTIVATE_ELEM;
   26460 	goto unexpected_elem;
   26461     }
   26462 
   26463     ptype = pielem->typeDef;
   26464 
   26465     if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
   26466 	/*
   26467 	* Workaround for "anyType": we have currently no content model
   26468 	* assigned for "anyType", so handle it explicitely.
   26469 	* "anyType" has an unbounded, lax "any" wildcard.
   26470 	*/
   26471 	vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
   26472 	    vctxt->inode->localName,
   26473 	    vctxt->inode->nsName);
   26474 
   26475 	if (vctxt->inode->decl == NULL) {
   26476 	    xmlSchemaAttrInfoPtr iattr;
   26477 	    /*
   26478 	    * Process "xsi:type".
   26479 	    * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
   26480 	    */
   26481 	    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   26482 		XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
   26483 	    if (iattr != NULL) {
   26484 		ret = xmlSchemaProcessXSIType(vctxt, iattr,
   26485 		    &(vctxt->inode->typeDef), NULL);
   26486 		if (ret != 0) {
   26487 		    if (ret == -1) {
   26488 			VERROR_INT("xmlSchemaValidateChildElem",
   26489 			    "calling xmlSchemaProcessXSIType() to "
   26490 			    "process the attribute 'xsi:nil'");
   26491 			return (-1);
   26492 		    }
   26493 		    return (ret);
   26494 		}
   26495 	    } else {
   26496 		 /*
   26497 		 * Fallback to "anyType".
   26498 		 *
   26499 		 * SPEC (cvc-assess-elt)
   26500 		 * "If the item cannot be strictly assessed, [...]
   26501 		 * an element information item's schema validity may be laxly
   26502 		 * assessed if its context-determined declaration is not
   26503 		 * skip by validating with respect to the ur-type
   26504 		 * definition as per Element Locally Valid (Type) (3.3.4)."
   26505 		*/
   26506 		vctxt->inode->typeDef =
   26507 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
   26508 	    }
   26509 	}
   26510 	return (0);
   26511     }
   26512 
   26513     switch (ptype->contentType) {
   26514 	case XML_SCHEMA_CONTENT_EMPTY:
   26515 	    /*
   26516 	    * SPEC (2.1) "If the {content type} is empty, then the
   26517 	    * element information item has no character or element
   26518 	    * information item [children]."
   26519 	    */
   26520 	    ACTIVATE_PARENT_ELEM
   26521 	    ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
   26522 	    VERROR(ret, NULL,
   26523 		"Element content is not allowed, "
   26524 		"because the content type is empty");
   26525 	    ACTIVATE_ELEM
   26526 	    goto unexpected_elem;
   26527 	    break;
   26528 
   26529 	case XML_SCHEMA_CONTENT_MIXED:
   26530         case XML_SCHEMA_CONTENT_ELEMENTS: {
   26531 	    xmlRegExecCtxtPtr regexCtxt;
   26532 	    xmlChar *values[10];
   26533 	    int terminal, nbval = 10, nbneg;
   26534 
   26535 	    /* VAL TODO: Optimized "anyType" validation.*/
   26536 
   26537 	    if (ptype->contModel == NULL) {
   26538 		VERROR_INT("xmlSchemaValidateChildElem",
   26539 		    "type has elem content but no content model");
   26540 		return (-1);
   26541 	    }
   26542 	    /*
   26543 	    * Safety belf for evaluation if the cont. model was already
   26544 	    * examined to be invalid.
   26545 	    */
   26546 	    if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
   26547 		VERROR_INT("xmlSchemaValidateChildElem",
   26548 		    "validating elem, but elem content is already invalid");
   26549 		return (-1);
   26550 	    }
   26551 
   26552 	    regexCtxt = pielem->regexCtxt;
   26553 	    if (regexCtxt == NULL) {
   26554 		/*
   26555 		* Create the regex context.
   26556 		*/
   26557 		regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
   26558 		    (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
   26559 		    vctxt);
   26560 		if (regexCtxt == NULL) {
   26561 		    VERROR_INT("xmlSchemaValidateChildElem",
   26562 			"failed to create a regex context");
   26563 		    return (-1);
   26564 		}
   26565 		pielem->regexCtxt = regexCtxt;
   26566 #ifdef DEBUG_AUTOMATA
   26567 		xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
   26568 		    pielem->localName);
   26569 #endif
   26570 	    }
   26571 
   26572 	    /*
   26573 	    * SPEC (2.4) "If the {content type} is element-only or mixed,
   26574 	    * then the sequence of the element information item's
   26575 	    * element information item [children], if any, taken in
   26576 	    * order, is valid with respect to the {content type}'s
   26577 	    * particle, as defined in Element Sequence Locally Valid
   26578 	    * (Particle) (3.9.4)."
   26579 	    */
   26580 	    ret = xmlRegExecPushString2(regexCtxt,
   26581 		vctxt->inode->localName,
   26582 		vctxt->inode->nsName,
   26583 		vctxt->inode);
   26584 #ifdef DEBUG_AUTOMATA
   26585 	    if (ret < 0)
   26586 		xmlGenericError(xmlGenericErrorContext,
   26587 		"AUTOMATON push ERROR for '%s' on '%s'\n",
   26588 		vctxt->inode->localName, pielem->localName);
   26589 	    else
   26590 		xmlGenericError(xmlGenericErrorContext,
   26591 		"AUTOMATON push OK for '%s' on '%s'\n",
   26592 		vctxt->inode->localName, pielem->localName);
   26593 #endif
   26594 	    if (vctxt->err == XML_SCHEMAV_INTERNAL) {
   26595 		VERROR_INT("xmlSchemaValidateChildElem",
   26596 		    "calling xmlRegExecPushString2()");
   26597 		return (-1);
   26598 	    }
   26599 	    if (ret < 0) {
   26600 		xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
   26601 		    &values[0], &terminal);
   26602 		xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
   26603 		    XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
   26604 		    "This element is not expected",
   26605 		    nbval, nbneg, values);
   26606 		ret = vctxt->err;
   26607 		goto unexpected_elem;
   26608 	    } else
   26609 		ret = 0;
   26610 	}
   26611 	    break;
   26612 	case XML_SCHEMA_CONTENT_SIMPLE:
   26613 	case XML_SCHEMA_CONTENT_BASIC:
   26614 	    ACTIVATE_PARENT_ELEM
   26615 	    if (WXS_IS_COMPLEX(ptype)) {
   26616 		/*
   26617 		* SPEC (cvc-complex-type) (2.2)
   26618 		* "If the {content type} is a simple type definition, then
   26619 		* the element information item has no element information
   26620 		* item [children], ..."
   26621 		*/
   26622 		ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
   26623 		VERROR(ret, NULL, "Element content is not allowed, "
   26624 		    "because the content type is a simple type definition");
   26625 	    } else {
   26626 		/*
   26627 		* SPEC (cvc-type) (3.1.2) "The element information item must
   26628 		* have no element information item [children]."
   26629 		*/
   26630 		ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
   26631 		VERROR(ret, NULL, "Element content is not allowed, "
   26632 		    "because the type definition is simple");
   26633 	    }
   26634 	    ACTIVATE_ELEM
   26635 	    ret = vctxt->err;
   26636 	    goto unexpected_elem;
   26637 	    break;
   26638 
   26639 	default:
   26640 	    break;
   26641     }
   26642     return (ret);
   26643 unexpected_elem:
   26644     /*
   26645     * Pop this element and set the skipDepth to skip
   26646     * all further content of the parent element.
   26647     */
   26648     vctxt->skipDepth = vctxt->depth;
   26649     vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
   26650     pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
   26651     return (ret);
   26652 }
   26653 
   26654 #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
   26655 #define XML_SCHEMA_PUSH_TEXT_CREATED 2
   26656 #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
   26657 
   26658 static int
   26659 xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
   26660 		  int nodeType, const xmlChar *value, int len,
   26661 		  int mode, int *consumed)
   26662 {
   26663     /*
   26664     * Unfortunately we have to duplicate the text sometimes.
   26665     * OPTIMIZE: Maybe we could skip it, if:
   26666     *   1. content type is simple
   26667     *   2. whitespace is "collapse"
   26668     *   3. it consists of whitespace only
   26669     *
   26670     * Process character content.
   26671     */
   26672     if (consumed != NULL)
   26673 	*consumed = 0;
   26674     if (INODE_NILLED(vctxt->inode)) {
   26675 	/*
   26676 	* SPEC cvc-elt (3.3.4 - 3.2.1)
   26677 	* "The element information item must have no character or
   26678 	* element information item [children]."
   26679 	*/
   26680 	VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
   26681 	    "Neither character nor element content is allowed "
   26682 	    "because the element is 'nilled'");
   26683 	return (vctxt->err);
   26684     }
   26685     /*
   26686     * SPEC (2.1) "If the {content type} is empty, then the
   26687     * element information item has no character or element
   26688     * information item [children]."
   26689     */
   26690     if (vctxt->inode->typeDef->contentType ==
   26691 	    XML_SCHEMA_CONTENT_EMPTY) {
   26692 	VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
   26693 	    "Character content is not allowed, "
   26694 	    "because the content type is empty");
   26695 	return (vctxt->err);
   26696     }
   26697 
   26698     if (vctxt->inode->typeDef->contentType ==
   26699 	    XML_SCHEMA_CONTENT_ELEMENTS) {
   26700 	if ((nodeType != XML_TEXT_NODE) ||
   26701 	    (! xmlSchemaIsBlank((xmlChar *) value, len))) {
   26702 	    /*
   26703 	    * SPEC cvc-complex-type (2.3)
   26704 	    * "If the {content type} is element-only, then the
   26705 	    * element information item has no character information
   26706 	    * item [children] other than those whose [character
   26707 	    * code] is defined as a white space in [XML 1.0 (Second
   26708 	    * Edition)]."
   26709 	    */
   26710 	    VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
   26711 		"Character content other than whitespace is not allowed "
   26712 		"because the content type is 'element-only'");
   26713 	    return (vctxt->err);
   26714 	}
   26715 	return (0);
   26716     }
   26717 
   26718     if ((value == NULL) || (value[0] == 0))
   26719 	return (0);
   26720     /*
   26721     * Save the value.
   26722     * NOTE that even if the content type is *mixed*, we need the
   26723     * *initial value* for default/fixed value constraints.
   26724     */
   26725     if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
   26726 	((vctxt->inode->decl == NULL) ||
   26727 	(vctxt->inode->decl->value == NULL)))
   26728 	return (0);
   26729 
   26730     if (vctxt->inode->value == NULL) {
   26731 	/*
   26732 	* Set the value.
   26733 	*/
   26734 	switch (mode) {
   26735 	    case XML_SCHEMA_PUSH_TEXT_PERSIST:
   26736 		/*
   26737 		* When working on a tree.
   26738 		*/
   26739 		vctxt->inode->value = value;
   26740 		break;
   26741 	    case XML_SCHEMA_PUSH_TEXT_CREATED:
   26742 		/*
   26743 		* When working with the reader.
   26744 		* The value will be freed by the element info.
   26745 		*/
   26746 		vctxt->inode->value = value;
   26747 		if (consumed != NULL)
   26748 		    *consumed = 1;
   26749 		vctxt->inode->flags |=
   26750 		    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
   26751 		break;
   26752 	    case XML_SCHEMA_PUSH_TEXT_VOLATILE:
   26753 		/*
   26754 		* When working with SAX.
   26755 		* The value will be freed by the element info.
   26756 		*/
   26757 		if (len != -1)
   26758 		    vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
   26759 		else
   26760 		    vctxt->inode->value = BAD_CAST xmlStrdup(value);
   26761 		vctxt->inode->flags |=
   26762 		    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
   26763 		break;
   26764 	    default:
   26765 		break;
   26766 	}
   26767     } else {
   26768 	if (len < 0)
   26769 	    len = xmlStrlen(value);
   26770 	/*
   26771 	* Concat the value.
   26772 	*/
   26773 	if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
   26774 	    vctxt->inode->value = BAD_CAST xmlStrncat(
   26775 		(xmlChar *) vctxt->inode->value, value, len);
   26776 	} else {
   26777 	    vctxt->inode->value =
   26778 		BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
   26779 	    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
   26780 	}
   26781     }
   26782 
   26783     return (0);
   26784 }
   26785 
   26786 static int
   26787 xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
   26788 {
   26789     int ret = 0;
   26790 
   26791     if ((vctxt->skipDepth != -1) &&
   26792 	(vctxt->depth >= vctxt->skipDepth)) {
   26793 	VERROR_INT("xmlSchemaValidateElem",
   26794 	    "in skip-state");
   26795 	goto internal_error;
   26796     }
   26797     if (vctxt->xsiAssemble) {
   26798 	/*
   26799 	* We will stop validation if there was an error during
   26800 	* dynamic schema construction.
   26801 	* Note that we simply set @skipDepth to 0, this could
   26802 	* mean that a streaming document via SAX would be
   26803 	* still read to the end but it won't be validated any more.
   26804 	* TODO: If we are sure how to stop the validation at once
   26805 	*   for all input scenarios, then this should be changed to
   26806 	*   instantly stop the validation.
   26807 	*/
   26808 	ret = xmlSchemaAssembleByXSI(vctxt);
   26809 	if (ret != 0) {
   26810 	    if (ret == -1)
   26811 		goto internal_error;
   26812 	    vctxt->skipDepth = 0;
   26813 	    return(ret);
   26814 	}
   26815         /*
   26816          * Augment the IDC definitions for the main schema and all imported ones
   26817          * NOTE: main schema is the first in the imported list
   26818          */
   26819         xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
   26820     }
   26821     if (vctxt->depth > 0) {
   26822 	/*
   26823 	* Validate this element against the content model
   26824 	* of the parent.
   26825 	*/
   26826 	ret = xmlSchemaValidateChildElem(vctxt);
   26827 	if (ret != 0) {
   26828 	    if (ret < 0) {
   26829 		VERROR_INT("xmlSchemaValidateElem",
   26830 		    "calling xmlSchemaStreamValidateChildElement()");
   26831 		goto internal_error;
   26832 	    }
   26833 	    goto exit;
   26834 	}
   26835 	if (vctxt->depth == vctxt->skipDepth)
   26836 	    goto exit;
   26837 	if ((vctxt->inode->decl == NULL) &&
   26838 	    (vctxt->inode->typeDef == NULL)) {
   26839 	    VERROR_INT("xmlSchemaValidateElem",
   26840 		"the child element was valid but neither the "
   26841 		"declaration nor the type was set");
   26842 	    goto internal_error;
   26843 	}
   26844     } else {
   26845 	/*
   26846 	* Get the declaration of the validation root.
   26847 	*/
   26848 	vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
   26849 	    vctxt->inode->localName,
   26850 	    vctxt->inode->nsName);
   26851 	if (vctxt->inode->decl == NULL) {
   26852 	    ret = XML_SCHEMAV_CVC_ELT_1;
   26853 	    VERROR(ret, NULL,
   26854 		"No matching global declaration available "
   26855 		"for the validation root");
   26856 	    goto exit;
   26857 	}
   26858     }
   26859 
   26860     if (vctxt->inode->decl == NULL)
   26861 	goto type_validation;
   26862 
   26863     if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
   26864 	int skip;
   26865 	/*
   26866 	* Wildcards.
   26867 	*/
   26868 	ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
   26869 	if (ret != 0) {
   26870 	    if (ret < 0) {
   26871 		VERROR_INT("xmlSchemaValidateElem",
   26872 		    "calling xmlSchemaValidateElemWildcard()");
   26873 		goto internal_error;
   26874 	    }
   26875 	    goto exit;
   26876 	}
   26877 	if (skip) {
   26878 	    vctxt->skipDepth = vctxt->depth;
   26879 	    goto exit;
   26880 	}
   26881 	/*
   26882 	* The declaration might be set by the wildcard validation,
   26883 	* when the processContents is "lax" or "strict".
   26884 	*/
   26885 	if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
   26886 	    /*
   26887 	    * Clear the "decl" field to not confuse further processing.
   26888 	    */
   26889 	    vctxt->inode->decl = NULL;
   26890 	    goto type_validation;
   26891 	}
   26892     }
   26893     /*
   26894     * Validate against the declaration.
   26895     */
   26896     ret = xmlSchemaValidateElemDecl(vctxt);
   26897     if (ret != 0) {
   26898 	if (ret < 0) {
   26899 	    VERROR_INT("xmlSchemaValidateElem",
   26900 		"calling xmlSchemaValidateElemDecl()");
   26901 	    goto internal_error;
   26902 	}
   26903 	goto exit;
   26904     }
   26905     /*
   26906     * Validate against the type definition.
   26907     */
   26908 type_validation:
   26909 
   26910     if (vctxt->inode->typeDef == NULL) {
   26911 	vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
   26912 	ret = XML_SCHEMAV_CVC_TYPE_1;
   26913     	VERROR(ret, NULL,
   26914     	    "The type definition is absent");
   26915 	goto exit;
   26916     }
   26917     if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
   26918 	vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
   26919 	ret = XML_SCHEMAV_CVC_TYPE_2;
   26920     	    VERROR(ret, NULL,
   26921     	    "The type definition is abstract");
   26922 	goto exit;
   26923     }
   26924     /*
   26925     * Evaluate IDCs. Do it here, since new IDC matchers are registered
   26926     * during validation against the declaration. This must be done
   26927     * _before_ attribute validation.
   26928     */
   26929     if (vctxt->xpathStates != NULL) {
   26930 	ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
   26931 	vctxt->inode->appliedXPath = 1;
   26932 	if (ret == -1) {
   26933 	    VERROR_INT("xmlSchemaValidateElem",
   26934 		"calling xmlSchemaXPathEvaluate()");
   26935 	    goto internal_error;
   26936 	}
   26937     }
   26938     /*
   26939     * Validate attributes.
   26940     */
   26941     if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
   26942 	if ((vctxt->nbAttrInfos != 0) ||
   26943 	    (vctxt->inode->typeDef->attrUses != NULL)) {
   26944 
   26945 	    ret = xmlSchemaVAttributesComplex(vctxt);
   26946 	}
   26947     } else if (vctxt->nbAttrInfos != 0) {
   26948 
   26949 	ret = xmlSchemaVAttributesSimple(vctxt);
   26950     }
   26951     /*
   26952     * Clear registered attributes.
   26953     */
   26954     if (vctxt->nbAttrInfos != 0)
   26955 	xmlSchemaClearAttrInfos(vctxt);
   26956     if (ret == -1) {
   26957 	VERROR_INT("xmlSchemaValidateElem",
   26958 	    "calling attributes validation");
   26959 	goto internal_error;
   26960     }
   26961     /*
   26962     * Don't return an error if attributes are invalid on purpose.
   26963     */
   26964     ret = 0;
   26965 
   26966 exit:
   26967     if (ret != 0)
   26968 	vctxt->skipDepth = vctxt->depth;
   26969     return (ret);
   26970 internal_error:
   26971     return (-1);
   26972 }
   26973 
   26974 #ifdef XML_SCHEMA_READER_ENABLED
   26975 static int
   26976 xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
   26977 {
   26978     const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
   26979     int depth, nodeType, ret = 0, consumed;
   26980     xmlSchemaNodeInfoPtr ielem;
   26981 
   26982     vctxt->depth = -1;
   26983     ret = xmlTextReaderRead(vctxt->reader);
   26984     /*
   26985     * Move to the document element.
   26986     */
   26987     while (ret == 1) {
   26988 	nodeType = xmlTextReaderNodeType(vctxt->reader);
   26989 	if (nodeType == XML_ELEMENT_NODE)
   26990 	    goto root_found;
   26991 	ret = xmlTextReaderRead(vctxt->reader);
   26992     }
   26993     goto exit;
   26994 
   26995 root_found:
   26996 
   26997     do {
   26998 	depth = xmlTextReaderDepth(vctxt->reader);
   26999 	nodeType = xmlTextReaderNodeType(vctxt->reader);
   27000 
   27001 	if (nodeType == XML_ELEMENT_NODE) {
   27002 
   27003 	    vctxt->depth++;
   27004 	    if (xmlSchemaValidatorPushElem(vctxt) == -1) {
   27005 		VERROR_INT("xmlSchemaVReaderWalk",
   27006 		    "calling xmlSchemaValidatorPushElem()");
   27007 		goto internal_error;
   27008 	    }
   27009 	    ielem = vctxt->inode;
   27010 	    ielem->localName = xmlTextReaderLocalName(vctxt->reader);
   27011 	    ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
   27012 	    ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
   27013 	    /*
   27014 	    * Is the element empty?
   27015 	    */
   27016 	    ret = xmlTextReaderIsEmptyElement(vctxt->reader);
   27017 	    if (ret == -1) {
   27018 		VERROR_INT("xmlSchemaVReaderWalk",
   27019 		    "calling xmlTextReaderIsEmptyElement()");
   27020 		goto internal_error;
   27021 	    }
   27022 	    if (ret) {
   27023 		ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
   27024 	    }
   27025 	    /*
   27026 	    * Register attributes.
   27027 	    */
   27028 	    vctxt->nbAttrInfos = 0;
   27029 	    ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
   27030 	    if (ret == -1) {
   27031 		VERROR_INT("xmlSchemaVReaderWalk",
   27032 		    "calling xmlTextReaderMoveToFirstAttribute()");
   27033 		goto internal_error;
   27034 	    }
   27035 	    if (ret == 1) {
   27036 		do {
   27037 		    /*
   27038 		    * VAL TODO: How do we know that the reader works on a
   27039 		    * node tree, to be able to pass a node here?
   27040 		    */
   27041 		    if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
   27042 			(const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
   27043 			xmlTextReaderNamespaceUri(vctxt->reader), 1,
   27044 			xmlTextReaderValue(vctxt->reader), 1) == -1) {
   27045 
   27046 			VERROR_INT("xmlSchemaVReaderWalk",
   27047 			    "calling xmlSchemaValidatorPushAttribute()");
   27048 			goto internal_error;
   27049 		    }
   27050 		    ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
   27051 		    if (ret == -1) {
   27052 			VERROR_INT("xmlSchemaVReaderWalk",
   27053 			    "calling xmlTextReaderMoveToFirstAttribute()");
   27054 			goto internal_error;
   27055 		    }
   27056 		} while (ret == 1);
   27057 		/*
   27058 		* Back to element position.
   27059 		*/
   27060 		ret = xmlTextReaderMoveToElement(vctxt->reader);
   27061 		if (ret == -1) {
   27062 		    VERROR_INT("xmlSchemaVReaderWalk",
   27063 			"calling xmlTextReaderMoveToElement()");
   27064 		    goto internal_error;
   27065 		}
   27066 	    }
   27067 	    /*
   27068 	    * Validate the element.
   27069 	    */
   27070 	    ret= xmlSchemaValidateElem(vctxt);
   27071 	    if (ret != 0) {
   27072 		if (ret == -1) {
   27073 		    VERROR_INT("xmlSchemaVReaderWalk",
   27074 			"calling xmlSchemaValidateElem()");
   27075 		    goto internal_error;
   27076 		}
   27077 		goto exit;
   27078 	    }
   27079 	    if (vctxt->depth == vctxt->skipDepth) {
   27080 		int curDepth;
   27081 		/*
   27082 		* Skip all content.
   27083 		*/
   27084 		if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
   27085 		    ret = xmlTextReaderRead(vctxt->reader);
   27086 		    curDepth = xmlTextReaderDepth(vctxt->reader);
   27087 		    while ((ret == 1) && (curDepth != depth)) {
   27088 			ret = xmlTextReaderRead(vctxt->reader);
   27089 			curDepth = xmlTextReaderDepth(vctxt->reader);
   27090 		    }
   27091 		    if (ret < 0) {
   27092 			/*
   27093 			* VAL TODO: A reader error occured; what to do here?
   27094 			*/
   27095 			ret = 1;
   27096 			goto exit;
   27097 		    }
   27098 		}
   27099 		goto leave_elem;
   27100 	    }
   27101 	    /*
   27102 	    * READER VAL TODO: Is an END_ELEM really never called
   27103 	    * if the elem is empty?
   27104 	    */
   27105 	    if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
   27106 		goto leave_elem;
   27107 	} else if (nodeType == END_ELEM) {
   27108 	    /*
   27109 	    * Process END of element.
   27110 	    */
   27111 leave_elem:
   27112 	    ret = xmlSchemaValidatorPopElem(vctxt);
   27113 	    if (ret != 0) {
   27114 		if (ret < 0) {
   27115 		    VERROR_INT("xmlSchemaVReaderWalk",
   27116 			"calling xmlSchemaValidatorPopElem()");
   27117 		    goto internal_error;
   27118 		}
   27119 		goto exit;
   27120 	    }
   27121 	    if (vctxt->depth >= 0)
   27122 		ielem = vctxt->inode;
   27123 	    else
   27124 		ielem = NULL;
   27125 	} else if ((nodeType == XML_TEXT_NODE) ||
   27126 	    (nodeType == XML_CDATA_SECTION_NODE) ||
   27127 	    (nodeType == WHTSP) ||
   27128 	    (nodeType == SIGN_WHTSP)) {
   27129 	    /*
   27130 	    * Process character content.
   27131 	    */
   27132 	    xmlChar *value;
   27133 
   27134 	    if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
   27135 		nodeType = XML_TEXT_NODE;
   27136 
   27137 	    value = xmlTextReaderValue(vctxt->reader);
   27138 	    ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
   27139 		-1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
   27140 	    if (! consumed)
   27141 		xmlFree(value);
   27142 	    if (ret == -1) {
   27143 		VERROR_INT("xmlSchemaVReaderWalk",
   27144 		    "calling xmlSchemaVPushText()");
   27145 		goto internal_error;
   27146 	    }
   27147 	} else if ((nodeType == XML_ENTITY_NODE) ||
   27148 	    (nodeType == XML_ENTITY_REF_NODE)) {
   27149 	    /*
   27150 	    * VAL TODO: What to do with entities?
   27151 	    */
   27152 	    TODO
   27153 	}
   27154 	/*
   27155 	* Read next node.
   27156 	*/
   27157 	ret = xmlTextReaderRead(vctxt->reader);
   27158     } while (ret == 1);
   27159 
   27160 exit:
   27161     return (ret);
   27162 internal_error:
   27163     return (-1);
   27164 }
   27165 #endif
   27166 
   27167 /************************************************************************
   27168  * 									*
   27169  * 			SAX validation handlers				*
   27170  * 									*
   27171  ************************************************************************/
   27172 
   27173 /*
   27174 * Process text content.
   27175 */
   27176 static void
   27177 xmlSchemaSAXHandleText(void *ctx,
   27178 		       const xmlChar * ch,
   27179 		       int len)
   27180 {
   27181     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27182 
   27183     if (vctxt->depth < 0)
   27184 	return;
   27185     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27186 	return;
   27187     if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
   27188 	vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
   27189     if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
   27190 	XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
   27191 	VERROR_INT("xmlSchemaSAXHandleCDataSection",
   27192 	    "calling xmlSchemaVPushText()");
   27193 	vctxt->err = -1;
   27194 	xmlStopParser(vctxt->parserCtxt);
   27195     }
   27196 }
   27197 
   27198 /*
   27199 * Process CDATA content.
   27200 */
   27201 static void
   27202 xmlSchemaSAXHandleCDataSection(void *ctx,
   27203 			     const xmlChar * ch,
   27204 			     int len)
   27205 {
   27206     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27207 
   27208     if (vctxt->depth < 0)
   27209 	return;
   27210     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27211 	return;
   27212     if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
   27213 	vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
   27214     if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
   27215 	XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
   27216 	VERROR_INT("xmlSchemaSAXHandleCDataSection",
   27217 	    "calling xmlSchemaVPushText()");
   27218 	vctxt->err = -1;
   27219 	xmlStopParser(vctxt->parserCtxt);
   27220     }
   27221 }
   27222 
   27223 static void
   27224 xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
   27225 			    const xmlChar * name ATTRIBUTE_UNUSED)
   27226 {
   27227     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27228 
   27229     if (vctxt->depth < 0)
   27230 	return;
   27231     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27232 	return;
   27233     /* SAX VAL TODO: What to do here? */
   27234     TODO
   27235 }
   27236 
   27237 static void
   27238 xmlSchemaSAXHandleStartElementNs(void *ctx,
   27239 				 const xmlChar * localname,
   27240 				 const xmlChar * prefix ATTRIBUTE_UNUSED,
   27241 				 const xmlChar * URI,
   27242 				 int nb_namespaces,
   27243 				 const xmlChar ** namespaces,
   27244 				 int nb_attributes,
   27245 				 int nb_defaulted ATTRIBUTE_UNUSED,
   27246 				 const xmlChar ** attributes)
   27247 {
   27248     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27249     int ret;
   27250     xmlSchemaNodeInfoPtr ielem;
   27251     int i, j;
   27252 
   27253     /*
   27254     * SAX VAL TODO: What to do with nb_defaulted?
   27255     */
   27256     /*
   27257     * Skip elements if inside a "skip" wildcard or invalid.
   27258     */
   27259     vctxt->depth++;
   27260     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27261 	return;
   27262     /*
   27263     * Push the element.
   27264     */
   27265     if (xmlSchemaValidatorPushElem(vctxt) == -1) {
   27266 	VERROR_INT("xmlSchemaSAXHandleStartElementNs",
   27267 	    "calling xmlSchemaValidatorPushElem()");
   27268 	goto internal_error;
   27269     }
   27270     ielem = vctxt->inode;
   27271     /*
   27272     * TODO: Is this OK?
   27273     */
   27274     ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
   27275     ielem->localName = localname;
   27276     ielem->nsName = URI;
   27277     ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
   27278     /*
   27279     * Register namespaces on the elem info.
   27280     */
   27281     if (nb_namespaces != 0) {
   27282 	/*
   27283 	* Although the parser builds its own namespace list,
   27284 	* we have no access to it, so we'll use an own one.
   27285 	*/
   27286         for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
   27287 	    /*
   27288 	    * Store prefix and namespace name.
   27289 	    */
   27290 	    if (ielem->nsBindings == NULL) {
   27291 		ielem->nsBindings =
   27292 		    (const xmlChar **) xmlMalloc(10 *
   27293 			sizeof(const xmlChar *));
   27294 		if (ielem->nsBindings == NULL) {
   27295 		    xmlSchemaVErrMemory(vctxt,
   27296 			"allocating namespace bindings for SAX validation",
   27297 			NULL);
   27298 		    goto internal_error;
   27299 		}
   27300 		ielem->nbNsBindings = 0;
   27301 		ielem->sizeNsBindings = 5;
   27302 	    } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
   27303 		ielem->sizeNsBindings *= 2;
   27304 		ielem->nsBindings =
   27305 		    (const xmlChar **) xmlRealloc(
   27306 			(void *) ielem->nsBindings,
   27307 			ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
   27308 		if (ielem->nsBindings == NULL) {
   27309 		    xmlSchemaVErrMemory(vctxt,
   27310 			"re-allocating namespace bindings for SAX validation",
   27311 			NULL);
   27312 		    goto internal_error;
   27313 		}
   27314 	    }
   27315 
   27316 	    ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
   27317 	    if (namespaces[j+1][0] == 0) {
   27318 		/*
   27319 		* Handle xmlns="".
   27320 		*/
   27321 		ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
   27322 	    } else
   27323 		ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
   27324 		    namespaces[j+1];
   27325 	    ielem->nbNsBindings++;
   27326 	}
   27327     }
   27328     /*
   27329     * Register attributes.
   27330     * SAX VAL TODO: We are not adding namespace declaration
   27331     * attributes yet.
   27332     */
   27333     if (nb_attributes != 0) {
   27334 	xmlChar *value;
   27335 
   27336         for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
   27337 	    /*
   27338 	    * Duplicate the value.
   27339 	    */
   27340 	    value = xmlStrndup(attributes[j+3],
   27341 		attributes[j+4] - attributes[j+3]);
   27342 	    /*
   27343 	    * TODO: Set the node line.
   27344 	    */
   27345 	    ret = xmlSchemaValidatorPushAttribute(vctxt,
   27346 		NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
   27347 		value, 1);
   27348 	    if (ret == -1) {
   27349 		VERROR_INT("xmlSchemaSAXHandleStartElementNs",
   27350 		    "calling xmlSchemaValidatorPushAttribute()");
   27351 		goto internal_error;
   27352 	    }
   27353 	}
   27354     }
   27355     /*
   27356     * Validate the element.
   27357     */
   27358     ret = xmlSchemaValidateElem(vctxt);
   27359     if (ret != 0) {
   27360 	if (ret == -1) {
   27361 	    VERROR_INT("xmlSchemaSAXHandleStartElementNs",
   27362 		"calling xmlSchemaValidateElem()");
   27363 	    goto internal_error;
   27364 	}
   27365 	goto exit;
   27366     }
   27367 
   27368 exit:
   27369     return;
   27370 internal_error:
   27371     vctxt->err = -1;
   27372     xmlStopParser(vctxt->parserCtxt);
   27373     return;
   27374 }
   27375 
   27376 static void
   27377 xmlSchemaSAXHandleEndElementNs(void *ctx,
   27378 			       const xmlChar * localname ATTRIBUTE_UNUSED,
   27379 			       const xmlChar * prefix ATTRIBUTE_UNUSED,
   27380 			       const xmlChar * URI ATTRIBUTE_UNUSED)
   27381 {
   27382     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27383     int res;
   27384 
   27385     /*
   27386     * Skip elements if inside a "skip" wildcard or if invalid.
   27387     */
   27388     if (vctxt->skipDepth != -1) {
   27389 	if (vctxt->depth > vctxt->skipDepth) {
   27390 	    vctxt->depth--;
   27391 	    return;
   27392 	} else
   27393 	    vctxt->skipDepth = -1;
   27394     }
   27395     /*
   27396     * SAX VAL TODO: Just a temporary check.
   27397     */
   27398     if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
   27399 	(!xmlStrEqual(vctxt->inode->nsName, URI))) {
   27400 	VERROR_INT("xmlSchemaSAXHandleEndElementNs",
   27401 	    "elem pop mismatch");
   27402     }
   27403     res = xmlSchemaValidatorPopElem(vctxt);
   27404     if (res != 0) {
   27405 	if (res < 0) {
   27406 	    VERROR_INT("xmlSchemaSAXHandleEndElementNs",
   27407 		"calling xmlSchemaValidatorPopElem()");
   27408 	    goto internal_error;
   27409 	}
   27410 	goto exit;
   27411     }
   27412 exit:
   27413     return;
   27414 internal_error:
   27415     vctxt->err = -1;
   27416     xmlStopParser(vctxt->parserCtxt);
   27417     return;
   27418 }
   27419 
   27420 /************************************************************************
   27421  * 									*
   27422  * 			Validation interfaces				*
   27423  * 									*
   27424  ************************************************************************/
   27425 
   27426 /**
   27427  * xmlSchemaNewValidCtxt:
   27428  * @schema:  a precompiled XML Schemas
   27429  *
   27430  * Create an XML Schemas validation context based on the given schema.
   27431  *
   27432  * Returns the validation context or NULL in case of error
   27433  */
   27434 xmlSchemaValidCtxtPtr
   27435 xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
   27436 {
   27437     xmlSchemaValidCtxtPtr ret;
   27438 
   27439     ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
   27440     if (ret == NULL) {
   27441         xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
   27442         return (NULL);
   27443     }
   27444     memset(ret, 0, sizeof(xmlSchemaValidCtxt));
   27445     ret->type = XML_SCHEMA_CTXT_VALIDATOR;
   27446     ret->dict = xmlDictCreate();
   27447     ret->nodeQNames = xmlSchemaItemListCreate();
   27448     ret->schema = schema;
   27449     return (ret);
   27450 }
   27451 
   27452 /**
   27453  * xmlSchemaClearValidCtxt:
   27454  * @ctxt: the schema validation context
   27455  *
   27456  * Free the resources associated to the schema validation context;
   27457  * leaves some fields alive intended for reuse of the context.
   27458  */
   27459 static void
   27460 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
   27461 {
   27462     if (vctxt == NULL)
   27463         return;
   27464 
   27465     /*
   27466     * TODO: Should we clear the flags?
   27467     *   Might be problematic if one reuses the context
   27468     *   and assumes that the options remain the same.
   27469     */
   27470     vctxt->flags = 0;
   27471     vctxt->validationRoot = NULL;
   27472     vctxt->doc = NULL;
   27473 #ifdef LIBXML_READER_ENABLED
   27474     vctxt->reader = NULL;
   27475 #endif
   27476     vctxt->hasKeyrefs = 0;
   27477 
   27478     if (vctxt->value != NULL) {
   27479         xmlSchemaFreeValue(vctxt->value);
   27480 	vctxt->value = NULL;
   27481     }
   27482     /*
   27483     * Augmented IDC information.
   27484     */
   27485     if (vctxt->aidcs != NULL) {
   27486 	xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
   27487 	do {
   27488 	    next = cur->next;
   27489 	    xmlFree(cur);
   27490 	    cur = next;
   27491 	} while (cur != NULL);
   27492 	vctxt->aidcs = NULL;
   27493     }
   27494     if (vctxt->idcMatcherCache != NULL) {
   27495 	xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
   27496 
   27497 	while (matcher) {
   27498 	    tmp = matcher;
   27499 	    matcher = matcher->nextCached;
   27500 	    xmlSchemaIDCFreeMatcherList(tmp);
   27501 	}
   27502 	vctxt->idcMatcherCache = NULL;
   27503     }
   27504 
   27505 
   27506     if (vctxt->idcNodes != NULL) {
   27507 	int i;
   27508 	xmlSchemaPSVIIDCNodePtr item;
   27509 
   27510 	for (i = 0; i < vctxt->nbIdcNodes; i++) {
   27511 	    item = vctxt->idcNodes[i];
   27512 	    xmlFree(item->keys);
   27513 	    xmlFree(item);
   27514 	}
   27515 	xmlFree(vctxt->idcNodes);
   27516 	vctxt->idcNodes = NULL;
   27517 	vctxt->nbIdcNodes = 0;
   27518 	vctxt->sizeIdcNodes = 0;
   27519     }
   27520     /*
   27521     * Note that we won't delete the XPath state pool here.
   27522     */
   27523     if (vctxt->xpathStates != NULL) {
   27524 	xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
   27525 	vctxt->xpathStates = NULL;
   27526     }
   27527     /*
   27528     * Attribute info.
   27529     */
   27530     if (vctxt->nbAttrInfos != 0) {
   27531 	xmlSchemaClearAttrInfos(vctxt);
   27532     }
   27533     /*
   27534     * Element info.
   27535     */
   27536     if (vctxt->elemInfos != NULL) {
   27537 	int i;
   27538 	xmlSchemaNodeInfoPtr ei;
   27539 
   27540 	for (i = 0; i < vctxt->sizeElemInfos; i++) {
   27541 	    ei = vctxt->elemInfos[i];
   27542 	    if (ei == NULL)
   27543 		break;
   27544 	    xmlSchemaClearElemInfo(vctxt, ei);
   27545 	}
   27546     }
   27547     xmlSchemaItemListClear(vctxt->nodeQNames);
   27548     /* Recreate the dict. */
   27549     xmlDictFree(vctxt->dict);
   27550     /*
   27551     * TODO: Is is save to recreate it? Do we have a scenario
   27552     * where the user provides the dict?
   27553     */
   27554     vctxt->dict = xmlDictCreate();
   27555 }
   27556 
   27557 /**
   27558  * xmlSchemaFreeValidCtxt:
   27559  * @ctxt:  the schema validation context
   27560  *
   27561  * Free the resources associated to the schema validation context
   27562  */
   27563 void
   27564 xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
   27565 {
   27566     if (ctxt == NULL)
   27567         return;
   27568     if (ctxt->value != NULL)
   27569         xmlSchemaFreeValue(ctxt->value);
   27570     if (ctxt->pctxt != NULL)
   27571 	xmlSchemaFreeParserCtxt(ctxt->pctxt);
   27572     if (ctxt->idcNodes != NULL) {
   27573 	int i;
   27574 	xmlSchemaPSVIIDCNodePtr item;
   27575 
   27576 	for (i = 0; i < ctxt->nbIdcNodes; i++) {
   27577 	    item = ctxt->idcNodes[i];
   27578 	    xmlFree(item->keys);
   27579 	    xmlFree(item);
   27580 	}
   27581 	xmlFree(ctxt->idcNodes);
   27582     }
   27583     if (ctxt->idcKeys != NULL) {
   27584 	int i;
   27585 	for (i = 0; i < ctxt->nbIdcKeys; i++)
   27586 	    xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
   27587 	xmlFree(ctxt->idcKeys);
   27588     }
   27589 
   27590     if (ctxt->xpathStates != NULL) {
   27591 	xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
   27592 	ctxt->xpathStates = NULL;
   27593     }
   27594     if (ctxt->xpathStatePool != NULL) {
   27595 	xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
   27596 	ctxt->xpathStatePool = NULL;
   27597     }
   27598 
   27599     /*
   27600     * Augmented IDC information.
   27601     */
   27602     if (ctxt->aidcs != NULL) {
   27603 	xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
   27604 	do {
   27605 	    next = cur->next;
   27606 	    xmlFree(cur);
   27607 	    cur = next;
   27608 	} while (cur != NULL);
   27609     }
   27610     if (ctxt->attrInfos != NULL) {
   27611 	int i;
   27612 	xmlSchemaAttrInfoPtr attr;
   27613 
   27614 	/* Just a paranoid call to the cleanup. */
   27615 	if (ctxt->nbAttrInfos != 0)
   27616 	    xmlSchemaClearAttrInfos(ctxt);
   27617 	for (i = 0; i < ctxt->sizeAttrInfos; i++) {
   27618 	    attr = ctxt->attrInfos[i];
   27619 	    xmlFree(attr);
   27620 	}
   27621 	xmlFree(ctxt->attrInfos);
   27622     }
   27623     if (ctxt->elemInfos != NULL) {
   27624 	int i;
   27625 	xmlSchemaNodeInfoPtr ei;
   27626 
   27627 	for (i = 0; i < ctxt->sizeElemInfos; i++) {
   27628 	    ei = ctxt->elemInfos[i];
   27629 	    if (ei == NULL)
   27630 		break;
   27631 	    xmlSchemaClearElemInfo(ctxt, ei);
   27632 	    xmlFree(ei);
   27633 	}
   27634 	xmlFree(ctxt->elemInfos);
   27635     }
   27636     if (ctxt->nodeQNames != NULL)
   27637 	xmlSchemaItemListFree(ctxt->nodeQNames);
   27638     if (ctxt->dict != NULL)
   27639 	xmlDictFree(ctxt->dict);
   27640     xmlFree(ctxt);
   27641 }
   27642 
   27643 /**
   27644  * xmlSchemaIsValid:
   27645  * @ctxt: the schema validation context
   27646  *
   27647  * Check if any error was detected during validation.
   27648  *
   27649  * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
   27650  *         of internal error.
   27651  */
   27652 int
   27653 xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
   27654 {
   27655     if (ctxt == NULL)
   27656         return(-1);
   27657     return(ctxt->err == 0);
   27658 }
   27659 
   27660 /**
   27661  * xmlSchemaSetValidErrors:
   27662  * @ctxt:  a schema validation context
   27663  * @err:  the error function
   27664  * @warn: the warning function
   27665  * @ctx: the functions context
   27666  *
   27667  * Set the error and warning callback informations
   27668  */
   27669 void
   27670 xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
   27671                         xmlSchemaValidityErrorFunc err,
   27672                         xmlSchemaValidityWarningFunc warn, void *ctx)
   27673 {
   27674     if (ctxt == NULL)
   27675         return;
   27676     ctxt->error = err;
   27677     ctxt->warning = warn;
   27678     ctxt->errCtxt = ctx;
   27679     if (ctxt->pctxt != NULL)
   27680 	xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
   27681 }
   27682 
   27683 /**
   27684  * xmlSchemaSetValidStructuredErrors:
   27685  * @ctxt:  a schema validation context
   27686  * @serror:  the structured error function
   27687  * @ctx: the functions context
   27688  *
   27689  * Set the structured error callback
   27690  */
   27691 void
   27692 xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
   27693 				  xmlStructuredErrorFunc serror, void *ctx)
   27694 {
   27695     if (ctxt == NULL)
   27696         return;
   27697 	ctxt->serror = serror;
   27698     ctxt->error = NULL;
   27699     ctxt->warning = NULL;
   27700     ctxt->errCtxt = ctx;
   27701     if (ctxt->pctxt != NULL)
   27702 	xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
   27703 }
   27704 
   27705 /**
   27706  * xmlSchemaGetValidErrors:
   27707  * @ctxt: a XML-Schema validation context
   27708  * @err: the error function result
   27709  * @warn: the warning function result
   27710  * @ctx: the functions context result
   27711  *
   27712  * Get the error and warning callback informations
   27713  *
   27714  * Returns -1 in case of error and 0 otherwise
   27715  */
   27716 int
   27717 xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
   27718 			xmlSchemaValidityErrorFunc * err,
   27719 			xmlSchemaValidityWarningFunc * warn, void **ctx)
   27720 {
   27721 	if (ctxt == NULL)
   27722 		return (-1);
   27723 	if (err != NULL)
   27724 		*err = ctxt->error;
   27725 	if (warn != NULL)
   27726 		*warn = ctxt->warning;
   27727 	if (ctx != NULL)
   27728 		*ctx = ctxt->errCtxt;
   27729 	return (0);
   27730 }
   27731 
   27732 
   27733 /**
   27734  * xmlSchemaSetValidOptions:
   27735  * @ctxt:	a schema validation context
   27736  * @options: a combination of xmlSchemaValidOption
   27737  *
   27738  * Sets the options to be used during the validation.
   27739  *
   27740  * Returns 0 in case of success, -1 in case of an
   27741  * API error.
   27742  */
   27743 int
   27744 xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
   27745 			 int options)
   27746 
   27747 {
   27748     int i;
   27749 
   27750     if (ctxt == NULL)
   27751 	return (-1);
   27752     /*
   27753     * WARNING: Change the start value if adding to the
   27754     * xmlSchemaValidOption.
   27755     * TODO: Is there an other, more easy to maintain,
   27756     * way?
   27757     */
   27758     for (i = 1; i < (int) sizeof(int) * 8; i++) {
   27759         if (options & 1<<i)
   27760 	    return (-1);
   27761     }
   27762     ctxt->options = options;
   27763     return (0);
   27764 }
   27765 
   27766 /**
   27767  * xmlSchemaValidCtxtGetOptions:
   27768  * @ctxt: a schema validation context
   27769  *
   27770  * Get the validation context options.
   27771  *
   27772  * Returns the option combination or -1 on error.
   27773  */
   27774 int
   27775 xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
   27776 
   27777 {
   27778     if (ctxt == NULL)
   27779 	return (-1);
   27780     else
   27781 	return (ctxt->options);
   27782 }
   27783 
   27784 static int
   27785 xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
   27786 {
   27787     xmlAttrPtr attr;
   27788     int ret = 0;
   27789     xmlSchemaNodeInfoPtr ielem = NULL;
   27790     xmlNodePtr node, valRoot;
   27791     const xmlChar *nsName;
   27792 
   27793     /* DOC VAL TODO: Move this to the start function. */
   27794     valRoot = xmlDocGetRootElement(vctxt->doc);
   27795     if (valRoot == NULL) {
   27796 	/* VAL TODO: Error code? */
   27797 	VERROR(1, NULL, "The document has no document element");
   27798 	return (1);
   27799     }
   27800     vctxt->depth = -1;
   27801     vctxt->validationRoot = valRoot;
   27802     node = valRoot;
   27803     while (node != NULL) {
   27804 	if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27805 	    goto next_sibling;
   27806 	if (node->type == XML_ELEMENT_NODE) {
   27807 
   27808 	    /*
   27809 	    * Init the node-info.
   27810 	    */
   27811 	    vctxt->depth++;
   27812 	    if (xmlSchemaValidatorPushElem(vctxt) == -1)
   27813 		goto internal_error;
   27814 	    ielem = vctxt->inode;
   27815 	    ielem->node = node;
   27816 	    ielem->nodeLine = node->line;
   27817 	    ielem->localName = node->name;
   27818 	    if (node->ns != NULL)
   27819 		ielem->nsName = node->ns->href;
   27820 	    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
   27821 	    /*
   27822 	    * Register attributes.
   27823 	    * DOC VAL TODO: We do not register namespace declaration
   27824 	    * attributes yet.
   27825 	    */
   27826 	    vctxt->nbAttrInfos = 0;
   27827 	    if (node->properties != NULL) {
   27828 		attr = node->properties;
   27829 		do {
   27830 		    if (attr->ns != NULL)
   27831 			nsName = attr->ns->href;
   27832 		    else
   27833 			nsName = NULL;
   27834 		    ret = xmlSchemaValidatorPushAttribute(vctxt,
   27835 			(xmlNodePtr) attr,
   27836 			/*
   27837 			* Note that we give it the line number of the
   27838 			* parent element.
   27839 			*/
   27840 			ielem->nodeLine,
   27841 			attr->name, nsName, 0,
   27842 			xmlNodeListGetString(attr->doc, attr->children, 1), 1);
   27843 		    if (ret == -1) {
   27844 			VERROR_INT("xmlSchemaDocWalk",
   27845 			    "calling xmlSchemaValidatorPushAttribute()");
   27846 			goto internal_error;
   27847 		    }
   27848 		    attr = attr->next;
   27849 		} while (attr);
   27850 	    }
   27851 	    /*
   27852 	    * Validate the element.
   27853 	    */
   27854 	    ret = xmlSchemaValidateElem(vctxt);
   27855 	    if (ret != 0) {
   27856 		if (ret == -1) {
   27857 		    VERROR_INT("xmlSchemaDocWalk",
   27858 			"calling xmlSchemaValidateElem()");
   27859 		    goto internal_error;
   27860 		}
   27861 		/*
   27862 		* Don't stop validation; just skip the content
   27863 		* of this element.
   27864 		*/
   27865 		goto leave_node;
   27866 	    }
   27867 	    if ((vctxt->skipDepth != -1) &&
   27868 		(vctxt->depth >= vctxt->skipDepth))
   27869 		goto leave_node;
   27870 	} else if ((node->type == XML_TEXT_NODE) ||
   27871 	    (node->type == XML_CDATA_SECTION_NODE)) {
   27872 	    /*
   27873 	    * Process character content.
   27874 	    */
   27875 	    if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
   27876 		ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
   27877 	    ret = xmlSchemaVPushText(vctxt, node->type, node->content,
   27878 		-1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
   27879 	    if (ret < 0) {
   27880 		VERROR_INT("xmlSchemaVDocWalk",
   27881 		    "calling xmlSchemaVPushText()");
   27882 		goto internal_error;
   27883 	    }
   27884 	    /*
   27885 	    * DOC VAL TODO: Should we skip further validation of the
   27886 	    * element content here?
   27887 	    */
   27888 	} else if ((node->type == XML_ENTITY_NODE) ||
   27889 	    (node->type == XML_ENTITY_REF_NODE)) {
   27890 	    /*
   27891 	    * DOC VAL TODO: What to do with entities?
   27892 	    */
   27893 	    VERROR_INT("xmlSchemaVDocWalk",
   27894 		"there is at least one entity reference in the node-tree "
   27895 		"currently being validated. Processing of entities with "
   27896 		"this XML Schema processor is not supported (yet). Please "
   27897 		"substitute entities before validation.");
   27898 	    goto internal_error;
   27899 	} else {
   27900 	    goto leave_node;
   27901 	    /*
   27902 	    * DOC VAL TODO: XInclude nodes, etc.
   27903 	    */
   27904 	}
   27905 	/*
   27906 	* Walk the doc.
   27907 	*/
   27908 	if (node->children != NULL) {
   27909 	    node = node->children;
   27910 	    continue;
   27911 	}
   27912 leave_node:
   27913 	if (node->type == XML_ELEMENT_NODE) {
   27914 	    /*
   27915 	    * Leaving the scope of an element.
   27916 	    */
   27917 	    if (node != vctxt->inode->node) {
   27918 		VERROR_INT("xmlSchemaVDocWalk",
   27919 		    "element position mismatch");
   27920 		goto internal_error;
   27921 	    }
   27922 	    ret = xmlSchemaValidatorPopElem(vctxt);
   27923 	    if (ret != 0) {
   27924 		if (ret < 0) {
   27925 		    VERROR_INT("xmlSchemaVDocWalk",
   27926 			"calling xmlSchemaValidatorPopElem()");
   27927 		    goto internal_error;
   27928 		}
   27929 	    }
   27930 	    if (node == valRoot)
   27931 		goto exit;
   27932 	}
   27933 next_sibling:
   27934 	if (node->next != NULL)
   27935 	    node = node->next;
   27936 	else {
   27937 	    node = node->parent;
   27938 	    goto leave_node;
   27939 	}
   27940     }
   27941 
   27942 exit:
   27943     return (ret);
   27944 internal_error:
   27945     return (-1);
   27946 }
   27947 
   27948 static int
   27949 xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
   27950     /*
   27951     * Some initialization.
   27952     */
   27953     vctxt->err = 0;
   27954     vctxt->nberrors = 0;
   27955     vctxt->depth = -1;
   27956     vctxt->skipDepth = -1;
   27957     vctxt->xsiAssemble = 0;
   27958     vctxt->hasKeyrefs = 0;
   27959 #ifdef ENABLE_IDC_NODE_TABLES_TEST
   27960     vctxt->createIDCNodeTables = 1;
   27961 #else
   27962     vctxt->createIDCNodeTables = 0;
   27963 #endif
   27964     /*
   27965     * Create a schema + parser if necessary.
   27966     */
   27967     if (vctxt->schema == NULL) {
   27968 	xmlSchemaParserCtxtPtr pctxt;
   27969 
   27970 	vctxt->xsiAssemble = 1;
   27971 	/*
   27972 	* If not schema was given then we will create a schema
   27973 	* dynamically using XSI schema locations.
   27974 	*
   27975 	* Create the schema parser context.
   27976 	*/
   27977 	if ((vctxt->pctxt == NULL) &&
   27978 	   (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
   27979 	   return (-1);
   27980 	pctxt = vctxt->pctxt;
   27981 	pctxt->xsiAssemble = 1;
   27982 	/*
   27983 	* Create the schema.
   27984 	*/
   27985 	vctxt->schema = xmlSchemaNewSchema(pctxt);
   27986 	if (vctxt->schema == NULL)
   27987 	    return (-1);
   27988 	/*
   27989 	* Create the schema construction context.
   27990 	*/
   27991 	pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
   27992 	if (pctxt->constructor == NULL)
   27993 	    return(-1);
   27994 	pctxt->constructor->mainSchema = vctxt->schema;
   27995 	/*
   27996 	* Take ownership of the constructor to be able to free it.
   27997 	*/
   27998 	pctxt->ownsConstructor = 1;
   27999     }
   28000     /*
   28001     * Augment the IDC definitions for the main schema and all imported ones
   28002     * NOTE: main schema if the first in the imported list
   28003     */
   28004     xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
   28005 
   28006     return(0);
   28007 }
   28008 
   28009 static void
   28010 xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
   28011     if (vctxt->xsiAssemble) {
   28012 	if (vctxt->schema != NULL) {
   28013 	    xmlSchemaFree(vctxt->schema);
   28014 	    vctxt->schema = NULL;
   28015 	}
   28016     }
   28017     xmlSchemaClearValidCtxt(vctxt);
   28018 }
   28019 
   28020 static int
   28021 xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
   28022 {
   28023     int ret = 0;
   28024 
   28025     if (xmlSchemaPreRun(vctxt) < 0)
   28026         return(-1);
   28027 
   28028     if (vctxt->doc != NULL) {
   28029 	/*
   28030 	 * Tree validation.
   28031 	 */
   28032 	ret = xmlSchemaVDocWalk(vctxt);
   28033 #ifdef LIBXML_READER_ENABLED
   28034     } else if (vctxt->reader != NULL) {
   28035 	/*
   28036 	 * XML Reader validation.
   28037 	 */
   28038 #ifdef XML_SCHEMA_READER_ENABLED
   28039 	ret = xmlSchemaVReaderWalk(vctxt);
   28040 #endif
   28041 #endif
   28042     } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
   28043 	/*
   28044 	 * SAX validation.
   28045 	 */
   28046 	ret = xmlParseDocument(vctxt->parserCtxt);
   28047     } else {
   28048 	VERROR_INT("xmlSchemaVStart",
   28049 	    "no instance to validate");
   28050 	ret = -1;
   28051     }
   28052 
   28053     xmlSchemaPostRun(vctxt);
   28054     if (ret == 0)
   28055 	ret = vctxt->err;
   28056     return (ret);
   28057 }
   28058 
   28059 /**
   28060  * xmlSchemaValidateOneElement:
   28061  * @ctxt:  a schema validation context
   28062  * @elem:  an element node
   28063  *
   28064  * Validate a branch of a tree, starting with the given @elem.
   28065  *
   28066  * Returns 0 if the element and its subtree is valid, a positive error
   28067  * code number otherwise and -1 in case of an internal or API error.
   28068  */
   28069 int
   28070 xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
   28071 {
   28072     if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
   28073 	return (-1);
   28074 
   28075     if (ctxt->schema == NULL)
   28076 	return (-1);
   28077 
   28078     ctxt->doc = elem->doc;
   28079     ctxt->node = elem;
   28080     ctxt->validationRoot = elem;
   28081     return(xmlSchemaVStart(ctxt));
   28082 }
   28083 
   28084 /**
   28085  * xmlSchemaValidateDoc:
   28086  * @ctxt:  a schema validation context
   28087  * @doc:  a parsed document tree
   28088  *
   28089  * Validate a document tree in memory.
   28090  *
   28091  * Returns 0 if the document is schemas valid, a positive error code
   28092  *     number otherwise and -1 in case of internal or API error.
   28093  */
   28094 int
   28095 xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
   28096 {
   28097     if ((ctxt == NULL) || (doc == NULL))
   28098         return (-1);
   28099 
   28100     ctxt->doc = doc;
   28101     ctxt->node = xmlDocGetRootElement(doc);
   28102     if (ctxt->node == NULL) {
   28103         xmlSchemaCustomErr(ACTXT_CAST ctxt,
   28104 	    XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
   28105 	    (xmlNodePtr) doc, NULL,
   28106 	    "The document has no document element", NULL, NULL);
   28107         return (ctxt->err);
   28108     }
   28109     ctxt->validationRoot = ctxt->node;
   28110     return (xmlSchemaVStart(ctxt));
   28111 }
   28112 
   28113 
   28114 /************************************************************************
   28115  * 									*
   28116  * 		Function and data for SAX streaming API			*
   28117  * 									*
   28118  ************************************************************************/
   28119 typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
   28120 typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
   28121 
   28122 struct _xmlSchemaSplitSAXData {
   28123     xmlSAXHandlerPtr      user_sax;
   28124     void                 *user_data;
   28125     xmlSchemaValidCtxtPtr ctxt;
   28126     xmlSAXHandlerPtr      schemas_sax;
   28127 };
   28128 
   28129 #define XML_SAX_PLUG_MAGIC 0xdc43ba21
   28130 
   28131 struct _xmlSchemaSAXPlug {
   28132     unsigned int magic;
   28133 
   28134     /* the original callbacks informations */
   28135     xmlSAXHandlerPtr     *user_sax_ptr;
   28136     xmlSAXHandlerPtr      user_sax;
   28137     void                **user_data_ptr;
   28138     void                 *user_data;
   28139 
   28140     /* the block plugged back and validation informations */
   28141     xmlSAXHandler         schemas_sax;
   28142     xmlSchemaValidCtxtPtr ctxt;
   28143 };
   28144 
   28145 /* All those functions just bounces to the user provided SAX handlers */
   28146 static void
   28147 internalSubsetSplit(void *ctx, const xmlChar *name,
   28148 	       const xmlChar *ExternalID, const xmlChar *SystemID)
   28149 {
   28150     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28151     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28152         (ctxt->user_sax->internalSubset != NULL))
   28153 	ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
   28154 	                               SystemID);
   28155 }
   28156 
   28157 static int
   28158 isStandaloneSplit(void *ctx)
   28159 {
   28160     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28161     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28162         (ctxt->user_sax->isStandalone != NULL))
   28163 	return(ctxt->user_sax->isStandalone(ctxt->user_data));
   28164     return(0);
   28165 }
   28166 
   28167 static int
   28168 hasInternalSubsetSplit(void *ctx)
   28169 {
   28170     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28171     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28172         (ctxt->user_sax->hasInternalSubset != NULL))
   28173 	return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
   28174     return(0);
   28175 }
   28176 
   28177 static int
   28178 hasExternalSubsetSplit(void *ctx)
   28179 {
   28180     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28181     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28182         (ctxt->user_sax->hasExternalSubset != NULL))
   28183 	return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
   28184     return(0);
   28185 }
   28186 
   28187 static void
   28188 externalSubsetSplit(void *ctx, const xmlChar *name,
   28189 	       const xmlChar *ExternalID, const xmlChar *SystemID)
   28190 {
   28191     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28192     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28193         (ctxt->user_sax->externalSubset != NULL))
   28194 	ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
   28195 	                               SystemID);
   28196 }
   28197 
   28198 static xmlParserInputPtr
   28199 resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
   28200 {
   28201     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28202     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28203         (ctxt->user_sax->resolveEntity != NULL))
   28204 	return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
   28205 	                                     systemId));
   28206     return(NULL);
   28207 }
   28208 
   28209 static xmlEntityPtr
   28210 getEntitySplit(void *ctx, const xmlChar *name)
   28211 {
   28212     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28213     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28214         (ctxt->user_sax->getEntity != NULL))
   28215 	return(ctxt->user_sax->getEntity(ctxt->user_data, name));
   28216     return(NULL);
   28217 }
   28218 
   28219 static xmlEntityPtr
   28220 getParameterEntitySplit(void *ctx, const xmlChar *name)
   28221 {
   28222     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28223     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28224         (ctxt->user_sax->getParameterEntity != NULL))
   28225 	return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
   28226     return(NULL);
   28227 }
   28228 
   28229 
   28230 static void
   28231 entityDeclSplit(void *ctx, const xmlChar *name, int type,
   28232           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
   28233 {
   28234     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28235     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28236         (ctxt->user_sax->entityDecl != NULL))
   28237 	ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
   28238 	                           systemId, content);
   28239 }
   28240 
   28241 static void
   28242 attributeDeclSplit(void *ctx, const xmlChar * elem,
   28243                    const xmlChar * name, int type, int def,
   28244                    const xmlChar * defaultValue, xmlEnumerationPtr tree)
   28245 {
   28246     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28247     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28248         (ctxt->user_sax->attributeDecl != NULL)) {
   28249 	ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
   28250 	                              def, defaultValue, tree);
   28251     } else {
   28252 	xmlFreeEnumeration(tree);
   28253     }
   28254 }
   28255 
   28256 static void
   28257 elementDeclSplit(void *ctx, const xmlChar *name, int type,
   28258 	    xmlElementContentPtr content)
   28259 {
   28260     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28261     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28262         (ctxt->user_sax->elementDecl != NULL))
   28263 	ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
   28264 }
   28265 
   28266 static void
   28267 notationDeclSplit(void *ctx, const xmlChar *name,
   28268 	     const xmlChar *publicId, const xmlChar *systemId)
   28269 {
   28270     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28271     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28272         (ctxt->user_sax->notationDecl != NULL))
   28273 	ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
   28274 	                             systemId);
   28275 }
   28276 
   28277 static void
   28278 unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
   28279 		   const xmlChar *publicId, const xmlChar *systemId,
   28280 		   const xmlChar *notationName)
   28281 {
   28282     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28283     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28284         (ctxt->user_sax->unparsedEntityDecl != NULL))
   28285 	ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
   28286 	                                   systemId, notationName);
   28287 }
   28288 
   28289 static void
   28290 setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
   28291 {
   28292     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28293     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28294         (ctxt->user_sax->setDocumentLocator != NULL))
   28295 	ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
   28296 }
   28297 
   28298 static void
   28299 startDocumentSplit(void *ctx)
   28300 {
   28301     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28302     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28303         (ctxt->user_sax->startDocument != NULL))
   28304 	ctxt->user_sax->startDocument(ctxt->user_data);
   28305 }
   28306 
   28307 static void
   28308 endDocumentSplit(void *ctx)
   28309 {
   28310     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28311     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28312         (ctxt->user_sax->endDocument != NULL))
   28313 	ctxt->user_sax->endDocument(ctxt->user_data);
   28314 }
   28315 
   28316 static void
   28317 processingInstructionSplit(void *ctx, const xmlChar *target,
   28318                       const xmlChar *data)
   28319 {
   28320     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28321     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28322         (ctxt->user_sax->processingInstruction != NULL))
   28323 	ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
   28324 }
   28325 
   28326 static void
   28327 commentSplit(void *ctx, const xmlChar *value)
   28328 {
   28329     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28330     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28331         (ctxt->user_sax->comment != NULL))
   28332 	ctxt->user_sax->comment(ctxt->user_data, value);
   28333 }
   28334 
   28335 /*
   28336  * Varargs error callbacks to the user application, harder ...
   28337  */
   28338 
   28339 static void XMLCDECL
   28340 warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
   28341     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28342     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28343         (ctxt->user_sax->warning != NULL)) {
   28344 	TODO
   28345     }
   28346 }
   28347 static void XMLCDECL
   28348 errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
   28349     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28350     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28351         (ctxt->user_sax->error != NULL)) {
   28352 	TODO
   28353     }
   28354 }
   28355 static void XMLCDECL
   28356 fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
   28357     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28358     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28359         (ctxt->user_sax->fatalError != NULL)) {
   28360 	TODO
   28361     }
   28362 }
   28363 
   28364 /*
   28365  * Those are function where both the user handler and the schemas handler
   28366  * need to be called.
   28367  */
   28368 static void
   28369 charactersSplit(void *ctx, const xmlChar *ch, int len)
   28370 {
   28371     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28372     if (ctxt == NULL)
   28373         return;
   28374     if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
   28375 	ctxt->user_sax->characters(ctxt->user_data, ch, len);
   28376     if (ctxt->ctxt != NULL)
   28377 	xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
   28378 }
   28379 
   28380 static void
   28381 ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
   28382 {
   28383     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28384     if (ctxt == NULL)
   28385         return;
   28386     if ((ctxt->user_sax != NULL) &&
   28387         (ctxt->user_sax->ignorableWhitespace != NULL))
   28388 	ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
   28389     if (ctxt->ctxt != NULL)
   28390 	xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
   28391 }
   28392 
   28393 static void
   28394 cdataBlockSplit(void *ctx, const xmlChar *value, int len)
   28395 {
   28396     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28397     if (ctxt == NULL)
   28398         return;
   28399     if ((ctxt->user_sax != NULL) &&
   28400         (ctxt->user_sax->cdataBlock != NULL))
   28401 	ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
   28402     if (ctxt->ctxt != NULL)
   28403 	xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
   28404 }
   28405 
   28406 static void
   28407 referenceSplit(void *ctx, const xmlChar *name)
   28408 {
   28409     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28410     if (ctxt == NULL)
   28411         return;
   28412     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28413         (ctxt->user_sax->reference != NULL))
   28414 	ctxt->user_sax->reference(ctxt->user_data, name);
   28415     if (ctxt->ctxt != NULL)
   28416         xmlSchemaSAXHandleReference(ctxt->user_data, name);
   28417 }
   28418 
   28419 static void
   28420 startElementNsSplit(void *ctx, const xmlChar * localname,
   28421 		    const xmlChar * prefix, const xmlChar * URI,
   28422 		    int nb_namespaces, const xmlChar ** namespaces,
   28423 		    int nb_attributes, int nb_defaulted,
   28424 		    const xmlChar ** attributes) {
   28425     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28426     if (ctxt == NULL)
   28427         return;
   28428     if ((ctxt->user_sax != NULL) &&
   28429         (ctxt->user_sax->startElementNs != NULL))
   28430 	ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
   28431 	                               URI, nb_namespaces, namespaces,
   28432 				       nb_attributes, nb_defaulted,
   28433 				       attributes);
   28434     if (ctxt->ctxt != NULL)
   28435 	xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
   28436 	                                 URI, nb_namespaces, namespaces,
   28437 					 nb_attributes, nb_defaulted,
   28438 					 attributes);
   28439 }
   28440 
   28441 static void
   28442 endElementNsSplit(void *ctx, const xmlChar * localname,
   28443 		    const xmlChar * prefix, const xmlChar * URI) {
   28444     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28445     if (ctxt == NULL)
   28446         return;
   28447     if ((ctxt->user_sax != NULL) &&
   28448         (ctxt->user_sax->endElementNs != NULL))
   28449 	ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
   28450     if (ctxt->ctxt != NULL)
   28451 	xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
   28452 }
   28453 
   28454 /**
   28455  * xmlSchemaSAXPlug:
   28456  * @ctxt:  a schema validation context
   28457  * @sax:  a pointer to the original xmlSAXHandlerPtr
   28458  * @user_data:  a pointer to the original SAX user data pointer
   28459  *
   28460  * Plug a SAX based validation layer in a SAX parsing event flow.
   28461  * The original @saxptr and @dataptr data are replaced by new pointers
   28462  * but the calls to the original will be maintained.
   28463  *
   28464  * Returns a pointer to a data structure needed to unplug the validation layer
   28465  *         or NULL in case of errors.
   28466  */
   28467 xmlSchemaSAXPlugPtr
   28468 xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
   28469 		 xmlSAXHandlerPtr *sax, void **user_data)
   28470 {
   28471     xmlSchemaSAXPlugPtr ret;
   28472     xmlSAXHandlerPtr old_sax;
   28473 
   28474     if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
   28475         return(NULL);
   28476 
   28477     /*
   28478      * We only allow to plug into SAX2 event streams
   28479      */
   28480     old_sax = *sax;
   28481     if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
   28482         return(NULL);
   28483     if ((old_sax != NULL) &&
   28484         (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
   28485         ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
   28486         return(NULL);
   28487 
   28488     /*
   28489      * everything seems right allocate the local data needed for that layer
   28490      */
   28491     ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
   28492     if (ret == NULL) {
   28493         return(NULL);
   28494     }
   28495     memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
   28496     ret->magic = XML_SAX_PLUG_MAGIC;
   28497     ret->schemas_sax.initialized = XML_SAX2_MAGIC;
   28498     ret->ctxt = ctxt;
   28499     ret->user_sax_ptr = sax;
   28500     ret->user_sax = old_sax;
   28501     if (old_sax == NULL) {
   28502         /*
   28503 	 * go direct, no need for the split block and functions.
   28504 	 */
   28505 	ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
   28506 	ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
   28507 	/*
   28508 	 * Note that we use the same text-function for both, to prevent
   28509 	 * the parser from testing for ignorable whitespace.
   28510 	 */
   28511 	ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
   28512 	ret->schemas_sax.characters = xmlSchemaSAXHandleText;
   28513 
   28514 	ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
   28515 	ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
   28516 
   28517 	ret->user_data = ctxt;
   28518 	*user_data = ctxt;
   28519     } else {
   28520        /*
   28521         * for each callback unused by Schemas initialize it to the Split
   28522 	* routine only if non NULL in the user block, this can speed up
   28523 	* things at the SAX level.
   28524 	*/
   28525         if (old_sax->internalSubset != NULL)
   28526             ret->schemas_sax.internalSubset = internalSubsetSplit;
   28527         if (old_sax->isStandalone != NULL)
   28528             ret->schemas_sax.isStandalone = isStandaloneSplit;
   28529         if (old_sax->hasInternalSubset != NULL)
   28530             ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
   28531         if (old_sax->hasExternalSubset != NULL)
   28532             ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
   28533         if (old_sax->resolveEntity != NULL)
   28534             ret->schemas_sax.resolveEntity = resolveEntitySplit;
   28535         if (old_sax->getEntity != NULL)
   28536             ret->schemas_sax.getEntity = getEntitySplit;
   28537         if (old_sax->entityDecl != NULL)
   28538             ret->schemas_sax.entityDecl = entityDeclSplit;
   28539         if (old_sax->notationDecl != NULL)
   28540             ret->schemas_sax.notationDecl = notationDeclSplit;
   28541         if (old_sax->attributeDecl != NULL)
   28542             ret->schemas_sax.attributeDecl = attributeDeclSplit;
   28543         if (old_sax->elementDecl != NULL)
   28544             ret->schemas_sax.elementDecl = elementDeclSplit;
   28545         if (old_sax->unparsedEntityDecl != NULL)
   28546             ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
   28547         if (old_sax->setDocumentLocator != NULL)
   28548             ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
   28549         if (old_sax->startDocument != NULL)
   28550             ret->schemas_sax.startDocument = startDocumentSplit;
   28551         if (old_sax->endDocument != NULL)
   28552             ret->schemas_sax.endDocument = endDocumentSplit;
   28553         if (old_sax->processingInstruction != NULL)
   28554             ret->schemas_sax.processingInstruction = processingInstructionSplit;
   28555         if (old_sax->comment != NULL)
   28556             ret->schemas_sax.comment = commentSplit;
   28557         if (old_sax->warning != NULL)
   28558             ret->schemas_sax.warning = warningSplit;
   28559         if (old_sax->error != NULL)
   28560             ret->schemas_sax.error = errorSplit;
   28561         if (old_sax->fatalError != NULL)
   28562             ret->schemas_sax.fatalError = fatalErrorSplit;
   28563         if (old_sax->getParameterEntity != NULL)
   28564             ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
   28565         if (old_sax->externalSubset != NULL)
   28566             ret->schemas_sax.externalSubset = externalSubsetSplit;
   28567 
   28568 	/*
   28569 	 * the 6 schemas callback have to go to the splitter functions
   28570 	 * Note that we use the same text-function for ignorableWhitespace
   28571 	 * if possible, to prevent the parser from testing for ignorable
   28572 	 * whitespace.
   28573 	 */
   28574         ret->schemas_sax.characters = charactersSplit;
   28575 	if ((old_sax->ignorableWhitespace != NULL) &&
   28576 	    (old_sax->ignorableWhitespace != old_sax->characters))
   28577 	    ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
   28578 	else
   28579 	    ret->schemas_sax.ignorableWhitespace = charactersSplit;
   28580         ret->schemas_sax.cdataBlock = cdataBlockSplit;
   28581         ret->schemas_sax.reference = referenceSplit;
   28582         ret->schemas_sax.startElementNs = startElementNsSplit;
   28583         ret->schemas_sax.endElementNs = endElementNsSplit;
   28584 
   28585 	ret->user_data_ptr = user_data;
   28586 	ret->user_data = *user_data;
   28587 	*user_data = ret;
   28588     }
   28589 
   28590     /*
   28591      * plug the pointers back.
   28592      */
   28593     *sax = &(ret->schemas_sax);
   28594     ctxt->sax = *sax;
   28595     ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
   28596     xmlSchemaPreRun(ctxt);
   28597     return(ret);
   28598 }
   28599 
   28600 /**
   28601  * xmlSchemaSAXUnplug:
   28602  * @plug:  a data structure returned by xmlSchemaSAXPlug
   28603  *
   28604  * Unplug a SAX based validation layer in a SAX parsing event flow.
   28605  * The original pointers used in the call are restored.
   28606  *
   28607  * Returns 0 in case of success and -1 in case of failure.
   28608  */
   28609 int
   28610 xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
   28611 {
   28612     xmlSAXHandlerPtr *sax;
   28613     void **user_data;
   28614 
   28615     if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
   28616         return(-1);
   28617     plug->magic = 0;
   28618 
   28619     xmlSchemaPostRun(plug->ctxt);
   28620     /* restore the data */
   28621     sax = plug->user_sax_ptr;
   28622     *sax = plug->user_sax;
   28623     if (plug->user_sax != NULL) {
   28624 	user_data = plug->user_data_ptr;
   28625 	*user_data = plug->user_data;
   28626     }
   28627 
   28628     /* free and return */
   28629     xmlFree(plug);
   28630     return(0);
   28631 }
   28632 
   28633 /**
   28634  * xmlSchemaValidateStream:
   28635  * @ctxt:  a schema validation context
   28636  * @input:  the input to use for reading the data
   28637  * @enc:  an optional encoding information
   28638  * @sax:  a SAX handler for the resulting events
   28639  * @user_data:  the context to provide to the SAX handler.
   28640  *
   28641  * Validate an input based on a flow of SAX event from the parser
   28642  * and forward the events to the @sax handler with the provided @user_data
   28643  * the user provided @sax handler must be a SAX2 one.
   28644  *
   28645  * Returns 0 if the document is schemas valid, a positive error code
   28646  *     number otherwise and -1 in case of internal or API error.
   28647  */
   28648 int
   28649 xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
   28650                         xmlParserInputBufferPtr input, xmlCharEncoding enc,
   28651                         xmlSAXHandlerPtr sax, void *user_data)
   28652 {
   28653     xmlSchemaSAXPlugPtr plug = NULL;
   28654     xmlSAXHandlerPtr old_sax = NULL;
   28655     xmlParserCtxtPtr pctxt = NULL;
   28656     xmlParserInputPtr inputStream = NULL;
   28657     int ret;
   28658 
   28659     if ((ctxt == NULL) || (input == NULL))
   28660         return (-1);
   28661 
   28662     /*
   28663      * prepare the parser
   28664      */
   28665     pctxt = xmlNewParserCtxt();
   28666     if (pctxt == NULL)
   28667         return (-1);
   28668     old_sax = pctxt->sax;
   28669     pctxt->sax = sax;
   28670     pctxt->userData = user_data;
   28671 #if 0
   28672     if (options)
   28673         xmlCtxtUseOptions(pctxt, options);
   28674 #endif
   28675     pctxt->linenumbers = 1;
   28676 
   28677     inputStream = xmlNewIOInputStream(pctxt, input, enc);;
   28678     if (inputStream == NULL) {
   28679         ret = -1;
   28680 	goto done;
   28681     }
   28682     inputPush(pctxt, inputStream);
   28683     ctxt->parserCtxt = pctxt;
   28684     ctxt->input = input;
   28685 
   28686     /*
   28687      * Plug the validation and launch the parsing
   28688      */
   28689     plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
   28690     if (plug == NULL) {
   28691         ret = -1;
   28692 	goto done;
   28693     }
   28694     ctxt->input = input;
   28695     ctxt->enc = enc;
   28696     ctxt->sax = pctxt->sax;
   28697     ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
   28698     ret = xmlSchemaVStart(ctxt);
   28699 
   28700     if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
   28701 	ret = ctxt->parserCtxt->errNo;
   28702 	if (ret == 0)
   28703 	    ret = 1;
   28704     }
   28705 
   28706 done:
   28707     ctxt->parserCtxt = NULL;
   28708     ctxt->sax = NULL;
   28709     ctxt->input = NULL;
   28710     if (plug != NULL) {
   28711         xmlSchemaSAXUnplug(plug);
   28712     }
   28713     /* cleanup */
   28714     if (pctxt != NULL) {
   28715 	pctxt->sax = old_sax;
   28716 	xmlFreeParserCtxt(pctxt);
   28717     }
   28718     return (ret);
   28719 }
   28720 
   28721 /**
   28722  * xmlSchemaValidateFile:
   28723  * @ctxt: a schema validation context
   28724  * @filename: the URI of the instance
   28725  * @options: a future set of options, currently unused
   28726  *
   28727  * Do a schemas validation of the given resource, it will use the
   28728  * SAX streamable validation internally.
   28729  *
   28730  * Returns 0 if the document is valid, a positive error code
   28731  *     number otherwise and -1 in case of an internal or API error.
   28732  */
   28733 int
   28734 xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
   28735                       const char * filename,
   28736 		      int options ATTRIBUTE_UNUSED)
   28737 {
   28738     int ret;
   28739     xmlParserInputBufferPtr input;
   28740 
   28741     if ((ctxt == NULL) || (filename == NULL))
   28742         return (-1);
   28743 
   28744     input = xmlParserInputBufferCreateFilename(filename,
   28745 	XML_CHAR_ENCODING_NONE);
   28746     if (input == NULL)
   28747 	return (-1);
   28748     ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
   28749 	NULL, NULL);
   28750     return (ret);
   28751 }
   28752 
   28753 /**
   28754  * xmlSchemaValidCtxtGetParserCtxt:
   28755  * @ctxt: a schema validation context
   28756  *
   28757  * allow access to the parser context of the schema validation context
   28758  *
   28759  * Returns the parser context of the schema validation context or NULL
   28760  *         in case of error.
   28761  */
   28762 xmlParserCtxtPtr
   28763 xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
   28764 {
   28765     if (ctxt == NULL)
   28766         return(NULL);
   28767     return (ctxt->parserCtxt);
   28768 }
   28769 
   28770 #define bottom_xmlschemas
   28771 #include "elfgcchack.h"
   28772 #endif /* LIBXML_SCHEMAS_ENABLED */
   28773